Mit einer Anruf-App können Nutzer Audio- oder Videoanrufe auf ihrem Gerät annehmen oder tätigen. Anruf-Apps verwenden für die Anrufe eine eigene Benutzeroberfläche anstelle der Standardoberfläche der Telefon App, wie im folgenden Screenshot dargestellt.
Das Android-Framework enthält das Paket android.telecom
mit Klassen, mit denen Sie eine aufrufende App gemäß dem Telekommunikations-Framework erstellen können. Das Erstellen Ihrer Anwendung gemäß dem Telekommunikations-Framework bietet folgende Vorteile:
- Ihre Anwendung arbeitet korrekt mit dem nativen Telekommunikationssubsystem des Geräts zusammen.
- Ihre App interagiert ordnungsgemäß mit anderen aufrufenden Apps, die ebenfalls dem Framework entsprechen.
- Das Framework unterstützt Ihre App bei der Verwaltung des Audio- und Videoroutings.
- Mithilfe des Frameworks kann Ihre App feststellen, ob die Aufrufe fokussiert sind.
Manifestdeklarationen und Berechtigungen
Geben Sie in Ihrem App-Manifest an, dass Ihre App die Berechtigung MANAGE_OWN_CALLS
verwendet, wie im folgenden Beispiel gezeigt:
<manifest … >
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
</manifest>
Weitere Informationen zum Deklarieren von App-Berechtigungen findest du unter Berechtigungen.
Sie müssen einen Dienst deklarieren, der die Klasse angibt, die die Klasse ConnectionService
in Ihrer App implementiert. Das Telekommunikationssubsystem erfordert, dass der Dienst die Berechtigung BIND_TELECOM_CONNECTION_SERVICE
deklariert, um eine Bindung daran vornehmen zu können. Das folgende Beispiel zeigt, wie Sie den Dienst in Ihrem App-Manifest deklarieren:
<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>
Weitere Informationen zum Deklarieren von Anwendungskomponenten, einschließlich Diensten, finden Sie unter Anwendungskomponenten.
Verbindungsdienst implementieren
Die aufrufende App muss eine Implementierung der ConnectionService
-Klasse bereitstellen, an die das Telekommunikationssubsystem gebunden werden kann.
Die Implementierung von ConnectionService
sollte die folgenden Methoden überschreiben:
onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
Das Telekommunikationssubsystem ruft diese Methode als Reaktion darauf auf, dass Ihre Anwendung
placeCall(Uri, Bundle)
aufruft, um einen neuen ausgehenden Aufruf zu erstellen. Die Anwendung gibt eine neue Instanz derConnection
-Klassenimplementierung zurück (weitere Informationen unter Verbindung implementieren), um den neuen ausgehenden Aufruf darzustellen. Sie können die ausgehende Verbindung weiter anpassen, indem Sie die folgenden Aktionen ausführen:- Ihre Anwendung sollte die Methode
setConnectionProperties(int)
mit der KonstantePROPERTY_SELF_MANAGED
als Argument aufrufen, um anzugeben, dass die Verbindung von einer aufrufenden Anwendung stammt. - Wenn Ihre Anwendung das Halten von Aufrufen unterstützt, rufen Sie die Methode
setConnectionCapabilities(int)
auf und legen Sie das Argument auf den Bitmaskenwert der KonstantenCAPABILITY_HOLD
undCAPABILITY_SUPPORT_HOLD
fest. - Verwenden Sie zum Festlegen des Namens des Aufrufs die Methode
setCallerDisplayName(String, int)
und übergeben Sie diePRESENTATION_ALLOWED
-Konstante alsint
-Parameter, um anzugeben, dass der Name des Aufrufers angezeigt werden soll. - Damit der ausgehende Aufruf den richtigen Videostatus hat, rufen Sie die Methode
setVideoState(int)
desConnection
-Objekts auf und senden Sie den Wert, der von dergetVideoState()
-Methode desConnectionRequest
-Objekts zurückgegeben wird.
- Ihre Anwendung sollte die Methode
onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
Das Telekommunikationssubsystem ruft diese Methode auf, wenn Ihre Anwendung die Methode
placeCall(Uri, Bundle)
aufruft und der ausgehende Aufruf nicht ausgeführt werden kann. In diesem Fall sollte Ihre Anwendung den Nutzer (z. B. mit einem Benachrichtigungsfeld oder einem Toast) darüber informieren, dass der ausgehende Anruf nicht getätigt werden konnte. Bei einem laufenden Notfall oder bei einem laufenden Anruf in einer anderen App, der vor dem Tätigen des Anrufs nicht in die Warteschleife gelegt werden kann, kann die App möglicherweise keine Anrufe tätigen.onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Das Telekommunikationssubsystem ruft diese Methode auf, wenn Ihre Anwendung die Methode
addNewIncomingCall(PhoneAccountHandle, Bundle)
aufruft, um das System über einen neuen eingehenden Aufruf in Ihrer Anwendung zu informieren. Ihre Anwendung gibt eine neue Instanz IhrerConnection
-Implementierung zurück (weitere Informationen finden Sie unter Verbindung implementieren), um den neuen eingehenden Aufruf darzustellen. Sie können die eingehende Verbindung weiter anpassen, indem Sie die folgenden Aktionen ausführen:- Ihre Anwendung sollte die Methode
setConnectionProperties(int)
mit der KonstantePROPERTY_SELF_MANAGED
als Argument aufrufen, um anzugeben, dass die Verbindung von einer aufrufenden Anwendung stammt. - Wenn Ihre Anwendung das Halten von Aufrufen unterstützt, rufen Sie die Methode
setConnectionCapabilities(int)
auf und legen Sie das Argument auf den Bitmaskenwert der KonstantenCAPABILITY_HOLD
undCAPABILITY_SUPPORT_HOLD
fest. - Verwenden Sie zum Festlegen des Namens des Aufrufs die Methode
setCallerDisplayName(String, int)
und übergeben Sie diePRESENTATION_ALLOWED
-Konstante alsint
-Parameter, um anzugeben, dass der Name des Aufrufers angezeigt werden soll. - Verwenden Sie die Methode
setAddress(Uri, int)
des ObjektsConnection
, um die Telefonnummer oder Adresse des eingehenden Anrufs anzugeben. - Damit der ausgehende Aufruf den richtigen Videostatus hat, rufen Sie die Methode
setVideoState(int)
desConnection
-Objekts auf und senden Sie den Wert, der von dergetVideoState()
-Methode desConnectionRequest
-Objekts zurückgegeben wird.
- Ihre Anwendung sollte die Methode
onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
Das Telekommunikationssubsystem ruft diese Methode auf, wenn Ihre Anwendung die Methode
addNewIncomingCall(PhoneAccountHandle, Bundle)
aufruft, um Telecom über einen neuen eingehenden Anruf zu informieren. Der eingehende Anruf ist jedoch nicht zulässig. Weitere Informationen finden Sie unter Einschränkungen für Aufrufe. Ihre App sollte den eingehenden Anruf stumm ablehnen und den Nutzer optional mit einer Benachrichtigung über den verpassten Anruf informieren.
Verbindung implementieren
Ihre Anwendung sollte eine abgeleitete Klasse von Connection
erstellen, um die Aufrufe in Ihrer Anwendung darzustellen. Sie sollten die folgenden Methoden in Ihrer Implementierung überschreiben:
onShowIncomingCallUi()
Das Telekommunikationssubsystem ruft diese Methode auf, wenn Sie einen neuen eingehenden Anruf hinzufügen und die Anwendung die UI für eingehende Anrufe anzeigen sollte.
onCallAudioStateChanged(CallAudioState)
Das Telekommunikationssubsystem ruft diese Methode auf, um Ihre App darüber zu informieren, dass sich die aktuelle Audioroute oder der aktuelle Audiomodus geändert hat. Dieser wird als Reaktion darauf aufgerufen, dass Ihre Anwendung den Audiomodus mit der Methode
setAudioRoute(int)
ändert. Diese Methode kann auch aufgerufen werden, wenn das System die Audioroute ändert, z. B. wenn die Verbindung eines Bluetooth-Headsets getrennt wird.onHold()
Das Telekommunikationssubsystem ruft diese Methode auf, wenn ein Anruf gehalten werden soll. Als Antwort auf diese Anfrage sollte Ihre App den Aufruf halten und dann die Methode
setOnHold()
aufrufen, um das System darüber zu informieren, dass der Anruf gehalten wird. Das Telekommunikationssubsystem kann diese Methode aufrufen, wenn ein Anrufdienst wie Android Auto, der deinen Anruf anzeigt, eine Nutzeranfrage weiterleiten möchte, um den Anruf zu halten. Das Telekommunikationssubsystem ruft diese Methode auch dann auf, wenn der Nutzer einen Aufruf in einer anderen Anwendung aktiviert. Weitere Informationen zu Diensten während des Anrufs finden Sie unterInCallService
.onUnhold()
Das Telekommunikationssubsystem ruft diese Methode auf, wenn ein angehaltener Anruf fortgesetzt werden soll. Sobald Ihre App den Aufruf fortgesetzt hat, sollte sie die Methode
setActive()
aufrufen, um das System darüber zu informieren, dass der Aufruf nicht mehr gehalten wird. Das Telekommunikationssubsystem kann diese Methode aufrufen, wenn ein im Anruf befindlicher Dienst wie Android Auto, der Ihren Anruf anzeigt, eine Anfrage zum Fortsetzen des Anrufs weiterleiten möchte. Weitere Informationen zu Diensten während des Anrufs finden Sie unterInCallService
.onAnswer()
Das Telekommunikationssubsystem ruft diese Methode auf, um Ihre App darüber zu informieren, dass ein eingehender Anruf angenommen werden soll. Sobald Ihre App den Aufruf angenommen hat, sollte die Methode
setActive()
aufgerufen werden, um das System darüber zu informieren, dass der Aufruf angenommen wurde. Das Telekommunikationssubsystem kann diese Methode aufrufen, wenn Ihre App einen neuen eingehenden Anruf hinzufügt und in einer anderen App bereits ein Anruf läuft, der nicht auf „Halten“ gesetzt werden kann. Das Telekommunikationssubsystem zeigt in diesen Instanzen die UI für eingehende Anrufe im Namen Ihrer Anwendung an. Das Framework bietet eine überlastete Methode, mit der der Videostatus angegeben werden kann, in dem der Anruf angenommen werden soll. Weitere Informationen finden Sie unteronAnswer(int)
.onReject()
Das Telekommunikationssubsystem ruft diese Methode auf, wenn ein eingehender Anruf abgelehnt werden soll. Sobald Ihre App den Aufruf abgelehnt hat, sollte
setDisconnected(DisconnectCause)
aufgerufen undREJECTED
als Parameter angegeben werden. Ihre App sollte dann die Methodedestroy()
aufrufen, um das System darüber zu informieren, dass die App den Aufruf verarbeitet hat. Das Telekommunikationssubsystem ruft diese Methode auf, wenn der Nutzer einen eingehenden Anruf von Ihrer Anwendung abgelehnt hat.onDisconnect()
Das Telekommunikationssubsystem ruft diese Methode auf, wenn ein Anruf getrennt werden soll. Sobald der Aufruf beendet ist, sollte Ihre App die Methode
setDisconnected(DisconnectCause)
aufrufen undLOCAL
als Parameter angeben, um anzugeben, dass die Verbindung des Aufrufs aufgrund einer Nutzeranfrage getrennt wurde. Ihre App sollte dann die Methodedestroy()
aufrufen, um das Telekommunikationssubsystem darüber zu informieren, dass die App den Aufruf verarbeitet hat. Das System kann diese Methode aufrufen, wenn der Nutzer einen Anruf über einen anderen Dienst während des Anrufs getrennt hat, z. B. Android Auto. Das System ruft diese Methode auch auf, wenn die Verbindung des Anrufs getrennt werden muss, damit andere Anrufe getätigt werden können, z. B. wenn der Nutzer einen Notruf absetzen möchte. Weitere Informationen zu Diensten während eines Anrufs finden Sie unterInCallService
.
Häufige Anrufszenarien verarbeiten
Wenn Sie die ConnectionService
API in Ihrem Aufrufablauf verwenden, interagieren Sie mit den anderen Klassen im Paket android.telecom
. In den folgenden Abschnitten werden gängige Aufrufszenarien und die dafür vorgesehenen APIs in Ihrer Anwendung beschrieben.
Eingehende Anrufe annehmen
Der Ablauf zur Verarbeitung eingehender Anrufe ändert sich unabhängig davon, ob Anrufe in anderen Apps stattfinden oder nicht. Der Grund für den Unterschied zwischen den Abläufen besteht darin, dass das Telekommunikations-Framework einige Einschränkungen festlegen muss, wenn aktive Aufrufe in anderen Apps vorhanden sind, um eine stabile Umgebung für alle aufrufenden Apps auf dem Gerät zu gewährleisten. Weitere Informationen finden Sie unter Aufrufeinschränkungen.
Keine aktiven Anrufe in anderen Apps
So kannst du eingehende Anrufe annehmen, während keine aktiven Anrufe in anderen Apps aktiv sind:
- Ihre App empfängt neue eingehende Anrufe mit den üblichen Methoden.
- Mit der Methode
addNewIncomingCall(PhoneAccountHandle, Bundle)
informieren Sie das Telekommunikationssubsystem über den neuen eingehenden Anruf. - Das Telekommunikationssubsystem bindet sich an die Implementierung
ConnectionService
Ihrer Anwendung und fordert mit der MethodeonCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
eine neue Instanz der KlasseConnection
an, die den neuen eingehenden Aufruf darstellt. - Das Telekommunikationssubsystem teilt der Anwendung mit, dass die Benutzeroberfläche für eingehende Anrufe mithilfe der Methode
onShowIncomingCallUi()
angezeigt werden soll. - Ihre App zeigt die eingehende UI über eine Benachrichtigung mit einem verknüpften Full-Screen-Intent an. Weitere Informationen findest du unter
onShowIncomingCallUi()
. - Rufen Sie die Methode
setActive()
auf, wenn der Nutzer den eingehenden Anruf annimmt, oder rufen Sie die MethodesetDisconnected(DisconnectCause)
auf, indem SieREJECTED
als Parameter angeben, gefolgt von einem Aufruf der Methodedestroy()
, wenn der Nutzer den eingehenden Anruf ablehnt.
Aktive Anrufe in anderen Apps, die nicht gehalten werden können
So nehmen Sie eingehende Anrufe an, während es aktive Anrufe in anderen Apps gibt, die nicht gehalten werden können:
- Ihre App empfängt neue eingehende Anrufe mit den üblichen Methoden.
- Mit der Methode
addNewIncomingCall(PhoneAccountHandle, Bundle)
informieren Sie das Telekommunikationssubsystem über den neuen eingehenden Anruf. - Das Telekommunikationssubsystem bindet sich an die
ConnectionService
-Implementierung Ihrer Anwendung und fordert mit der MethodeonCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
eine neue Instanz desConnection
-Objekts an, das den neuen eingehenden Aufruf darstellt. - Das Telekommunikationssubsystem zeigt die Benutzeroberfläche für eingehende Anrufe für Ihren eingehenden Anruf an.
- Wenn der Nutzer den Aufruf annimmt, ruft das Telekommunikationssubsystem die Methode
onAnswer()
auf. Sie sollten die MethodesetActive()
aufrufen, um dem Telekommunikationssubsystem zu signalisieren, dass der Aufruf jetzt verbunden ist. - Wenn der Nutzer den Aufruf ablehnt, ruft das Telekommunikationssubsystem die Methode
onReject()
auf. Sie sollten die MethodesetDisconnected(DisconnectCause)
aufrufen undREJECTED
als Parameter angeben, gefolgt von einem Aufruf der Methodedestroy()
.
Ausgehende Anrufe tätigen
Der Ablauf zum Tätigen eines ausgehenden Anrufs beinhaltet die Möglichkeit, dass der Aufruf aufgrund von Einschränkungen, die vom Telekommunikations-Framework auferlegt werden, nicht getätigt werden kann. Weitere Informationen finden Sie unter Aufrufeinschränkungen.
So können Sie einen ausgehenden Anruf tätigen:
- Der Nutzer initiiert einen ausgehenden Anruf in Ihrer App.
- Verwenden Sie die Methode
placeCall(Uri, Bundle)
, um das Telekommunikationssubsystem über den neuen ausgehenden Anruf zu informieren. Beachten Sie bei den Methodenparametern Folgendes:- Der Parameter
Uri
steht für die Adresse, an die der Aufruf gesendet wird. Verwenden Sie für normale Telefonnummern das URI-Schematel:
. - Mit dem Parameter
Bundle
können Sie Informationen zu Ihrer aufrufenden App angeben. Dazu fügen Sie dasPhoneAccountHandle
-Objekt Ihrer App zumEXTRA_PHONE_ACCOUNT_HANDLE
-Extra hinzu. Ihre App muss bei jedem ausgehenden Anruf das ObjektPhoneAccountHandle
bereitstellen. - Mit dem Parameter
Bundle
können Sie auch angeben, ob der ausgehende Anruf Video umfasst. Dazu geben Sie den WertSTATE_BIDIRECTIONAL
im zusätzlichenEXTRA_START_CALL_WITH_VIDEO_STATE
an. Beachten Sie, dass das Telekommunikationssubsystem Videoanrufe standardmäßig an die Freisprechfunktion weiterleitet.
- Der Parameter
- Das Telekommunikationssubsystem bindet sich an die
ConnectionService
-Implementierung Ihrer Anwendung. - Wenn Ihre Anwendung keine ausgehenden Anrufe tätigen kann, ruft das Telekommunikationssubsystem die Methode
onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
auf, um die Anwendung zu informieren, dass der Aufruf zum aktuellen Zeitpunkt nicht möglich ist. Der Nutzer sollte in der App darüber informiert werden, dass der Anruf nicht möglich ist. - Wenn Ihre Anwendung den ausgehenden Aufruf ausführen kann, ruft das Telekommunikationssubsystem die Methode
onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
auf. Die App sollte eine Instanz derConnection
-Klasse zurückgeben, die den neuen ausgehenden Anruf darstellt. Weitere Informationen zu den Attributen, die in der Verbindung festgelegt werden sollten, finden Sie unter Verbindungsdienst implementieren. - Wenn der ausgehende Anruf verbunden wurde, rufen Sie die Methode
setActive()
auf, um das Telekommunikationssubsystem darüber zu informieren, dass der Aufruf aktiv ist.
Anruf beenden
So beenden Sie einen Anruf:
- Rufen Sie das
setDisconnected(DisconnectCause)
auf, dasLOCAL
als Parameter sendet, wenn der Nutzer den Aufruf beendet hat, oderREMOTE
als Parameter, wenn die andere Partei den Aufruf beendet hat. - Rufen Sie die Methode
destroy()
auf.
Aufrufeinschränkungen
Um eine einheitliche und einfache Anruferfahrung für Ihre Nutzer zu gewährleisten, erzwingt das Telekommunikations-Framework einige Einschränkungen für die Verwaltung von Anrufen auf dem Gerät. Angenommen, der Nutzer hat zwei aufrufende Apps installiert, die die selbstverwaltete ConnectionService
API implementieren, nämlich FooTalk und BarTalk. In diesem Fall gelten die folgenden Einschränkungen:
Auf Geräten mit API-Level 27 oder niedriger kann jeweils nur eine App einen laufenden Aufruf aufrechterhalten. Diese Einschränkung bedeutet, dass ein Nutzer während eines laufenden Anrufs mit der FooTalk-App keinen neuen Anruf initiieren oder empfangen kann.
Wenn auf Geräten mit API-Level 28 oder höher sowohl FooTalk als auch BarTalk die Berechtigungen
CAPABILITY_SUPPORT_HOLD
undCAPABILITY_HOLD
deklariert, kann der Nutzer mehr als einen laufenden Anruf aufrechterhalten, indem er zwischen den Apps wechselt, um einen weiteren Anruf zu initiieren oder anzunehmen.Wenn der Nutzer regelmäßige verwaltete Anrufe tätigt (z. B. über die integrierte Telefon App oder Telefon App), kann er nicht an Anrufen teilnehmen, die aus Anruf-Apps stammen. Das bedeutet, dass ein Nutzer, der über seinen Mobilfunkanbieter verbunden ist, nicht gleichzeitig an einem FooTalk- oder BarTalk-Anruf teilnehmen kann.
Das Telekommunikationssubsystem trennt die Anrufe Ihrer App, wenn der Nutzer einen Notruf tätigt.
Solange der Nutzer einen Notruf absetzt, kann die App keine Anrufe empfangen oder tätigen.
Wenn während eines eingehenden Anrufs in der anderen Anruf-App ein laufender Anruf in der App eingeht, werden durch die Annahme des eingehenden Anrufs alle laufenden Anrufe in der anderen App beendet. In der App sollte nicht die normale Benutzeroberfläche für eingehende Anrufe angezeigt werden. Das Telekommunikations-Framework zeigt die Benutzeroberfläche für eingehende Anrufe an und informiert den Nutzer, dass durch Annehmen des neuen Anrufs die laufenden Anrufe beendet werden. Wenn der Nutzer also an einem FooTalk-Anruf teilnimmt und die BarTalk-App einen eingehenden Anruf empfängt, informiert das Telekommunikations-Framework den Nutzer darüber, dass er einen neuen eingehenden BarTalk-Anruf hat und dass er durch Annehmen des BarTalk-Anrufs beendet wird.