Mengonfigurasi, menerapkan, dan memverifikasi Link Aplikasi Android

1. Sebelum memulai

Tujuan utama pengguna saat mengikuti deep link adalah untuk mendapatkan konten yang ingin mereka lihat. Deep link memiliki semua fungsi untuk membantu pengguna mencapai tujuan ini. Android menangani jenis link berikut:

  • Deep link: URI dari skema apa pun yang membawa pengguna ke bagian tertentu dari aplikasi Anda.
  • Link web: Deep link dengan skema HTTP dan HTTPS.
  • Link Aplikasi Android: Link web dengan skema HTTP dan HTTPS yang berisi atribut android:autoVerify.

Untuk informasi lebih detail tentang deep link, link web, dan link Aplikasi Android, lihat dokumentasi Android serta kursus kilat di YouTube dan Medium.

Jika Anda sudah mengetahui semua detail teknisnya, lihat penerapan cepat dari postingan blog yang menyertai dan membantu Anda menyiapkannya dalam beberapa langkah.

Tujuan codelab

Codelab ini memandu Anda melakukan praktik terbaik dalam proses konfigurasi, penerapan, dan verifikasi aplikasi dengan Link Aplikasi Android.

Salah satu manfaat Link Aplikasi Android adalah keamanannya. Artinya, tidak ada aplikasi tidak resmi yang dapat menangani link Anda. Android OS harus memverifikasi link dengan situs yang Anda miliki agar memenuhi syarat sebagai Link Aplikasi Android. Proses ini disebut pengaitan situs.

Codelab ini berfokus pada developer yang memiliki situs dan aplikasi Android. Link Aplikasi Android memberikan pengalaman pengguna yang lebih baik dengan mengaktifkan integrasi tanpa hambatan antara aplikasi dan situs Anda.

Prasyarat

Yang akan Anda pelajari

  • Mempelajari praktik terbaik dalam mendesain URL untuk Link Aplikasi Android.
  • Mengonfigurasi semua jenis deep link di Aplikasi Android.
  • Memahami karakter pengganti jalur (path, pathPrefix, pathPattern, pathAdvancePattern).
  • Mempelajari proses verifikasi Link Aplikasi Android, yang meliputi upload file Digital Asset Links (DAL) Google, proses verifikasi manual Link Aplikasi Android, dan dasbor deep link Konsol Developer Play.
  • Membangun aplikasi Android dengan berbagai restoran di lokasi berbeda.

Tampilan akhir aplikasi web restoran. Tampilan akhir Aplikasi Android Restoran.

Yang akan Anda butuhkan

  • Android Studio Dolphin (2021.3.1) atau yang lebih baru.
  • Domain untuk menghosting file Digital Asset Link (DAL) Google. (Opsional: Baca postingan blog, yang membantu Anda menyiapkannya dalam beberapa menit.)
  • Opsional: akun developer Konsol Google Play. Ini memungkinkan pendekatan lain untuk men-debug konfigurasi Link Aplikasi Android Anda.

2. Menyiapkan kode

Membuat Aplikasi Compose kosong

Untuk memulai project Compose, ikuti langkah-langkah berikut:

  1. Di Android Studio, pilih File > New > New Project.

Menu File dan memilih jalur berikut: New ke New Project.

  1. Pilih Empty Compose Activity dari template yang tersedia.

Modal project 'New' Android Studio dengan 'Empty Compose Activity' dipilih.

  1. Klik Next dan konfigurasikan project Anda, dengan nama Deep Links Basics. Pastikan Anda memilih versi Minimum SDK dengan setidaknya level API 21, yaitu API minimum yang didukung Compose.

Modal setelan project baru Android Studio dengan nilai dan opsi menu berikut. 'Deep Links Basics' untuk Nama. 'com.devrel.deeplinksbasics' untuk Nama Paket. Lokasi penyimpanan memiliki nilai default. 'Kotlin' untuk Bahasa. API 21 untuk SDK Minimum.

  1. Klik Finish dan tunggu project Anda dibuat.
  2. Mulai aplikasi. Pastikan aplikasi berjalan. Akan ada layar kosong dengan pesan Hello Android!.

Layar kosong Aplikasi Android yang menampilkan teks berikut: 'Hello Android'.

Solusi untuk codelab

Anda dapat memperoleh kode untuk solusi codelab ini dari GitHub:

git clone https://github.com/android/deep-links

Atau, Anda dapat mendownload repositori sebagai file Zip:

Pertama, masuk ke direktori deep-links-introduction. Anda akan menemukan aplikasi di direktori solution. Sebaiknya ikuti codelab langkah demi langkah sesuai kemampuan Anda dan lihat solusinya jika diperlukan. Selama codelab, Anda akan melihat cuplikan kode yang harus ditambahkan ke project.

3. Meninjau desain URL berorientasi Deep Link

Desain RESTful API

Link adalah bagian penting dari pengembangan web, dan desain link telah melalui iterasi yang tak terhitung jumlahnya, menghasilkan berbagai standar. Ada baiknya untuk melihat dan menerapkan standar desain link pengembangan web, yang akan membuatnya lebih mudah digunakan dan dikelola.

Salah satu standar tersebut adalah REST (representational state transfer), yaitu arsitektur yang umumnya digunakan untuk membangun API untuk layanan web. Open API adalah inisiatif yang menstandardisasi REST API. Atau, Anda dapat menggunakan REST untuk mendesain URL untuk deep link.

Perhatikan bahwa Anda tidak sedang membuat layanan web. Bagian ini hanya berfokus pada desain URL.

Mendesain URL

Pertama, tinjau URL yang dihasilkan di situs Anda dan pahami apa yang diwakilinya di Aplikasi Android:

  • /restaurants mencantumkan semua restoran yang Anda kelola.
  • /restaurants/:restaurantName menampilkan detail dari satu restoran.
  • /restaurants/:restaurantName/orders menunjukkan beberapa pesanan di sebuah restoran.
  • /restaurants/:restaurantName/orders/:orderNumber menunjukkan pesanan tertentu di sebuah restoran.
  • /restaurants/:restaurantName/orders/latest menunjukkan pesanan terakhir di sebuah restoran.

Mengapa desain URL itu penting

Android memiliki filter intent yang menangani tindakan dari komponen aplikasi lain dan juga digunakan untuk menangkap URL. Ketika menentukan filter intent untuk menangkap URL, Anda harus mengikuti struktur yang mengandalkan awalan jalur dan karakter pengganti langsung. Berikut ini contoh cara penyusunan dari URL yang sudah ada di situs restoran Anda:

https://example.com/pawtato-3140-Skinner-Hollow-Road

Meskipun URL ini menentukan restoran Anda dan lokasinya, jalur tersebut dapat menimbulkan masalah saat menentukan filter intent untuk Android guna menangkap URL karena aplikasi Anda didasarkan pada berbagai URL restoran seperti ini:

https://example.com/rawrbucha-2064-carriage-lane

https://example.com/pizzabus-1447-davis-avenue

Ketika menentukan filter intent dengan jalur dan karakter pengganti untuk menangkap URL ini, Anda bisa menggunakan sesuatu seperti https://example.com/*, yang pada dasarnya berfungsi. Meskipun demikian, Anda belum benar-benar menyelesaikan masalah karena ada jalur lain yang sudah ada untuk berbagai bagian dari situs Anda, seperti berikut ini:

Pengiriman: https://example.com/deliveries

Admin: https://example.com/admin

Anda mungkin tidak ingin Android menangkap URL ini karena beberapa di antaranya mungkin bersifat internal, tetapi filter intent https://example.com/* yang ditentukan akan menangkapnya, termasuk URL yang tidak ada. Dan ketika pengguna mengklik salah satu URL ini, URL akan terbuka di browser (> Android 12) atau dialog disambiguasi mungkin muncul (< Android 12). Dalam desain ini, itu bukanlah perilaku yang dimaksudkan.

Android sekarang menawarkan awalan jalur yang memecahkan masalah ini, tetapi melibatkan desain ulang URL, dari:

https://example.com/*

menjadi:

https://example.com/restaurants/*

Menambahkan struktur bertingkat dengan hierarki membuat filter intent Anda terdefinisi dengan jelas, dan Android akan menangkap URL yang Anda perintahkan untuk ditangkap.

Praktik terbaik desain URL

Berikut ini beberapa praktik terbaik yang dikumpulkan dari Open API dan diterapkan ke perspektif deep link:

  • Fokuskan desain URL pada entitas bisnis yang diekspos. Misalnya, dalam e-commerce, hal itu dapat berupa pelanggan dan pesanan. Untuk travel, hal itu dapat berupa tiket dan penerbangan. Di aplikasi dan situs restoran Anda, Anda akan menggunakan restoran dan pesanan.
  • Sebagian besar metode HTTP (GET, POST, DELETE, PUT) adalah kata kerja yang menjelaskan permintaan yang dibuat, tetapi penggunaan kata kerja untuk endpoint di URL akan membingungkan.
  • Untuk mendeskripsikan koleksi, gunakan bentuk jamak dari entity, seperti /restaurants/:restaurantName. Ini membuat URL lebih mudah dibaca dan dikelola. Berikut ini contoh dengan masing-masing metode HTTP:

GET /restaurants/pawtato

POST /restaurants

DELETE /restaurants

PUT /restaurants/pawtato

Setiap URL lebih mudah dibaca dan dipahami fungsinya. Perlu diperhatikan bahwa codelab ini tidak mencakup desain API layanan web dan fungsi masing-masing metode.

  • Gunakan penyusunan bertingkat yang logis untuk mengelompokkan URL yang berisi informasi terkait. Misalnya, URL untuk salah satu restoran kita mungkin memiliki pesanan yang sedang dikerjakan:

/restaurants/1/orders

4. Meninjau elemen data

File AndroidManifest.xml adalah bagian penting dari Android. File ini menjelaskan informasi aplikasi ke alat build Android, Android OS, dan Google Play.

Untuk deep link, Anda harus menentukan filter intent menggunakan 3 tag utama: <action>, <category>, dan <data>. Fokus utama kita di bagian ini adalah tag <data>.

Elemen <data> memberitahukan struktur URL link ke Android OS setelah link diklik oleh pengguna. Format dan struktur URL yang dapat Anda gunakan pada filter intent adalah sebagai berikut:

<scheme>://<host>:<port>[<path>|<pathPrefix>|<pathPattern>|<pathAdvancedPattern>|<pathSuffix>]

Android membaca, mengurai, dan menggabungkan semua elemen <data> dalam filter intent untuk memperhitungkan semua variasi atribut. Sebagai contoh:

AndroidManifest.xml

<intent-filter>
  ...
  <data android:scheme="http" />
  <data android:scheme="https" />
  <data android:host="example.com" />
  <data android:path="/restaurants" />
  <data android:pathPrefix="/restaurants/orders" />
</intent-filter>

Android akan menangkap URL berikut:

  • http://example.com/restaurants
  • https://example.com/restaurants
  • http://example.com/restaurants/orders/*
  • https://example.com/restaurants/orders/*

Atribut Jalur

path (tersedia di API 1)

Atribut ini menentukan jalur lengkap, dimulai dengan /, yang dicocokkan dengan jalur lengkap di intent. Misalnya, android:path="/restaurants/pawtato" hanya cocok dengan jalur situs /restaurants/pawtato, dan jika kita memiliki /restaurant/pawtato, URL ini tidak akan cocok karena s yang hilang.

pathPrefix (tersedia di API 1)

Atribut ini menentukan jalur parsial yang cocok dengan bagian awal saja dari jalur intent. Misalnya,

android:pathPrefix="/restaurants" akan cocok dengan jalur restoran: /restaurants/pawtato, /restaurants/pizzabus, dan sebagainya.

pathSuffix (tersedia di API 31)

Atribut ini menentukan jalur yang sama persis dengan bagian akhir dari jalur dalam intent. Misalnya,

android:pathSuffix="tato" akan cocok dengan semua jalur restoran yang diakhiri dengan tato seperti /restaurants/pawtato dan /restaurants/corgtato.

pathPattern (tersedia di API 1)

Atribut ini menentukan jalur lengkap yang cocok dengan jalur lengkap dengan karakter pengganti di intent:

  • Tanda bintang (*) cocok dengan urutan dari 0 hingga sekian kemunculan dari karakter sebelumnya.
  • Titik diikuti tanda bintang (.*) cocok dengan urutan apa pun dari 0 hingga sekian karakter.

Contoh:

  • /restaurants/piz*abus: pola ini cocok dengan restoran pizzabus, tetapi juga akan cocok dengan restoran yang memiliki 0 atau lebih karakter z pada namanya, seperti /restaurants/pizzabus, /restaurants/pizzzabus, dan /restaurants/pizabus.
  • /restaurants/.*: pola ini cocok dengan nama restoran apa pun dengan jalur /restaurants, seperti /restaurants/pizzabus dan /restaurants/pawtato, juga nama yang tidak diketahui aplikasi, seperti /restaurants/wateriehall.

pathAdvancePattern (tersedia di API 31)

Atribut ini menentukan jalur lengkap yang cocok dengan jalur lengkap dengan pola seperti ekspresi reguler:

  • Titik (.) cocok dengan karakter apa pun.
  • Sepasang tanda kurung siku ([...]) cocok dengan berbagai karakter. Pasangan tanda ini juga mendukung pengubah bukan (^).
  • Tanda bintang (*) cocok dengan pola sebelumnya 0 atau sekian kali.
  • Tanda plus (+) cocok dengan pola sebelumnya 1 atau sekian kali.
  • Kurung kurawal ({...}) mewakili sekian kali sebuah pola mungkin cocok.

Atribut ini dapat dianggap sebagai perluasan dari pathPattern. Ini memberi lebih banyak fleksibilitas pada URL yang cocok, misalnya:

  • /restaurants/[a-zA-Z]*/orders/[0-9]{3} cocok dengan pesanan restoran apa pun yang panjangnya hingga tiga digit.
  • /restaurants/[a-zA-Z]*/orders/latest cocok dengan pesanan terbaru dari salah satu restoran aplikasi

5. Membuat Deep link dan link web

Deep link dengan skema kustom adalah jenis deep link yang paling umum dan paling mudah diterapkan, tetapi memiliki kekurangan. Link ini tidak dapat dibuka oleh situs. Dan aplikasi apa pun yang menyatakan dukungannya untuk skema tersebut dalam manifesnya dapat membuka link itu.

Anda dapat menggunakan skema apa pun pada elemen <data>. Misalnya, codelab ini menggunakan URL food://restaurants/keybabs.

  1. Di Android Studio, tambahkan filter intent berikut ke file manifes:

AndroidManifest.xml

<activity ... >
  <intent-filter>
    <action android:name="android.intent.action.VIEW"/>
    <category android:name="android.intent.category.BROWSABLE"/>
    <category android:name="android.intent.category.DEFAULT"/>
    <data android:scheme="food"/>
    <data android:path="/restaurants/keybabs"/>
  </intent-filter>
</activity>
  1. Untuk memverifikasi bahwa aplikasi Anda dapat membuka link dengan skema kustom, cetaklah di layar utama dengan menambahkan hal berikut ke aktivitas utama:

MainActivity.kt

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

        // Receive the intent action and data
        val action: String? = intent?.action;
        val data: Uri? = intent?.data;

        setContent {
            DeepLinksBasicsTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    // Add a Column to print a message per line
                    Column {
                        // Print it on the home screen
                        Greeting("Android")
                        Text(text = "Action: $action")
                        Text(text = "Data: $data")
                    }
                }
            }
        }
    }
}
  1. Untuk menguji apakah intent diterima, gunakan Android Debug Bridge (adb) dengan perintah berikut:
adb shell am start -W -a android.intent.action.VIEW -d "food://restaurants/keybabs"

Perintah ini memulai intent dengan tindakan VIEW dan menggunakan URL yang disediakan sebagai data. Saat Anda menjalankan perintah ini, aplikasi akan diluncurkan dan menerima intent. Perhatikan perubahan pada bagian teks layar utama. Yang pertama menampilkan pesan Hello Android!, yang kedua menampilkan tindakan yang dipanggil intent, dan yang ketiga menampilkan URL yang dipanggil intent.

Pada gambar berikut, perhatikan bahwa di bagian bawah Android Studio, perintah adb tersebut dijalankan. Di sebelah kanan, aplikasi menampilkan informasi intent di layar utama, artinya intent telah diterima. Layar penuh Android Studio memiliki tab terbuka berikut: 'tampilan kode', 'emulator', dan 'terminal'. Tampilan kode menampilkan file MainActivity.kt dasar. Emulator menampilkan kolom teks deep link yang mengonfirmasi bahwa link tersebut berhasil diterima. Terminal menampilkan perintah adb yang baru saja dibahas di codelab.

Link web adalah deep link yang menggunakan http dan https, bukan skema kustom.

Untuk penerapan link web, gunakan jalur /restaurants/keybabs/order/latest.html, yang mewakili pesanan terakhir yang diterima di restoran.

  1. Sesuaikan file manifes menggunakan filter intent yang sudah ada.

AndroidManifest.xml

<intent-filter>
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:scheme="food"/>
  <data android:path="/restaurants/keybabs"/>

  <!-- Web link configuration -->
  <data android:scheme="http"/>
  <data android:scheme="https"/>
  <data android:host="sabs-deeplinks-test.web.app"/>
  <data android:path="/restaurants/keybabs/order/latest.html"/>
</intent-filter>

Karena kedua jalur digunakan bersama (/restaurants/keybabs), menempatkannya di bagian filter intent yang sama adalah praktik yang baik karena membuat penerapannya menjadi lebih sederhana dan file manifes lebih mudah dibaca.

  1. Sebelum menguji link web, mulai ulang aplikasi untuk menerapkan perubahan baru.
  2. Gunakan perintah adb yang sama untuk meluncurkan intent, tetapi dalam hal ini kami akan memperbarui URL.
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/keybabs/orders/latest.html"

Di screenshot, perhatikan bahwa intent diterima dan browser web dibuka untuk menampilkan situs, sebuah fitur dari versi yang lebih baru daripada Android 12. Tampilan lengkap Android Studio dengan tab berikut: 'tampilan Kode' menampilkan file AndroidManifest.xml yang menunjukkan filter intent yang dibahas; 'tampilan Emulator' menampilkan halaman web yang dibuka berkat link web, halaman web mengarah ke aplikasi web Restoran; dan 'tampilan Terminal' menampilkan perintah adb untuk link web.

6. Mengonfigurasi Link Aplikasi Android

Link ini menawarkan pengalaman pengguna yang paling lancar karena saat pengguna mengklik link, link tersebut dijamin akan membawa mereka ke aplikasi tanpa dialog disambiguasi. Link Aplikasi Android diterapkan di Android 6.0 dan merupakan jenis deep link yang paling spesifik. Link ini adalah link web yang menggunakan skema http/https dan atribut android:autoVerify, yang menjadikan aplikasi ini pengendali default untuk setiap link yang cocok. Ada dua langkah utama untuk menerapkan Link Aplikasi Android:

  1. Mengupdate file manifes dengan filter intent yang sesuai.
  2. Menambahkan pengaitan situs untuk verifikasi.

Mengupdate file Manifes

  1. Untuk mendukung Link Aplikasi Android, dalam file manifes, ganti konfigurasi lama dengan yang berikut ini:

AndroidManifest.xml

<!-- Replace deep link and web link configuration with this -->
<!-- Please update the host with your own domain -->
<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:scheme="https"/>
  <data android:host="example.com"/>
  <data android:pathPrefix="/restaurants"/>
</intent-filter>

Filter intent ini menambahkan atribut android:autoVerify dan menyetelnya ke true. Filter ini memungkinkan Android OS memverifikasi domain ketika aplikasi dipasang, dan pada setiap update baru.

Pengaitan Situs

Untuk memverifikasi Link Aplikasi Android, buat pengaitan antara aplikasi dan situs. File JSON Digital Asset Links (DAL) Google harus dipublikasikan di situs agar validasi dapat dilakukan.

DAL Google adalah protokol dan API yang menetapkan pernyataan yang dapat diverifikasi tentang aplikasi dan situs lain. Dalam codelab ini, Anda akan membuat pernyataan tentang aplikasi Android di file assetlinks.json. Berikut contohnya:

assetlinks.json

[{
  "relation": ["delegate_permission/common.handle_all_urls"],
  "target": {
    "namespace": "android_app",
    "package_name": "com.devrel.deeplinksbasics",
    "sha256_cert_fingerprints":
   ["B0:4E:29:05:4E:AB:44:C6:9A:CB:D5:89:A3:A8:1C:FF:09:6B:45:00:C5:FD:D1:3E:3E:12:C5:F3:FB:BD:BA:D3"]
  }
}]

File ini dapat menyimpan daftar pernyataan, tetapi contoh hanya menampilkan satu item. Setiap pernyataan harus berisi kolom-kolom berikut:

  • Hubungan. Menjelaskan satu atau beberapa hubungan yang dideklarasikan tentang target.
  • Target. Aset tempat pernyataan ini berlaku. Aset itu mungkin adalah salah satu dari dua target yang tersedia: web atau android_app.

Properti target pernyataan Android berisi kolom berikut:

  • namespace. android_app untuk semua aplikasi Android.
  • package_name. Nama paket yang sepenuhnya memenuhi syarat (com.devrel.deeplinksbasics).
  • sha256_cert_fingerprints. Sidik jari sertifikat untuk aplikasi. Anda akan mempelajari cara membuat sertifikat ini di bagian berikutnya.

Sidik jari sertifikat

Ada berbagai metode untuk mendapatkan sidik jari sertifikat. Codelab ini menggunakan dua metode, satu untuk build debug aplikasi dan yang lainnya untuk membantu merilis aplikasi ke Google Play Store.

Konfigurasi Debug

Saat pertama kali menjalankan project Anda, Android Studio akan otomatis menandatangani aplikasi dengan sertifikat debug. Lokasi sertifikat ini adalah $HOME/.android/debug.keystore. Anda dapat menggunakan perintah Gradle untuk mendapatkan sidik jari sertifikat SHA-256 ini. Berikut ini langkah-langkahnya:

  1. Tekan Control dua kali dan menu Run anything akan muncul. Jika menu itu tidak muncul, Anda dapat menemukannya di menu Gradle sidebar kanan, lalu klik ikon Gradle.

Tab menu Gradle Android Studio dengan ikon gradle dipilih.

  1. Ketik gradle signingReport, lalu tekan Enter. Perintah dijalankan di konsol dan menampilkan informasi sidik jari untuk varian aplikasi debug.

Jendela terminal menampilkan hasil laporan penandatanganan Gradle.

  1. Untuk menyelesaikan pengaitan situs, salin sidik jari sertifikat SHA-256, update file JSON, dan upload ke situs Anda di lokasi https://<domain>/.well-know/assetlinks.json. Postingan blog Link Aplikasi Android ini membantu Anda menyiapkannya.
  2. Jika aplikasi Anda masih berjalan, tekan Stop untuk menghentikan aplikasi.
  3. Untuk meluncurkan kembali proses verifikasi, hapus aplikasi dari simulator. Pada simulator, klik lama ikon aplikasi DeepLinksBasics, lalu pilih App Info. Klik Uninstall dan Confirm pada modal. Kemudian, jalankan aplikasi agar Android Studio dapat memverifikasi pengaitan.

f112e0d252c5eb48.gif

  1. Pastikan Anda memilih aplikasi yang menjalankan konfigurasi. Jika tidak, laporan penandatanganan Gradle akan berjalan lagi. Android studio menjalankan menu konfigurasi dengan konfigurasi 'aplikasi' dipilih.
  2. Mulai ulang aplikasi dan luncurkan intent dengan URL Link Aplikasi Android:
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/"
  1. Perhatikan bahwa aplikasi diluncurkan dan intent muncul di layar utama.

Layar utama emulator Android dengan kolom teks yang menunjukkan link aplikasi Android berhasil diterapkan.

Selamat, Anda baru saja membuat Link Aplikasi Android pertama Anda.

Konfigurasi rilis

Sekarang, agar dapat mengupload aplikasi Anda dengan Link Aplikasi Android ke Play Store, Anda harus menggunakan build rilis dengan sidik jari sertifikat yang tepat. Untuk membuat dan menguploadnya, ikuti langkah-langkah ini:

  1. Di menu utama Android Studio, klik Build > Generate Signed Bundle/APK.
  2. Dalam dialog berikutnya, pilih Android App Bundle untuk Penandatanganan Aplikasi Play atau APK jika Anda men-deploy ke perangkat secara langsung.
  3. Dalam dialog berikutnya, di bagian Key store path, klik Create new. Tindakan ini membuka jendela baru.
  4. Pilih path untuk keystore dan beri nama basics-keystore.jks.
  5. Buat dan konfirmasi sandi untuk keystore.
  6. Biarkan default untuk kunci Alias.
  7. Pastikan sandi dan konfirmasi sama dengan yang ada di keystore. Semuanya harus cocok.
  8. Isi informasi Certificate, lalu klik OK.

Modal keystore baru Android Studio dengan nilai dan item menu berikut: Direktori yang dipilih di 'keystore path', sandi yang dipilih di 'password' dan 'confirm', key0 untuk 'alias', sandi yang sama untuk 'password' dan 'confirm', nilai default untuk 'validity', sabs sabs untuk 'first and last name', Android untuk 'organizational unit', my org untuk 'organization', my city untuk 'city or locality', my state untuk 'state or province', dan US untuk 'country code'.

  1. Pastikan opsi untuk mengekspor kunci terenkripsi dicentang untuk Penandatanganan Aplikasi Play, lalu klik Next.

Buat Paket Tanda Tangan atau modal menu APK dengan nilai dan item menu berikut: Default untuk 'Module', jalur yang dibuat untuk 'key store path', sandi yang dibuat sebelumnya untuk 'key store password', key0 untuk 'key alias', sandi yang dibuat sebelumnya untuk 'key password', Selected untuk 'export encrypted key for enrolling published apps in Google Play App Signing', dan nilai default untuk 'Encrypted key export path'.

  1. Pada dialog ini, pilih varian build rilis dan klik Finish. Sekarang Anda dapat mengupload aplikasi ke Google Play Store dan menggunakan Penandatanganan Aplikasi Play.

Penandatanganan Aplikasi Play

Dengan Penandatanganan Aplikasi Play, Google membantu Anda mengelola dan melindungi kunci penandatanganan aplikasi Anda. Anda hanya perlu mengupload paket aplikasi yang telah ditandatangani, yang telah Anda selesaikan pada langkah sebelumnya.

Guna mengambil sidik jari sertifikat untuk file assetlinks.json dan memasukkan Link Aplikasi Android Anda dalam build varian rilis, ikuti langkah-langkah berikut:

  1. Di Konsol Google Play, klik Create app.
  2. Untuk nama aplikasi, ketik Deep Links Basics.
  3. Pilih App dan Free untuk dua opsi berikutnya. Buat menu aplikasi dengan nilai yang diupdate berikut: Deep links basics untuk 'app name', Aplikasi dipilih untuk 'app or game', free dipilih untuk 'free or paid', dan menerima dua deklarasi.
  4. Terima Declarations dan klik Create app.
  5. Untuk mengupload paket dan dapat menguji Link Aplikasi Android, pilih di bagian menu kiri Testing > internal testing.
  6. Klik Create new release.

Bagian 'internal testing' Konsol Play yang menampilkan tombol 'create new release'.

  1. Di layar berikutnya, klik Upload lalu pilih paket yang dihasilkan dari bagian terakhir. Anda dapat menemukan file app-release.aab di bagian DeepLinksBascis > app > release. Klik Open dan tunggu sampai paketnya diupload.
  2. Setelah diupload, biarkan kolom lainnya dengan default-nya untuk saat ini. Klik Save.

Bagian rilis pengujian internal Konsol Play dengan aplikasi deep links basics yang diupload. Nilai default diisi.

  1. Untuk mempersiapkan bagian berikutnya, klik Review release, lalu pada layar berikutnya, klik Start rollout to Internal testing. Abaikan peringatan, karena memublikasikan ke Play Store berada di luar cakupan codelab ini.
  2. Klik Rollout pada modal.
  3. Untuk mendapatkan sidik jari sertifikat SHA-256 yang dibuat oleh Penandatanganan Aplikasi Play, buka tab Deep links di menu kiri, lalu lihat dasbor deep link.

Dasbor deep link di bagian Konsol Play, yang menampilkan semua informasi deep link tentang deep link yang baru saja diupload.

  1. Di bagian Domains, klik domain situs. Perhatikan bahwa Konsol Google Play menyebutkan bahwa Anda belum memvalidasi domain dengan aplikasi Anda (pengaitan situs).
  2. Di bagian Fix Domain Issues, klik panah Show More.
  3. Di layar ini, Konsol Google Play menunjukkan cara mengupdate file assetlinks.json dengan sidik jari sertifikat. Salin cuplikan kode dan update file assetlinks.json.

Bagian verifikasi domain dasbor deep link menampilkan cara mengupdate domain dengan sidik jari sertifikat yang benar.

  1. Setelah file assetlinks.json diupdate, klik Recheck verification. Jika verifikasi belum berhasil, tunggu hingga lima menit agar layanan verifikasi mendeteksi perubahan baru.
  2. Jika Anda memuat ulang halaman dasbor Deep links, Anda akan melihat bahwa tidak ada lagi error verifikasi.

Verifikasi aplikasi yang diupload

Anda sudah mengetahui cara memverifikasi aplikasi yang ada di simulator. Sekarang, Anda akan memverifikasi aplikasi Anda yang diupload ke Play Store.

Untuk menginstal aplikasi di emulator dan memastikan Link Aplikasi Android telah diverifikasi, ikuti langkah-langkah berikut:

  1. Di sidebar kiri, klik Releases Overview, lalu pilih rilis terbaru yang baru saja Anda uploaded, yang seharusnya adalah 1 (1.0) release.
  2. Klik Release details (panah biru kanan) untuk melihat detail rilis.
  3. Klik tombol panah biru kanan yang sama untuk mendapatkan informasi app bundle.
  4. Pada modal ini, pilih tab Downloads, lalu klik download untuk aset Signed, universal APK.
  5. Sebelum menginstal paket ini ke dalam simulator, hapus aplikasi yang sebelumnya diinstal oleh Android Studio.
  6. Pada simulator, klik lama ikon aplikasi DeepLinksBasics, lalu pilih App Info. Klik Uninstall dan Confirm pada modal.

f112e0d252c5eb48.gif

  1. Untuk menginstal paket yang didownload, tarik lalu lepas file 1.apk yang didownload ke layar simulator dan tunggu hingga diinstal.

8967dac36ae545ee.gif

  1. Untuk menguji validasi, buka terminal di Android Studio dan jalankan proses verifikasi dengan dua perintah berikut:
adb shell pm verify-app-links --re-verify com.devrel.deeplinksbasics
adb shell pm get-app-links com.devrel.deeplinksbasics
  1. Setelah perintah get-app-links, Anda akan melihat pesan verified di konsol. Jika Anda melihat pesan legacy_failure, pastikan sidik jari sertifikat cocok dengan yang Anda upload untuk situs. Jika keduanya cocok dan Anda tetap tidak melihat pesan verifikasi, coba jalankan langkah 6, 7, dan 8 lagi.

Output konsol.

7. Menerapkan Link Aplikasi Android

Sekarang setelah Anda mengonfigurasi semuanya, saatnya untuk menerapkan aplikasi.

Jetpack Compose akan digunakan untuk penerapan. Untuk mempelajari lebih lanjut tentang Jetpack Compose, lihat Membangun aplikasi yang lebih baik dan lebih cepat dengan Jetpack Compose.

Dependensi Kode

Untuk menyertakan dan mengupdate beberapa dependensi yang Anda perlukan untuk project ini, ikuti langkah ini:

  • Tambahkan hal berikut ke file Module dan Project Gradle:

build.gradle (Project)

buildscript {
  ...
  dependencies {
    classpath "com.google.dagger:hilt-android-gradle-plugin:2.43"
  }
}

build.gradle (Modul)

plugins {
  ...
  id 'kotlin-kapt'
  id 'dagger.hilt.android.plugin'
}
...
dependencies {
  ...
  implementation 'androidx.compose.material:material:1.2.1'
  ...
  implementation "androidx.lifecycle:lifecycle-viewmodel-ktx:2.5.1"
  implementation "androidx.lifecycle:lifecycle-viewmodel-compose:2.5.1"
  implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
  implementation "com.google.dagger:hilt-android:2.43"
  kapt "com.google.dagger:hilt-compiler:2.43"
}

Direktori gambar dengan 10 gambar bebas royalti yang dapat digunakan untuk setiap restoran turut disertakan dalam file project zip. Jangan ragu untuk menggunakannya, atau Anda dapat menyertakan gambar Anda sendiri.

Guna menambahkan titik entri utama untuk HiltAndroidApp, ikuti langkah ini:

  • Buat Class/File Kotlin baru bernama DeepLinksBasicsApplication.kt, lalu update file manifes dengan nama aplikasi baru.

DeepLinksBasicsApplication.kt

package com.devrel.deeplinksbasics

import android.app.Application
import dagger.hilt.android.HiltAndroidApp

@HiltAndroidApp
class DeepLinksBasicsApplication : Application() {}

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools">
    <!-- Update name property -->
    <application
        android:name=".DeepLinksBasicsApplication"
        ...

Data

Anda perlu membuat lapisan data untuk restoran dengan sumber data lokal, repositori, dan class Restaurant. Semuanya akan berada di bawah paket data yang perlu Anda buat. Untuk melakukannya, ikuti langkah berikut:

  1. Di file Restaurant.kt, buat class Restaurant dengan cuplikan kode berikut:

Restaurant.kt

package com.devrel.deeplinksbasics.data

import androidx.annotation.DrawableRes
import androidx.compose.runtime.Immutable

@Immutable
data class Restaurant(
    val id: Int = -1,
    val name: String = "",
    val address: String = "",
    val type: String = "",
    val website: String = "",
    @DrawableRes val drawable: Int = -1
)
  1. Di file RestaurantLocalDataSource.kt, tambahkan beberapa restoran di class sumber data. Jangan lupa untuk memperbarui data dengan domain Anda sendiri. Referensikan cuplikan kode berikut:

RestaurantLocalDataSource.kt

package com.devrel.deeplinksbasics.data

import com.devrel.deeplinksbasics.R
import javax.inject.Inject
import javax.inject.Singleton

@Singleton
class RestaurantLocalDataSource @Inject constructor() {
    val restaurantList = listOf(
        Restaurant(
            id = 1,
            name = "Pawtato",
            address = "3140 Skinner Hollow Road, Medford, Oregon 97501",
            type = "Potato and gnochi",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/pawtato/",
            drawable = R.drawable.restaurant1,
        ),
        Restaurant(
            id = 2,
            name = "Rawrbucha",
            address = "2064 Carriage Lane, Mansfield, Ohio 44907",
            type = "Kombucha",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/rawrbucha/",
            drawable = R.drawable.restaurant2,
        ),
        Restaurant(
            id = 3,
            name = "Pizzabus",
            address = "1447 Davis Avenue, Petaluma, California 94952",
            type = "Pizza",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/pizzabus/",
            drawable = R.drawable.restaurant3,
        ),
        Restaurant(
            id = 4,
            name = "Keybabs",
            address = "3708 Pinnickinnick Street, Perth Amboy, New Jersey 08861",
            type = "Kebabs",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/keybabs/",
            drawable = R.drawable.restaurant4,
        ),
        Restaurant(
            id = 5,
            name = "BBQ",
            address = "998 Newton Street, Saint Cloud, Minnesota 56301",
            type = "BBQ",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/bbq/",
            drawable = R.drawable.restaurant5,
        ),
        Restaurant(
            id = 6,
            name = "Salades",
            address = "4522 Rockford Mountain Lane, Oshkosh, Wisconsin 54901",
            type = "salads",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/salades/",
            drawable = R.drawable.restaurant6,
        ),
        Restaurant(
            id = 7,
            name = "Gyros and moar",
            address = "1993 Bird Spring Lane, Houston, Texas 77077",
            type = "Gyro",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/gyrosAndMoar/",
            drawable = R.drawable.restaurant7,
        ),
        Restaurant(
            id = 8,
            name = "Peruvian ceviche",
            address = "2125 Deer Ridge Drive, Newark, New Jersey 07102",
            type = "seafood",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/peruvianCeviche/",
            drawable = R.drawable.restaurant8,
        ),
        Restaurant(
            id = 9,
            name = "Vegan burgers",
            address = "594 Warner Street, Casper, Wyoming 82601",
            type = "vegan",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/veganBurgers/",
            drawable = R.drawable.restaurant9,
        ),
        Restaurant(
            id = 10,
            name = "Taquitos",
            address = "1654 Hart Country Lane, Blue Ridge, Georgia 30513",
            type = "mexican",
            // TODO: Update with your own domain
            website = "https://your.own.domain/restaurants/taquitos/",
            drawable = R.drawable.restaurant10,
        ),
    )
}
  1. Ingatlah untuk mengimpor gambar ke project Anda.
  2. Selanjutnya, di file RestaurantRepository.kt, tambahkan repositori Restaurant dengan fungsi untuk mendapatkan restoran berdasarkan namanya, seperti pada cuplikan kode berikut:

RestaurantRepository.kt

package com.devrel.deeplinksbasics.data

import javax.inject.Inject

class RestaurantRepository @Inject constructor(
    private val restaurantLocalDataSource: RestaurantLocalDataSource
){
    val restaurants: List<Restaurant> = restaurantLocalDataSource.restaurantList

    // Method to obtain a restaurant object by its name
    fun getRestaurantByName(name: String): Restaurant ? {
        return restaurantLocalDataSource.restaurantList.find {
            val processedName = it.name.filterNot { it.isWhitespace() }.lowercase()
            val nameToTest = name.filterNot { it.isWhitespace() }.lowercase()
            nameToTest == processedName
        }
    }
}

ViewModel

Untuk dapat memilih restoran melalui aplikasi dan Link Aplikasi Android, Anda perlu membuat ViewModel yang mengubah nilai restoran yang dipilih. Ikuti langkah ini:

  • Di file RestaurantViewModel.kt, tambahkan cuplikan kode berikut:

RestaurantViewModel.kt

package com.devrel.deeplinksbasics.ui.restaurant

import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import com.devrel.deeplinksbasics.data.Restaurant
import com.devrel.deeplinksbasics.data.RestaurantRepository
import dagger.hilt.android.lifecycle.HiltViewModel
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.launch
import javax.inject.Inject

@HiltViewModel
class RestaurantViewModel @Inject constructor(
    private val restaurantRepository: RestaurantRepository,
) : ViewModel() {
    // restaurants and selected restaurant could be used as one UIState stream
    // which will scale better when exposing more data.
    // Since there are only these two, it is okay to expose them as separate streams
    val restaurants: List<Restaurant> = restaurantRepository.restaurants

    private val _selectedRestaurant = MutableStateFlow<Restaurant?>(value = null)
    val selectedRestaurant: StateFlow<Restaurant?>
        get() = _selectedRestaurant

    // Method to update the current restaurant selection
    fun updateSelectedRestaurantByName(name: String) {
        viewModelScope.launch {
            val selectedRestaurant: Restaurant? = restaurantRepository.getRestaurantByName(name)
            if (selectedRestaurant != null) {
                _selectedRestaurant.value = selectedRestaurant
            }
        }
    }
}

Compose

Sekarang setelah Anda memiliki logika model tampilan dan lapisan data, saatnya untuk menambahkan lapisan UI. Berkat library Jetpack Compose, Anda dapat melakukannya dalam beberapa langkah. Untuk aplikasi ini, Anda ingin merender restoran Anda di petak kartu. Pengguna dapat mengklik setiap kartu dan membuka detail setiap restoran. Anda memerlukan tiga fungsi composable utama dan satu komponen navigasi yang merutekan ke restoran terkait.

Emulator Android menampilkan aplikasi restoran yang telah selesai.

Untuk menambahkan lapisan UI, ikuti langkah-langkah berikut:

  1. Mulailah dengan fungsi composable yang merender setiap detail restoran. Di file RestaurantCardDetails.kt, tambahkan cuplikan kode berikut:

RestaurantCardDetails.kt

package com.devrel.deeplinksbasics.ui

import androidx.activity.compose.BackHandler
import androidx.compose.foundation.Image
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.selection.SelectionContainer
import androidx.compose.material.Card
import androidx.compose.material.Icon
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ArrowBack
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant

@Composable
fun RestaurantCardDetails (
    restaurant: Restaurant,
    onBack: () -> Unit,
) {
    BackHandler() {
       onBack()
    }
    Scaffold(
        topBar = {
            TopAppBar(
                backgroundColor = Color.Transparent,
                elevation = 0.dp,
            ) {
                Row(
                    horizontalArrangement = Arrangement.Start,
                    modifier = Modifier.padding(start = 8.dp)
                ) {
                    Icon(
                        imageVector = Icons.Default.ArrowBack,
                        contentDescription = "Arrow Back",
                       modifier = Modifier.clickable {
                            onBack()
                        }
                    )
                    Spacer(modifier = Modifier.width(8.dp))
                    Text(text = restaurant.name)
                }
            }
        }
    ) { paddingValues ->
        Card(
            modifier = Modifier
                .padding(paddingValues)
                .fillMaxWidth(),
            elevation = 2.dp,
            shape = RoundedCornerShape(corner = CornerSize(8.dp))
        ) {
            Column(
                modifier = Modifier
                    .padding(16.dp)
                    .fillMaxWidth()
            ) {
                Text(text = restaurant.name, style = MaterialTheme.typography.h6)
                Text(text = restaurant.type, style = MaterialTheme.typography.caption)
                Text(text = restaurant.address, style = MaterialTheme.typography.caption)
                SelectionContainer {
                    Text(text = restaurant.website, style = MaterialTheme.typography.caption)
                }
                Image(painter = painterResource(id = restaurant.drawable), contentDescription = "${restaurant.name}")
            }
        }
    }
}
  1. Selanjutnya, terapkan sel petak dan petak itu sendiri. Di file RastaurantCell.kt, tambahkan cuplikan kode berikut:

RestaurantCell.kt

package com.devrel.deeplinksbasics.ui

import androidx.compose.foundation.Image
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.CornerSize
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.Card
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant

@Composable
fun RestaurantCell(
    restaurant: Restaurant
){
    Card(
        modifier = Modifier
            .padding(horizontal = 8.dp, vertical = 8.dp)
            .fillMaxWidth(),
        elevation = 2.dp,
        shape = RoundedCornerShape(corner = CornerSize(8.dp))
    ) {
        Column(
            modifier = Modifier
                .padding(16.dp)
                .fillMaxWidth()
        ) {
            Text(text = restaurant.name, style = MaterialTheme.typography.h6)
            Text(text = restaurant.address, style = MaterialTheme.typography.caption)
            Image(painter = painterResource(id = restaurant.drawable), contentDescription = "${restaurant.name}")
        }
    }
}
  1. Di file RestaurantGrid.kt, tambahkan cuplikan kode berikut:

RestaurantGrid.kt

package com.devrel.deeplinksbasics.ui

import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.grid.GridCells
import androidx.compose.foundation.lazy.grid.LazyVerticalGrid
import androidx.compose.foundation.lazy.grid.items
import androidx.compose.material.Scaffold
import androidx.compose.material.Text
import androidx.compose.material.TopAppBar
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp
import com.devrel.deeplinksbasics.data.Restaurant

@Composable
fun RestaurantGrid(
    restaurants: List<Restaurant>,
    onRestaurantSelected: (String) -> Unit,
    navigateToRestaurant: (String) -> Unit,
) {
    Scaffold(topBar = {
        TopAppBar(
            backgroundColor = Color.Transparent,
            elevation = 0.dp,
        ) {
            Text(text = "Restaurants", fontWeight = FontWeight.Bold)
        }
    }) { paddingValues ->
        LazyVerticalGrid(
            columns = GridCells.Adaptive(minSize = 200.dp),
            modifier = Modifier.padding(paddingValues)
        ) {
            items(items = restaurants) { restaurant ->
                Column(
                    modifier = Modifier
                        .fillMaxWidth()
                        .clickable(onClick = {
                            onRestaurantSelected(restaurant.name)
                            navigateToRestaurant(restaurant.name)
                        })
                ) {
                    RestaurantCell(restaurant)
                }
            }
        }
    }
}
  1. Selanjutnya, Anda perlu menerapkan status aplikasi dan logika navigasi, lalu update MainActivity.kt. Tindakan ini dapat mengarahkan ke restoran tertentu ketika pengguna mengklik kartu restoran. Di file RestaurantAppState.kt, tambahkan cuplikan kode berikut:

RestaurantAppState.kt

package com.devrel.deeplinksbasics.ui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController

sealed class Screen(val route: String) {
   object Grid : Screen("restaurants")
   object Name : Screen("restaurants/{name}") {
       fun createRoute(name: String) = "restaurants/$name"
   }
}

@Composable
fun rememberRestaurantAppState(
    navController: NavHostController = rememberNavController(),
) = remember(navController) {
    RestaurantAppState(navController)
}

class RestaurantAppState(
    val navController: NavHostController,
) {
    fun navigateToRestaurant(restaurantName: String) {
        navController.navigate(Screen.Name.createRoute(restaurantName))
    }

    fun navigateBack() {
        navController.popBackStack()
    }
}
  1. Untuk navigasi, Anda perlu membuat NavHost dan menggunakan rute composable untuk mengarahkan ke setiap restoran. Di file RestaurantApp.kt, tambahkan cuplikan kode berikut:

RestaurantApp.kt

package com.devrel.deeplinksbasics.ui

import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import com.devrel.deeplinksbasics.ui.restaurant.RestaurantViewModel

@Composable
fun RestaurantApp(
   viewModel: RestaurantViewModel = viewModel(),
   appState: RestaurantAppState = rememberRestaurantAppState(),
) {
    val selectedRestaurant by viewModel.selectedRestaurant.collectAsState()
    val onRestaurantSelected: (String) -> Unit = { viewModel.updateSelectedRestaurantByName(it) }

    NavHost(
        navController = appState.navController,
        startDestination = Screen.Grid.route,
    ) {
        // Default route that points to the restaurant grid
        composable(Screen.Grid.route) {
            RestaurantGrid(
                restaurants = viewModel.restaurants,
                onRestaurantSelected = onRestaurantSelected,
                navigateToRestaurant = { restaurantName ->
                    appState.navigateToRestaurant(restaurantName)
                },
            )
        }
        // Route for the navigation to a particular restaurant when a user clicks on it
        composable(Screen.Name.route) {
            RestaurantCardDetails(restaurant = selectedRestaurant!!, onBack = appState::navigateBack)
        }
    }
}
  1. Sekarang Anda siap untuk mengupdate MainActivity.kt dengan instance aplikasi. Ganti file dengan kode berikut:

MainActivity .kt

package com.devrel.deeplinksbasics

import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.ui.Modifier
import com.devrel.deeplinksbasics.ui.RestaurantApp
import com.devrel.deeplinksbasics.ui.theme.DeepLinksBasicsTheme
import dagger.hilt.android.AndroidEntryPoint

@AndroidEntryPoint
class MainActivity : ComponentActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContent {
            DeepLinksBasicsTheme {
                Surface(
                    modifier = Modifier.fillMaxSize(),
                    color = MaterialTheme.colors.background
                ) {
                    RestaurantApp()
                }
            }
        }
    }
}
  1. Jalankan aplikasi untuk menavigasi petak dan pilih restoran tertentu. Anda akan melihat bahwa ketika Anda memilih restoran, aplikasi akan menampilkan restoran itu beserta detailnya.

fecffce863113fd5.gif

Sekarang, tambahkan Link Aplikasi Android Anda ke petak dan ke setiap restoran. Anda sudah memiliki bagian AndroidManifest.xml untuk petak di bawah /restaurants. Yang benar-benar hebat adalah Anda dapat menggunakan hal yang sama untuk setiap restoran. Anda hanya perlu menambahkan konfigurasi rute baru ke logika. Untuk melakukannya, ikuti langkah berikut:

  1. Update file Manifest dengan filter intent untuk menerima /restaurants sebagai jalur, dan ingatlah untuk menyertakan domain Anda sebagai host. Di file AndroidManifest.xml, tambahkan cuplikan kode berikut:

AndroidManifest.xml

...
<intent-filter android:autoVerify="true">
  <action android:name="android.intent.action.VIEW"/>
  <category android:name="android.intent.category.BROWSABLE"/>
  <category android:name="android.intent.category.DEFAULT"/>
  <data android:scheme="http"/>
  <data android:scheme="https"/>
  <data android:host="your.own.domain"/>
  <data android:pathPrefix="/restaurants"/>
</intent-filter>
  1. Di file RestaurantApp.kt, tambahkan cuplikan kode berikut:

RestaurantApp.kt

...
import androidx.navigation.NavType
import androidx.navigation.navArgument
import androidx.navigation.navDeepLink

fun RestaurantApp(...){
  NavHost(...){
    ...
    //  Route for the navigation to a particular restaurant when a user clicks on it
    //  and for an incoming deep link
    // Update with your own domain
        composable(Screen.Name.route,
            deepLinks = listOf(
                navDeepLink { uriPattern = "https://your.own.domain/restaurants/{name}" }
            ),
            arguments = listOf(
                navArgument("name") {
                    type = NavType.StringType
                }
            )
        ) { entry ->
            val restaurantName = entry.arguments?.getString("name")
            if (restaurantName != null) {
                LaunchedEffect(restaurantName) {
                    viewModel.updateSelectedRestaurantByName(restaurantName)
                }
            }
            selectedRestaurant?.let {
                RestaurantCardDetails(
                    restaurant = it,
                    onBack = appState::navigateBack
                )
            }
        }
  }
}

Di balik layar, NavHost mencocokkan data Uri Intent Android dengan rute composable. Jika rute cocok, composable akan dirender.

Komponen composable dapat mengambil parameter deepLinks yang berisi daftar URI yang diterima dari filter intent. Dalam codelab ini, Anda menambahkan URL situs yang dibuat dan menentukan parameter ID untuk menerima dan mengirim pengguna ke restoran tertentu.

  1. Untuk memastikan logika aplikasi mengirim pengguna ke restoran yang sesuai setelah mengklik Link Aplikasi Android, gunakan adb:
adb shell am start -W -a android.intent.action.VIEW -d "https://sabs-deeplinks-test.web.app/restaurants/gyrosAndMoar"

Perhatikan bahwa aplikasi menunjukkan restoran yang sesuai.

Aplikasi restoran emulator Android menampilkan layar restoran 'gyros and moar'.

8. Meninjau Dasbor Konsol Developer Play

Anda telah melihat dasbor deep link. Dasbor ini memberikan semua informasi yang diperlukan untuk memastikan deep link Anda berfungsi dengan baik. Anda bahkan dapat melihat per versi aplikasi. Dasbor ini menunjukkan kepada Anda domain, link, dan link kustom yang ditambahkan dalam file manifes Anda. Dasbor ini bahkan menunjukkan tempat mengupdate file assetlinks.json jika terjadi masalah.

Dasbor deep link Konsol Play dengan satu link aplikasi Android terverifikasi.

9. Kesimpulan

Selamat, Anda telah berhasil membangun aplikasi Link Aplikasi Android pertama Anda.

Anda telah memahami proses mendesain, mengonfigurasi, membuat, dan menguji Link Aplikasi Android Anda. Proses ini memiliki banyak bagian berbeda. Itulah sebabnya codelab ini menggabungkan semua detail tersebut agar Anda berhasil dalam pengembangan Android OS.

Sekarang Anda telah mengetahui langkah-langkah utama agar Link Aplikasi Android berfungsi.

Bacaan lebih lanjut

Dokumen referensi