Membangun host widget

Layar utama Android, yang tersedia di sebagian besar perangkat Android, memungkinkan pengguna menyematkan widget aplikasi (atau widget) untuk akses cepat ke konten. Jika membuat pengganti layar utama atau aplikasi serupa, Anda juga dapat mengizinkan pengguna menyematkan widget dengan menerapkan AppWidgetHost. Ini bukanlah sesuatu yang perlu dilakukan oleh sebagian besar aplikasi, tetapi jika Anda membuat host sendiri, penting untuk memahami kewajiban kontrak yang disetujui host secara implisit.

Halaman ini berfokus pada tanggung jawab yang termasuk dalam penerapan AppWidgetHost kustom. Untuk contoh spesifik cara menerapkan AppWidgetHost, lihat kode sumber untuk layar utama Android LauncherAppWidgetHost.

Berikut adalah ringkasan class dan konsep utama yang terlibat dalam penerapan AppWidgetHost kustom:

  • Host widget aplikasi: AppWidgetHost menyediakan interaksi dengan layanan AppWidget untuk aplikasi yang menyematkan widget di UI-nya. AppWidgetHost harus memiliki ID yang unik dalam paket host sendiri. ID ini akan tetap ada di semua penggunaan host. ID biasanya berupa nilai hardcode yang Anda tetapkan dalam aplikasi.

  • ID widget aplikasi: setiap instance widget diberi ID unik pada saat binding. Lihat bindAppWidgetIdIfAllowed(), dan untuk detail selengkapnya, baca bagian Binding widget berikut. Host mendapatkan ID unik menggunakan allocateAppWidgetId(). ID ini akan tetap ada selama masa aktif widget hingga dihapus dari host. Semua status khusus host—seperti ukuran dan lokasi widget—harus dipertahankan oleh paket hosting dan dikaitkan dengan ID widget aplikasi.

  • Tampilan host widget aplikasi: anggap AppWidgetHostView sebagai frame yang menggabungkan widget setiap kali perlu ditampilkan. Widget akan dikaitkan dengan AppWidgetHostView setiap kali widget di-inflate oleh host.

    • Secara default, sistem akan membuat AppWidgetHostView, tetapi host dapat membuat subclass-nya sendiri dari AppWidgetHostView dengan memperluasnya.
    • Mulai Android 12 (level API 31), AppWidgetHostView memperkenalkan metode setColorResources() dan resetColorResources() untuk menangani warna yang kelebihan beban secara dinamis. Host bertanggung jawab menyediakan warna ke metode ini.
  • Paket opsi: AppWidgetHost menggunakan paket opsi untuk mengomunikasikan informasi ke AppWidgetProvider tentang cara widget ditampilkan—misalnya, daftar rentang ukuran—dan apakah widget berada di layar kunci atau layar utama. Informasi ini memungkinkan AppWidgetProvider menyesuaikan konten dan tampilan widget berdasarkan cara dan tempat widget ditampilkan. Anda dapat menggunakan updateAppWidgetOptions() dan updateAppWidgetSize() untuk mengubah paket widget. Kedua metode ini memicu callback onAppWidgetOptionsChanged() ke AppWidgetProvider.

Mengikat widget

Saat pengguna menambahkan widget ke host, proses yang disebut binding akan terjadi. Binding mengacu pada mengaitkan ID widget aplikasi tertentu dengan host tertentu dan AppWidgetProvider tertentu.

Binding API juga memungkinkan host menyediakan UI kustom untuk binding. Untuk menggunakan proses ini, aplikasi Anda harus mendeklarasikan izin BIND_APPWIDGET dalam manifes host:

<uses-permission android:name="android.permission.BIND_APPWIDGET" />

Namun, ini hanyalah langkah pertama. Saat runtime, pengguna harus secara eksplisit memberikan izin ke aplikasi Anda untuk mengizinkannya menambahkan widget ke host. Untuk menguji apakah aplikasi Anda memiliki izin untuk menambahkan widget, gunakan metode bindAppWidgetIdIfAllowed(). Jika bindAppWidgetIdIfAllowed() menampilkan false, aplikasi Anda harus menampilkan dialog yang meminta pengguna untuk memberikan izin: "izinkan" untuk penambahan widget saat ini, atau "selalu izinkan" untuk mencakup semua penambahan widget mendatang.

Cuplikan berikut menunjukkan contoh cara menampilkan dialog:

Kotlin

val intent = Intent(AppWidgetManager.ACTION_APPWIDGET_BIND).apply {
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId)
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName)
    // This is the options bundle described in the preceding section.
    putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options)
}
startActivityForResult(intent, REQUEST_BIND_APPWIDGET)

Java

Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.componentName);
// This is the options bundle described in the preceding section.
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options);
startActivityForResult(intent, REQUEST_BIND_APPWIDGET);

Host harus memeriksa apakah widget yang ditambahkan pengguna memerlukan konfigurasi. Untuk mengetahui informasi selengkapnya, lihat Memungkinkan pengguna mengonfigurasi widget aplikasi.

Tanggung jawab penyelenggara

Anda dapat menentukan sejumlah setelan konfigurasi untuk widget menggunakan metadata AppWidgetProviderInfo. Anda dapat mengambil opsi konfigurasi ini, yang dibahas secara lebih mendetail di bagian berikut, dari objek AppWidgetProviderInfo yang terkait dengan penyedia widget.

Terlepas dari versi Android yang Anda targetkan, semua host memiliki tanggung jawab berikut:

  • Saat menambahkan widget, alokasikan ID widget seperti yang dijelaskan sebelumnya. Saat widget dihapus dari host, panggil deleteAppWidgetId() untuk membatalkan alokasi ID widget.

  • Saat menambahkan widget, periksa apakah aktivitas konfigurasi perlu diluncurkan. Biasanya, host perlu meluncurkan aktivitas konfigurasi widget jika ada dan tidak ditandai sebagai opsional dengan menentukan tanda configuration_optional dan reconfigurable. Lihat Mengupdate widget dari aktivitas konfigurasi untuk mengetahui detailnya. Ini adalah langkah yang diperlukan agar banyak widget dapat ditampilkan.

  • Widget menentukan lebar dan tinggi default dalam metadata AppWidgetProviderInfo. Nilai ini ditentukan dalam sel—mulai di Android 12, jika targetCellWidth dan targetCellHeight ditentukan—atau dp jika hanya minWidth dan minHeight yang ditentukan. Lihat Atribut ukuran widget.

    Pastikan tata letak widget setidaknya dengan jumlah dp ini. Misalnya, banyak host menyelaraskan ikon dan widget dalam petak. Dalam skenario ini, secara default, host menambahkan widget menggunakan jumlah sel minimum yang memenuhi batasan minWidth dan minHeight.

Selain persyaratan yang tercantum di bagian sebelumnya, versi platform tertentu memperkenalkan fitur yang memberikan tanggung jawab baru kepada host.

Menentukan pendekatan Anda berdasarkan versi Android yang ditargetkan

Android 12

Android 12 (level API 31) memaketkan List<SizeF> tambahan yang berisi daftar kemungkinan ukuran dalam dp yang dapat diambil instance widget dalam paket opsi. Jumlah ukuran yang disediakan bergantung pada implementasi host. Host biasanya menyediakan dua ukuran untuk ponsel—potret dan lanskap—serta empat ukuran untuk perangkat foldable.

Ada batas MAX_INIT_VIEW_COUNT (16) untuk jumlah RemoteViews berbeda yang dapat diberikan oleh AppWidgetProvider ke RemoteViews. Karena objek AppWidgetProvider memetakan objek RemoteViews ke setiap ukuran di List<SizeF>, jangan berikan ukuran lebih dari MAX_INIT_VIEW_COUNT.

Android 12 juga memperkenalkan atribut maxResizeWidth dan maxResizeHeight dalam dp. Sebaiknya widget yang menggunakan setidaknya salah satu atribut ini tidak melebihi ukuran yang ditentukan oleh atribut.

Referensi lainnya

  • Lihat dokumentasi referensi Glance.