Memperbolehkan App lain Untuk Mengakses/Memulai 'Activity' Kita

Dua latihan sebelumnya hanya berfokus pada satu sisi saja, yaitu mengakses/memulai 'activity' app lain dari app kita. Tetapi apabila app kita bisa melakukan sesuatu yang barangkali bermanfaat bagi app lain, app kita bisa juga disiapkan untuk merespon request dari app lain. Contohnya, bila kita membuat app sosial yang bisa men-share pesan dan photo dengan teman-teman dari user, maka kita perlu menyediakan 'intent ACTION_SEND' sehingga user bisa melakukan 'share' dari app lain dan memulai/mengakses app kita untuk melakukannya aksi tersebut.

Untuk memperbolehkan app lain untuk mengeksekusi 'activity' kita, maka kita perlu menambahkan elemen '<intent-filter>' di dalam file manifest kita untuk elemen '<activity>' yang terkait.

Ketika app kita di-install pada suatu perangkat, sistem akan mengetahui 'intent filter' kita dan menambahkan informasi ke katalog internal 'intent' yang di-support oleh semua app yang ter-install. Ketika suatu app memanggil 'startActivity()' atau 'startActivityForResult()', dengan 'intent' implisit, sistem akan menemukan 'activity' mana saja yang bisa merespon 'intent' tersebut.

Menambahkan 'Intent Filter'

Supaya bisa mendefinisikan dengan benar 'intent' mana saja yang bisa ditangani 'activity' kita, masing-masing 'intent filter' yang kita tambahkan seharusnya bisa se-spesifik mungkin tentang aksi/tindakan apa dan data yang diterima 'activity' tersebut.

Sistem mungkin mengirim 'Intent' yang diberikan ke suatu 'activity' bila 'activity' tersebut memiliki 'intent filter' yang memenuhi kriteria object 'Intent' berikut:

Aksi/Tindakan 
Suatu string yang menyebut/memberi nama suatu aksi/tindakan untuk dilakukan. Biasanya salah satu dari nilai yang sudah diefinisikan oleh platform misalnya, 'ACTION_SEND' atau 'ACTION_VIEW'. Tentukan ini di dalam 'intent filter' dengan elemen '<action>'. Nilai yang kita tentukan di dalam elemen ini harus berupa nama string untuk aksi/tindakan yang disebutkan, sebagai ganti dari kontanta API (lihat contoh di bawah).

Data
Penjelasan dari data yang terkait dengan 'intent'. Tentukan ini di dalam 'intent filter' dengan elemen <data>. Dengan menggunakan satu atau lebih atribut di dalam elemen ini, kita bisa menentukan hanya jenis MIME saja, hanya prefix URI saja, hanya skema URI saja, atau kombinasi dari itu semua dan yang lain yang menunjukkan jenis data yang diterima. 
Catatan:
Bila kita tidak ingin menuliskan hal-hal spesifik tentang data 'Uri' (misalnya ketika 'activity' kita menangani semacam data 'extra' yang lain, dan bukan URI), kita seharusnya hanya menentukan atribut 'android:mimeType' untuk jenis data yang ditangani oleh 'activity' kita, misalnya 'text/plain' atau 'image/jpeg'.

Kategori
Menyediakan cara tambahan untuk men-karakteristik-an 'activity' yang menangani 'intent', bisasanya terkait dengan gesture dari user atau lokasi asal 'activity' dimulai/diakses. Ada beberapa kategori berbeda yang di-support oleh sistem, tetapi kebanyakan jarang digunakan. Tetapi secara default semua 'intent' implisit didefinisikan dengan 'CATEGORY_DEFAULT'. Tentukan ini di dalam 'intent filter' dengan elemen '<category>'.

Di dalam 'intent filter' kita, kita bisa menuliskan kriteria mana yang diterima 'activity' kita dengan menuliskan masing-masing kriteria dengan elemen-elemen XML terkait yang dikalang di dalam elemen '<intent-filter>'.

Contohnya, di bawah ini adalah 'activity' dengan 'intent filter' yang menangani 'intent ACTION_SEND' untuk jenis data text maupun image:

 android:name="ShareActivity">
    
         android:name="android.intent.action.SEND"/>
         android:name="android.intent.category.DEFAULT"/>
         android:mimeType="text/plain"/>
         android:mimeType="image/*"/>
    


Masing-masing 'intent' yang datang menentukan hanya satu aksi/tindakan dan satu jenis data saja, tetapi kita diperbolehkan menuliskan beberapa elemen '<action>', '<category>', dan '<data>' di dalam setiap '<intent-filter>'.

Bila dua pasang 'aksi/tindakan dan data' saling eksklusif dalam perilaku mereka, kita seharusnya membuat 'intent filter' yang terpisah untuk menentukan aksi/tindakan mana yang bisa diterima ketika dipasangkan dengan jenis data tertentu.

Contohnya, andaikan 'activity' kita menangani keduanya baik itu text dan image untuk intent 'ACTION_SEND' dan 'ACTION_SENDTO'. Dalam hal ini, kita harus mendefinisikan dua 'intent filter' terpisah untuk kedua aksi/tindakan tersebut karena 'intent ACTION_SENDTO' harus menggunakan data 'Uri' untuk menentukan alamat penerima dengan menggunakan skema URI 'send' atau 'sendto'. Contohnya:

 android:name="ShareActivity">
    
    
         android:name="android.intent.action.SENDTO"/>
         android:name="android.intent.category.DEFAULT"/>
         android:scheme="sms" />
         android:scheme="smsto" />
    

   

   

       
android:name="android.intent.action.SEND"/>
       
android:name="android.intent.category.DEFAULT"/>
       
android:mimeType="image/*"/>
       
android:mimeType="text/plain"/>
   


Catatan:
Untuk menerima 'intent' implisit, kita harus memasukkan kategori 'CATEGORY_DEFAULT' di dalam 'intent filter'. Method 'startActivity()' dan 'startActivityForResult()' memperlakukan semua 'intent' seolah-olah mereka memiliki kategori 'CATEGORY_DEFAULT'. Bila kita tidak menuliskannya di dalam 'intent filter', tidak akan ada 'intent implisit' yang akan menangani 'activity' kita.
Untuk info lebih lanjut tentang mengirim dan menerima 'intent ACTION_SEND' yang melakukan 'social sharing', lihat latihan tentang 'Menerima Data Sederhana dari App lain.


Menangani 'Intent' pada 'Activity' kita

Untuk memutuskan aksi/tindakan apa yang akan diambil pada 'activity' kita, kita bisa membaca 'Intent' yang sudah digunakan untuk mengakses/memulainya.

Ketika 'activity' mulai, kita memanggil 'getIntent()' untuk mendapatkan 'Intent' yang memulai 'activity' tersebut. Kita bisa melakukan hal tersebut kapanpun selama siklus hidup 'activity' tersebut, tetapi kita sebaiknya melakukan itu pada method-method awal seperti 'onCreate()' atau 'onStart()'.

Contohnya:

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

Mengembalikan suatu Hasil

Bila kita ingin mengembalikan suatu hasil ke 'activity' yang memanggil 'activity' kita, gampangnya cukup dengan memanggil 'setResult()' untuk menentukan kode hasil dan 'Intent' hasil. Ketika proses ini sudah selesai dan user seharusnya kembali ke 'activity' asal, kemudian kita panggil 'finish()' untuk menutup dan destroy 'activity' kita. Contohnya:

// 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();
Kita harus selalu menentukan kode hasil bersama hasilnya. Pada umumnya, bisa berupa 'RESULT_OK' atau 'RESULT_CANCELED'. Kemudian kita bisa memberikan data tambahan bersama dengan 'Intent', bila diperlukan.
Catatan:
Hasil secara default di-set ke 'RESULT_CANCELED'. Jadi, bila user menekan tombol 'Back' sebelum menyelesaikan aksi/tindakan tersebut dan sebelum kita men-set hasilnya, 'activity' asal akan menerima hasil 'canceled'.
Bila kita perlu mengembalikan suatu integer yang mengindikasikan satu dari beberapa opsi hasil, kita bisa men-set kode hasil ke nilai apapaun yang lebih dari 0. Bila kita menggunakan kode hasil untuk menghasilkan suatu integer dan kita tidak perlu memasukkan 'Intent' nya, kita bisa memanggil 'setResult()' dan hanya melewatkan kode hasil saja. Contohnya:

setResult(RESULT_COLOR_RED);
finish();

Dalam hal ini, mungkin hanya akan ada beberapa hasil yang mungkin terjadi, sehingga kode hasil tersebut berupa integer yang didefinisilan secara lokal (lebih besar dari 0). Ini akan berhasil ketika kita mengembalikan suatu hasil ke 'activity' pada app kita sendiri, karena 'activity' yang akan menerima hasil tersebut bisa mengacu ke konstanta 'public' untuk menentukan nilai dari kode hasil tersebut.
Catatan:
Tidak perlu men-cek apakah 'activity' kita dimulai dengan 'startActivity()' atau 'startActivityForResult()'. Gampangnya cukup panggil saja 'setResult()' bila 'intent' yang memanggil/memulai 'activity' kita menginginkan suatu hasil. Bila 'activity' asal memanggil 'startActivityForResult()', maka sistem akan mengeluarkan hasil yang kita berikan ke 'setResult()', bila sebaliknya, hasil akan diabaikan.

license: cc by 

No comments: