eSIMs und SIM-Karten erkennen
Karten erkennen
Android-Geräte mit SIM-Karten und eSIMs verwenden bei der Telefonie die folgenden IDs APIs, einschließlich [`TelephonyManager`](/reference/android/telephony/TelephonyManager) und [AboManager](/reference/android/telephony/SubscriptionManager): * Subscription ID: eindeutige ID für ein Mobilfunkabo * Logischer Slotindex oder ID: eindeutiger Index, der auf einen logischen SIM-Steckplatz verweist. Logische Slot-IDs beginnen bei 0 und steigen abhängig von der Anzahl der unterstützten aktiven Slots auf einem Gerät. Ein Dual-SIM-Gerät kann beispielsweise Slot 0 und Slot 1. Wenn ein Gerät über mehrere physische Steckplätze verfügt, einen aktiven Slot unterstützt, hat er nur die logische Slot-ID 0. * Index oder ID des physischen Slots: eindeutiger Index, der sich auf einen physischen SIM-Steckplatz bezieht. Physische Slot-IDs beginnen bei 0 und steigen je nach Anzahl der physischen am Gerät befinden. Sie unterscheidet sich von der Anzahl der logischen Slots auf einem Gerät. was der Anzahl der aktiven Slots entspricht, die ein Gerät haben kann. verwenden. Beispiel: Ein Gerät, das zwischen Dual-SIM und Single-SIM wechselt. hat der Modus immer zwei physische Steckplätze. Im Einzel-SIM-Modus hat er nur einen logischen Slot. * Card ID: eindeutige ID zur Identifizierung einer UiccCard ![Diagramm zur Verwendung von IDs in einem Fall mit zwei logischen und drei physischen Slots](/images/guide/topics/connectivity/tel-ids.png) Im obigen Diagramm gilt Folgendes: * Das Gerät hat zwei logische Steckplätze. * Im physischen Slot 0 befindet sich eine physische UICC-Karte mit einem aktiven Profil. * Im physischen Slot 2 ist eine eUICC mit einem aktiven Profil. * Der physische Slot 1 wird derzeit nicht verwendet. ![Diagramm zur Verwendung von IDs in einem Fall mit drei logischen und zwei physischen Slots](/images/guide/topics/connectivity/tel-ids-2.png) Im obigen Diagramm gilt Folgendes: * Das Gerät hat drei logische Slots. * Im physischen Slot 0 befindet sich eine physische UICC-Karte mit einem aktiven Profil. * Im physischen Slot 1 ist eine eUICC mit zwei heruntergeladenen Profilen vorhanden, die beide mit MEP (Multiple Enabled Profiles) aktiv sind.
Session Initiation Protocol – Übersicht
Android bietet eine API, die das Session Initiation Protocol (SIP) unterstützt. So können Sie Ihren Anwendungen SIP-basierte Internettelefoniefunktionen hinzufügen. Android umfasst einen vollständigen SIP-Protokollstack und integrierte Anrufverwaltung mit denen Anwendungen ganz einfach ausgehende und eingehende Sprachanrufe einrichten können, ohne sich um Sitzungen, die Kommunikation auf Transportebene oder können Sie sie direkt aufzeichnen oder wiedergeben.
Hier sind Beispiele für die Arten von Anwendungen, die die SIP API verwenden können:
- Videokonferenz
- Chat
Anforderungen und Einschränkungen
Folgende Anforderungen gelten für die Entwicklung einer SIP-Anwendung:
- Sie benötigen ein Mobilgerät mit Android 2.3 oder höher.
- SIP läuft über eine drahtlose Datenverbindung, daher muss Ihr Gerät über -Verbindung (über einen mobilen Datendienst oder WLAN) Das bedeutet, dass Sie Sie können keine AVD-Tests durchführen, sondern nur ein physisches Gerät. Weitere Informationen finden Sie unter SIP-Anwendungen testen
- Jeder Teilnehmer in der Kommunikationssitzung der Anwendung muss eine SIP-Konto. Es gibt viele verschiedene SIP-Anbieter, die SIP-Konten anbieten.
Hinweis:Videos werden von der Bibliothek android.net.sip
nicht unterstützt.
Anrufe. Wenn Sie VoIP-Anrufe mit einem SIP-Stack wie
android.net.sip
, sehen Sie sich eine der vielen modernen Open-Source-
als Basis für VoIP-Anrufe. Alternativ können Sie
können Sie die
ConnectionService
API für eine enge Integration dieser Aufrufe in die Telefonfunktion des Geräts
SIP API-Klassen und -Schnittstellen
Hier ist eine Zusammenfassung der Klassen und einer Benutzeroberfläche
(SipRegistrationListener
), die im Android SIP enthalten sind
API:
Klasse/Schnittstelle | Beschreibung |
---|---|
SipAudioCall |
Verarbeitet Audioanrufe über das Internet über SIP. |
SipAudioCall.Listener |
Listener für Ereignisse in Verbindung mit einem SIP-Anruf, z. B. wenn ein Anruf empfangen („beim Klingeln“) oder ein Anruf ausgehend („bei Anrufen“) ist. |
SipErrorCode |
Definiert Fehlercodes, die während SIP-Aktionen zurückgegeben werden. |
SipManager |
Stellt APIs für SIP-Aufgaben wie das Initiieren von SIP-Verbindungen und den Zugriff bereit zu zugehörigen SIP-Diensten. |
SipProfile |
Definiert ein SIP-Profil, einschließlich SIP-Konto, Domain und Serverinformationen. |
SipProfile.Builder |
Hilfsklasse zum Erstellen eines SipProfile |
SipSession |
Stellt eine SIP-Sitzung dar, die einem SIP-Dialog oder einer eigenständigen Transaktion zugeordnet ist nicht innerhalb eines Dialogfelds. |
SipSession.Listener |
Listener für Ereignisse im Zusammenhang mit einer SIP-Sitzung, z. B. wenn eine Sitzung registriert wird („bei der Registrierung“) oder ein Anruf ist ausgehend („bei Anrufen“). |
SipSession.State |
Definiert den SIP-Sitzungsstatus, z. B. „Registrierung“, „Ausgehender Anruf“ und „Im Anruf“. |
SipRegistrationListener |
Eine Schnittstelle, die ein Listener für SIP-Registrierungsereignisse ist. |
Manifest wird erstellt
Wenn Sie eine Anwendung entwickeln, die die SIP API verwendet, denken Sie daran, dass das wird nur unter Android 2.3 (API Level 9) und höheren Versionen der auf der Plattform. Bei Geräten mit Android 2.3 (API-Level 9) oder höher nicht alle Geräte SIP-Unterstützung bieten.
Fügen Sie dem Manifest Ihrer Anwendung die folgenden Berechtigungen hinzu, um SIP zu verwenden:
android.permission.USE_SIP
android.permission.INTERNET
Damit Ihre App nur auf Geräten installiert werden kann, die SIP unterstützen, fügen Sie Folgendes in die Manifest:
<uses-sdk android:minSdkVersion="9" />
Dies bedeutet, dass Ihre Anwendung Android 2.3 oder höher erfordert. Für
finden Sie unter
API-Ebenen
und die Dokumentation für die
<uses-sdk>
-Elements.
Um zu steuern, wie Ihre App von nicht unterstützten Geräten gefiltert wird SIP (z. B. bei Google Play) im Abschnitt Manifest:
<uses-feature android:name="android.software.sip.voip" />
Damit wird angegeben, dass Ihre Anwendung die SIP API verwendet. Die Erklärung sollte
fügen Sie ein android:required
-Attribut hinzu, das angibt,
möchten, dass die Anwendung nach Geräten gefiltert wird, die keine SIP-Unterstützung bieten.
Möglicherweise sind auch andere <uses-feature>
-Deklarationen erforderlich.
abhängig von Ihrer Implementierung. Weitere Informationen finden Sie in der Dokumentation
für die
<uses-feature>
-Elements.
Wenn deine App darauf ausgelegt ist, Anrufe zu empfangen, musst du im Manifest der App auch einen Empfänger (Unterklasse BroadcastReceiver
) definieren:
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
Hier sind Auszüge aus dem SipDemo-Manifest:
<?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 wird erstellt
Damit Sie die SIP API verwenden können, muss Ihre Anwendung ein SipManager
-Objekt erstellen. Die SipManager
nimmt
auf Folgendes achten:
- SIP-Sitzungen werden gestartet.
- Anrufe starten und empfangen
- Registrieren und Aufheben der Registrierung bei einem SIP-Anbieter
- Die Sitzungsverbindung wird geprüft.
So instanziieren Sie eine neue SipManager
:
Kotlin
val sipManager: SipManager? by lazy(LazyThreadSafetyMode.NONE) { SipManager.newInstance(this) }
Java
public SipManager sipManager = null; ... if (sipManager == null) { sipManager = SipManager.newInstance(this); }
Bei einem SIP-Server registrieren
An einer typischen Android SIP-Anwendung sind ein oder mehrere Nutzende beteiligt, von denen jeder
hat ein SIP-Konto. In einer Android SIP-Anwendung ist jedes SIP-Konto
dargestellt durch ein SipProfile
-Objekt.
Ein SipProfile
definiert ein SIP-Profil, einschließlich eines SIP
Konto-, Domain- und Serverinformationen. Das mit dem SIP verknüpfte Profil
Konto auf dem Gerät, auf dem die Anwendung läuft, heißt lokale
Profil. Das Profil, mit dem die Sitzung verbunden ist,
Peer-Profil. Wenn sich Ihre SIP-Anwendung beim SIP-Server mit
die lokale SipProfile
, registriert dies effektiv die
Gerät als Standort für SIP-Anrufe für Ihre SIP-Adresse festlegen.
In diesem Abschnitt erfahren Sie, wie Sie eine SipProfile
,
auf einem SIP-Server registrieren und Registrierungsereignisse erfassen.
So erstellen Sie ein SipProfile
-Objekt:
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();
Mit dem folgenden Codeauszug wird das lokale Profil geöffnet, um Anrufe zu tätigen und/oder
generische SIP-Anrufe empfangen. Der Anrufer kann weitere Anrufe über
mSipManager.makeAudioCall
Dieser Auszug legt auch die Handlung
android.SipDemo.INCOMING_CALL
, die von einem Intent verwendet wird
Filter, wenn das Gerät einen Anruf empfängt (siehe Einrichten der
Intent-Filter zum Empfangen von Anrufen) verwenden. Dies ist der Registrierungsschritt:
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);
Schließlich wird mit diesem Code ein SipRegistrationListener
für den SipManager
festgelegt. Hier wird nachverfolgt, ob die SipProfile
bei Ihrem SIP-Dienst registriert wurde
Anbieter:
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."); } }
Wenn Ihre Anwendung mit der Nutzung eines Profils fertig ist, sollte es geschlossen werden, damit es kostenlos verfügbar ist. zugehörige Objekte im Arbeitsspeicher verschieben und das Gerät vom Server abmelden. Für Beispiel:
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); } }
Tätigen eines Sprachanrufs
Für Sprachanrufe müssen folgende Voraussetzungen erfüllt sein:
- Ein
SipProfile
, der den Aufruf tätigt (die „lokales Profil“) und eine gültige SIP-Adresse zum Empfang des Anrufs (die „Peer-Profil“). - Ein
SipManager
-Objekt.
Für Audioanrufe musst du eine SipAudioCall.Listener
einrichten. Ein Großteil der Interaktion der Kundschaft mit
den SIP-Stack über Hörer. In diesem Snippet sehen Sie, wie SipAudioCall.Listener
nach dem Anruf eingerichtet wird.
gegründet:
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. } };
Sobald du das Gerät (SipAudioCall.Listener
) eingerichtet hast, kannst du Folgendes tun:
den Anruf zu starten. Die Methode SipManager
makeAudioCall
verwendet die folgenden Parameter:
- Ein lokales SIP-Profil (der Anrufer)
- Ein Peer-SIP-Profil (der aufgerufene Nutzer)
SipAudioCall.Listener
, um den Anruf anzuhören Events vonSipAudioCall
. Das kannnull
sein, Wie oben gezeigt, wird der Listener jedoch zur Einrichtung verwendet, sobald der Aufruf festgelegt ist.- Der Wert für das Zeitlimit in Sekunden.
Beispiel:
Kotlin
val call: SipAudioCall? = sipManager?.makeAudioCall( sipProfile?.uriString, sipAddress, listener, 30 )
Java
call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);
Anrufe erhalten
Zum Empfangen von Anrufen muss eine SIP-Anwendung eine Unterklasse von BroadcastReceiver
enthalten, die in der Lage ist, auf einen Intent zu antworten
zeigt an, dass ein Anruf eingeht. Daher müssen Sie Folgendes in
Ihre Anwendung:
- Deklarieren Sie in
AndroidManifest.xml
Folgendes:<receiver>
. In SipDemo ist das<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
- Implementieren Sie den Empfänger, eine abgeleitete Klasse von
BroadcastReceiver
. In SipDemo ist dasIncomingCallReceiver
- Initialisieren Sie das lokale Profil (
SipProfile
) mit einem Pending Intent, der den Empfänger auslöst, wenn jemand das lokale Profil anruft. - Richten Sie einen Intent-Filter ein, der nach der Aktion filtert, die ein
Eingehender Anruf. In SipDemo ist diese Aktion
android.SipDemo.INCOMING_CALL
Abgeleitete Klassen für BroadcastReceiver erstellen
Zum Empfangen von Anrufen muss Ihre SIP-Anwendung eine abgeleitete Klasse von BroadcastReceiver
erstellen. Die
Das Android-System verarbeitet eingehende SIP-Anrufe und sendet eine
Call"-Intent (wie von der Anwendung definiert), wenn er
anrufen. Hier ist die abgeleitete Klasse
BroadcastReceiver
Code aus dem SipDemo-Beispiel.
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-Filter zum Empfangen von Anrufen einrichten
Wenn der SIP-Dienst einen neuen Anruf empfängt, sendet er einen Intent mit dem Parameter
Aktions-String, der von der Anwendung bereitgestellt wird. In SipDemo lautet dieser Aktionsstring
android.SipDemo.INCOMING_CALL
Dieser Codeauszug aus SipDemo zeigt, wie das Objekt SipProfile
mit einem ausstehenden Intent erstellt wird.
Aktionsstring android.SipDemo.INCOMING_CALL
Die
Das PendingIntent
-Objekt führt eine Übertragung aus, wenn SipProfile
einen Aufruf empfängt:
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);
Die Übertragung wird vom Intent-Filter abgefangen, der dann
Empfänger (IncomingCallReceiver
). Sie können einen Intent angeben,
in der Manifest-Datei Ihrer App filtern oder dies im Code wie in der SipDemo
Methode onCreate()
der Beispielanwendung
des Activity
der Anwendung:
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-Anwendungen testen
Zum Testen von SIP-Anwendungen ist Folgendes erforderlich:
- Ein Mobilgerät mit Android 2.3 oder höher. SIP-Laufzeiten über die drahtlose Verbindung erfordern, Sie müssen den Test daher auf einem echten Gerät durchführen. Das Testen mit AVD funktioniert nicht.
- Ein SIP-Konto. Es gibt viele verschiedene SIP-Anbieter, die SIP-Konten anbieten.
- Wenn du jemanden anrufst, muss es sich auch um ein gültiges SIP-Konto handeln.
So testen Sie eine SIP-Anwendung:
- Stellen Sie auf Ihrem Gerät eine Verbindung zu WLAN her (Einstellungen > Drahtlos & Netzwerke). > WLAN > WLAN-Einstellungen).
- Richten Sie Ihr Mobilgerät für Tests ein, wie unter Auf einem Gerät entwickeln beschrieben.
- Führen Sie Ihre Anwendung auf Ihrem Mobilgerät aus, wie unter Auf einem Gerät entwickeln beschrieben.
- Wenn Sie Android Studio verwenden, können Sie die Ausgabe des Anwendungsprotokolls folgendermaßen aufrufen: Öffnen Sie die Konsole des Ereignisprotokolls (Ansicht > Toolfenster > Ereignisprotokoll).
- Achten Sie darauf, dass Ihre Anwendung so konfiguriert ist, dass Logcat bei der Ausführung automatisch gestartet wird:
<ph type="x-smartling-placeholder">
- </ph>
- Wählen Sie Ausführen > Konfigurationen bearbeiten.
- Wählen Sie im Fenster Run/Debug Configurations (Ausführungs-/Fehlerbehebungskonfigurationen) den Tab Verschiedenes aus.
- Wählen Sie unter Logcat die Option Show logcat automatisch (Logcat automatisch anzeigen) aus. wählen Sie OK aus.