Mengalihkan Pengguna ke Aplikasi Lain

Salah satu fitur Android yang paling penting adalah kemampuan aplikasi untuk mengalihkan pengguna ke aplikasi lainnya berdasarkan "tindakan" yang ingin dilakukannya. Misalnya, jika aplikasi Anda memiliki alamat bisnis yang ingin ditampilkan pada peta, Anda tidak perlu membuat aktivitas dalam aplikasi yang menampilkan peta. Namun, Anda dapat membuat permintaan untuk menampilkan alamat tersebut menggunakan Intent. Sistem Android lalu akan memulai aplikasi yang dapat menampilkan alamat tersebut di peta.

Seperti yang sudah dijelaskan pada tutorial pertama, Mem-build Aplikasi Pertama Anda, Anda harus menggunakan intent untuk beralih antaraktivitas dalam aplikasi Anda sendiri. Secara umum, hal ini dapat dilakukan dengan intent eksplisit yang menentukan nama persis class komponen yang ingin Anda mulai. Namun, ketika Anda ingin aplikasi lain melakukan suatu tindakan, seperti ”melihat peta”, Anda harus menggunakan intent implisit.

Tutorial ini menunjukkan cara membuat intent implisit untuk tindakan tertentu, serta cara menggunakannya untuk memulai aktivitas yang melakukan tindakan tersebut dalam aplikasi lain. Lihat juga video yang disematkan di sini untuk memahami pentingnya menyertakan pemeriksaan runtime untuk intent implisit Anda.

Membuat Intent Implisit

Intent implisit tidak mendeklarasikan nama class komponen yang akan dimulai, tetapi mendeklarasikan tindakan yang akan dilakukan. Tindakan ini menetapkan hal yang ingin Anda lakukan, misalnya lihat, edit, kirim, atau dapatkan sesuatu. Intent juga sering menyertakan data yang terkait dengan tindakan, seperti alamat yang ingin Anda lihat, atau pesan email yang ingin Anda kirim. Tergantung pada intent yang akan dibuat, data tersebut mungkin berupa Uri, salah satu dari beberapa jenis data lainnya, atau mungkin intent tidak memerlukan data sama sekali.

Jika data berupa Uri, ada konstruktor Intent() sederhana yang dapat Anda gunakan untuk menentukan tindakan dan datanya.

Sebagai contoh, berikut adalah cara membuat intent untuk memulai panggilan telepon menggunakan data Uri guna menetapkan nomor telepon:

Kotlin

    val callIntent: Intent = Uri.parse("tel:5551234").let { number ->
        Intent(Intent.ACTION_DIAL, number)
    }
    

Java

    Uri number = Uri.parse("tel:5551234");
    Intent callIntent = new Intent(Intent.ACTION_DIAL, number);
    

Saat aplikasi memanggil intent ini dengan memanggil startActivity(), aplikasi Telepon akan menginisiasi panggilan ke nomor telepon yang ditentukan.

Berikut adalah beberapa intent lainnya beserta pasangan tindakan dan data Uri-nya:

  • Lihat peta:

    Kotlin

        // Map point based on address
        val mapIntent: Intent = Uri.parse(
                "geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California"
        ).let { location ->
            // Or map point based on latitude/longitude
            // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
            Intent(Intent.ACTION_VIEW, location)
        }
        

    Java

        // Map point based on address
        Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
        // Or map point based on latitude/longitude
        // Uri location = Uri.parse("geo:37.422219,-122.08364?z=14"); // z param is zoom level
        Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);
        
  • Lihat halaman web:

    Kotlin

        val webIntent: Intent = Uri.parse("http://www.android.com").let { webpage ->
            Intent(Intent.ACTION_VIEW, webpage)
        }
        

    Java

        Uri webpage = Uri.parse("http://www.android.com");
        Intent webIntent = new Intent(Intent.ACTION_VIEW, webpage);
        

Jenis intent implisit lainnya memerlukan data "tambahan" yang menyediakan jenis data yang berbeda, seperti string. Anda dapat menambahkan satu atau beberapa bagian data tambahan menggunakan metode putExtra() yang beragam.

Secara default, sistem akan menentukan jenis MIME yang tepat sebagaimana diperlukan oleh intent berdasarkan data Uri yang disertakan. Jika Uri tidak disertakan dalam intent, Anda biasanya harus menggunakan setType() untuk menentukan jenis data yang terkait dengan intent tersebut. Menentukan jenis MIME akan menjelaskan secara lebih mendetail tentang jenis aktivitas yang akan menerima intent.

Berikut adalah beberapa intent lainnya yang memberikan data tambahan untuk menetapkan tindakan yang diinginkan:

  • Kirim email dengan lampiran:

    Kotlin

        Intent(Intent.ACTION_SEND).apply {
            // The intent does not have a URI, so declare the "text/plain" MIME type
            type = HTTP.PLAIN_TEXT_TYPE
            putExtra(Intent.EXTRA_EMAIL, arrayOf("jon@example.com")) // recipients
            putExtra(Intent.EXTRA_SUBJECT, "Email subject")
            putExtra(Intent.EXTRA_TEXT, "Email message text")
            putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"))
            // You can also attach multiple items by passing an ArrayList of Uris
        }
        

    Java

        Intent emailIntent = new Intent(Intent.ACTION_SEND);
        // The intent does not have a URI, so declare the "text/plain" MIME type
        emailIntent.setType(HTTP.PLAIN_TEXT_TYPE);
        emailIntent.putExtra(Intent.EXTRA_EMAIL, new String[] {"jon@example.com"}); // recipients
        emailIntent.putExtra(Intent.EXTRA_SUBJECT, "Email subject");
        emailIntent.putExtra(Intent.EXTRA_TEXT, "Email message text");
        emailIntent.putExtra(Intent.EXTRA_STREAM, Uri.parse("content://path/to/email/attachment"));
        // You can also attach multiple items by passing an ArrayList of Uris
        
  • Buat acara kalender:

    Kotlin

        Intent(Intent.ACTION_INSERT, Events.CONTENT_URI).apply {
            val beginTime: Calendar = Calendar.getInstance().apply {
                set(2012, 0, 19, 7, 30)
            }
            val endTime = Calendar.getInstance().apply {
                set(2012, 0, 19, 10, 30)
            }
            putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.timeInMillis)
            putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.timeInMillis)
            putExtra(Events.TITLE, "Ninja class")
            putExtra(Events.EVENT_LOCATION, "Secret dojo")
        }
        

    Java

        Intent calendarIntent = new Intent(Intent.ACTION_INSERT, Events.CONTENT_URI);
        Calendar beginTime = Calendar.getInstance();
        beginTime.set(2012, 0, 19, 7, 30);
        Calendar endTime = Calendar.getInstance();
        endTime.set(2012, 0, 19, 10, 30);
        calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_BEGIN_TIME, beginTime.getTimeInMillis());
        calendarIntent.putExtra(CalendarContract.EXTRA_EVENT_END_TIME, endTime.getTimeInMillis());
        calendarIntent.putExtra(Events.TITLE, "Ninja class");
        calendarIntent.putExtra(Events.EVENT_LOCATION, "Secret dojo");
        

    Catatan: Intent untuk acara kalender ini hanya didukung dengan API level 14 dan yang lebih tinggi.

Catatan: Anda harus menentukan Intent sejelas mungkin. Misalnya, jika ingin menampilkan gambar menggunakan intent ACTION_VIEW, Anda harus menentukan jenis MIME untuk image/*. Dengan demikian, aplikasi yang dapat “menampilkan” jenis data lain (seperti aplikasi peta) pun tidak akan terpicu oleh intent tersebut.

Memverifikasi Adanya Aplikasi yang Akan Menerima Intent

Walaupun platform Android menjamin bahwa intent tertentu akan dicocokkan ke salah satu aplikasi bawaan (seperti aplikasi Telepon, Email, atau Kalender), Anda harus selalu menyertakan langkah verifikasi sebelum memanggil salah satu intent.

Catatan: Jika Anda memanggil intent dan tidak ada aplikasi di perangkat yang dapat menanganinya, aplikasi akan berhenti berfungsi.

Untuk memverifikasi adanya aktivitas yang dapat merespons intent, panggil queryIntentActivities() untuk mendapatkan daftar aktivitas yang dapat menangani Intent Anda. Jika List yang dikembalikan tidak kosong, Anda dapat menggunakan intent tersebut dengan aman. Contoh:

Kotlin

    val activities: List<ResolveInfo> = packageManager.queryIntentActivities(
            intent,
            PackageManager.MATCH_DEFAULT_ONLY
    )
    val isIntentSafe: Boolean = activities.isNotEmpty()
    

Java

    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(intent,
            PackageManager.MATCH_DEFAULT_ONLY);
    boolean isIntentSafe = activities.size() > 0;
    

Jika isIntentSafe bernilai true, setidaknya satu aplikasi akan merespons intent tersebut. Jika false, tidak ada aplikasi yang akan menanganinya.

Catatan: Lakukan pemeriksaan ini pada kali pertama aktivitas Anda dimulai untuk mengantisipasi jika Anda perlu menonaktifkan fitur yang menggunakan intent tersebut sebelum pengguna mencoba menggunakannya. Jika sudah mengetahui bahwa aplikasi tertentu dapat menangani intent tersebut, Anda juga dapat memberikan link bagi pengguna untuk mendownload aplikasi (lihat cara menghubungkan ke produk Anda di Google Play).

Memulai Aktivitas dengan Intent

Gambar 1. Contoh dialog pemilihan yang muncul ketika ada lebih dari satu aplikasi yang dapat menangani intent.

Setelah Anda membuat Intent dan mengatur info tambahannya, panggil startActivity() untuk mengirimkannya ke sistem. Jika sistem mengidentifikasi ada lebih dari satu aktivitas yang dapat menangani intent tersebut, akan muncul dialog (terkadang disebut "dialog disambiguasi") bagi pengguna untuk memilih aplikasi yang akan digunakan, seperti dalam gambar 1. Jika hanya ada satu aktivitas yang menangani intent, sistem akan langsung memulainya.

Kotlin

    startActivity(intent)
    

Java

    startActivity(intent);
    

Berikut adalah contoh lengkap yang menunjukkan cara membuat intent untuk menampilkan peta, memverifikasi adanya aplikasi yang akan menangani intent tersebut, lalu memulainya:

Kotlin

    // Build the intent
    val location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California")
    val mapIntent = Intent(Intent.ACTION_VIEW, location)

    // Verify it resolves
    val activities: List<ResolveInfo> = packageManager.queryIntentActivities(mapIntent, 0)
    val isIntentSafe: Boolean = activities.isNotEmpty()

    // Start an activity if it's safe
    if (isIntentSafe) {
        startActivity(mapIntent)
    }
    

Java

    // Build the intent
    Uri location = Uri.parse("geo:0,0?q=1600+Amphitheatre+Parkway,+Mountain+View,+California");
    Intent mapIntent = new Intent(Intent.ACTION_VIEW, location);

    // Verify it resolves
    PackageManager packageManager = getPackageManager();
    List<ResolveInfo> activities = packageManager.queryIntentActivities(mapIntent, 0);
    boolean isIntentSafe = activities.size() > 0;

    // Start an activity if it's safe
    if (isIntentSafe) {
        startActivity(mapIntent);
    }
    

Menampilkan Pemilih Aplikasi

Gambar 2. Dialog pemilih.

Perhatikan bahwa saat Anda memulai aktivitas dengan meneruskan Intent ke startActivity() dan ada lebih dari satu aplikasi yang merespons intent tersebut, pengguna dapat memilih aplikasi yang akan digunakan secara default (dengan memilih kotak centang di bagian bawah dialog; lihat gambar 1). Hal ini cukup berguna saat melakukan tindakan yang berkaitan dengan situasi ketika pengguna ingin selalu menggunakan aplikasi yang sama, seperti saat membuka halaman web (pengguna cenderung menggunakan satu browser web saja) atau mengambil foto (pengguna cenderung menyukai satu kamera).

Namun, jika tindakan yang akan dilakukan dapat ditangani oleh beberapa aplikasi dan pengguna mungkin lebih suka berganti-ganti aplikasi, seperti tindakan “berbagi” ketika pengguna mungkin memiliki beberapa aplikasi yang digunakan untuk berbagi item, Anda harus menampilkan dialog pemilih secara eksplisit seperti dalam gambar 2. Dialog pemilih ini akan memaksa pengguna untuk memilih aplikasi yang akan selalu digunakan bagi tindakan tersebut (pengguna tidak dapat memilih aplikasi default untuknya).

Untuk menampilkan pemilih, buat Intent menggunakan createChooser() dan teruskan ke startActivity(). Contoh:

Kotlin

    val intent = Intent(Intent.ACTION_SEND)
    ...

    // Always use string resources for UI text.
    // This says something like "Share this photo with"
    val title = resources.getString(R.string.chooser_title)
    // Create intent to show chooser
    val chooser = Intent.createChooser(intent, title)

    // Verify the intent will resolve to at least one activity
    if (intent.resolveActivity(packageManager) != null) {
        startActivity(chooser)
    }
    

Java

    Intent intent = new Intent(Intent.ACTION_SEND);
    ...

    // Always use string resources for UI text.
    // This says something like "Share this photo with"
    String title = getResources().getString(R.string.chooser_title);
    // Create intent to show chooser
    Intent chooser = Intent.createChooser(intent, title);

    // Verify the intent will resolve to at least one activity
    if (intent.resolveActivity(getPackageManager()) != null) {
        startActivity(chooser);
    }
    

Intent ini akan menampilkan dialog berisi daftar aplikasi yang merespons intent yang diteruskan ke metode createChooser() dan menggunakan teks yang disediakan sebagai judul dialog.