Oturum başlatma protokolüne genel bakış

eSIM'leri ve SIM kartları algılama

Kartları algılama

SIM kartlı ve eSIM'i olan Android cihazlar, telefonda aşağıdaki kimlikleri kullanır API'ler, [`TelephonyManager`](/reference/android/telephony/TelephonyManager) ve ["SubscriptionManager"](/reference/android/telephony/SubscriptionManager): * Abonelik kimliği: mobil abonelik için benzersiz kimlik. * Mantıksal yuva dizini veya kimliği: Mantıksal bir SIM yuvasını belirten benzersiz dizin. Mantıksal slot kimlikleri 0'dan başlar ve bir cihazda desteklenen etkin yuvalar olduğundan emin olun. Örneğin, genellikle çift SIM kartlı bir cihaz yuva 0 ve yuva 1 var. Bir cihazda birden fazla fiziksel yuva varsa, ancak bir etkin yuvayı destekliyorsa yalnızca mantıksal yuva kimliği 0 olur. * Fiziksel yuva dizini veya kimliği: Fiziksel bir SIM yuvasını belirten benzersiz dizin. Fiziksel alan kimlikleri 0'dan başlar ve fiziksel alan sayısına bağlı olarak yükselir. çıkarılabilir. Bu, bir cihazdaki mantıksal yuvaların sayısından farklıdır Bu, bir cihazın sahip olduğu etkin yuvaların sayısına karşılık gelir yardımcı oluyorum. Örneğin, çift SIM kart ile tek SIM kart arasında geçiş yapan bir cihaz mod her zaman iki fiziksel yuvaya sahip olabilir, ancak tek SIM modunda tek bir mantıksal alan olur. * Kart kimliği: UiccCard'ı tanımlamak için kullanılan benzersiz kimlik. ![İki mantıksal slot ve üç fiziksel yuvalı bir vakada kimliklerin nasıl kullanıldığını gösteren diyagram](/images/guide/topics/connectivity/tel-ids.png) Yukarıdaki şemada: * Cihazda iki mantıksal yuva vardır. * 0. fiziksel alanda, etkin profili olan fiziksel bir UICC kartı bulunur. * 2. fiziksel yuvada, etkin profili olan bir eUICC var. * 1. fiziksel alan şu anda kullanımda değil. ![Üç mantıksal slot ve iki fiziksel yuvalı bir vakada kimliklerin nasıl kullanıldığını gösteren diyagram](/images/guide/topics/connectivity/tel-ids-2.png) Yukarıdaki şemada: * Cihazda üç mantıksal yuva vardır. * 0. fiziksel alanda, etkin profili olan fiziksel bir UICC kartı bulunur. * 1. fiziksel yuvada, her ikisi de MEP (Birden Fazla Etkinleştirilmiş Profil) kullanılarak etkin durumda olan iki adet indirilmiş profili olan bir eUICC'dir.

Oturum başlatma protokolüne genel bakış

Android, Oturum Başlatma Protokolü'nü (SIP) destekleyen bir API sağlar. Bu, uygulamalarınıza SIP tabanlı internet telefon özellikleri eklemenize olanak tanır. Android, tam bir SIP protokolü yığını ve entegre çağrı yönetimi içerir uygulamaların giden ve gelen sesli aramaları kolayca ayarlamasını sağlayan özellikler ve veya ses iletimini yönetmek zorunda kalmadan doğrudan kaydetme veya oynatma.

Aşağıda, SIP API'yi kullanabilecek uygulama türlerine örnekler verilmiştir:

  • Video konferans
  • Anında mesajlaşma

Şartlar ve sınırlamalar

SIP uygulaması geliştirmeyle ilgili şartlar şunlardır:

  • Android 2.3 veya sonraki sürümleri çalıştıran bir mobil cihazınız olmalıdır.
  • SIP kablosuz veri bağlantısı üzerinden çalıştığından cihazınızda veri bulunması gerekir. bağlantı (mobil veri hizmeti veya kablosuz ağ ile) gerektirir. Bu, sizin için Ortalama görüntüleme süresi, ortalama görüntüleme süresi ve ölçümü yalnızca fiziksel bir cihazda test edebileceğiniz anlamına gelir. Ayrıntılar için bkz. SIP uygulamalarını test etme.
  • Uygulamanın iletişim oturumundaki her katılımcının SIP hesabı. SIP hesapları sunan birçok farklı SIP sağlayıcısı vardır.

Not: android.net.sip kitaplığı videoları desteklemez çağrısının en iyi yolu. VOIP aramasını aşağıdaki gibi bir SIP yığını kullanarak uygulamak isterseniz: android.net.sip, pek çok modern açık kaynak arasından her tür VOIP çağrısının temelini oluşturur. Alternatif olarak: anahtar kelimeleri ConnectionService Bu çağrıların, cihazın Çevirici'ye sıkı bir şekilde entegre edilmesini sağlayan API uygulamasını indirin.

SIP API sınıfları ve arayüzleri

Aşağıda, sınıfların ve bir arayüzün özeti verilmiştir (SipRegistrationListener) Android SIP'ye dahildir API:

Sınıf/Arayüz Açıklama
SipAudioCall SIP üzerinden yapılan internet sesli aramasını işler.
SipAudioCall.Listener SIP çağrısıyla ilgili etkinlikleri (ör. arama yapılırken) dinleyici gelen ("çağrıda") veya giden bir arama ise ("çağrıda").
SipErrorCode SIP işlemleri sırasında döndürülen hata kodlarını tanımlar.
SipManager SIP bağlantıları başlatma gibi SIP görevleri için API'ler ve erişim sağlar ilgili SIP hizmetleriyle bağlantılıdır.
SipProfile SIP hesabı, alan ve sunucu bilgileri dahil olmak üzere bir SIP profili tanımlar.
SipProfile.Builder SipProfile oluşturmak için yardımcı sınıf.
SipSession SIP iletişim kutusu veya bağımsız bir işlemle ilişkili SIP oturumunu temsil eder iletişim kutusu içinde değil.
SipSession.Listener Oturumun kaydedilmesi gibi SIP oturumuyla ilgili etkinlikleri dinleyici ("kaydolduğunda") ya da giden bir aramaysa ("arama sırasında").
SipSession.State SIP oturumu durumlarını (ör. "kayıt", "giden arama" ve "görüşmede") tanımlar.
SipRegistrationListener SIP kayıt etkinlikleri için işleyici olan bir arayüz.

Manifest oluşturuluyor

SIP API kullanan bir uygulama geliştiriyorsanız Bu özellik, yalnızca Android 2.3 (API düzeyi 9) ve yardımcı oluyorum. Ayrıca, Android 2.3 (API düzeyi 9) veya sonraki sürümleri çalıştıran cihazlarda tüm cihazlar SIP desteği sunmaz.

SIP kullanmak için uygulamanızın manifest dosyasına aşağıdaki izinleri ekleyin:

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

Uygulamanızın yalnızca SIP destekleme özelliğine sahip, aşağıdakini uygulamanızın manifesto:

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

Bu simge, uygulamanızın Android 2.3 veya daha yeni bir sürüm gerektirdiğini gösterir. Örneğin, daha fazla bilgi için API Düzeyleri ve belgeleri, <uses-sdk> öğesine dokunun.

Uygulamanızın, SIP (örneğin, Google Play'de), uygulamanızın manifesto:

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

Bu durum, uygulamanızın SIP API'yi kullandığını gösterir. Bu beyan, android:required özelliği ekleyerek Uygulamanın, SIP desteği sunmayan cihazlardan filtrelenmesini isteme. Başka <uses-feature> beyanları da gerekebilir. izin vermiş olursunuz. Daha fazla bilgi için belgelere göz atın - <uses-feature>. öğesine dokunun.

Uygulamanız çağrı almak üzere tasarlandıysa uygulamanın manifest dosyasında bir alıcı (BroadcastReceiver alt sınıfı) da tanımlamanız gerekir:

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

SipDemo manifestinden alıntılar aşağıda verilmiştir:

<?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 Oluşturma

SIP API'yi kullanmak için uygulamanızın bir SipManager nesnesi oluşturması gerekir. SipManager alır şunlara dikkat etmeniz gerekir:

  • SIP oturumları başlatılıyor.
  • Çağrı başlatma ve alma.
  • SIP sağlayıcısına kaydolma ve kaydı iptal etme
  • Oturum bağlantısı doğrulanıyor.

Yeni bir SipManager örneğini şu şekilde oluşturursunuz:

Kotlin

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

Java

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

SIP sunucusuna kaydolma

Tipik bir Android SIP uygulaması bir veya daha fazla kullanıcı içerir ve bu kullanıcıların her biri SIP hesabı var. Bir Android SIP uygulamasında her SIP hesabı SipProfile nesnesiyle gösterilir.

SipProfile, SIP dahil olmak üzere bir SIP profilini tanımlar hem de alan ve sunucu bilgilerini içerir. SIP ile ilişkili profil uygulamayı çalıştıran cihazdaki hesabın adı yerel profil. Oturumun bağlı olduğu profile emsal profili. SIP uygulamanız ile SIP sunucusuna giriş yaptığında yerel SipProfile kullanıyorsanız bu, cihazı, SIP adresiniz için SIP çağrılarının gönderileceği konum olarak belirleyin.

Bu bölümde, SipProfile, veri feed'i veya bu kaydı bir SIP sunucusuna kaydetme ve kayıt etkinliklerini izleme.

SipProfile nesnesini aşağıdaki gibi oluşturursunuz:

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();

Aşağıdaki kod alıntısı çağrı yapmak için yerel profili açar ve/veya genel SIP aramaları alınıyor. Arayan, sonraki aramaları mSipManager.makeAudioCall Bu alıntı da Bir amaç tarafından kullanılacak android.SipDemo.INCOMING_CALL filtre uygulayın (bkz. Kurulumu ayarlama arama almak için intent filtresine) dokunun. Kayıt adımı şudur:

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);

Son olarak, bu kod SipManager üzerinde bir SipRegistrationListener belirler. Bu, SipProfile cihazının SIP hizmetinize başarılı bir şekilde kaydedilip kaydedilmediğini takip eder sağlayıcı:

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.");
    }
}

Başvurunuz bir profil kullanılarak tamamlandığında, profil ücretsiz olarak kapatılmalıdır. belleğe alma ve cihazın sunucudaki kaydını silme. Örneğin, örnek:

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);
     }
}

Sesli arama yapma

Sesli arama yapmak için aşağıdaki özelliklere sahip olmanız gerekir:

  • Aramayı yapan bir SipProfile ( "yerel profil") ve çağrıyı almak için geçerli bir SIP adresi ( "emsal profili").
  • SipManager nesnesi.

Sesli arama yapmak için bir SipAudioCall.Listener kurmanız gerekir. Müşteriyle etkileşimin büyük bir kısmı SIP yığını, işleyiciler aracılığıyla gerçekleşir. Bu snippet'te, görüşmeden sonra SipAudioCall.Listener ayarlarının nasıl yapıldığını görebilirsiniz. yerleşik:

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 cihazını kurduktan sonra şunları yapabilirsiniz: telefon et. SipManager yöntemi makeAudioCall şu parametreleri alır:

  • Yerel bir SIP profili (arayan).
  • Eş SIP profili (aranan kullanıcı).
  • Aramayı dinlemek için SipAudioCall.Listener SipAudioCall kaynağından etkinlik. Bu, null, Ancak yukarıda gösterildiği gibi, görüşme oluşturulduğunda yerleşik olarak bulunur.
  • Saniye cinsinden zaman aşımı değeri.

Örnek:

Kotlin

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

Java

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

Çağrıları alıyor

Arama almak için SIP uygulamasının bir amaca yanıt verebilen bir BroadcastReceiver alt sınıfı içermesi gerekir. olduğunu gösterir. Bu nedenle, uygulamanız:

  • AndroidManifest.xml bölgesinde şunu beyan edin: <receiver>. SipDemo'da bu işlevin <receiver android:name=".IncomingCallReceiver" android:label="Call Receiver" />.
  • BroadcastReceiver alt sınıfı olan alıcıyı uygulayın. SipDemo'da bu işlevin IncomingCallReceiver.
  • Yerel profili (SipProfile) şununla başlatın: yerel profil arandığında alıcınızı tetikleyen beklemedeki niyet.
  • Bir niyeti temsil eden işleme göre filtreleyen bir intent filtresi gelen arama. SipDemo'da bu işlem android.SipDemo.INCOMING_CALL.

BroadcastReceiver'ı Alt Sınıflandırma

Arama almak için SIP uygulamanızın BroadcastReceiver alt sınıfı olması gerekir. Android sistemi gelen SIP aramalarını işler ve "gelen SIP aramalarını" yayınlar " intent (uygulama tarafından tanımlandığı şekilde) kullanıldığında, çağrı. Alt sınıf BroadcastReceiver kodu SipDemo örneğinden alın.

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();
            }
        }
    }
}

Arama almak için intent filtresi oluşturma

SIP hizmeti yeni bir çağrı aldığında uygulama tarafından sağlanan işlem dizesi. SipDemo'da bu işlem dizesi android.SipDemo.INCOMING_CALL

SipDemo'daki bu kod alıntısı, SipProfile nesnesinin android.SipDemo.INCOMING_CALL işlem dizesi. İlgili içeriği oluşturmak için kullanılan SipProfile bir çağrı aldığında PendingIntent nesnesi bir yayın gerçekleştirecek:

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);

Yayın intent filtresi tarafından kesilecek ve daha sonra bu filtre alıcı (IncomingCallReceiver). Bir amaç belirtebilirsiniz uygulamanızın manifest dosyasında filtreleyin veya SipDemo'daki gibi bir kod kullanarak yapın. örnek uygulamanın onCreate() yöntemi uygulamanın 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 uygulamalarını test etme

SIP uygulamalarını test etmek için aşağıdakilere ihtiyacınız vardır:

  • Android 2.3 veya sonraki sürümleri çalıştıran bir mobil cihaz. SIP şunun üzerinden geçer: kablosuz olduğundan gerçek bir cihazda test etmeniz gerekir. Ortalama görüntüleme süresi (AVD) için yapılan testler işe yaramaz.
  • SIP hesabı. SIP hesapları sunan birçok farklı SIP sağlayıcısı vardır.
  • Arama yapıyorsanız bu arama da geçerli bir SIP hesabına yönelik olmalıdır.

Bir SIP uygulamasını test etmek için:

  1. Cihazınızda kablosuza bağlanın (Ayarlar > Kablosuz ve ağlar &gt; Kablosuz > Kablosuz ayarları).
  2. Mobil cihazınızı Cihaz Üzerinde Geliştirme bölümünde açıklandığı şekilde test için ayarlayın.
  3. Uygulamanızı mobil cihazınızda, Cihazda Geliştirme bölümünde açıklandığı şekilde çalıştırın.
  4. Android Studio kullanıyorsanız uygulama günlüğü çıkışını şurada görüntüleyebilirsiniz: Olay Günlüğü konsolunu açın (Görünüm > Araç Pencereleri > Olay Günlüğü).
  5. Uygulamanızın, çalıştırıldığında Logcat'i otomatik olarak başlatacak şekilde yapılandırıldığından emin olun:
    1. Çalıştır > Yapılandırmaları Düzenleyin.
    2. Çalıştır/Hata Ayıklama Yapılandırmaları penceresinde Miscellaneous (Çeşitli) sekmesini seçin.
    3. Logcat altında, Show logcat automatically'i (logcat'i otomatik olarak göster) seçin, ardından Tamam'ı seçin.