Pozwól innym aplikacjom uruchamiać Twoją aktywność

Jeśli Twoja aplikacja może wykonywać działanie, które może być przydatne dla innej aplikacji, przygotuj ją do reagowania na żądania działań, wskazując w aktywności odpowiedni filtr intencji.

Jeśli na przykład tworzysz aplikację społecznościową do udostępniania wiadomości lub zdjęć znajomym użytkownika, obsługuj intencję ACTION_SEND. Gdy użytkownik wykona czynność „udostępniania” w innej aplikacji, aplikacja pojawi się jako opcja w oknie wyboru (nazywanym też oknem ujednoznacznienia), jak widać na ilustracji 1.

Rysunek 1. Okno wyboru.

Aby inne aplikacje mogły rozpoczynać Twoją aktywność w ten sposób, musisz dodać do pliku manifestu element <intent-filter> dla odpowiedniego elementu <activity>.

Gdy aplikacja jest zainstalowana na urządzeniu, system identyfikuje filtry intencji i dodaje te informacje do wewnętrznego katalogu intencji obsługiwanych przez wszystkie zainstalowane aplikacje. Gdy aplikacja wywołuje funkcję startActivity() lub startActivityForResult() z niejawną intencją, system szuka aktywności, które mogą odpowiedzieć na tę intencję.

Dodaj filtr intencji

Aby poprawnie określić intencje obsługiwane przez aktywność, zadbaj o to, aby każdy dodany filtr intencji był jak najbardziej szczegółowy pod względem typu działania i danych akceptowanych przez aktywność.

System może wysłać określony Intent do działania, jeśli ma ono filtr intencji spełniający te kryteria obiektu Intent:

Działanie
Ciąg tekstowy z nazwą działania do wykonania. Zwykle jest to jedna z wartości zdefiniowanych na platformie, np. ACTION_SEND lub ACTION_VIEW.

Określ to w filtrze intencji za pomocą elementu <action>. Wartość podana w tym elemencie musi być pełnym ciągiem znaków działania, a nie stałą interfejsu API, jak pokazano w przykładach na tej stronie.

Dane
Opis danych powiązanych z intencją.

Określ to w filtrze intencji za pomocą elementu <data>. Używając co najmniej jednego atrybutu w tym elemencie, możesz określić typ MIME, prefiks identyfikatora URI, schemat identyfikatora URI lub ich kombinację wskazującą akceptowany typ danych.

Uwaga: jeśli nie musisz deklarować szczegółów dotyczących danych Uri, np. gdy Twoja aktywność obsługuje inne rodzaje „dodatkowych” danych, zamiast identyfikatora URI, określ tylko atrybut android:mimeType, aby zadeklarować typ danych, których obsługuje Twoja aktywność, np. text/plain lub image/jpeg.

Kategoria
Udostępnia dodatkowy sposób scharakteryzowania aktywności obsługującej intencję, zwykle związaną z gestem użytkownika lub lokalizacją, od której się rozpoczęła. System obsługuje kilka różnych kategorii, z których większość jest rzadko używana. Jednak wszystkie intencje niejawne są domyślnie zdefiniowane za pomocą funkcji CATEGORY_DEFAULT.

Określ to w filtrze intencji za pomocą elementu <category>.

W filtrze intencji możesz zadeklarować, które kryteria akceptuje Twoja aktywność, deklarując każde z nich za pomocą odpowiednich elementów XML zagnieżdżonego w elemencie <intent-filter>.

Na przykład oto aktywność z filtrem intencji, który obsługuje intencję ACTION_SEND, gdy typem danych jest tekst lub obraz:

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

Wskazówka: jeśli chcesz, aby ikona w oknie wyboru różniła się od domyślnej ikony aktywności, dodaj android:icon w elemencie <intent-filter>.

Każda intencja przychodzący wskazuje tylko 1 działanie i 1 typ danych, ale można zadeklarować wiele wystąpień elementów <action>, <category> i <data> w każdym z <intent-filter>.

Jeśli dowolne 2 pary działań i danych wzajemnie się wykluczają w swoich zachowaniach, utwórz osobne filtry intencji, aby wskazać działania akceptowane w połączeniu z jakimi typami danych.

Załóżmy np., że Twoja aktywność obsługuje zarówno tekst, jak i obrazy w intencji ACTION_SEND i ACTION_SENDTO. W tym przypadku musisz zdefiniować 2 osobne filtry intencji dla 2 działań, ponieważ intencja ACTION_SENDTO musi korzystać z danych Uri, aby określić adres odbiorcy za pomocą schematu URI send lub sendto. Widać to w tym przykładzie:

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

Uwaga: aby otrzymywać intencje niejawne, musisz uwzględnić w filtrze intencji kategorię CATEGORY_DEFAULT. Metody startActivity() i startActivityForResult() traktują wszystkie intencje tak, jakby deklarowały kategorię CATEGORY_DEFAULT. Jeśli tego nie zrobisz w filtrze intencji, do Twojej aktywności nie będą trafiać żadne intencje niejawne.

Więcej informacji o wysyłaniu i odbieraniu zamiarów ACTION_SEND służących do udostępniania danych w mediach społecznościowych znajdziesz w artykule Odbieranie prostych danych z innych aplikacji. Przydatne informacje o udostępnianiu danych znajdziesz też w sekcjach Udostępnianie prostych danych i Udostępnianie plików.

Obsługa intencji w aktywności

Aby zdecydować, jakie działanie chcesz wykonać w ramach działania, przeczytaj dokument Intent używany do jego rozpoczęcia.

Po rozpoczęciu aktywności użyj wywołania getIntent(), aby pobrać element Intent, który rozpoczął aktywność. Możesz to zrobić w dowolnym momencie cyklu aktywności, ale zazwyczaj robisz to podczas wczesnych wywołań zwrotnych, np. onCreate() lub onStart().

Widać to w tym przykładzie:

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

Zwracanie wyniku

Jeśli chcesz zwrócić wynik do aktywności, która wywołała Twoją, wywołaj setResult(), aby podać kod wyniku i wynik Intent. Po zakończeniu operacji, a użytkownik powróci do pierwotnej aktywności, wywołaj finish(), aby zamknąć i zniszczyć aktywność. Widać to w tym przykładzie:

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

Zawsze musisz podawać kod wyniku wraz z wynikiem. Zwykle jest to RESULT_OK lub RESULT_CANCELED. W razie potrzeby możesz podać dodatkowe dane za pomocą funkcji Intent.

Uwaga: domyślny wynik to RESULT_CANCELED. Jeśli więc użytkownik kliknie przycisk Wstecz przed zakończeniem działania i przed ustawieniem wyniku, pierwotna aktywność otrzyma wynik „anulowano”.

Jeśli potrzebujesz po prostu liczby całkowitej wskazującej jedną z kilku opcji wyników, możesz ustawić kod wyniku na dowolną wartość większą niż 0. Jeśli używasz kodu wyniku do wyświetlenia liczby całkowitej i nie musisz dodawać Intent, możesz wywołać metodę setResult() i przekazać tylko kod wyniku:

Kotlin

setResult(RESULT_COLOR_RED)
finish()

Java

setResult(RESULT_COLOR_RED);
finish();

W tym przypadku może być tylko kilka możliwych wyników, więc kod wyniku jest lokalnie zdefiniowaną liczbą całkowitą (większą niż 0). Sprawdza się to dobrze, gdy zwracasz wynik dla działania w swojej aplikacji, ponieważ aktywność, która go otrzymuje, może odwoływać się do stałej publicznej, aby określić wartość kodu wyniku.

Uwaga: nie musisz sprawdzać, czy Twoja aktywność rozpoczęła się w usługach startActivity() czy startActivityForResult(). Po prostu wywołaj funkcję setResult(), jeśli intencja, która rozpoczęła działanie, może oczekiwać konkretnego wyniku. Jeśli aktywność źródłowa to startActivityForResult(), system dostarczy ją wynik, który podasz w funkcji setResult(). W przeciwnym razie wynik będzie ignorowany.