c_icare_sipcall 0.0.9 copy "c_icare_sipcall: ^0.0.9" to clipboard
c_icare_sipcall: ^0.0.9 copied to clipboard

A Flutter package for SIP calling using WebRTC and sip_ua.

c_icare_sipcall - Flutter SIP Call SDK #

c_icare_sipcall adalah SDK Flutter untuk melakukan panggilan SIP berbasis VoIP. SDK ini dibangun di atas sip_ua dan dibungkus ulang agar lebih mudah digunakan untuk pemula. Cocok untuk aplikasi seperti call center, customer service, atau aplikasi internal perusahaan.


1. Instalasi #

Tambahkan package ini ke dalam pubspec.yaml:

dependencies:
  flutter:
    sdk: flutter
  c_icare_sipcall: ^1.0.0 # Ganti dengan versi terbaru

Lalu jalankan:

flutter pub get

2. Konfigurasi Android #

Tambahkan permission berikut ke file android/app/src/main/AndroidManifest.xml:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.CAMERA" />

3. Import Package #

import 'package:c_icare_sipcall/c_icare_sipcall.dart';

🧩 Komponen Utama #

CicareSipcall #

  • Registrasi dan unregistrasi akun SIP
  • Melakukan panggilan keluar dan menerima panggilan
  • Event listener: status registrasi, status panggilan, dan panggilan masuk

Call #

  • Objek panggilan (incoming/outgoing)
  • Dapat digunakan untuk accept(), hangup(), dan reject()

Fitur Utama #

Registrasi SIP #

final sipCall = CicareSipcall(
  exten: 'your-extension',
  password: 'your-password',
  displayName: 'C-Icare.cc',
  realm: 'your-domain',
);

await sipCall.requestPermissions();
await sipCall.register();

Event perubahan status registrasi:

sipCall.onRegistrationStateChanged = (RegistrationState state) {
  print('Status: ${state.state}');
};

Panggilan Masuk #

sipCall.onIncomingCall = (Call call) {
  // Tampilkan UI menerima atau menolak
};

Panggilan Keluar #

sipCall.call('1002'); // Ganti dengan nomor tujuan

Mengakhiri Panggilan #

sipCall.hangup(call);

Lifecycle #

Jangan lupa membersihkan resource:

@override
void dispose() {
  _extendController.dispose();
  _passwordController.dispose();
  sip?.unregister();
  super.dispose();
}

Validasi #

  • Field yang divalidasi: extension, password
  • Nomor tujuan hanya divalidasi saat ingin melakukan panggilan

UI Utama (Komponen) #

Komponen Fungsi
TextFormField Input extension dan password
Button "Register SIP" Memulai proses registrasi
TextFormField Nomor tujuan panggilan
Button "Call" Memulai panggilan SIP
Incoming Call UI Tampilkan tombol "Terima" dan "Tolak"

Konfigurasi Default #

  • Domain: demo.c-icare.cc
  • Display name: Agent <extension>
  • Tombol panggilan tidak aktif jika belum register
  • Status ditampilkan secara real-time di UI & debug console

Contoh penggunaan #

Dukungan #

import 'package:flutter/material.dart';
import 'package:c_icare_sipcall/c_icare_sipcall.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Cicare SIP Demo',
      theme: ThemeData(primarySwatch: Colors.blue),
      home: SipHomePage(),
    );
  }
}

class SipHomePage extends StatefulWidget {
  const SipHomePage({super.key});

  @override
  SipHomePageState createState() => SipHomePageState();
}

class SipHomePageState extends State<SipHomePage> {
  final _formKey = GlobalKey<FormState>();
  final _extendController = TextEditingController();
  final _passwordController = TextEditingController();
  final _numberController = TextEditingController();
  String _statusMessage = 'Not connected';
  String targetNumber = '';
  bool _isConnected = false;

  CicareSipcall? sip;
  Call? incomingCall;

  @override
  void dispose() {
    _extendController.dispose();
    _passwordController.dispose();
    sip?.unregister();
    super.dispose();
  }

  void _registerSip() async {
    print(" Tombol Register SIP ditekan");

    if (_formKey.currentState!.validate()) {
      FocusScope.of(context).unfocus();

      final extend = _extendController.text;
      final password = _passwordController.text;

      final sipCall = CicareSipcall(
        exten: extend,
        password: password,
        displayName: 'Agent $extend',
        realm: 'demo.c-icare.cc',
      );

      sipCall.onRegistrationStateChanged = (RegistrationState state) {
        setState(() {
          _statusMessage = ' ${state.state.toString()}';
        });
        print(" Registration State: ${state.state}");
      };

      sipCall.onIncomingCall = (Call call) {
        setState(() {
          incomingCall = call;
          _statusMessage = ' Incoming call from $call';
        });
        print(" Incoming call from $call");
      };

      sipCall.onCallStateChanged = (Call call, CallState state) {
        setState(() {
          _statusMessage = ' Call state: $state';
        });
        print("Call state: ${state.state}");
        if (state.state == CallStateEnum.ENDED ||
            state.state == CallStateEnum.FAILED) {
          incomingCall = null;
        }
      };

      await sipCall.requestPermissions();
      await sipCall.register();

      setState(() {
        sip = sipCall;
        _isConnected = true;
        _statusMessage = ' Registered as $extend';
      });

      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(' SIP Registered as $extend')),
      );
    } else {
      print(' Form tidak valid');
      ScaffoldMessenger.of(context).showSnackBar(
        SnackBar(content: Text(' Mohon isi semua form yang dibutuhkan')),
      );
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Cicare SIP Demo'),
      ),
      body: SingleChildScrollView(
        padding: EdgeInsets.all(16.0),
        child: Form(
            key: _formKey,
            child: Column(
              children: [
                Text(
                  "Status: $_statusMessage",
                  style: const TextStyle(fontSize: 18),
                ),
                const SizedBox(height: 16.0),
                TextFormField(
                  controller: _extendController,
                  decoration: InputDecoration(
                    labelText: 'Extension',
                    border: OutlineInputBorder(),
                  ),
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Mohon isi extension';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 16.0),
                TextFormField(
                  controller: _passwordController,
                  decoration: InputDecoration(
                    labelText: 'Password',
                    border: OutlineInputBorder(),
                  ),
                  obscureText: true,
                  validator: (value) {
                    if (value == null || value.isEmpty) {
                      return 'Mohon isi password';
                    }
                    return null;
                  },
                ),
                const SizedBox(height: 10.0),
                ElevatedButton(
                  onPressed: _registerSip,
                  child: Text(_isConnected ? ' Registered' : ' Register SIP'),
                ),
                const SizedBox(height: 16.0),
                TextFormField(
                  decoration: InputDecoration(
                    labelText: 'Target Number',
                    border: OutlineInputBorder(),
                  ),
                  controller: _numberController,
                  // onChanged: (value) => targetNumber = value,
                ),
                const SizedBox(height: 16.0),
                ElevatedButton(
                  onPressed: () {
                    if (!_isConnected || sip == null) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(
                            content: Text(
                                ' Anda belum terhubung. Silakan register dulu.')),
                      );
                      return;
                    }

                    final number = _numberController.text.trim();
                    if (number.isEmpty) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        SnackBar(content: Text(' Masukkan nomor tujuan')),
                      );
                      return;
                    }

                    setState(() {
                      targetNumber = number;
                    });

                    sip?.call(targetNumber);
                  },
                  child: Text('Call $targetNumber'),
                ),
                const SizedBox(height: 20.0),
                if (incomingCall != null) ...[
                  Text(
                      " Panggilan dari: ${incomingCall ?? 'Tidak diketahui'}"),
                  Row(
                    mainAxisAlignment: MainAxisAlignment.spaceAround,
                    children: [
                      ElevatedButton(
                        onPressed: () => sip!.accept(incomingCall!),
                        style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.green),
                        child: const Text("Terima"),
                      ),
                      ElevatedButton(
                        onPressed: () => sip!.hangup(incomingCall!),
                        style: ElevatedButton.styleFrom(
                            backgroundColor: Colors.red),
                        child: const Text("Tolak"),
                      ),
                    ],
                  ),
                ],
              ],
            )),
      ),
    );
  }
}

Jika kamu mengalami kendala, silakan buat issue di GitHub repo atau hubungi tim pengembang.

0
likes
135
points
59
downloads

Publisher

unverified uploader

Weekly Downloads

A Flutter package for SIP calling using WebRTC and sip_ua.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter, flutter_webrtc, permission_handler, sip_ua

More

Packages that depend on c_icare_sipcall