ภาพรวมโปรโตคอลการเริ่มต้นเซสชัน

ตรวจหา eSIM และซิมการ์ด

กำลังตรวจหาบัตร

อุปกรณ์ Android ที่มีซิมการ์ดและ eSIM ใช้รหัสต่อไปนี้ในโทรศัพท์ API ได้แก่ [`TelephonyManager`](/reference/android/telephony/TelephonyManager) และ ["SubscriptionManager"](/reference/android/telephony/SubscriptionManager): * รหัสการสมัครใช้บริการ: รหัสที่ไม่ซ้ำกันสำหรับการสมัครใช้บริการในอุปกรณ์เคลื่อนที่ * ดัชนีช่องลอจิคัลหรือรหัส: ดัชนีที่ไม่ซ้ำกันซึ่งอ้างอิงถึงช่องซิมเชิงตรรกะ รหัสช่องโฆษณาแบบตรรกะเริ่มต้นที่ 0 และเพิ่มขึ้นขึ้นอยู่กับจำนวนของ สล็อตที่ใช้งานอยู่ที่รองรับในอุปกรณ์ เช่น ปกติแล้วอุปกรณ์แบบ 2 ซิม มีช่อง 0 และช่อง 1 หากอุปกรณ์มีช่องเสียบอุปกรณ์หลายช่อง แต่มีเพียง รองรับสล็อตแอ็กทีฟหนึ่งช่อง ซึ่งจะมีเฉพาะรหัสสล็อตลอจิคัล 0 เท่านั้น * ดัชนีช่องจริงหรือรหัส: ดัชนีที่ไม่ซ้ำกันซึ่งอ้างอิงถึงช่องซิมจริง รหัสช่องจริงเริ่มต้นที่ 0 และเพิ่มขึ้นขึ้นอยู่กับจำนวนจริง บนอุปกรณ์ ซึ่งแตกต่างจากจำนวนสล็อตตรรกะที่อุปกรณ์หนึ่ง ซึ่งสอดคล้องกับจำนวนช่องที่ใช้งานอยู่ซึ่งอุปกรณ์รองรับได้ ด้วย ตัวอย่างเช่น อุปกรณ์ที่สลับระหว่างแบบ 2 ซิมและซิมเดียว โหมดอาจมีช่องจริง 2 ช่องเสมอ แต่ในโหมดซิมเดียว สล็อตลอจิคัลเดียวเท่านั้น * รหัสการ์ด: รหัสที่ไม่ซ้ำกันซึ่งใช้ในการระบุ UiccCard ![แผนภาพการใช้รหัสในกรณีที่มีสล็อตเชิงตรรกะ 2 สล็อตและช่องจริง 3 สล็อต](/images/guide/topics/connectivity/tel-ids.png) ในแผนภาพด้านบน * อุปกรณ์มีสล็อตเชิงตรรกะ 2 ช่อง * ในช่องจริง 0 จะมีการ์ด UICC จริงที่มีโปรไฟล์ที่ใช้งานอยู่ * ในช่องจริง 2 คือ eUICC ที่มีโปรไฟล์ที่ใช้งานอยู่ * ช่องจริง 1 ไม่มีการใช้งานในขณะนี้ ![แผนภาพการใช้รหัสในกรณีที่มีสล็อตเชิงตรรกะ 3 สล็อตและช่องจริง 2 สล็อต](/images/guide/topics/connectivity/tel-ids-2.png) ในแผนภาพด้านบน * อุปกรณ์มีสล็อตเชิงตรรกะ 3 สล็อต * ในช่องจริง 0 จะมีการ์ด UICC จริงที่มีโปรไฟล์ที่ใช้งานอยู่ * ในช่องจริง 1 คือ eUICC ที่มีโปรไฟล์ที่ดาวน์โหลด 2 โปรไฟล์ ทั้งคู่มีการใช้งานโดยใช้ MEP (โปรไฟล์ที่เปิดใช้หลายรายการ)

ภาพรวมโปรโตคอลการเริ่มต้นเซสชัน

Android มี API ที่รองรับโปรโตคอลการเริ่มต้นเซสชัน (SIP) ซึ่งจะช่วยให้คุณเพิ่มฟีเจอร์โทรศัพท์ทางอินเทอร์เน็ตผ่าน SIP ลงในแอปพลิเคชันได้ Android มีสแต็กโปรโตคอล SIP เต็มรูปแบบและการจัดการการโทรแบบผสานรวม บริการที่ช่วยให้แอปพลิเคชันตั้งค่าสายโทรออกและโทรเข้าได้อย่างง่ายดาย โดยไม่ต้องจัดการเซสชัน การสื่อสารระดับการขนส่ง หรือเสียง บันทึกหรือเล่นได้โดยตรง

ต่อไปนี้คือตัวอย่างประเภทแอปพลิเคชันที่อาจใช้ SIP API

  • การประชุมทางวิดีโอ
  • การส่งข้อความทันที

ข้อกำหนดและข้อจำกัด

ข้อกำหนดสำหรับการพัฒนาแอปพลิเคชัน SIP มีดังนี้

  • คุณต้องมีอุปกรณ์เคลื่อนที่ที่ใช้ Android 2.3 ขึ้นไป
  • SIP จะทำงานผ่านการเชื่อมต่อข้อมูลแบบไร้สาย อุปกรณ์ของคุณจึงต้องมีอินเทอร์เน็ตมือถือ (กับบริการอินเทอร์เน็ตมือถือหรือ Wi-Fi) ซึ่งหมายความว่าคุณ ทดสอบใน AVD ไม่ได้ โดยจะทดสอบได้ในอุปกรณ์จริงเท่านั้น โปรดดูรายละเอียดที่หัวข้อ การทดสอบแอปพลิเคชัน SIP
  • ผู้เข้าร่วมเซสชันการสื่อสารของแอปพลิเคชันแต่ละคนต้องมี บัญชี SIP มีผู้ให้บริการ SIP หลายรายที่ให้บริการบัญชี SIP

หมายเหตุ: ไลบรารี android.net.sip ไม่รองรับวิดีโอ หากต้องการใช้การโทร VOIP โดยใช้สแต็ก SIP เช่น android.net.sip ลองดูหนึ่งในโอเพนซอร์สสมัยใหม่ต่างๆ ทางเลือกเป็นพื้นฐานสําหรับการโทร VOIP หรือ คุณสามารถใช้ ConnectionService API เพื่อมอบการผสานรวมการโทรเหล่านี้ลงในแป้นโทรศัพท์ของอุปกรณ์อย่างสมบูรณ์ แอป

คลาสและอินเทอร์เฟซ SIP API

นี่คือข้อมูลสรุปชั้นเรียนและอินเทอร์เฟซ 1 รายการ (SipRegistrationListener) ที่รวมอยู่ใน Android SIP API:

คลาส/อินเทอร์เฟซ คำอธิบาย
SipAudioCall จัดการการโทรด้วยเสียงผ่านอินเทอร์เน็ตผ่าน SIP
SipAudioCall.Listener Listener เหตุการณ์ที่เกี่ยวข้องกับการโทร SIP เช่น เมื่อมีการโทรออก ที่ได้รับ ("ขณะส่งเสียง") หรือมีการโทรออก ("ขณะโทร")
SipErrorCode กำหนดรหัสข้อผิดพลาดที่แสดงระหว่างการดำเนินการ SIP
SipManager มี API สำหรับงาน SIP เช่น การเริ่มต้นการเชื่อมต่อ SIP และให้สิทธิ์เข้าถึง กับบริการ SIP ที่เกี่ยวข้อง
SipProfile กำหนดโปรไฟล์ SIP รวมถึงบัญชี SIP, ข้อมูลโดเมน และเซิร์ฟเวอร์
SipProfile.Builder ชั้นเรียน Helper สำหรับการสร้าง SipProfile
SipSession แสดงเซสชัน SIP ที่เชื่อมโยงกับกล่องโต้ตอบ SIP หรือธุรกรรมแบบสแตนด์อโลน ไม่อยู่ในกล่องโต้ตอบ
SipSession.Listener Listener เหตุการณ์ที่เกี่ยวข้องกับเซสชัน SIP เช่น เมื่อมีการลงทะเบียนเซสชัน ("ขณะลงทะเบียน") หรือมีการโทรออก ("ขณะลงทะเบียน")
SipSession.State กำหนดสถานะเซสชัน SIP เช่น "ลงทะเบียน" "โทรออก" และ "อยู่ในสาย"
SipRegistrationListener อินเทอร์เฟซที่ Listener สำหรับกิจกรรมการลงทะเบียน SIP

กำลังสร้างไฟล์ Manifest

หากคุณกำลังพัฒนาแอปพลิเคชันที่ใช้ SIP API โปรดทราบว่า คุณลักษณะนี้ได้รับการสนับสนุนเฉพาะใน Android 2.3 (API ระดับ 9) และเวอร์ชันที่สูงกว่า แพลตฟอร์ม นอกจากนี้ ในอุปกรณ์ที่ใช้ Android 2.3 (API ระดับ 9) ขึ้นไป อุปกรณ์บางประเภทไม่รองรับ SIP

หากต้องการใช้ SIP ให้เพิ่มสิทธิ์ต่อไปนี้ในไฟล์ Manifest ของแอปพลิเคชัน

  • android.permission.USE_SIP
  • android.permission.INTERNET

เพื่อให้มั่นใจว่าแอปพลิเคชันของคุณสามารถติดตั้งได้เฉพาะในอุปกรณ์ที่ สามารถรองรับ SIP โปรดเพิ่มสิ่งต่อไปนี้ลงในแอปพลิเคชัน ไฟล์ Manifest:

<uses-sdk android:minSdkVersion="9" />

ข้อความนี้ระบุว่าแอปพลิเคชันของคุณต้องการ Android 2.3 ขึ้นไป สำหรับ ข้อมูลเพิ่มเติม โปรดดู ระดับ API และเอกสารประกอบสำหรับ <uses-sdk>

การควบคุมวิธีการกรองแอปพลิเคชันออกจากอุปกรณ์ที่ไม่รองรับ SIP (เช่น ใน Google Play) ให้เพิ่มการตั้งค่าต่อไปนี้ลงใน ไฟล์ Manifest:

<uses-feature android:name="android.software.sip.voip" />

ข้อความนี้ระบุว่าแอปพลิเคชันของคุณใช้ SIP API การประกาศควร มีแอตทริบิวต์ android:required ที่ระบุว่าคุณ ต้องการให้กรองแอปพลิเคชันออกจากอุปกรณ์ที่ไม่รองรับ SIP อาจต้องประกาศ<uses-feature>อื่นๆ ด้วย โดยขึ้นอยู่กับการติดตั้งใช้งาน สำหรับข้อมูลเพิ่มเติม โปรดดูเอกสารประกอบ สำหรับ <uses-feature>

หากแอปพลิเคชันของคุณออกแบบมาเพื่อรับสาย คุณต้องกำหนดตัวรับ (BroadcastReceiver คลาสย่อย) ในไฟล์ Manifest ของแอปพลิเคชันด้วย

<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />

ข้อความที่ตัดตอนมาจากไฟล์ Manifest SipDemo มีดังนี้

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
          package="com.example.android.sip">
  ...
     <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
  ...
  <uses-sdk android:minSdkVersion="9" />
  <uses-permission android:name="android.permission.USE_SIP" />
  <uses-permission android:name="android.permission.INTERNET" />
  ...
  <uses-feature android:name="android.software.sip.voip" android:required="true" />
  <uses-feature android:name="android.hardware.wifi" android:required="true" />
  <uses-feature android:name="android.hardware.microphone" android:required="true" />
</manifest>

การสร้าง SipManager

หากต้องการใช้ SIP API แอปพลิเคชันของคุณต้องสร้างออบเจ็กต์ SipManager SipManager ใช้เวลา ดูแลสิ่งต่อไปนี้ในแอปพลิเคชันของคุณ

  • กำลังเริ่มเซสชัน SIP
  • กำลังเริ่มต้นและรับสาย
  • กำลังลงทะเบียนและยกเลิกการลงทะเบียนกับผู้ให้บริการ SIP
  • กำลังยืนยันการเชื่อมต่อเซสชัน

คุณจะสร้างอินสแตนซ์ SipManager ใหม่ดังนี้

Kotlin

val sipManager: SipManager? by lazy(LazyThreadSafetyMode.NONE) {
    SipManager.newInstance(this)
}

Java

public SipManager sipManager = null;
...
if (sipManager == null) {
    sipManager = SipManager.newInstance(this);
}

การลงทะเบียนด้วยเซิร์ฟเวอร์ SIP

แอปพลิเคชัน SIP ของ Android ทั่วไปจะมีผู้ใช้อย่างน้อย 1 คน โดยแต่ละคน มีบัญชี SIP ในแอปพลิเคชัน SIP ของ Android บัญชี SIP แต่ละบัญชี แสดงด้วยออบเจ็กต์ SipProfile

SipProfile กำหนดโปรไฟล์ SIP รวมถึง SIP บัญชี และข้อมูลโดเมนและเซิร์ฟเวอร์ โปรไฟล์ที่เชื่อมโยงกับ SIP บนอุปกรณ์ที่เรียกใช้แอปพลิเคชันจะเรียกว่า โปรไฟล์ โปรไฟล์ที่เซสชันเชื่อมต่ออยู่จะเรียกว่า โปรไฟล์แอปเทียบเท่า เมื่อแอปพลิเคชัน SIP เข้าสู่ระบบเซิร์ฟเวอร์ SIP ด้วย SipProfile ซึ่งเป็นการลงทะเบียน อุปกรณ์เป็นตำแหน่งที่จะส่งสาย SIP ไปให้สำหรับที่อยู่ SIP

ส่วนนี้จะแสดงวิธีสร้าง SipProfile ลงทะเบียนด้วยเซิร์ฟเวอร์ SIP และติดตามกิจกรรมการลงทะเบียน

คุณสร้างออบเจ็กต์ SipProfile ได้ดังนี้

Kotlin

private var sipProfile: SipProfile? = null
...

val builder = SipProfile.Builder(username, domain)
        .setPassword(password)
sipProfile = builder.build()

Java

public SipProfile sipProfile = null;
...

SipProfile.Builder builder = new SipProfile.Builder(username, domain);
builder.setPassword(password);
sipProfile = builder.build();

ข้อความโค้ดที่ตัดตอนมาต่อไปนี้จะเปิดโปรไฟล์ในเครื่องสำหรับการโทรและ/หรือ รับสาย SIP ทั่วไป ผู้โทรจะโทรออกครั้งต่อๆ ไปได้ผ่านทาง mSipManager.makeAudioCall ข้อความที่ตัดตอนมานี้จะกำหนดการดำเนินการ android.SipDemo.INCOMING_CALL ซึ่งจะใช้โดย Intent กรองเมื่ออุปกรณ์ได้รับสาย (โปรดดูการตั้งค่า ตัวกรอง Intent เพื่อรับสาย) ขั้นตอนการลงทะเบียนมีดังนี้

Kotlin

val intent = Intent("android.SipDemo.INCOMING_CALL")
val pendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA)
sipManager?.open(sipProfile, pendingIntent, null)

Java

Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
sipManager.open(sipProfile, pendingIntent, null);

สุดท้าย โค้ดนี้จะตั้งค่า SipRegistrationListener ใน SipManager การติดตามข้อมูลนี้จะติดตามการลงทะเบียน SipProfile กับบริการ SIP ของคุณเรียบร้อยแล้วหรือไม่ ผู้ให้บริการ:

Kotlin

sipManager?.setRegistrationListener(sipProfile?.uriString, object : SipRegistrationListener {

    override fun onRegistering(localProfileUri: String) {
        updateStatus("Registering with SIP Server...")
    }

    override fun onRegistrationDone(localProfileUri: String, expiryTime: Long) {
        updateStatus("Ready")
    }

    override fun onRegistrationFailed(
            localProfileUri: String,
            errorCode: Int,
            errorMessage: String
    ) {
        updateStatus("Registration failed. Please check settings.")
    }
})

Java

sipManager.setRegistrationListener(sipProfile.getUriString(), new SipRegistrationListener() {

    public void onRegistering(String localProfileUri) {
        updateStatus("Registering with SIP Server...");
    }

    public void onRegistrationDone(String localProfileUri, long expiryTime) {
        updateStatus("Ready");
    }

    public void onRegistrationFailed(String localProfileUri, int errorCode,
        String errorMessage) {
        updateStatus("Registration failed.  Please check settings.");
    }
}

เมื่อแอปพลิเคชันใช้โปรไฟล์เสร็จสิ้น โปรไฟล์ควรจะปิดโปรไฟล์นั้นเป็นแบบฟรี ออบเจ็กต์ที่เชื่อมโยงลงในหน่วยความจำและยกเลิกการลงทะเบียนอุปกรณ์จากเซิร์ฟเวอร์ สำหรับ ตัวอย่าง:

Kotlin

fun closeLocalProfile() {
    try {
        sipManager?.close(sipProfile?.uriString)
    } catch (ee: Exception) {
        Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee)
    }
}

Java

public void closeLocalProfile() {
    if (sipManager == null) {
       return;
    }
    try {
       if (sipProfile != null) {
          sipManager.close(sipProfile.getUriString());
       }
     } catch (Exception ee) {
       Log.d("WalkieTalkieActivity/onDestroy", "Failed to close local profile.", ee);
     }
}

กำลังโทรด้วยเสียง

หากต้องการโทรด้วยเสียง คุณต้องมีสิ่งต่อไปนี้

  • SipProfile ที่จะทำการโทร (การเรียก "local profile") และที่อยู่ SIP ที่ถูกต้องในการรับสาย ( "โปรไฟล์ที่คล้ายกัน")
  • ออบเจ็กต์ SipManager

หากต้องการโทรด้วยเสียง คุณควรตั้งค่าSipAudioCall.Listener การโต้ตอบส่วนใหญ่ของลูกค้ากับ สแต็ก SIP จะเกิดขึ้นผ่านผู้ฟัง ในข้อมูลโค้ดนี้ คุณจะเห็นวิธีที่ SipAudioCall.Listener ตั้งค่าหลังจากการโทร สร้างเมื่อ:

Kotlin

var listener: SipAudioCall.Listener = object : SipAudioCall.Listener() {

    override fun onCallEstablished(call: SipAudioCall) {
        call.apply {
            startAudio()
            setSpeakerMode(true)
            toggleMute()
        }
    }

    override fun onCallEnded(call: SipAudioCall) {
        // Do something.
    }
}

Java

SipAudioCall.Listener listener = new SipAudioCall.Listener() {

   @Override
   public void onCallEstablished(SipAudioCall call) {
      call.startAudio();
      call.setSpeakerMode(true);
      call.toggleMute();
         ...
   }

   @Override

   public void onCallEnded(SipAudioCall call) {
      // Do something.
   }
};

เมื่อตั้งค่า SipAudioCall.Listener แล้ว คุณจะทำสิ่งต่อไปนี้ได้ โทรออก เมธอด SipManager makeAudioCall จะใช้พารามิเตอร์ต่อไปนี้

  • โปรไฟล์ SIP ในเครื่อง (ผู้โทร)
  • โปรไฟล์ SIP ของเพียร์ (ผู้ใช้ที่ระบบจะโทรหา)
  • SipAudioCall.Listener เพื่อฟังการโทร กิจกรรมจาก SipAudioCall ซึ่งอาจเป็น null แต่ดังที่แสดงด้านบน Listener จะถูกใช้เพื่อตั้งค่าต่างๆ เมื่อการโทร แล้ว
  • ค่าระยะหมดเวลาเป็นวินาที

เช่น

Kotlin

val call: SipAudioCall? = sipManager?.makeAudioCall(
        sipProfile?.uriString,
        sipAddress,
        listener,
        30
)

Java

call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);

รับสายโทรเข้า

หากต้องการรับสาย แอปพลิเคชัน SIP ต้องมีคลาสย่อยของ BroadcastReceiver ที่มีความสามารถในการตอบสนองต่อ Intent บ่งบอกว่ามีสายเรียกเข้า ดังนั้น คุณจึงต้องทำสิ่งต่อไปนี้ใน แอปพลิเคชันของคุณ:

  • ใน AndroidManifest.xml ให้ประกาศ <receiver> ใน SipDemo นี่คือ <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
  • ใช้ตัวรับซึ่งเป็นคลาสย่อยของ BroadcastReceiver ใน SipDemo นี่คือ IncomingCallReceiver
  • เริ่มต้นโปรไฟล์ในเครื่อง (SipProfile) ด้วย Intent ที่รอดำเนินการซึ่งทำให้ผู้รับเริ่มทำงานเมื่อมีคนโทรหาโปรไฟล์ในเครื่อง
  • ตั้งค่าตัวกรอง Intent ที่กรองตามการดำเนินการที่แสดง สายเรียกเข้า การดำเนินการนี้ใน SipDemo android.SipDemo.INCOMING_CALL

คลาสย่อย BroadcastReceiver

หากต้องการรับสาย แอปพลิเคชัน SIP ของคุณต้องคลาสย่อย BroadcastReceiver ระบบ Android จัดการสาย SIP ขาเข้าและประกาศข้อความ "สายเรียกเข้า เรียก" Intent (ตามที่กำหนดโดยแอปพลิเคชัน) เมื่อได้รับการ การติดต่อ นี่คือ BroadcastReceiver ที่จัดหมวดหมู่ย่อย จากตัวอย่าง SipDemo

Kotlin

/**
 * Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
 */
class IncomingCallReceiver : BroadcastReceiver() {

    /**
     * Processes the incoming call, answers it, and hands it over to the
     * WalkieTalkieActivity.
     * @param context The context under which the receiver is running.
     * @param intent The intent being received.
     */
    override fun onReceive(context: Context, intent: Intent) {
        val wtActivity = context as WalkieTalkieActivity

        var incomingCall: SipAudioCall? = null
        try {
            incomingCall = wtActivity.sipManager?.takeAudioCall(intent, listener)
            incomingCall?.apply {
                answerCall(30)
                startAudio()
                setSpeakerMode(true)
                if (isMuted) {
                    toggleMute()
                }
                wtActivity.call = this
                wtActivity.updateStatus(this)
            }
        } catch (e: Exception) {
            incomingCall?.close()
        }
    }

    private val listener = object : SipAudioCall.Listener() {

        override fun onRinging(call: SipAudioCall, caller: SipProfile) {
            try {
                call.answerCall(30)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        }
    }
}

Java

/**
 * Listens for incoming SIP calls, intercepts and hands them off to WalkieTalkieActivity.
 */
public class IncomingCallReceiver extends BroadcastReceiver {
    /**
     * Processes the incoming call, answers it, and hands it over to the
     * WalkieTalkieActivity.
     * @param context The context under which the receiver is running.
     * @param intent The intent being received.
     */
    @Override
    public void onReceive(Context context, Intent intent) {
        SipAudioCall incomingCall = null;
        try {
            SipAudioCall.Listener listener = new SipAudioCall.Listener() {
                @Override
                public void onRinging(SipAudioCall call, SipProfile caller) {
                    try {
                        call.answerCall(30);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            };
            WalkieTalkieActivity wtActivity = (WalkieTalkieActivity) context;
            incomingCall = wtActivity.sipManager.takeAudioCall(intent, listener);
            incomingCall.answerCall(30);
            incomingCall.startAudio();
            incomingCall.setSpeakerMode(true);
            if(incomingCall.isMuted()) {
                incomingCall.toggleMute();
            }
            wtActivity.call = incomingCall;
            wtActivity.updateStatus(incomingCall);
        } catch (Exception e) {
            if (incomingCall != null) {
                incomingCall.close();
            }
        }
    }
}

การตั้งค่าตัวกรอง Intent เพื่อรับสาย

เมื่อบริการ SIP ได้รับสายใหม่ บริการจะส่ง Intent ที่มี สตริงการดำเนินการที่แอปพลิเคชันระบุไว้ ใน SipDemo สตริงการดำเนินการนี้คือ android.SipDemo.INCOMING_CALL

โค้ดที่ตัดตอนมาจาก SipDemo นี้แสดงวิธีสร้างออบเจ็กต์ SipProfile โดยมี Intent ที่รอดำเนินการโดยอิงจาก สตริงการดำเนินการ android.SipDemo.INCOMING_CALL ออบเจ็กต์ PendingIntent จะประกาศเมื่อ SipProfile ได้รับสายเรียกเข้า:

Kotlin

val sipManager: SipManager? by lazy(LazyThreadSafetyMode.NONE) {
    SipManager.newInstance(this)
}

var sipProfile: SipProfile? = null
...

val intent = Intent("android.SipDemo.INCOMING_CALL")
val pendingIntent: PendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA)
sipManager?.open (sipProfile, pendingIntent, null)

Java

public SipManager sipManager = null;
public SipProfile sipProfile = null;
...

Intent intent = new Intent();
intent.setAction("android.SipDemo.INCOMING_CALL");
PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 0, intent, Intent.FILL_IN_DATA);
sipManager.open(sipProfile, pendingIntent, null);

ตัวกรอง Intent จะขัดขวางการออกอากาศ ซึ่งจะเริ่มสตรีม ผู้รับ (IncomingCallReceiver) คุณสามารถระบุความตั้งใจได้ กรองในไฟล์ Manifest ของแอปพลิเคชัน หรือทำงานในโค้ดเหมือนใน SipDemo เมธอด onCreate() ของแอปพลิเคชันตัวอย่าง จาก Activity ของแอปพลิเคชัน

Kotlin

class WalkieTalkieActivity : Activity(), View.OnTouchListener {
    ...
    lateinit var callReceiver: IncomingCallReceiver
    ...

    override fun onCreate(savedInstanceState: Bundle) {
        val filter = IntentFilter().apply {
            addAction("android.SipDemo.INCOMING_CALL")
        }
        callReceiver = IncomingCallReceiver()
        this.registerReceiver(callReceiver, filter)
        ...
    }
    ...
}

Java

public class WalkieTalkieActivity extends Activity implements View.OnTouchListener {
...
    public IncomingCallReceiver callReceiver;
    ...

    @Override
    public void onCreate(Bundle savedInstanceState) {

       IntentFilter filter = new IntentFilter();
       filter.addAction("android.SipDemo.INCOMING_CALL");
       callReceiver = new IncomingCallReceiver();
       this.registerReceiver(callReceiver, filter);
       ...
    }
    ...
}

การทดสอบแอปพลิเคชัน SIP

หากต้องการทดสอบแอปพลิเคชัน SIP คุณต้องมีสิ่งต่อไปนี้

  • อุปกรณ์เคลื่อนที่ที่ใช้ Android 2.3 ขึ้นไป SIP ทำงานเกิน แบบไร้สาย คุณจึงต้องทดสอบกับอุปกรณ์จริง การทดสอบโดยใช้ AVD จะไม่ทำงาน
  • บัญชี SIP มีผู้ให้บริการ SIP หลายรายที่ให้บริการบัญชี SIP
  • หากคุณโทรออก สายนั้นต้องเป็นบัญชี SIP ที่ถูกต้อง

วิธีทดสอบแอปพลิเคชัน SIP

  1. บนอุปกรณ์ของคุณ ให้เชื่อมต่อกับระบบไร้สาย (การตั้งค่า > ระบบไร้สายและเครือข่าย) Wi-Fi > การตั้งค่า Wi-Fi)
  2. ตั้งค่าอุปกรณ์เคลื่อนที่สำหรับการทดสอบ ตามที่อธิบายไว้ในการพัฒนาในอุปกรณ์
  3. เรียกใช้แอปพลิเคชันบนอุปกรณ์เคลื่อนที่ตามที่อธิบายไว้ในการพัฒนาในอุปกรณ์
  4. หากคุณใช้ Android Studio คุณสามารถดูเอาต์พุตบันทึกแอปพลิเคชันได้โดยดำเนินการดังนี้ เปิดคอนโซลบันทึกเหตุการณ์ (มุมมอง > หน้าต่างเครื่องมือ > บันทึกเหตุการณ์)
  5. ตรวจสอบว่าแอปพลิเคชันของคุณได้รับการกำหนดค่าให้เปิด Logcat โดยอัตโนมัติเมื่อทำงาน โดยทำดังนี้
    1. เลือกเรียกใช้ > แก้ไขการกำหนดค่า
    2. เลือกแท็บเบ็ดเตล็ดในหน้าต่างเรียกใช้/การกำหนดค่าการแก้ไขข้อบกพร่อง
    3. ในส่วน Logcat ให้เลือก Show logcat โดยอัตโนมัติ จากนั้น ให้เลือกตกลง