Consenti ad altre app di iniziare la tua attività

Se la tua app può eseguire un'azione che potrebbe essere utile per un'altra app, preparala a rispondere alle richieste di azione specificando il filtro per intent appropriato nella tua attività.

Ad esempio, se crei un'app social in grado di condividere messaggi o foto con gli amici dell'utente, supporta l'intent ACTION_SEND. Successivamente, quando gli utenti avviano un'azione di "condivisione" da un'altra app, l'app viene visualizzata tra le opzioni della finestra di dialogo di selezione (nota anche come finestra di dialogo di disambiguazione), come mostrato nella Figura 1.

Figura 1. La finestra di dialogo del selettore.

Per consentire ad altre app di iniziare la tua attività in questo modo, devi aggiungere un elemento <intent-filter> nel file manifest per l'elemento <activity> corrispondente.

Quando l'app viene installata su un dispositivo, il sistema identifica i filtri di intent e aggiunge le informazioni a un catalogo interno di intent supportati da tutte le app installate. Quando un'app chiama startActivity() o startActivityForResult() con un intent implicito, il sistema controlla se ci sono attività in grado di rispondere all'intent.

Aggiungere un filtro per intent

Per definire correttamente gli intent che la tua attività può gestire, rendi ogni filtro per intent aggiunto il più specifico possibile in termini di tipo di azione e dati accettati dall'attività.

Il sistema potrebbe inviare un determinato Intent a un'attività se quest'ultima ha un filtro per intent che soddisfa i seguenti criteri dell'oggetto Intent:

Azione
Una stringa che assegna il nome all'azione da eseguire. Solitamente si tratta di uno dei valori definiti dalla piattaforma, ad esempio ACTION_SEND o ACTION_VIEW.

Specificalo nel filtro per intent con l'elemento <action>. Il valore specificato in questo elemento deve essere il nome completo della stringa per l'azione, anziché la costante API, come mostrato negli esempi in questa pagina.

Dati
Una descrizione dei dati associati all'intent.

Specificalo nel filtro per intent con l'elemento <data>. Utilizzando uno o più attributi in questo elemento, puoi specificare il tipo MIME, un prefisso URI, uno schema URI o una combinazione di questi e altri che indicano il tipo di dati accettato.

Nota: se non devi dichiarare specifiche sui dati Uri, ad esempio quando la tua attività gestisce altri tipi di dati "extra", invece di un URI, specifica solo l'attributo android:mimeType per dichiarare il tipo di dati gestiti dall'attività, ad esempio text/plain o image/jpeg.

Categoria
Offre un ulteriore modo per caratterizzare l'attività che gestisce l'intent, in genere correlata al gesto dell'utente o alla posizione da cui è iniziata. Il sistema supporta diverse categorie, ma la maggior parte viene utilizzata raramente. Tuttavia, tutti gli intent impliciti sono definiti con CATEGORY_DEFAULT per impostazione predefinita.

Specifica questo valore nel filtro per intent con l'elemento <category>.

Nel filtro per intent, puoi dichiarare quali criteri accetta la tua attività dichiarando ciascuno di essi con gli elementi XML corrispondenti nidificati nell'elemento <intent-filter>.

Ad esempio, ecco un'attività con un filtro per intent che gestisce l'intent ACTION_SEND quando il tipo di dati è di testo o immagine:

<activity android:name="ShareActivity">
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="text/plain"/>
        <data android:mimeType="image/*"/>
    </intent-filter>
</activity>

Suggerimento: se vuoi che l'icona nella finestra di dialogo del selettore sia diversa da quella predefinita dell'attività, aggiungi android:icon nell'elemento <intent-filter>.

Ogni intent in entrata specifica solo un'azione e un tipo di dati, ma è consentito dichiarare più istanze degli elementi <action>, <category> e <data> in <intent-filter>.

Se due coppie di azioni e dati si escludono a vicenda nei loro comportamenti, crea filtri di intent separati per specificare quali azioni sono accettabili se abbinate ai tipi di dati.

Ad esempio, supponi che la tua attività gestisca testo e immagini per entrambi gli intent ACTION_SEND e ACTION_SENDTO. In questo caso, devi definire due filtri di intent separati per le due azioni, poiché un intent ACTION_SENDTO deve utilizzare i dati Uri per specificare l'indirizzo del destinatario utilizzando lo schema URI send o sendto. Questo è quanto mostrato nell'esempio seguente:

<activity android:name="ShareActivity">
    <!-- Filter for sending text; accepts SENDTO action with sms URI schemes -->
    <intent-filter>
        <action android:name="android.intent.action.SENDTO"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:scheme="sms" />
        <data android:scheme="smsto" />
    </intent-filter>
    <!-- Filter for sending text or images; accepts SEND action and text or image data -->
    <intent-filter>
        <action android:name="android.intent.action.SEND"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <data android:mimeType="image/*"/>
        <data android:mimeType="text/plain"/>
    </intent-filter>
</activity>

Nota: per ricevere intent impliciti, devi includere la categoria CATEGORY_DEFAULT nel filtro per intent. I metodi startActivity() e startActivityForResult() trattano tutti gli intent come se dichiarassero la categoria CATEGORY_DEFAULT. Se non lo dichiari nel filtro per intent, nessun intent implicito viene risolto nella tua attività.

Per ulteriori informazioni sull'invio e la ricezione di intent ACTION_SEND che eseguono comportamenti di condivisione sui social, consulta Ricezione di dati semplici da altre app. Inoltre, puoi trovare informazioni utili sulla condivisione dei dati in Condivisione di dati semplici e Condivisione di file.

Gestire l'intent nell'attività

Per decidere quale azione eseguire nella tua attività, leggi la Intent utilizzata per avviarla.

All'inizio dell'attività, chiama getIntent() per recuperare l'elemento Intent che ha avviato l'attività. Puoi eseguire questa operazione in qualsiasi momento durante il ciclo di vita dell'attività, ma in genere lo fai durante le richiamate iniziali, ad esempio onCreate() o onStart().

Questo è quanto mostrato nell'esempio seguente:

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)

    setContentView(R.layout.main)

    val data: Uri? = intent?.data

    // Figure out what to do based on the intent type
    if (intent?.type?.startsWith("image/") == true) {
        // Handle intents with image data
    } else if (intent?.type == "text/plain") {
        // Handle intents with text
    }
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setContentView(R.layout.main);

    // Get the intent that started this activity
    Intent intent = getIntent();
    Uri data = intent.getData();

    // Figure out what to do based on the intent type
    if (intent.getType().indexOf("image/") != -1) {
        // Handle intents with image data
    } else if (intent.getType().equals("text/plain")) {
        // Handle intents with text
    }
}

Restituire un risultato

Se vuoi restituire un risultato nell'attività che ha richiamato il tuo, chiama setResult() per specificare il codice risultato e il risultato Intent. Al termine dell'operazione e quando l'utente torna all'attività originale, chiama finish() per chiudere ed eliminare l'attività. Questo è quanto mostrato nell'esempio seguente:

Kotlin

// Create intent to deliver some kind of result data
Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri")).also { result ->
    setResult(Activity.RESULT_OK, result)
}
finish()

Java

// Create intent to deliver some kind of result data
Intent result = new Intent("com.example.RESULT_ACTION", Uri.parse("content://result_uri"));
setResult(Activity.RESULT_OK, result);
finish();

Devi sempre specificare un codice risultato insieme al risultato. In genere, è RESULT_OK o RESULT_CANCELED. Se necessario, puoi fornire dati aggiuntivi con un Intent.

Nota: il risultato è impostato su RESULT_CANCELED per impostazione predefinita. Quindi, se l'utente tocca il pulsante Indietro prima di completare l'azione e prima che tu imposti il risultato, l'attività originale riceve il risultato "Annullato".

Se devi semplicemente restituire un numero intero che indichi una delle diverse opzioni di risultato, puoi impostare il codice risultato su qualsiasi valore superiore a 0. Se utilizzi il codice risultato per fornire un numero intero e non hai bisogno di includere Intent, puoi chiamare setResult() e trasmettere solo un codice risultato:

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

In questo caso, potrebbero esserci solo pochi risultati possibili, quindi il codice risultato è un numero intero definito localmente (maggiore di 0). Questo metodo funziona bene quando restituisci un risultato a un'attività nella tua app, perché l'attività che riceve il risultato può fare riferimento alla costante pubblica per determinare il valore del codice risultato.

Nota: non è necessario verificare se la tua attività è stata avviata con startActivity() o startActivityForResult(). Chiama setResult() se l'intent che ha avviato la tua attività potrebbe prevedere un risultato. Se l'attività di origine denominata startActivityForResult(), il sistema la restituisce il risultato da te fornito a setResult(); in caso contrario, il risultato viene ignorato.