Un'applicazione telefonica predefinita consente al framework Android Telecom di informare l'applicazione dello stato della chiamata utilizzando il gestore dei ruoli e il servizio durante la chiamata per creare una sostituzione dell'app per smartphone predefinita su un dispositivo Android e implementare l'API InCallService. La tua implementazione deve soddisfare i seguenti requisiti:
Non deve avere funzionalità di chiamata e deve consistere esclusivamente nell'interfaccia utente per le chiamate. Deve gestire tutte le chiamate di cui il framework Telecom è a conoscenza e non fare ipotesi sulla natura delle chiamate. Ad esempio, non deve presupporre che le chiamate siano chiamate di telefonia basate su SIM, né implementare restrizioni sulle chiamate basate su un qualsiasi servizio ConnectionService, come l'applicazione di restrizioni alla telefonia per le videochiamate.
Un'app per le chiamate consente agli utenti di ricevere o effettuare chiamate audio o videochiamate sul proprio dispositivo. Le app per le chiamate utilizzano una propria interfaccia utente anziché utilizzare l'interfaccia predefinita dell'app Telefono, come mostrato nello screenshot seguente.
Il framework Android include il pacchetto android.telecom
, che
contiene classi che aiutano a creare un'app per le chiamate secondo lo standard
il modello di machine learning. Creare l'app in base al framework per le telecomunicazioni fornisce la
i seguenti vantaggi:
- La tua app interagisce correttamente con il sottosistema di telecomunicazioni nativo nella dispositivo.
- La tua app interagisce correttamente con altre app di chiamata che rispettano anche le il framework.
- Il framework consente all'app di gestire il routing audio e video.
- Il framework aiuta la tua app a determinare se le chiamate sono state attivate.
Dichiarazioni e autorizzazioni del file manifest
Nel file manifest dell'app, dichiara che l'app utilizza la classe
MANAGE_OWN_CALLS
come mostrato nell'esempio seguente:
<manifest … >
<uses-permission android:name="android.permission.MANAGE_OWN_CALLS"/>
</manifest>
Per ulteriori informazioni sulla dichiarazione delle autorizzazioni app, vedi Autorizzazioni.
Devi dichiarare un servizio che specifica la classe che implementa
ConnectionService
corso nella tua app. Il settore delle telecomunicazioni
richiede che il servizio dichiari che l'autorizzazione BIND_TELECOM_CONNECTION_SERVICE
essere in grado di associarsi. L'esempio seguente mostra come dichiarare il servizio in
del file manifest dell'app:
<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>
Per ulteriori informazioni sulla dichiarazione dei componenti dell'app, inclusi i servizi, vedi Componenti dell'app.
Implementare il servizio di connessione
L'app per le chiamate deve fornire un'implementazione della classe ConnectionService
a cui il sottosistema di telecomunicazioni può associarsi.
L'implementazione di ConnectionService
dovrebbe sostituire
utilizza i seguenti metodi:
onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
Il sottosistema di telecomunicazioni chiama questo metodo in risposta a la tua app chiama
placeCall(Uri, Bundle)
per creare una nuova chiamata in uscita. L'app restituisce una nuova istanza dell'implementazione della classeConnection
. Per ulteriori informazioni, consulta Implementa la connessione) per rappresentare la nuova chiamata in uscita. Puoi personalizzare ulteriormente la connessione in uscita eseguendo le seguenti azioni:- La tua app deve chiamare il metodo
setConnectionProperties(int)
con la costantePROPERTY_SELF_MANAGED
come argomento per indicare che la connessione proviene da un'app per la chiamata. - Se la tua app supporta la messa in attesa delle chiamate, chiama il metodo
setConnectionCapabilities(int)
e imposta il al valore della maschera di bit delle costantiCAPABILITY_HOLD
eCAPABILITY_SUPPORT_HOLD
. - Per impostare il nome del chiamante, usa il metodo
setCallerDisplayName(String, int)
superandoPRESENTATION_ALLOWED
costante come il parametroint
per indicare che il nome del chiamante deve in cui possono apparire. - Per assicurarti che la chiamata in uscita abbia lo stato video appropriato, chiama il
setVideoState(int)
dell'oggettoConnection
e invia il valore restituito dalgetVideoState()
delConnectionRequest
oggetto.
- La tua app deve chiamare il metodo
onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
Il sottosistema di telecomunicazioni chiama questo metodo quando la tua app chiama il metodo
placeCall(Uri, Bundle)
e la chiamata in uscita non può in fase di posizionamento. In risposta a questa situazione, l'app deve informare l'utente (ad ad esempio utilizzando una casella di avviso o un avviso popup). inserito. La tua app potrebbe non riuscire a effettuare una chiamata se è in corso un chiamata di emergenza o se è in corso una chiamata in un'altra app che non può essere mettilo in attesa prima di effettuare la chiamata.onCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
Il sottosistema di telecomunicazioni chiama questo metodo quando la tua app chiama il metodo
addNewIncomingCall(PhoneAccountHandle, Bundle)
per informare il sistema di una nuova chiamata in arrivo nella tua app. La tua app restituisce un nuova istanza dell'implementazioneConnection
(ad per maggiori informazioni, consulta Implementare la connessione). per rappresentare la nuova chiamata in arrivo. Puoi personalizzare ulteriormente la connessione eseguendo le seguenti azioni:- La tua app deve chiamare il metodo
setConnectionProperties(int)
con la costantePROPERTY_SELF_MANAGED
come argomento per indicare che la connessione proviene da un'app per la chiamata. - Se la tua app supporta la messa in attesa delle chiamate, chiama il metodo
setConnectionCapabilities(int)
e imposta il al valore della maschera di bit delle costantiCAPABILITY_HOLD
eCAPABILITY_SUPPORT_HOLD
. - Per impostare il nome del chiamante, usa il metodo
setCallerDisplayName(String, int)
superandoPRESENTATION_ALLOWED
costante come il parametroint
per indicare che il nome del chiamante deve in cui possono apparire. - Per specificare il numero di telefono o l'indirizzo della chiamata in arrivo, utilizza il
Metodo
setAddress(Uri, int)
dell'oggettoConnection
. - Per assicurarti che la chiamata in uscita abbia lo stato video appropriato, chiama il
setVideoState(int)
dell'oggettoConnection
e invia il valore restituito dalgetVideoState()
delConnectionRequest
oggetto.
- La tua app deve chiamare il metodo
onCreateIncomingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
Il sottosistema di telecomunicazioni chiama questo metodo quando la tua app chiama il metodo
addNewIncomingCall(PhoneAccountHandle, Bundle)
per informare Telecom di una nuova chiamata in arrivo, ma non è consentita (per maggiori informazioni, consulta i vincoli di chiamata). La tua app dovrebbe rifiutare automaticamente la chiamata in arrivo, pubblicando una notifica per informare l'utente della chiamata senza risposta.
Implementa la connessione
L'app deve creare una sottoclasse Connection
per
che rappresentano le chiamate nella tua app. Devi sostituire i seguenti metodi in
la tua implementazione:
onShowIncomingCallUi()
Il sottosistema di telecomunicazioni chiama questo metodo quando aggiungi una nuova chiamata in arrivo e nell'app dovrebbe essere visualizzata la UI delle chiamate in arrivo.
onCallAudioStateChanged(CallAudioState)
Il sottosistema di telecomunicazioni chiama questo metodo per informare la tua app che l'audio corrente o la modalità di navigazione sono cambiate. Viene chiamato in risposta al cambiamento dell'app modalità audio utilizzando
setAudioRoute(int)
. Questo metodo può essere chiamato anche se il sistema cambia il percorso audio. (ad esempio, quando si disconnettono le cuffie Bluetooth).onHold()
Il sottosistema di telecomunicazioni chiama questo metodo quando vuole mettere una chiamata in attesa. In risposta a questa richiesta, l'app deve sospendere la chiamata e richiamare il metodo
setOnHold()
metodo per informare il sistema che la chiamata è in attesa. Il sottosistema di telecomunicazioni può chiamare questo metodo quando un servizio durante le chiamate, come Android Auto, che indica che la chiamata vuole inoltrare la richiesta di un utente di mettere la chiamata in attesa. Il sottosistema di telecomunicazioni chiama anche questo metodo se l'utente effettua una chiamata attiva in un'altra app. Per ulteriori informazioni informazioni sui servizi disponibili durante le chiamate, vediInCallService
.onUnhold()
Il sottosistema di telecomunicazioni chiama questo metodo quando vuole riprendere una chiamata che è stata messa in attesa. Una volta ripresa l'app la chiamata, dovrebbe richiamare
setActive()
per informare il sistema che la chiamata non è più in attesa. Il settore delle telecomunicazioni potrebbe chiamare questo metodo quando un servizio in-call, come Android Auto, che indica che la tua chiamata vuole inoltrare una richiesta per riprenderla. Per Per ulteriori informazioni sui servizi disponibili durante le chiamate, consultaInCallService
.onAnswer()
Il sottosistema di telecomunicazioni chiama questo metodo per informare alla tua app di rispondere a una chiamata in arrivo. Dopo che l'app ha risposto la chiamata, dovrebbe richiamare
setActive()
per informare il sistema che la chiamata ha ricevuto risposta. Il settore delle telecomunicazioni il sottosistema potrebbe chiamare questo metodo quando la tua app aggiunge una nuova chiamata in arrivo e è già in corso una chiamata in un'altra app che non può essere messa in attesa. Il sottosistema di telecomunicazioni visualizza l'UI delle chiamate in arrivo per conto della tua app in queste istanze. Il framework offre un metodo di sovraccarico che fornisce per specificare lo stato del video in cui rispondere alla chiamata. Per ulteriori informazioni informazioni, vedionAnswer(int)
.onReject()
Il sottosistema di telecomunicazioni chiama questo metodo quando vuole rifiutare un messaggio in arrivo chiamata. Una volta che l'app ha rifiutato la chiamata, deve chiamare
setDisconnected(DisconnectCause)
e specificareREJECTED
come parametro. La tua app dovrebbe quindi chiama il metododestroy()
per informare il sistema su cui l'app ha elaborato la chiamata. Il sottosistema di telecomunicazione questo metodo quando l'utente rifiuta una chiamata in arrivo dalla tua app.onDisconnect()
Il sottosistema di telecomunicazioni chiama questo metodo quando vuole disconnettere una chiamata. Al termine della chiamata, l'app deve chiamare il metodo
setDisconnected(DisconnectCause)
e specificareLOCAL
come parametro per indicare che richiesta dell'utente ha causato la disconnessione della chiamata. L'app dovrebbe quindi chiamare Metododestroy()
per informare il servizio di telecomunicazioni sottosistema con cui l'app ha elaborato la chiamata. Il sistema potrebbe chiamare questo metodo Quando l'utente ha disconnesso una chiamata tramite un altro servizio interno, come Android Auto. Il sistema chiama questo metodo anche quando la chiamata deve essere disconnesso per consentire l'esecuzione di altre chiamate, ad esempio se l'utente vuole per effettuare una chiamata di emergenza. Per ulteriori informazioni sui servizi disponibili durante le chiamate, vediInCallService
.
Gestire scenari di chiamata comuni
Utilizzo dell'API ConnectionService
nella chiamata
prevede l'interazione con le altre classi nell'android.telecom
pacchetto. Le seguenti sezioni descrivono scenari di chiamata comuni e il modo in cui
devono utilizzare le API per gestirli.
Risposta alle chiamate in arrivo
Il flusso per gestire le chiamate in arrivo cambia se sono presenti chiamate in altre app o meno. Il motivo della differenza nei flussi è che il framework per le telecomunicazioni devi stabilire alcuni vincoli quando ci sono chiamate attive in altre app per garantire un ambiente stabile per tutte le app di chiamata sul dispositivo. Per ulteriori informazioni informazioni, consulta la sezione Limitazioni delle chiamate.
Nessuna chiamata attiva in altre app
Per rispondere alle chiamate in arrivo quando non ci sono chiamate attive in altre app, segui questi passaggi:
- L'app riceve una nuova chiamata in arrivo utilizzando i suoi consueti meccanismi.
- Usa il metodo
addNewIncomingCall(PhoneAccountHandle, Bundle)
per informare il sottosistema di telecomunicazioni della nuova chiamata in arrivo. - Il sottosistema di telecomunicazioni si collega all'implementazione di
ConnectionService
della tua app e richiede una nuova istanza della classeConnection
che rappresenta la nuova utilizzando il metodoonCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
. - Il sottosistema di telecomunicazioni comunica alla tua app che deve mostrare la chiamata in arrivo
utente usando il metodo
onShowIncomingCallUi()
. - La tua app mostra la UI in entrata tramite una notifica con un
intent a schermo intero. Per ulteriori informazioni, vedi
onShowIncomingCallUi()
. - Chiama il metodo
setActive()
se l'utente accetta la chiamata in arrivo osetDisconnected(DisconnectCause)
specificaREJECTED
come parametro seguito da al metododestroy()
se l'utente rifiuta la chiamata in arrivo.
Chiamate attive in altre app che non possono essere messe in attesa
Per rispondere alle chiamate in arrivo quando sono presenti chiamate attive in altre app che non possono essere messo in attesa, svolgi i seguenti passaggi:
- L'app riceve una nuova chiamata in arrivo utilizzando i suoi consueti meccanismi.
- Usa il metodo
addNewIncomingCall(PhoneAccountHandle, Bundle)
per informare il sottosistema di telecomunicazioni della nuova chiamata in arrivo. - Il sottosistema di telecomunicazioni si collega all'implementazione di
ConnectionService
della tua app e richiede una nuova istanza dell'oggettoConnection
che rappresenta il nuovo chiamata in arrivo con il metodoonCreateIncomingConnection(PhoneAccountHandle, ConnectionRequest)
. - Il sottosistema di telecomunicazione visualizza l'UI della chiamata in arrivo per quella in arrivo.
- Se l'utente accetta la chiamata, il sottosistema di telecomunicazioni chiama il metodo
onAnswer()
. Devi chiamare il metodosetActive()
per indicare al servizio di telecomunicazione a cui è ora connessa la chiamata. - Se l'utente rifiuta la chiamata, il sottosistema di telecomunicazioni chiama il metodo
onReject()
. Devi chiamare il metodosetDisconnected(DisconnectCause)
che specificaREJECTED
come parametro seguito da un al metododestroy()
.
Effettuare chiamate in uscita
Il flusso per effettuare una chiamata in uscita implica gestire la possibilità che impossibile effettuare una chiamata a causa dei vincoli imposti dal framework di telecom. Per ulteriori informazioni, consulta la sezione Limitazioni delle chiamate.
Per effettuare una chiamata in uscita:
- L'utente avvia una chiamata in uscita all'interno dell'app.
- Utilizza il metodo
placeCall(Uri, Bundle)
per informare il un sottosistema di telecomunicazioni sulla nuova chiamata in uscita. Prendi le seguenti considerazioni sui parametri del metodo:- Il parametro
Uri
rappresenta l'indirizzo in cui a cui viene effettuata la chiamata. Per i numeri di telefono normali, utilizza l'URItel:
. - Il parametro
Bundle
ti consente di fornire informazioni sulla tua app per le chiamate, aggiungendo l'oggettoPhoneAccountHandle
della tua app all'extra diEXTRA_PHONE_ACCOUNT_HANDLE
. Il tuo l'app deve fornire l'oggettoPhoneAccountHandle
a ogni chiamata in uscita. - Il parametro
Bundle
ti consente anche di specificare se la chiamata in uscita include il video specificando il valoreSTATE_BIDIRECTIONAL
nel extraEXTRA_START_CALL_WITH_VIDEO_STATE
. Tieni presente che, per impostazione predefinita, il sottosistema di telecomunicazioni instrada le videochiamate al vivavoce.
- Il parametro
- Il sottosistema di telecomunicazioni si collega a
ConnectionService
dell'app implementazione. - Se la tua app non è in grado di effettuare una chiamata in uscita, il sottosistema Telecomunicazioni
il metodo
onCreateOutgoingConnectionFailed(PhoneAccountHandle, ConnectionRequest)
per comunicare alla tua app che non è possibile effettuare la chiamata al momento. La tua app Deve informare l'utente che non è possibile effettuare la chiamata. - Se la tua app è in grado di effettuare la chiamata in uscita, il sottosistema di telecomunicazione
onCreateOutgoingConnection(PhoneAccountHandle, ConnectionRequest)
. L'app deve restituire un'istanza della classeConnection
per rappresentare la nuova chiamata in uscita. Per sulle proprietà da impostare nella connessione, consulta Implementare il servizio di connessione. - Dopo aver connesso la chiamata in uscita, chiama il metodo
setActive()
per informare il sottosistema di telecomunicazioni che la chiamata sia attiva.
Terminare una chiamata
Per terminare una chiamata, procedi nel seguente modo:
- Richiama
setDisconnected(DisconnectCause)
che inviaLOCAL
come parametro se l'utente hai terminato la chiamata o inviaREMOTE
come parametro se l'altra parte ha terminato la chiamata. - Chiama il metodo
destroy()
.
Vincoli delle chiamate
Per garantire agli utenti un'esperienza di chiamata semplice e coerente, lo strumento
applica alcuni vincoli per la gestione delle chiamate sul dispositivo. Per
Ad esempio, supponiamo che l'utente abbia installato due app di chiamata che implementano
l'API ConnectionService
autogestita, FooTalk
BarTalk. In questo caso, si applicano i seguenti vincoli:
Sui dispositivi con livello API 27 o precedente, solo un'app può mantenere un chiamata in corso in qualsiasi momento. Questo vincolo significa che, mentre un utente ha chiamata in corso tramite l'app FooTalk, l'app BarTalk non può avviare né ricevere una nuova chiamata.
Sui dispositivi in esecuzione con livello API 28 o superiore, se sia FooTalk che BarTalk dichiarare
CAPABILITY_SUPPORT_HOLD
eCAPABILITY_HOLD
autorizzazioni, l'utente può mantenere più di una chiamata in corso passare da un'app all'altra per avviare o rispondere a un'altra chiamata.Se l'utente è coinvolto in chiamate gestite standard (ad esempio, utilizzando integrata Telefono o Telefono), l'utente non può partecipare alle chiamate app per chiamare. Ciò significa che se l'utente è in una normale chiamata utilizzando il suo operatore di telefonia mobile, non possono partecipare anche a una chiamata FooTalk o BarTalk.
Il sottosistema di telecomunicazioni disconnette le chiamate della tua app se l'utente chiama chiamata di emergenza.
L'app non può ricevere o effettuare chiamate mentre l'utente è in una chiamata di emergenza.
Se è in corso una chiamata in un'altra app per le chiamate quando l'app riceve una chiamata in arrivo, se si risponde alla chiamata in arrivo, tutte le chiamate in corso un'altra app. L'app non dovrebbe visualizzare la sua normale interfaccia utente per le chiamate in arrivo. Il framework di telecomunicazione visualizza l'interfaccia utente della chiamata in arrivo e informa l'utente che risponde alla nuova chiamata terminerà le chiamate in corso. Questo significa che se l'utente sta partecipando a una chiamata FooTalk e l'app BarTalk riceve chiamata in arrivo, il framework di telecomunicazione informa l'utente che ha una nuova chiamata BarTalk in arrivo e che rispondendo alla chiamata BarTalk Chiamata FooTalk.
Impostazione dell'app per telefono predefinita
L'app Telefono/Telefono predefinita fornisce l'interfaccia utente durante la chiamata mentre il dispositivo è
durante una chiamata. Offre inoltre all'utente un mezzo per avviare chiamate e visualizzare una cronologia delle chiamate
sul loro dispositivo. Un dispositivo è integrato con un'app Telefono/Telefono predefinita fornita dal sistema. L'utente
può scegliere un'unica app che assuma questo ruolo dall'app di sistema. Un'app che vuole
Il completamento di questo ruolo utilizza RoleManager
per richiedere di compilare il
Ruolo RoleManager.ROLE_DIALER
.
L'app Telefono predefinita fornisce un'interfaccia utente durante una chiamata e il dispositivo è
non in modalità automobile (ad esempio, UiModeManager#getCurrentModeType()
non
Configuration.UI_MODE_TYPE_CAR
).
Per ricoprire il ruolo RoleManager.ROLE_DIALER
, un'app deve soddisfare un
di requisiti:
- Deve gestire l'intent
Intent#ACTION_DIAL
. Ciò significa che l'app deve fornire un'interfaccia utente con tastierino numerico per consentire all'utente di avviare chiamate in uscita. - Deve implementare completamente l'API
InCallService
e fornire una chiamata in arrivo UI e una UI per le chiamate in corso.
Nota: se l'app che compila il RoleManager.ROLE_DIALER
restituisce un
null
InCallService
durante l'associazione, il framework Telecom verrà disattivato automaticamente
all'utilizzo dell'app Telefono precaricata sul dispositivo. Il sistema visualizza una notifica all'indirizzo
l'utente ha comunicato che la chiamata è proseguita utilizzando l'app Telefono precaricata. Il tuo
l'app non deve mai restituire un'associazione null
. ciò significa che non soddisfa
requisiti di RoleManager.ROLE_DIALER
.
Nota: se la tua app riempie RoleManager.ROLE_DIALER
e apporta modifiche in
a causa del quale non soddisfa più i requisiti di questo ruolo,
RoleManager
rimuoverà automaticamente la tua app dal ruolo e chiuderà
la tua app. Ad esempio, se utilizzi
PackageManager.setComponentEnabledSetting(ComponentName, int, int)
per
disattivare in modo programmatico il InCallService
dichiarato dalla tua app nel file manifest,
non soddisferà più i requisiti previsti
RoleManager.ROLE_DIALER
.
La tastiera precaricata verrà SEMPRE usata quando l'utente effettua una chiamata di emergenza, anche se
l'app riempie il ruolo RoleManager.ROLE_DIALER
. Per garantire un'ottimizzazione
durante le chiamate di emergenza, la tastiera predefinita deve SEMPRE utilizzare
TelecomManager.placeCall(Uri, Bundle)
per effettuare chiamate (incluse
chiamate di emergenza). Ciò garantisce che la piattaforma possa verificare che la richiesta provenga da
la tastiera predefinita. Se un'app Telefono non precaricata utilizza Intent#ACTION_CALL
per posizionare un
chiamata di emergenza, verrà passata all'app Telefono precaricata utilizzando Intent#ACTION_DIAL
per conferma; l'esperienza utente non è ottimale.
Di seguito è riportato un esempio di registrazione di un file manifest per un InCallService
. I metadati
TelecomManager#METADATA_IN_CALL_SERVICE_UI
indica che questo particolare
L'implementazione di InCallService
intende sostituire l'interfaccia utente integrata durante la chiamata.
Il meta-data TelecomManager#METADATA_IN_CALL_SERVICE_RINGING
indica che
InCallService
suonerà la suoneria per le chiamate in arrivo. Consulta
di seguito per ulteriori informazioni sulla visualizzazione della chiamata in arrivo
UI e la riproduzione della suoneria nell'app.
<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>
Nota: NON devi contrassegnare InCallService
con l'attributo
android:exported="false"
; ciò può causare un errore di associazione alla tua implementazione
durante le chiamate.
Oltre a implementare l'API InCallService
, devi anche dichiarare un'attività in
il tuo manifest che gestisce l'intent Intent#ACTION_DIAL
. L'esempio seguente illustra
come procedere:
<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>
Quando un utente installa la tua applicazione e la esegue per la prima volta, devi utilizzare lo
RoleManager
per chiedere all'utente di vedere se vuole che la tua app
sarà la nuova app predefinita per smartphone.
Il codice riportato di seguito mostra in che modo la tua app può richiedere di diventare l'app predefinita per telefono/Telefono:
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
}
}
}
Accesso a InCallService per dispositivi indossabili
-
Se la tua app è un'app complementare di terze parti e desidera accedere alle API InCallService,
dell'app sono:
- Dichiara l'autorizzazione MANAGE_ONGOING_CALLS nel file manifest
- Associare un dispositivo indossabile fisico tramite la
API
CompanionDeviceManager
come app complementare. Consulta: https://developer.android.com/guide/topics/connectivity/companion-device-pairing - Implementa questo InCallService con l'autorizzazione BIND_INCALL_SERVICE
Visualizzazione del avviso di chiamata in arrivo
Quando la tua app riceve una nuova chiamata in arrivo tramiteInCallService#onCallAdded(Call)
,
responsabile di visualizzare l'interfaccia utente della chiamata in arrivo. Dovrebbe eseguire questa operazione utilizzando
NotificationManager
API per pubblicare un nuovo avviso di chiamata in arrivo.
Dove la tua app dichiara i metadati TelecomManager#METADATA_IN_CALL_SERVICE_RINGING
,
consente di riprodurre la suoneria per le chiamate in arrivo. La tua app deve creare un
NotificationChannel
che specifica la suoneria desiderata. Ad esempio:
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);
Quando la tua app riceve una nuova chiamata in arrivo, crea un Notification
per
chiamata in arrivo e la associa al canale di notifica delle chiamate in arrivo. Puoi specificare un
PendingIntent
sulla notifica che aprirà la schermata a schermo intero
UI per le chiamate in arrivo. Il framework di gestione delle notifiche mostra la notifica come
un avviso se l'utente sta utilizzando attivamente lo smartphone. Se l'utente non utilizza
viene utilizzata l'interfaccia utente per le chiamate in arrivo a schermo intero.
Ad esempio:
// 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());
```