Détecter les eSIM et les cartes SIM
Détecter des cartes
Les appareils Android équipés de cartes SIM et d'eSIM utilisent les identifiants suivants pour les services de téléphonie API, y compris [`TelephonyManager`](/reference/android/telephony/TelephonyManager) et [`SubscriptionManager`](/reference/android/telephony/SubscriptionManager): * ID d'abonnement: identifiant unique d'un abonnement mobile. * Index ou identifiant d'emplacement logique: index unique faisant référence à un emplacement de carte SIM logique. Les ID d'emplacements logiques commencent à 0 et augmentent en fonction du nombre de d'emplacements actifs compatibles sur un appareil. Par exemple, un appareil avec double carte SIM comporte l'emplacement 0 et l'emplacement 1. Si un appareil possède plusieurs emplacements physiques, mais seulement prend en charge un emplacement actif, il n'aura que l'ID d'emplacement logique 0. * Index ou ID d'emplacement physique: index unique faisant référence à un emplacement physique pour carte SIM. Les ID d'emplacements physiques commencent à 0 et augmentent en fonction du nombre d'emplacements physiques emplacements sur l'appareil. Cela diffère du nombre d'emplacements logiques qu'un périphérique possède, qui correspond au nombre d'emplacements actifs qu'un appareil peut obtenir utilisent. Par exemple, un appareil qui alterne entre une double carte SIM et une carte SIM unique. peut toujours avoir deux emplacements physiques, mais en mode SIM simple, un seul emplacement logique. * ID de carte: identifiant unique utilisé pour identifier une carte UiccCard. ![Schéma illustrant l'utilisation des ID dans un cas avec deux emplacements logiques et trois emplacements physiques](/images/guide/topics/connectivity/tel-ids.png) Dans le diagramme ci-dessus: * L'appareil possède deux emplacements logiques. * L'emplacement physique 0 contient une carte UICC physique avec un profil actif. * Dans l'emplacement physique 2, il y a un eUICC avec un profil actif. * L'emplacement physique 1 n'est pas utilisé actuellement. ![Schéma illustrant l'utilisation des ID dans un cas avec trois emplacements logiques et deux emplacements physiques](/images/guide/topics/connectivity/tel-ids-2.png) Dans le diagramme ci-dessus: * L'appareil dispose de trois emplacements logiques. * L'emplacement physique 0 contient une carte UICC physique avec un profil actif. * Dans l'emplacement physique 1, il y a un eUICC qui comporte deux profils téléchargés, tous deux actifs à l'aide de MEP (Multiple Enabled Profiles).
Présentation du protocole SIP
Android fournit une API compatible avec le protocole SIP (Session Initiation Protocol). Cela vous permet d'ajouter des fonctionnalités de téléphonie Internet basées sur SIP à vos applications. Android inclut une pile de protocoles SIP complète et une gestion des appels intégrée des services qui permettent aux applications de configurer facilement des appels vocaux sortants et entrants, sans avoir à gérer de sessions, de communication de niveau transport ou directement lors de l'enregistrement ou de la lecture.
Voici des exemples de types d'applications qui peuvent utiliser l'API SIP:
- Visioconférence
- Messagerie instantanée
Conditions requises et limites
Voici les conditions requises pour développer une application SIP:
- Votre appareil mobile doit être équipé d'Android 2.3 ou version ultérieure.
- SIP s'exécute via une connexion de données sans fil, votre appareil doit donc disposer d'un (via un service de données mobiles ou Wi-Fi). Cela signifie que vous Impossible d'effectuer un test sur un AVD (vous ne pouvez le tester que sur un appareil physique). Pour en savoir plus, consultez Tester les applications SIP
- Chaque participant à la session de communication de l'application doit avoir un Compte SIP. De nombreux fournisseurs SIP différents proposent des comptes SIP.
Remarque:La bibliothèque android.net.sip
n'est pas compatible avec les vidéos
appels. Si vous souhaitez implémenter les appels VoIP à l'aide d'une pile SIP telle que
android.net.sip
, découvrez l'une des nombreuses solutions Open Source modernes
comme base pour toute mise en œuvre
des appels VoIP. Par ailleurs,
vous pouvez mettre en œuvre
ConnectionService
API permettant d'intégrer étroitement ces appels au clavier de l'appareil
l'application.
Classes et interfaces de l'API SIP
Voici un récapitulatif des classes et une interface
(SipRegistrationListener
) inclus dans le SIP Android
API:
Classe/Interface | Description |
---|---|
SipAudioCall |
Gère un appel audio Internet via SIP. |
SipAudioCall.Listener |
Paramètre "Listener" pour les événements liés à un appel SIP, par exemple lorsqu'un appel est en cours reçu ("en cours de sonnerie") ou sortant ("en cours d'appel"). |
SipErrorCode |
Définit les codes d'erreur renvoyés lors des actions SIP. |
SipManager |
Fournit des API pour les tâches SIP, telles que le lancement de connexions SIP, et fournit un accès aux services SIP associés. |
SipProfile |
Définit un profil SIP, y compris un compte SIP, ainsi que des informations sur le domaine et le serveur. |
SipProfile.Builder |
Classe d'assistance pour la création d'un SipProfile. |
SipSession |
Représente une session SIP associée à une boîte de dialogue SIP ou à une transaction autonome. et non dans une boîte de dialogue. |
SipSession.Listener |
Paramètre "Listener" pour les événements en lien avec une session SIP, par exemple lorsqu'une session est en cours d'enregistrement ("en cours d'enregistrement") ou qu'un appel est sortant ("en appel"). |
SipSession.State |
Définit les états des sessions SIP, tels que "enregistrement", "appel sortant" et "appel en cours". |
SipRegistrationListener |
Interface qui écoute les événements d'enregistrement SIP. |
Création du fichier manifeste...
Si vous développez une application qui utilise l'API SIP, n'oubliez pas que cette fonctionnalité n'est compatible qu'avec Android 2.3 (niveau d'API 9) ou version ultérieure de la plate-forme. De plus, sur les appareils équipés d'Android 2.3 (niveau d'API 9) ou version ultérieure, tous les appareils ne sont pas compatibles avec le SIP.
Pour utiliser SIP, ajoutez les autorisations suivantes au fichier manifeste de votre application:
android.permission.USE_SIP
android.permission.INTERNET
Pour vous assurer que votre application ne peut être installée que sur les appareils compatible SIP, ajoutez ce qui suit au répertoire fichier manifeste:
<uses-sdk android:minSdkVersion="9" />
Cela signifie que votre application nécessite Android 2.3 ou une version ultérieure. Pour
Pour en savoir plus, consultez
Niveaux d'API
ainsi que la documentation
<uses-sdk>
.
Pour contrôler la manière dont votre application est exclue des appareils non compatibles SIP (par exemple, sur Google Play), ajoutez les éléments suivants au fichier manifeste:
<uses-feature android:name="android.software.sip.voip" />
Cela indique que votre application utilise l'API SIP. La déclaration doit
incluent un attribut android:required
qui indique si
que l'application soit exclue des appareils
qui n'offrent pas de prise en charge SIP.
D'autres déclarations <uses-feature>
peuvent également être nécessaires,
en fonction de votre implémentation. Pour en savoir plus, consultez la documentation
pour le
<uses-feature>
.
Si votre application est conçue pour recevoir des appels, vous devez également définir un destinataire (sous-classe BroadcastReceiver
) dans le fichier manifeste de l'application:
<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
Voici des extraits du fichier manifeste 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>
Création de SipManager...
Pour utiliser l'API SIP, votre application doit créer un objet SipManager
. SipManager
prend
s'occupe des éléments suivants dans votre application:
- Lancement de sessions SIP.
- Émission et réception d'appels
- Enregistrement et annulation de l'enregistrement auprès d'un fournisseur SIP...
- Vérification de la connectivité de la session...
Instanciez un nouveau SipManager
comme suit:
Kotlin
val sipManager: SipManager? by lazy(LazyThreadSafetyMode.NONE) { SipManager.newInstance(this) }
Java
public SipManager sipManager = null; ... if (sipManager == null) { sipManager = SipManager.newInstance(this); }
Enregistrement auprès d'un serveur SIP
Une application SIP Android typique implique un ou plusieurs utilisateurs, chacun
dispose d'un compte SIP. Dans une application SIP Android, chaque compte SIP est
représentées par un objet SipProfile
.
Un SipProfile
définit un profil SIP, y compris un SIP
les informations sur le compte, le domaine et le serveur. Profil associé au SIP
sur l'appareil qui exécute l'application s'appelle la localisation
profil. Le profil auquel la session est connectée s'appelle
profil pair. Lorsque votre application SIP se connecte au serveur SIP avec
le SipProfile
local, qui enregistre effectivement le
comme l'emplacement vers lequel envoyer les appels SIP pour votre adresse SIP.
Cette section explique comment créer un SipProfile
,
l'enregistrer auprès d'un serveur SIP
et suivre les événements d'enregistrement.
Pour créer un objet SipProfile
, procédez comme suit:
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();
L'extrait de code suivant ouvre le profil local permettant de passer des appels et/ou
de recevoir des appels
SIP génériques. L'appelant peut effectuer les appels suivants via
mSipManager.makeAudioCall
Cet extrait définit également l'action
android.SipDemo.INCOMING_CALL
, qui sera utilisé par un intent
lorsque l'appareil reçoit un appel (voir la section Configuration
un filtre d'intent pour recevoir des appels). Voici l'étape d'inscription:
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);
Enfin, ce code définit un SipRegistrationListener
sur SipManager
. Permet de savoir si le SipProfile
a bien été enregistré auprès de votre service SIP
fournisseur:
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."); } }
Lorsque votre application utilise un profil, elle doit le fermer comme étant libre. les objets associés en mémoire et annuler l'enregistrement de l'appareil sur le serveur. Exemple :
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); } }
Passer un appel audio
Pour passer un appel audio, vous devez:
- Un
SipProfile
qui effectue l'appel (le "profil local") et d'une adresse SIP valide pour recevoir l'appel (les "profil pair"). - Un objet
SipManager
.
Pour passer un appel audio, vous devez configurer un SipAudioCall.Listener
. Une grande partie de l'interaction
du client avec
la pile SIP se fait
par les écouteurs. Dans cet extrait, SipAudioCall.Listener
configure les choses une fois l'appel terminé
établi:
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. } };
Après avoir configuré SipAudioCall.Listener
, vous pouvez :
passer l'appel. La méthode SipManager
makeAudioCall
utilise les paramètres suivants:
- Un profil SIP local (l'appelant).
- Un profil SIP du pair (l'utilisateur appelé).
- Un
SipAudioCall.Listener
pour écouter l'appel événements deSipAudioCall
. Il peut s'agir denull
, mais comme indiqué ci-dessus, l'écouteur est utilisé pour configurer les éléments une fois que l'appel est établi. - Valeur du délai avant expiration, en secondes.
Exemple :
Kotlin
val call: SipAudioCall? = sipManager?.makeAudioCall( sipProfile?.uriString, sipAddress, listener, 30 )
Java
call = sipManager.makeAudioCall(sipProfile.getUriString(), sipAddress, listener, 30);
Recevoir des appels
Pour recevoir des appels, une application SIP doit inclure une sous-classe de BroadcastReceiver
capable de répondre à un intent.
indiquant la présence d'un appel entrant. Vous devez donc procéder comme suit dans
votre application:
- Dans
AndroidManifest.xml
, déclarez un<receiver>
Dans SipDemo, il s'agit<receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />
- Implémentez le récepteur, qui est une sous-classe de
BroadcastReceiver
. Dans SipDemo, il s'agitIncomingCallReceiver
- Initialisez le profil local (
SipProfile
) avec une intent en attente qui déclenche votre récepteur lorsqu'un utilisateur appelle le profil local. - Configurez un filtre d'intent qui filtre les données en fonction de l'action qui représente
appel entrant. Dans SipDemo, cette action est
android.SipDemo.INCOMING_CALL
Sous-classement de BroadcastReceiver
Pour recevoir des appels, votre application SIP doit sous-classer BroadcastReceiver
.
Le système Android gère les appels SIP entrants et diffuse un message
appeler l'intent (tel que défini par l'application) lorsqu'elle reçoit
lors d'un appel. Voici la sous-classe
BroadcastReceiver
de l'exemple 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(); } } } }
Configurer un filtre d'intent pour recevoir des appels
Lorsque le service SIP reçoit un nouvel appel, il envoie un intent avec
fournie par l'application. Dans SipDemo, cette chaîne d'action est
android.SipDemo.INCOMING_CALL
Cet extrait de code de SipDemo montre comment l'objet SipProfile
est créé avec un intent en attente basé sur
la chaîne d'action android.SipDemo.INCOMING_CALL
. La
L'objet PendingIntent
effectue une diffusion lorsque SipProfile
reçoit un appel:
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);
La diffusion sera interceptée par le filtre d'intent, qui se déclenchera
le récepteur (IncomingCallReceiver
). Vous pouvez spécifier un intent
dans le fichier manifeste de votre application, ou dans le code comme dans SipDemo
la méthode onCreate()
de l'exemple d'application
du Activity
de l'application:
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); ... } ... }
Tester les applications SIP
Pour tester les applications SIP, vous avez besoin des éléments suivants:
- Un appareil mobile équipé d'Android 2.3 ou version ultérieure. Exécution de SIP sur sans fil. Vous devez donc le tester sur un appareil réel. Les tests sur AVD ne fonctionneront pas.
- Un compte SIP. De nombreux fournisseurs SIP différents proposent des comptes SIP.
- Si vous passez un appel, celui-ci doit également être destiné à un compte SIP valide.
Pour tester une application SIP:
- Sur votre appareil, connectez-vous à un réseau sans fil en sélectionnant Paramètres > Sans fil et réseaux. > Wi-Fi > paramètres Wi-Fi).
- Configurez votre appareil mobile pour les tests, comme décrit dans la section Développer sur un appareil.
- Exécutez votre application sur votre appareil mobile, comme décrit dans la section Développer sur un appareil.
- Si vous utilisez Android Studio, vous pouvez afficher la sortie du journal de l'application en en ouvrant la console du journal des événements (View > Tool Windows > Event Log [Vue > Fenêtres d'outil > Journal des événements]).
- Assurez-vous que votre application est configurée pour lancer Logcat automatiquement lorsqu'elle s'exécute:
<ph type="x-smartling-placeholder">
- </ph>
- Sélectionnez Exécuter > Modifier les configurations.
- Sélectionnez l'onglet Miscellaneous (Divers) dans la fenêtre Run/Debug Configurations (Configurations d'exécution/de débogage).
- Sous Logcat, sélectionnez Afficher Logcat automatiquement, puis sélectionnez OK.