Tworzenie domyślnej aplikacji telefonicznej

Domyślna aplikacja telefoniczna umożliwia usłudze Android Telecom informowanie aplikacji o stanie połączenia przez wdrożenie interfejsu InCallService API za pomocą menedżera ról i usługi w trakcie połączenia w celu utworzenia zastąpienia dla domyślnej aplikacji telefonicznej na urządzeniu z Androidem. Implementacja musi spełniać te wymagania:

Nie może umożliwiać nawiązywania połączeń i musi zawierać wyłącznie interfejs użytkownika do nawiązywania połączeń. Musi obsługiwać wszystkie wywołania, o których rozumie platformę telekomunikacyjną, i nie może przyjmować żadnych założeń dotyczących ich charakteru. Nie wolno na przykład zakładać, że połączenia są połączeniami telefonicznymi opartymi na karcie SIM, ani wprowadzać ograniczeń w zakresie połączeń opartych na dowolnej usłudze ConnectionService (np. egzekwowania ograniczeń dotyczących połączeń telefonicznych w przypadku rozmów wideo).

Aplikacja do rozmów pozwala użytkownikom odbierać i nawiązywać połączenia audio i wideo na urządzenia. Aplikacje do wykonywania połączeń używają własnego interfejsu użytkownika do obsługi połączeń zamiast w domyślnym interfejsie aplikacji Telefon, jak widać na zrzucie ekranu poniżej.

Przykład aplikacji do rozmów
Przykład aplikacji do rozmów korzystającej z własnego interfejsu

Platforma Androida zawiera pakiet android.telecom, który zawiera klasy, które pomogą Ci utworzyć aplikację do rozmów (zgodnie z branżą telekomunikacyjną). platformy. Tworzenie aplikacji zgodnie z platformą telekomunikacyjną zapewnia następujące korzyści:

  • Aplikacja współpracuje prawidłowo z natywnym podsystemem telekomunikacyjnym w urządzenia.
  • Aplikacja współpracuje prawidłowo z innymi aplikacjami do wykonywania połączeń, które również są zgodne z zasadami do tworzenia zasad Google.
  • Ułatwia ona aplikacji zarządzanie routingiem audio i wideo.
  • Platforma pomaga aplikacji określić, czy jej wywołania mają ukierunkować na działania.

Deklaracje i uprawnienia w pliku manifestu

W manifeście aplikacji zadeklaruj, że aplikacja używa atrybutu MANAGE_OWN_CALLS zgodnie z tym przykładem:

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

Więcej informacji o deklarowaniu uprawnień aplikacji znajdziesz tutaj: Uprawnienia:

Musisz zadeklarować usługę, która określa klasę, która implementuje metodę ConnectionService zajęcia w aplikacji. Telekomunikacja wymaga, aby usługa deklarowała uprawnienia BIND_TELECOM_CONNECTION_SERVICE jako tworzyć powiązania. Przykład poniżej pokazuje, jak zadeklarować usługę w manifestu aplikacji:

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

Więcej informacji o deklarowaniu komponentów aplikacji, w tym usług, znajdziesz w artykule Komponenty aplikacji.

Wdróż usługę połączeń

Aplikacja do połączeń musi udostępniać implementację klasy ConnectionService, z którą może powiązać podsystem telekomunikacyjny. Implementacja ConnectionService powinna zastąpić następujące metody:

onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)

Podsystem telekomunikacyjny wywołuje tę metodę w odpowiedzi na Twoja aplikacja wywołuje placeCall(Uri, Bundle) , aby utworzyć nowe połączenie wychodzące. Aplikacja zwraca nowe wystąpienie implementacji klasy Connection (więcej informacji znajdziesz w artykule Zaimplementuj połączenie), aby reprezentować nowy interfejs. połączenia wychodzącego. Możesz jeszcze bardziej dostosować połączenie wychodzące, wykonując następujące działania:

onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

Podsystem telekomunikacyjny wywołuje tę metodę, gdy aplikacja wywołuje metodę placeCall(Uri, Bundle), a połączenie wychodzące nie może i reklamy. W związku z tą sytuacją aplikacja powinna informować użytkownika (na przykład np. za pomocą pola alertów lub komunikatu), że nie można umieszczonego tekstu. Aplikacja może nie być w stanie nawiązać połączenia, jeśli trwa jakieś połączenie alarmowe lub jeśli trwa połączenie w innej aplikacji, której nie można zawieszenia połączenia przed nawiązaniem połączenia.

onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)

Podsystem telekomunikacyjny wywołuje tę metodę, gdy aplikacja wywołuje metodę addNewIncomingCall(PhoneAccountHandle, Bundle) aby poinformować system o nowym połączeniu przychodzącym w aplikacji. Aplikacja zwraca błąd nowej instancji implementacji Connection (na przykład więcej informacji znajdziesz w artykule na temat implementowania połączenia). oznacza nowe połączenie przychodzące. Możesz dodatkowo dostosować wiadomości przychodzące przez wykonanie tych czynności:

onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)

Podsystem telekomunikacyjny wywołuje tę metodę, gdy aplikacja wywołuje metodę addNewIncomingCall(PhoneAccountHandle, Bundle), aby poinformować Telecom nowe połączenie przychodzące, ale połączenie przychodzące jest niedozwolone (aby więcej informacji znajdziesz w artykule o ograniczeniach dotyczących wywołań. Aplikacja powinna dyskretnie odrzucić połączenie przychodzące i (opcjonalnie) opublikować powiadomienie informujące, nazwa użytkownika nieodebranego połączenia.

Wdróż połączenie

Aplikacja powinna utworzyć podklasę Connection do reprezentują połączenia w Twojej aplikacji. Należy zastąpić następujące metody w na potrzeby implementacji:

onShowIncomingCallUi()

Podsystem telekomunikacyjny wywołuje tę metodę, gdy dodajesz nowe połączenie przychodzące i Aplikacja powinna wyświetlać interfejs połączeń przychodzących.

onCallAudioStateChanged(CallAudioState)

Podsystem telekomunikacyjny wywołuje tę metodę, aby poinformować aplikację, że bieżący dźwięk Trasa lub tryb uległ zmianie. Ta funkcja jest wywoływana w odpowiedzi na zmianę przez aplikację tryb „Tylko dźwięk” za pomocą urządzenia setAudioRoute(int) . Metodę tę można też wywołać, jeśli system zmieni trasę audio. (na przykład po rozłączeniu zestawu słuchawkowego Bluetooth).

onHold()

Podsystem telekomunikacyjny wywołuje tę metodę, gdy chce wstrzymać połączenie. W odpowiedzi na to żądanie aplikacja powinna wstrzymać wywołanie, a następnie wywołać Metoda setOnHold() informująca system że rozmowa jest wstrzymana. Podsystem telekomunikacyjny może wywoływać tę metodę, gdy usługa do obsługi połączeń (np. Android Auto) pokazuje, że połączenie chce przekazać użytkownikowi prośbę o zawieszenie połączenia. Podsystem telekomunikacyjny wywołuje również tę metodę, jeśli użytkownik nawiązuje połączenie w innej aplikacji. Więcej informacje o usługach telefonicznych znajdziesz tutaj: InCallService.

onUnhold()

Podsystem telekomunikacyjny wywołuje tę metodę, gdy: chce wznowić zawieszone połączenie. Po wznowieniu aplikacji powinno ono wywołać metodę setActive() informuje system, że połączenie nie jest już wstrzymane. Telekomunikacja może wywołać tę metodę, gdy usługa odbierająca połączenia, taka jak Android Auto, który wyświetla Twoje połączenie, chce przekazać prośbę o jego wznowienie. Dla: więcej informacji o usługach połączeń telefonicznych znajdziesz tutaj: InCallService.

onAnswer()

Podsystem telekomunikacyjny wywołuje tę metodę, aby poinformować w aplikacji, że powinno zostać odebrane połączenie przychodzące. Gdy aplikacja odpowie powinno ono wywołać metodę setActive() informuje system, że połączenie zostało odebrane. Telekomunikacja może wywołać tę metodę, gdy aplikacja doda nowe połączenie przychodzące i W innej aplikacji trwa już połączenie, którego nie można zawiesić. Podsystem telekomunikacyjny wyświetla interfejs połączeń przychodzących w imieniu Twojej aplikacji tych instancji. Platforma udostępnia przeciążoną metodę, która zapewnia umożliwiają określanie stanu wideo, w którym chcesz odebrać połączenie. Więcej Więcej informacji: onAnswer(int).

onReject()

Podsystem telekomunikacyjny wywołuje tę metodę, gdy chce odrzucić przychodzące . Gdy aplikacja odrzuci wywołanie, powinna wywołać metodę setDisconnected(DisconnectCause) i określić REJECTED jako parametr. Aplikacja powinna a następnie wywołaj metodę destroy(), aby poinformować system, w którym aplikacja przetworzyła połączenie. Wywołania podsystemu telekomunikacyjnego w przypadku, gdy użytkownik odrzucił połączenie przychodzące z aplikacji.

onDisconnect()

Podsystem telekomunikacyjny wywołuje tę metodę, gdy chce zakończyć połączenie. Po zakończeniu połączenia aplikacja powinna wywołać metodę setDisconnected(DisconnectCause) i określić LOCAL jako parametr, który wskazuje, że żądanie użytkownika spowodowało przerwanie połączenia. Aplikacja powinna następnie wywołać metodę Metoda destroy(), która informuje dostawcę telekomunikacyjnego podsystemu, w którym aplikacja przetworzyła wywołanie. System może wywoływać tę metodę gdy użytkownik przerwie połączenie w innej usłudze, takiej jak Android Auto System wywołuje tę metodę także wtedy, gdy wywołanie musi być rozłączone, aby umożliwić nawiązywanie innych połączeń, np. gdy użytkownik chce aby wykonać połączenie alarmowe. Więcej informacji o usługach połączeń telefonicznych: InCallService

Obsługa typowych scenariuszy połączeń

Wykorzystanie interfejsu API ConnectionService w wywołaniu przepływ obejmuje interakcję z innymi klasami w android.telecom pakietu SDK. W sekcjach poniżej znajdziesz opis typowych scenariuszy połączeń oraz sposób, w jaki do obsługi tych aplikacji powinny używać interfejsów API.

Odbieranie połączeń przychodzących

Sposób obsługi połączeń przychodzących zmienia się w zależności od tego, czy są połączenia w innych aplikacjach lub nie. Różnice w przepływie pracy wynika z tego, że platforma telekomunikacyjna musi wprowadzić pewne ograniczenia w przypadku aktywnych wywołań w innych aplikacjach, zapewnić stabilne środowisko dla wszystkich aplikacji do połączeń na urządzeniu. Więcej informacje znajdziesz w artykule Ograniczenia połączeń.

Brak aktywnych połączeń w innych aplikacjach

Aby odbierać połączenia przychodzące, gdy nie ma aktywnych połączeń w innych aplikacjach, postępuj zgodnie z wykonaj te czynności:

  1. Aplikacja odbiera nowe połączenie przychodzące za pomocą standardowych mechanizmów.
  2. Użyj metody addNewIncomingCall(PhoneAccountHandle, Bundle) do: komunikuje się podsystemem telekomunikacyjnym o nowym połączeniu przychodzącym.
  3. Podsystem telekomunikacyjny wiąże się z implementacją ConnectionService Twojej aplikacji i wysyła żądanie nowej instancji klasy Connection reprezentującej nowe przychodzące za pomocą metody onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest).
  4. Podsystem telekomunikacyjny informuje aplikację, że powinna wyświetlać połączenie przychodzące za pomocą metody onShowIncomingCallUi().
  5. Aplikacja pokazuje przychodzący interfejs użytkownika za pomocą powiadomienia z powiązanym intencję pełnoekranową. Więcej informacji: onShowIncomingCallUi().
  6. Wywołaj metodę setActive(), jeśli użytkownik akceptuje połączenie przychodzące lub setDisconnected(DisconnectCause) z parametrem REJECTED, po którym następuje znak do metody destroy(), jeśli użytkownik odrzuca połączenie przychodzące.

Aktywne połączenia w innych aplikacjach, których nie można zawiesić

Aby odbierać połączenia przychodzące, gdy są aktywne połączenia w innych aplikacjach, które nie mogą aby zawiesić konto, wykonaj te czynności:

  1. Aplikacja odbiera nowe połączenie przychodzące za pomocą standardowych mechanizmów.
  2. Użyj metody addNewIncomingCall(PhoneAccountHandle, Bundle) do: komunikuje się podsystemem telekomunikacyjnym o nowym połączeniu przychodzącym.
  3. Podsystem telekomunikacyjny wiąże się z implementacją ConnectionService Twojej aplikacji i wysyła żądanie nowej instancji obiektu Connection reprezentującego nowy obiekt połączenie przychodzące za pomocą metody onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest).
  4. Podsystem telekomunikacyjny wyświetla interfejs dla połączeń przychodzących dla połączeń przychodzących.
  5. Jeśli użytkownik zaakceptuje połączenie, podsystem telekomunikacyjny wywołuje metodę onAnswer(). Należy wywołać metodę setActive(), aby wskazać operatorowi telekomunikacyjnego podsystemu, w którym połączenie zostało połączone.
  6. Jeśli użytkownik odrzuci połączenie, podsystem telekomunikacyjny wywołuje metodę onReject(). Należy wywołać metodę setDisconnected(DisconnectCause) z parametrem REJECTED, po którym następuje znak do metody destroy().

Nawiązuj połączenia wychodzące

Proces nawiązywania połączeń wychodzących obejmuje obsługę możliwości, nie można nawiązać połączenia z powodu ograniczeń nałożonych przez platformę telekomunikacyjną. Więcej informacji znajdziesz w artykule Ograniczenia połączeń.

Aby nawiązać połączenie wychodzące, wykonaj te czynności:

  1. Użytkownik nawiązuje połączenie wychodzące w aplikacji.
  2. Użyj metody placeCall(Uri, Bundle), aby poinformować podsystemem telekomunikacyjnym dotyczącym nowego połączenia wychodzącego. Wykonaj te czynności parametry metody:
    • Parametr Uri reprezentuje adres, pod którym . W przypadku zwykłych numerów telefonów użyj identyfikatora URI tel: oszustw.
    • Parametr Bundle umożliwia podanie informacji o aplikacji do wykonywania połączeń – dodaj do elementu EXTRA_PHONE_ACCOUNT_HANDLE obiekt PhoneAccountHandle swojej aplikacji. Twoje aplikacja musi dostarczać obiekt PhoneAccountHandle w przypadku każdego wywołania wychodzącego.
    • Parametr Bundle pozwala też określić, czy połączenie wychodzące obejmuje wideo przez określenie wartości STATE_BIDIRECTIONAL w dodatkowym ustawieniu EXTRA_START_CALL_WITH_VIDEO_STATE. Pamiętaj, że domyślnie podsystem telekomunikacyjny kieruje połączenia wideo do głośnika.
  3. Podsystem telekomunikacyjny łączy się z podsystemem ConnectionService aplikacji implementacji.
  4. Jeśli aplikacja nie może nawiązać połączenia wychodzącego, podsystem telekomunikacyjny metody onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest) do informuje aplikację, że nie można nawiązać połączenia w bieżącej godzinie. Twoja aplikacja powinien informować użytkownika, że nie można nawiązać połączenia.
  5. Jeśli aplikacja może nawiązywać połączenia wychodzące, podsystem telekomunikacyjny może nawiązywać połączenia onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest) . Aplikacja powinna zwrócić instancję klasy Connection, aby reprezentować nowe połączenie wychodzące. Dla: o właściwościach, które należy ustawić w połączeniu, Więcej informacji znajdziesz w artykule o implementowaniu usługi połączeń.
  6. Po nawiązaniu połączenia wychodzącego wywołaj metodę setActive(), aby poinformować podsystem telekomunikacyjny że jest ono aktywne.

Kończenie połączenia

Aby zakończyć połączenie, wykonaj te czynności:

  1. Wywołaj funkcję setDisconnected(DisconnectCause) wysyłającą LOCAL jako parametr, jeśli użytkownik zakończył(a) połączenie lub wyślij REMOTE jako parametru, jeśli druga strona zakończyła połączenie.
  2. Wywołaj metodę destroy().

Ograniczenia połączeń

Aby zapewnić użytkownikom spójną i prostą obsługę połączeń, firma telekomunikacyjna narzuca pewne ograniczenia dotyczące zarządzania wywołaniami na urządzeniu. Dla: użytkownik zainstalował dwie aplikacje do połączeń, które wykorzystują samodzielnie zarządzany interfejs API ConnectionService, FooTalk i BarTalk. W takim przypadku obowiązują te ograniczenia:

  • Na urządzeniach z interfejsem API poziomu 27 lub niższym tylko jedna aplikacja może obsługiwać trwającego połączenia w dowolnym momencie. To ograniczenie oznacza, że chociaż użytkownik ma trwającego połączenia za pomocą aplikacji FooTalk, aplikacja BarTalk nie może rozpocząć ani odebrać połączenia na nowe połączenie.

    Na urządzeniach korzystających z interfejsu API poziomu 28 lub nowszego, jeśli obie te funkcje działają zarówno w FooTalk, jak i BarTalk zadeklaruj CAPABILITY_SUPPORT_HOLD oraz CAPABILITY_HOLD uprawnień, użytkownik może prowadzić więcej niż jedno trwające wywołanie do przełączać się między aplikacjami, aby nawiązać lub odebrać kolejne połączenie.

  • Jeśli użytkownik bierze udział w zwykłych zarządzanych wywołaniach (np. za pomocą funkcji wbudowanej aplikacji Telefon lub Telefon), użytkownik nie może nawiązywać połączeń pochodzących z do rozmów. Oznacza to, że jeśli użytkownik bierze udział w zwykłej rozmowie przy użyciu operatora komórkowego, nie mogą oni jednocześnie uczestniczyć w połączeniu FooTalk ani BarTalk.

  • Podsystem telekomunikacyjny rozłączy połączenia w aplikacji, jeśli użytkownik wybierze numer połączenie alarmowe.

  • Aplikacja nie może odbierać ani nawiązywać połączeń, gdy użytkownik ma połączenie alarmowe.

  • Jeśli trwa połączenie w innej aplikacji do połączeń, gdy Twoja aplikacja przyjdzie połączenie przychodzące, odebranie połączenia spowoduje zakończenie wszystkich trwających połączeń w innej aplikacji. Aplikacja nie powinna wyświetlać swojego zwykłego interfejsu połączeń przychodzących. Platforma telekomunikacyjna wyświetla interfejs użytkownika połączeń przychodzących i informuje, użytkownik, który odbierze nowe połączenie, zakończy trwające połączenia. Ten oznacza, że użytkownik bierze udział w rozmowie w FooTalk, a aplikacja BarTalk odbierze połączenie przychodzące, platforma telekomunikacyjna informuje użytkownika, że połączenia przychodzącego BarTalk, odebranie połączenia spowoduje zakończenie Rozmowa FooTalk.

Jak zostać domyślną aplikacją telefoniczną

Domyślna aplikacja telefonu/telefonu udostępnia interfejs użytkownika podczas połączenia, gdy urządzenie jest w trakcie rozmowy. Użytkownik może też inicjować połączenia i przeglądać ich historię. na swoim urządzeniu. Urządzenie jest dołączone do systemu z domyślną aplikacją do wybierania numerów/telefonów. Użytkownik może wybrać jedną aplikację, która przejmie tę rolę od aplikacji systemowej. Aplikacja, która chce Użytkownik, który ma tę rolę, korzysta z: RoleManager, aby prosić o wypełnienie: Rola RoleManager.ROLE_DIALER.

Domyślna aplikacja telefoniczna zapewnia interfejs użytkownika, gdy urządzenie prowadzi rozmowę. nie jest w trybie samochodowym (tj. UiModeManager#getCurrentModeType() nie jest Configuration.UI_MODE_TYPE_CAR).

Aby pełnić rolę RoleManager.ROLE_DIALER, aplikacja musi spełniać liczba wymagań:

  • Musi obsługiwać intencję Intent#ACTION_DIAL. Oznacza to, że aplikacja musi udostępniać interfejs na klawiaturze, który umożliwia użytkownikowi inicjowanie połączeń wychodzących.
  • Musi w pełni wdrożyć interfejs API InCallService i zapewnić zarówno wywołanie przychodzące, Interfejs użytkownika, a także interfejsu trwającego połączenia.

Uwaga: jeśli aplikacja, która wypełnia pole RoleManager.ROLE_DIALER, zwraca błąd null InCallService podczas wiązania, platforma telekomunikacyjna automatycznie spada z powrotem do aplikacji telefonu zainstalowanej fabrycznie na urządzeniu. System wyświetli powiadomienie użytkownika, aby powiadomić go, że połączenie było kontynuowane, używając wstępnie załadowanej aplikacji telefonu. Twoje aplikacja nigdy nie powinna zwracać powiązania null; oznacza to, że nie spełnia wymagania RoleManager.ROLE_DIALER.

Uwaga: jeśli aplikacja spełnia wymagania RoleManager.ROLE_DIALER i wprowadza zmiany na: środowiska wykonawczego, przez co nie spełnia już wymagań tej roli; RoleManager automatycznie usunie Twoją aplikację z roli i zamknie ją do aplikacji. Na przykład, jeśli używasz PackageManager.setComponentEnabledSetting(ComponentName, int, int) dla automatycznie wyłączyć opcję InCallService deklarowaną przez aplikację w swoim manifeście, przestanie spełniać wymagania oczekiwane RoleManager.ROLE_DIALER.

Wstępnie załadowana funkcja telefonu będzie ZAWSZE używana podczas nawiązywania połączenia alarmowego, nawet jeśli spełnia rolę RoleManager.ROLE_DIALER. Aby zapewnić optymalną przy nawiązywaniu połączeń alarmowych, domyślny telefon powinien ZAWSZE używać TelecomManager.placeCall(Uri, Bundle), aby dzwonić (w tym połączeń alarmowych). Dzięki temu platforma może zweryfikować, czy żądanie pochodzi z z domyślnego telefonu. Jeśli niewstępnie wczytana aplikacja telefoniczna używa numeru Intent#ACTION_CALL do wykonywania połączenie alarmowe zostanie podniesione do wstępnie załadowanej aplikacji telefonu za pomocą numeru Intent#ACTION_DIAL w celu potwierdzenia; co nie jest najkorzystniejsze.

Poniżej znajdziesz przykładową rejestrację pliku manifestu dla InCallService. Metadane TelecomManager#METADATA_IN_CALL_SERVICE_UI wskazuje, że ten konkretny Wdrożenie InCallService ma na celu zastąpienie wbudowanego interfejsu połączenia. Metadane TelecomManager#METADATA_IN_CALL_SERVICE_RINGING wskazują, że InCallService odtworzy dzwonek dla połączeń przychodzących. Zobacz poniżej, aby dowiedzieć się więcej o wyświetlaniu połączenia przychodzącego. Interfejs użytkownika i odtwarzanie dzwonka w aplikacji.

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

Uwaga: NIE należy zaznaczać atrybutu InCallService za pomocą tego atrybutu android:exported="false"; może to spowodować brak powiązania z implementacją w trakcie rozmów.

Oprócz zaimplementowania interfejsu API InCallService musisz też zadeklarować aktywność w w pliku manifestu, który obsługuje intencję Intent#ACTION_DIAL. Poniższy przykład pokazuje, Jak to się robi:

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

Jeśli użytkownik zainstaluje i uruchomi ją po raz pierwszy, użyj metody RoleManager, aby zapytać użytkownika, czy chce, aby Twoja aplikacja być nową domyślną aplikacją telefoniczną.

Poniższy kod ilustruje, w jaki sposób Twoja aplikacja może poprosić o zostanie domyślną aplikacją do obsługi telefonu/dialera:

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

Dostęp do InCallService na urządzeniach do noszenia

    Jeśli Twoja aplikacja to aplikacja towarzysząca innej firmy i chcesz uzyskać dostęp do interfejsów InCallService API, co aplikacja może robić:

    1. Zadeklaruj uprawnienia MANAGE_ONGOING_CALLS w pliku manifestu
    2. Powiąż z urządzeniem do noszenia za pomocą CompanionDeviceManager API jako aplikacja towarzysząca. Zobacz: https://developer.android.com/guide/topics/connectivity/Companion-device-pairing
    3. Wdróż tę usługę InCallService z uprawnieniem BIND_INCALL_SERVICE

Pokazywanie powiadomień o połączeniach przychodzących

Gdy do aplikacji zostanie odebrane nowe połączenie przychodzące za pomocą numeru InCallService#onCallAdded(Call), odpowiada za wyświetlanie interfejsu dla połączeń przychodzących. Powinna to zrobić za pomocą NotificationManager interfejsów API do publikowania nowych powiadomień o połączeniach przychodzących.

Tam, gdzie aplikacja deklaruje metadane TelecomManager#METADATA_IN_CALL_SERVICE_RINGING, odpowiada za odtwarzanie dzwonka dla połączeń przychodzących. Aplikacja powinna utworzyć NotificationChannel, który określa żądany dzwonek. Na przykład:

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

Gdy aplikacja otrzyma nowe połączenie przychodzące, tworzy Notification dla: połączenie przychodzące i zostanie powiązane z kanałem powiadomień o połączeniu przychodzącym. Jako PendingIntent w powiadomieniu, co spowoduje włączenie pełnego ekranu UI połączeń przychodzących. W strukturze menedżera powiadomień Twoje powiadomienie będzie wyświetlane jako powiadomienie HUD, jeśli użytkownik aktywnie korzysta z telefonu. Gdy użytkownik nie używa tagu telefonu, zamiast niego używany jest pełnoekranowy interfejs połączeń przychodzących. Na przykład:

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