Varsayılan telefon uygulaması oluşturma

Varsayılan telefon uygulaması, bir Android cihazdaki varsayılan telefon uygulamasının yerine yeni bir uygulama oluşturmak ve InCallService API'yi uygulamak için rol yöneticisini ve çağrı içi hizmeti kullanarak Android Telecom çerçevesinin çağrı durumu uygulamanıza bilgi sağlamasına olanak tanır. Uygulamanız aşağıdaki şartları karşılamalıdır:

Arama özelliği bulunmamalı ve yalnızca arama için kullanılan kullanıcı arayüzünden oluşmalıdır. Telefon, Telekomünikasyon çerçevesinin farkında olduğu tüm çağrıları ele almalı ve çağrıların niteliği hakkında varsayımlarda bulunmamalıdır. Örneğin, çağrıların SIM tabanlı telefon aramaları olduğu varsaymamalı veya görüntülü görüşmeler için telefon kısıtlamalarının uygulanması gibi herhangi bir ConnectionService hizmetini temel alan arama kısıtlamaları uygulamamalıdır.

Arama uygulaması, kullanıcıların cihazlarında sesli veya görüntülü görüşme almasına ya da yapmasına olanak tanır. Arama uygulamaları, aşağıdaki ekran görüntüsünde gösterildiği gibi, varsayılan Telefon uygulaması arayüzünü kullanmak yerine, aramalar için kendi kullanıcı arayüzlerini kullanır.

Telefon etme uygulaması örneği
Kendi kullanıcı arayüzünü kullanan arama uygulaması örneği

Android çerçevesi, telekomünikasyon çerçevesine göre bir çağrı uygulaması oluşturmanıza yardımcı olacak sınıflar içeren android.telecom paketini içerir. Uygulamanızı telekomünikasyon çerçevesine göre oluşturmak şu avantajları sağlar:

  • Uygulamanız, cihazdaki yerel telekom alt sistemiyle doğru bir şekilde birlikte çalışıyor.
  • Uygulamanız, bu çerçeveye de uyan diğer çağrı uygulamalarıyla doğru bir şekilde birlikte çalışır.
  • Bu çerçeve, uygulamanızın ses ve video yönlendirmesini yönetmesine yardımcı olur.
  • Bu çerçeve, uygulamanızın, çağrılarına odaklanıp odaklanmadığını belirlemesine yardımcı olur.

Manifest beyanları ve izinler

Aşağıdaki örnekte gösterildiği gibi, uygulama manifestinizde uygulamanızın MANAGE_OWN_CALLS iznini kullandığını beyan edin:

<manifest … >
    <uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
</manifest>

Uygulama izinlerini bildirme hakkında daha fazla bilgi için İzinler bölümüne bakın.

Uygulamanızda ConnectionService sınıfını uygulayan sınıfı belirten bir hizmet bildirmeniz gerekir. Telekom alt sistemi, hizmetin kendisine bağlanabilmek için BIND_TELECOM_CONNECTION_SERVICE iznini beyan etmesini gerektirir. Aşağıdaki örnekte, uygulama manifestinizde hizmetin nasıl beyan edileceği gösterilmektedir:

<service android:name="com.example.MyConnectionService"
    android:permission="android.permission.BIND_TELECOM_CONNECTION_SERVICE">
    <intent-filter>
        <action android:name="android.telecom.ConnectionService" />
    </intent-filter>
</service>

Hizmetler dahil olmak üzere uygulama bileşenlerini bildirme hakkında daha fazla bilgi için Uygulama Bileşenleri bölümüne bakın.

Bağlantı hizmetini uygulayın

Arama uygulamanız, telekom alt sisteminin bağlanabileceği ConnectionService sınıfının uygulanmasını sağlamalıdır. ConnectionService uygulamanız şu yöntemleri geçersiz kılacaktır:

onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)

Telekom alt sistemi, placeCall(Uri, Bundle) yöntemini çağıran uygulamanızın yeni bir giden çağrı oluşturmasına yanıt olarak bu yöntemi çağırır. Uygulamanız, yeni giden çağrıyı temsil etmek için Connection sınıfı uygulamanızın yeni bir örneğini döndürür (daha fazla bilgi için Bağlantıyı uygulama sayfasını inceleyin). Aşağıdaki işlemleri gerçekleştirerek giden bağlantıyı daha da özelleştirebilirsiniz:

onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

Uygulamanız placeCall(Uri, Bundle) yöntemini çağırdığında ve giden arama yapılamıyorsa telekom alt sistemi bu yöntemi çağırır. Bu duruma yanıt olarak, uygulamanız kullanıcıya giden aramanın yapılamadığını bildirmelidir (örneğin, bir uyarı kutusu veya durum mesajı kullanarak). Devam eden bir acil durum araması varsa veya başka bir uygulamada devam eden ve arama yapılmadan önce beklemeye alınamayan bir arama varsa uygulamanız arama yapamayabilir.

onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)

Uygulamanız, uygulamanızda yeni bir gelen çağrı olduğunu bildirmek için addNewIncomingCall(PhoneAccountHandle, Bundle) yöntemini çağırdığında telekomünikasyon alt sistemi bu yöntemi çağırır. Uygulamanız, yeni gelen aramayı temsil etmek için Connection uygulamanızın yeni bir örneğini döndürür (daha fazla bilgi için Bağlantıyı uygulama bölümüne bakın). Aşağıdaki işlemleri gerçekleştirerek gelen bağlantıyı daha da özelleştirebilirsiniz:

onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

Uygulamanız yeni bir gelen çağrıyı Telekom'a bildirmek için addNewIncomingCall(PhoneAccountHandle, Bundle) yöntemini çağırdığında telekom alt sistemi bu yöntemi çağırır ancak gelen çağrıya izin verilmez (daha fazla bilgi için arama kısıtlamalarına bakın). Uygulamanız gelen aramayı sessiz bir şekilde reddetmeli ve isteğe bağlı olarak kullanıcıyı cevapsız çağrı hakkında bilgilendirmek için bir bildirim yayınlamalıdır.

Bağlantıyı uygulama

Uygulamanız, uygulamanızdaki çağrıları temsil edecek bir Connection alt sınıfı oluşturmalıdır. Uygulamanızda aşağıdaki yöntemleri geçersiz kılmanız gerekir:

onShowIncomingCallUi()

Yeni bir gelen arama eklediğinizde telekomünikasyon alt sistemi bu yöntemi çağırır ve uygulamanızın gelen arama kullanıcı arayüzünü göstermesi gerekir.

onCallAudioStateChanged(CallAudioState)

Telekom alt sistemi, geçerli ses rotasının veya modunun değiştiğini uygulamanıza bildirmek için bu yöntemi çağırır. Bu çağrı, uygulamanızın setAudioRoute(int) yöntemi kullanılarak ses modunu değiştirmesine karşılık olarak çağrılır. Bu yöntem, sistem ses rotasını değiştirirse (örneğin, bir Bluetooth mikrofonlu kulaklığın bağlantısı kesildiğinde) de çağrılabilir.

onHold()

Telekom alt sistemi, bir çağrıyı beklemeye almak istediğinde bu yöntemi çağırır. Bu isteğe yanıt olarak, uygulamanızın çağrıyı beklemesi ve ardından çağrının bekletildiğini sisteme bildirmek için setOnHold() yöntemini çağırması gerekir. Android Auto gibi bir çağrı hizmeti, çağrınızı beklemeye almak için bir kullanıcı isteğini yeniden aktarmak istediğinde telekomünikasyon alt sistemi bu yöntemi çağırabilir. Kullanıcı bir aramayı başka bir uygulamada etkinleştirdiğinde telekom alt sistemi de bu yöntemi çağırır. Çağrı içi hizmetler hakkında daha fazla bilgi için InCallService adresine bakın.

onUnhold()

Telekom alt sistemi, beklemeye alınmış bir çağrıyı devam ettirmek istediğinde bu yöntemi çağırır. Uygulamanız çağrıyı devam ettirdiğinde sisteme çağrının artık beklemede olmadığını bildirmek için setActive() yöntemini çağırmalıdır. Çağrınızı gösteren Android Auto gibi bir çağrı içi hizmet çağrıyı devam ettirmek için bir isteği aktarmak istediğinde telekomünikasyon alt sistemi bu yöntemi çağırabilir. Görüşme içi hizmetler hakkında daha fazla bilgi için InCallService inceleyin.

onAnswer()

Telekom alt sistemi, gelen bir çağrının yanıtlanması gerektiğini uygulamanıza bildirmek için bu yöntemi çağırır. Uygulamanız çağrıyı yanıtladıktan sonra, sisteme çağrının yanıtlandığını bildirmek için setActive() yöntemini çağırmalıdır. Uygulamanız yeni bir gelen arama eklediğinde ve başka bir uygulamada zaten devam eden ve beklemeye alınamayan bir çağrı varsa telekom alt sistemi bu yöntemi çağırabilir. Telekom alt sistemi, bu gibi durumlarda gelen arama kullanıcı arayüzünü uygulamanız adına görüntüler. Çerçeve, çağrının yanıtlanacağı video durumunu belirtme desteği sağlayan aşırı yüklenmiş bir yöntem sağlar. Daha fazla bilgi için onAnswer(int) inceleyin.

onReject()

Telekom alt sistemi, gelen bir aramayı reddetmek istediğinde bu yöntemi çağırır. Uygulamanız çağrıyı reddettikten sonra setDisconnected(DisconnectCause)'i çağırmalı ve REJECTED parametresini parametre olarak belirtmelidir. Ardından uygulamanız, çağrıyı işlediğini sisteme bildirmek için destroy() yöntemini çağırmalıdır. Kullanıcı, uygulamanızdan gelen bir aramayı reddettiğinde telekom alt sistemi bu yöntemi çağırır.

onDisconnect()

Telekom alt sistemi, bir çağrının bağlantısını kesmek istediğinde bu yöntemi çağırır. Görüşme sona erdikten sonra, uygulamanız setDisconnected(DisconnectCause) yöntemini çağırmalı ve bir kullanıcı isteğinin arama bağlantısının kesilmesine neden olduğunu belirtmek için parametre olarak LOCAL yöntemini belirtmelidir. Ardından uygulamanız, çağrıyı işlediğini telekom alt sistemine bildirmek için destroy() yöntemini çağırmalıdır. Kullanıcı, Android Auto gibi başka bir çağrı içi hizmeti kullanarak arama bağlantısını kestiğinde sistem bu yöntemi çağırabilir. Sistem, başka bir aramanın yapılmasına izin vermek için aramanızın bağlantısının kesilmesi gerektiğinde de (ör. kullanıcının acil durum araması yapmak istemesi) bu yöntemi çağırır. Görüşme içi hizmetler hakkında daha fazla bilgi için InCallService adresini inceleyin.

Sık karşılaşılan görüşme senaryolarını yönetme

Çağrı akışınızda ConnectionService API'den yararlanmak için android.telecom paketindeki diğer sınıflarla etkileşimde bulunmanız gerekir. Aşağıdaki bölümlerde yaygın çağrı senaryoları ve uygulamanızın bunları ele almak için API'leri nasıl kullanması gerektiği açıklanmaktadır.

Gelen sesli aramaları yanıtlama

Gelen aramaları işleme süreci, diğer uygulamalarda arama olup olmadığına bakılmaksızın değişir. Akışlardaki farkın nedeni, diğer uygulamalarda aktif çağrılar olduğunda telekomünikasyon çerçevesinin bazı kısıtlamalar belirlemesinin gerekmesidir. Bu sayede, cihazdaki tüm çağrı uygulamaları için kararlı bir ortam sağlanır. Daha fazla bilgi edinmek için Arama kısıtlamaları bölümünü inceleyin.

Diğer uygulamalarda etkin görüşme yok

Diğer uygulamalarda etkin arama olmadığında gelen aramaları yanıtlamak için aşağıdaki adımları uygulayın:

  1. Uygulamanız her zamanki mekanizmalarını kullanarak yeni bir gelen aramayı alıyor.
  2. Telekom alt sistemini yeni gelen arama hakkında bilgilendirmek için addNewIncomingCall(PhoneAccountHandle, Bundle) yöntemini kullanın.
  3. Telekom alt sistemi, uygulamanızın ConnectionService uygulamasına bağlanır ve yeni gelen aramayı temsil eden Connection sınıfının yeni bir örneğini onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest) yöntemini kullanarak ister.
  4. Telekom alt sistemi, uygulamanıza onShowIncomingCallUi() yöntemini kullanarak gelen arama kullanıcı arayüzünü göstermesi gerektiğini bildirir.
  5. Uygulamanız, gelen kullanıcı arayüzünü, ilişkili bir tam ekran intent'e sahip bildirim kullanarak gösterir. Daha fazla bilgi için onShowIncomingCallUi() başlıklı makaleyi inceleyin.
  6. Kullanıcı gelen aramayı kabul ederse setActive() yöntemini veya kullanıcı gelen çağrıyı reddederse setDisconnected(DisconnectCause) tarafından parametre olarak REJECTED belirterek, ardından destroy() yöntemini çağırın.

Diğer uygulamalarda, beklemeye alınamayan aktif aramalar

Diğer uygulamalarda, beklemeye alınamayan aktif aramalar olduğunda gelen aramaları yanıtlamak için aşağıdaki adımları uygulayın:

  1. Uygulamanız her zamanki mekanizmalarını kullanarak yeni bir gelen aramayı alıyor.
  2. Telekom alt sistemini yeni gelen arama hakkında bilgilendirmek için addNewIncomingCall(PhoneAccountHandle, Bundle) yöntemini kullanın.
  3. Telekom alt sistemi, uygulamanızın ConnectionService uygulamasına bağlanır ve yeni gelen çağrıyı temsil eden Connection nesnesinin yeni bir örneğini onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest) yöntemini kullanarak ister.
  4. Telekom alt sistemi, gelen aramanız için gelen çağrı kullanıcı arayüzünü görüntüler.
  5. Kullanıcı aramayı kabul ederse telekom alt sistemi onAnswer() yöntemini çağırır. Telekom alt sistemine çağrının artık bağlandığını belirtmek için setActive() yöntemini çağırmanız gerekir.
  6. Kullanıcı çağrıyı reddederse telekom alt sistemi onReject() yöntemini çağırır. Parametre olarak REJECTED öğesini belirten setDisconnected(DisconnectCause) yöntemini ve ardından destroy() yöntemini çağırmalısınız.

Giden arama yapma

Giden bir arama yapma akışı, telekomünikasyon çerçevesinin uyguladığı kısıtlamalar nedeniyle aramanın yapılamama olasılığının ele alınmasını içerir. Daha fazla bilgi için Arama kısıtlamaları başlıklı makaleyi inceleyin.

Giden arama yapmak için aşağıdaki adımları uygulayın:

  1. Kullanıcı, uygulamanızda giden arama başlatır.
  2. Telekom alt sistemini yeni giden çağrı hakkında bilgilendirmek için placeCall(Uri, Bundle) yöntemini kullanın. Yöntem parametreleri için aşağıdaki noktaları göz önünde bulundurun:
    • Uri parametresi, çağrının yapıldığı adresi temsil eder. Normal telefon numaraları için tel: URI şemasını kullanın.
    • Bundle parametresi, uygulamanızın PhoneAccountHandle nesnesini EXTRA_PHONE_ACCOUNT_HANDLE ekstra öğesine ekleyerek çağrı uygulamanız hakkında bilgi sağlamanıza olanak tanır. Uygulamanız her giden çağrıya PhoneAccountHandle nesnesini sağlamalıdır.
    • Bundle parametresi, EXTRA_START_CALL_WITH_VIDEO_STATE ekstra öğesinde STATE_BIDIRECTIONAL değerini belirterek giden çağrının video içerip içermediğini belirtmenize de olanak tanır. Varsayılan olarak, telekomünikasyon alt sisteminin video görüşmeleri hoparlöre yönlendirdiğini unutmayın.
  3. Telekom alt sistemi, uygulamanızın ConnectionService uygulamasına bağlanır.
  4. Uygulamanız giden arama yapamıyorsa telekom alt sistemi, uygulamanıza çağrının o anda yapılamayacağını bildirmek için onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest) yöntemini çağırır. Uygulamanız, kullanıcıyı aramanın yapılamayacağını bildirmelidir.
  5. Uygulamanız giden aramayı yapabiliyorsa telekom alt sistemi, onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest) yöntemini çağırır. Uygulamanız, yeni giden çağrıyı temsil etmek için Connection sınıfınızın bir örneğini döndürmelidir. Bağlantıda ayarlamanız gereken özellikler hakkında daha fazla bilgi için Bağlantı hizmetini uygulama bölümüne bakın.
  6. Giden arama bağlandığında telekom alt sistemine aramanın etkin olduğunu bildirmek için setActive() yöntemini çağırın.

Çağrıyı bitirme

Bir çağrıyı sonlandırmak için aşağıdaki adımları uygulayın:

  1. Kullanıcı çağrıyı sonlandırdıysa parametre olarak LOCAL gönderen setDisconnected(DisconnectCause) yöntemini çağırın. Diğer taraf aramayı sonlandırdıysa parametre olarak REMOTE değerini gönderin.
  2. destroy() yöntemini çağırın.

Arama kısıtlamaları

Kullanıcılarınıza tutarlı ve basit bir arama deneyimi sunmak için telekomünikasyon çerçevesi, cihazdaki çağrıların yönetiminde bazı kısıtlamalar uygular. Örneğin, kullanıcının kendiliğinden yönetilen ConnectionService API'sini (FoTalk ve BarTalk) uygulayan iki çağrı uygulaması yüklediğini varsayalım. Bu durumda aşağıdaki sınırlamalar geçerlidir:

  • API düzeyi 27 veya daha düşük bir düzeyde çalışan cihazlarda, aynı anda yalnızca bir uygulama devam eden bir çağrıyı sürdürebilir. Bu kısıtlama, kullanıcı FooTalk uygulamasını kullanarak devam eden bir çağrı yaparken BarTalk uygulamasının yeni bir arama başlatamayacağı veya alamayacağı anlamına gelir.

    API düzeyi 28 veya sonraki sürümleri çalıştıran cihazlarda hem FooTalk hem de BarTalk CAPABILITY_SUPPORT_HOLD ve CAPABILITY_HOLD izinlerini beyan ederse kullanıcı, başka bir çağrı başlatmak veya yanıtlamak için uygulamalar arasında geçiş yaparak birden fazla devam eden çağrıyı sürdürebilir.

  • Kullanıcı düzenli olarak yönetilen aramalarla etkileşimde bulunduysa (örneğin, yerleşik Telefon veya Çevirici uygulamasını kullanarak), arama uygulamalarından kaynaklanan aramalarda kullanıcı bulunamaz. Bu, kullanıcı mobil operatörünü kullanarak normal bir görüşmedeyse aynı anda bir FooTalk veya BarTalk görüşmesinde de bulunamayacağı anlamına gelir.

  • Kullanıcı bir acil durum aramasını ararsa telekomünikasyon alt sistemi, uygulamanızın aramalarının bağlantısını keser.

  • Kullanıcı acil durum araması yaparken uygulamanız arama alamaz veya yapamaz.

  • Uygulamanız gelen bir arama aldığında başka bir arama uygulamasında devam eden bir arama varsa, gelen çağrıyı cevapladığınızda diğer uygulamada devam eden çağrılar sonlandırılır. Uygulamanız, her zamanki gelen arama kullanıcı arayüzünü görüntülememelidir. Telekomünikasyon çerçevesi, gelen arama kullanıcı arayüzünü görüntüler ve kullanıcıya, yeni çağrı cevaplandığında devam eden çağrıların sona ereceğini bildirir. Bunun anlamı, kullanıcı bir FooTalk görüşmesindeyse ve BarTalk uygulaması gelen bir arama alırsa, telekomünikasyon çerçevesi kullanıcıyı yeni bir BarTalk görüşmesi yaptığı ve BarTalk araması cevaplandığında FooTalk aramasının sona ereceği konusunda bilgilendirir.

Varsayılan Telefon Uygulaması olma

Varsayılan numara çevirici/telefon uygulaması, cihaz arama sırasında görüşme sırasındaki kullanıcı arayüzünü sağlayan bir uygulamadır. Ayrıca, kullanıcıya arama başlatma ve cihazında arama geçmişini görme olanağı da sunar. Bir cihaz, sistem tarafından sağlanan varsayılan bir numara çevirici/telefon uygulamasıyla paket hâline getirilir. Kullanıcı, sistem uygulamasından bu rolü devralmak için tek bir uygulama seçebilir. Bu rolü yerine getirmek isteyen bir uygulama, RoleManager.ROLE_DIALER rolünü doldurmasını istemek için RoleManager özelliğini kullanır.

Varsayılan telefon uygulaması, cihaz arama sırasında ve araç modunda değilken (UiModeManager#getCurrentModeType(), Configuration.UI_MODE_TYPE_CAR değil) bir kullanıcı arayüzü sağlar.

Uygulamanın RoleManager.ROLE_DIALER rolünü üstlenebilmesi için bazı gereksinimleri karşılaması gerekir:

  • Intent#ACTION_DIAL amacını yerine getirmelidir. Bu, kullanıcının giden çağrıları başlatabilmesi için uygulamanın bir tuş takımı kullanıcı arayüzü sağlaması gerektiği anlamına gelir.
  • InCallService API'yi tam olarak uygulamalı ve hem gelen arama kullanıcı arayüzünü hem de devam eden arama kullanıcı arayüzünü sağlamalıdır.

Not: RoleManager.ROLE_DIALER dolduran uygulama bağlama sırasında null InCallService döndürürse Telekomünikasyon çerçevesi otomatik olarak cihaza önceden yüklenmiş çevirici uygulamasını kullanmaya başlar. Sistem, aramanın önceden yüklenmiş numara çevirici uygulaması kullanılarak devam ettiğini bildirmek için kullanıcıya bir bildirim gösterir. Uygulamanız hiçbir zaman null bağlantısı döndürmemelidir. Yani, bu durumda uygulama RoleManager.ROLE_DIALER koşullarını karşılamaz.

Not: Uygulamanız RoleManager.ROLE_DIALER kapasitesini doldurur ve çalışma zamanında bu rolün şartlarını karşılamamasına neden olacak değişiklikler yaparsa RoleManager, uygulamanızı otomatik olarak rolden kaldırır ve uygulamanızı kapatır. Örneğin, uygulamanızın manifest dosyasında beyan ettiği InCallService öğesini programatik olarak devre dışı bırakmak için PackageManager.setComponentEnabledSetting(ComponentName, int, int) kullanırsanız uygulamanız artık RoleManager.ROLE_DIALER adlı kullanıcıdan beklenen şartları yerine getiremez.

Uygulamanız RoleManager.ROLE_DIALER rolünü üstlese bile, kullanıcı bir acil durum araması yaptığında önceden yüklenmiş numara çevirici HER ZAMAN kullanılır. Acil durum araması yapılırken optimum bir deneyim sağlamak amacıyla varsayılan numara çevirici, arama yaparken (acil durum aramaları dahil) HER ZAMAN TelecomManager.placeCall(Uri, Bundle) hizmetini kullanmalıdır. Bu sayede platform, isteğin varsayılan numara çeviriciden geldiğini doğrulayabilir. Önceden yüklenmeyen bir numara çevirici uygulaması, acil durum araması yapmak için Intent#ACTION_CALL kullanıyorsa onay için Intent#ACTION_DIAL ile önceden yüklenmiş numara çevirici uygulamasına yükseltilir. Bu, optimum olmayan bir kullanıcı deneyimidir.

Aşağıda, InCallService için örnek bir manifest kaydı gösterilmektedir. TelecomManager#METADATA_IN_CALL_SERVICE_UI meta verisi, bu özel InCallService uygulamasının yerleşik çağrı içi kullanıcı arayüzünün yerini almayı amaçladığını belirtir. TelecomManager#METADATA_IN_CALL_SERVICE_RINGING meta verisi, bu InCallService öğesinin gelen aramalar için zil sesini çalacağını belirtir. Gelen aramanın kullanıcı arayüzünü gösterme ve uygulamanızda zil sesini çalmayla ilgili daha fazla bilgi için aşağıdaki bilgilere bakın.

 <service android:name="your.package.YourInCallServiceImplementation"
          android:permission="android.permission.BIND_INCALL_SERVICE"
          android:exported="true">
      <meta-data android:name="android.telecom.IN_CALL_SERVICE_UI" android:value="true" />
      <meta-data android:name="android.telecom.IN_CALL_SERVICE_RINGING"
          android:value="true" />
      <intent-filter>
          <action android:name="android.telecom.InCallService"/>
      </intent-filter>
 </service>

Not: InCallService öğenizi android:exported="false" özelliğiyle İŞARETLEMEMELİSİNİZ; bu, çağrılar sırasında uygulamanıza bağlanamamasına neden olabilir.

InCallService API'sini uygulamanın yanı sıra, manifest dosyanızda Intent#ACTION_DIAL amacını işleyen bir etkinlik de tanımlamanız gerekir. Aşağıdaki örnekte bunun nasıl yapıldığı gösterilmektedir:

 <activity android:name="your.package.YourDialerActivity"
           android:label="@string/yourDialerActivityLabel">
      <intent-filter>
           <action android:name="android.intent.action.DIAL" />
           <category android:name="android.intent.category.DEFAULT" />
      </intent-filter>
      <intent-filter>
           <action android:name="android.intent.action.DIAL" />
           <category android:name="android.intent.category.DEFAULT" />
           <data android:scheme="tel" />
      </intent-filter>
 </activity>

Bir kullanıcı uygulamanızı yüklediğinde ve ilk kez çalıştırdığında, kullanıcıdan uygulamanızın yeni varsayılan telefon uygulaması olmasını isteyip istemediğini öğrenmesini istemek için RoleManager kullanmanız gerekir.

Aşağıdaki kod, uygulamanızın nasıl varsayılan telefon/çevirmen uygulaması olmak için istekte bulunabileceğini gösterir:

 private static final int REQUEST_ID = 1;

 public void requestRole() {
     RoleManager roleManager = (RoleManager) getSystemService(ROLE_SERVICE);
     Intent intent = roleManager.createRequestRoleIntent(RoleManager.ROLE_DIALER);
     startActivityForResult(intent, REQUEST_ID);
 }

 public void onActivityResult(int requestCode, int resultCode, Intent data) {
     if (requestCode == REQUEST_ID) {
         if (resultCode == android.app.Activity.RESULT_OK) {
             // Your app is now the default dialer app
         } else {
             // Your app is not the default dialer app
         }
     }
 }

Giyilebilir Cihazlar için InCallService Erişimi

    Uygulamanız bir üçüncü taraf tamamlayıcı uygulamasıysa ve InCallService API'lerine erişmek istiyorsa uygulamanız şunları yapabilir:

    1. Manifest'inizde MANAGE_ONGOING_CALLS izni beyan edin
    2. Tamamlayıcı uygulama olarak CompanionDeviceManager API aracılığıyla fiziksel bir giyilebilir cihazla ilişkilendirin. Şu adrese göz atın: https://developer.android.com/guide/topics/connectivity/companion-device-pairing
    3. Bu InCallService'i BIND_INCALL_SERVICE izniyle uygulayın

Gelen Arama Bildirimini Gösterme

Uygulamanız InCallService#onCallAdded(Call) üzerinden yeni bir gelen arama aldığında, gelen arama için bir gelen arama kullanıcı arayüzünü görüntülemekten sorumludur. Bu işlemi, yeni bir gelen arama bildirimi yayınlamak için NotificationManager API'lerini kullanarak yapmalıdır.

Uygulamanız, TelecomManager#METADATA_IN_CALL_SERVICE_RINGING meta verilerini bildirdiğinde gelen aramalarda zil sesini çalmaktan sorumludur. Uygulamanız istenen zil sesini belirten bir NotificationChannel oluşturmalıdır. Örneğin:

 NotificationChannel channel = new NotificationChannel(YOUR_CHANNEL_ID, "Incoming Calls",
          NotificationManager.IMPORTANCE_MAX);
 // other channel setup stuff goes here.

 // We'll use the default system ringtone for our incoming call notification channel.  You can
 // use your own audio resource here.
 Uri ringtoneUri = RingtoneManager.getDefaultUri(RingtoneManager.TYPE_RINGTONE);
 channel.setSound(ringtoneUri, new AudioAttributes.Builder()
          // Setting the AudioAttributes is important as it identifies the purpose of your
          // notification sound.
          .setUsage(AudioAttributes.USAGE_NOTIFICATION_RINGTONE)
          .setContentType(AudioAttributes.CONTENT_TYPE_SONIFICATION)
      .build());

 NotificationManager mgr = getSystemService(NotificationManager.class);
 mgr.createNotificationChannel(channel);

Uygulamanız yeni bir gelen arama aldığında, gelen arama için bir Notification oluşturur ve bunu gelen arama bildirimi kanalınızla ilişkilendirir. Bildirimde, gelen arama kullanıcı arayüzünü tam ekran olarak başlatacak bir PendingIntent belirtebilirsiniz. Kullanıcı, telefonu etkin bir şekilde kullanıyorsa bildirim yöneticisi çerçevesi, bildiriminizi bir uyarı bildirimi olarak görüntüler. Kullanıcı telefonu kullanmıyorsa bunun yerine tam ekran gelen arama kullanıcı arayüzünüz kullanılır. Örneğin:

 // Create an intent which triggers your fullscreen incoming call user interface.
 Intent intent = new Intent(Intent.ACTION_MAIN, null);
 intent.setFlags(Intent.FLAG_ACTIVITY_NO_USER_ACTION | Intent.FLAG_ACTIVITY_NEW_TASK);
 intent.setClass(context, YourIncomingCallActivity.class);
 PendingIntent pendingIntent = PendingIntent.getActivity(context, 1, intent, PendingIntent.FLAG_MUTABLE_UNAUDITED);
 // Build the notification as an ongoing high priority item; this ensures it will show as
 // a heads up notification which slides down over top of the current content.
 final Notification.Builder builder = new Notification.Builder(context);
 builder.setOngoing(true);
 builder.setPriority(Notification.PRIORITY_HIGH);
 // Set notification content intent to take user to the fullscreen UI if user taps on the
 // notification body.
 builder.setContentIntent(pendingIntent);
 // Set full screen intent to trigger display of the fullscreen UI when the notification
 // manager deems it appropriate.
 builder.setFullScreenIntent(pendingIntent, true);
 // Setup notification content.
 builder.setSmallIcon( yourIconResourceId );
 builder.setContentTitle("Your notification title");
 builder.setContentText("Your notification content.");
 // Use builder.addAction(..) to add buttons to answer or reject the call.
 NotificationManager notificationManager = mContext.getSystemService(
     NotificationManager.class);
 notificationManager.notify(YOUR_CHANNEL_ID, YOUR_TAG, YOUR_ID, builder.build());
```