Membuat kartu Setelan Cepat kustom untuk aplikasi Anda

Setelan Cepat adalah kartu yang ditampilkan di panel Setelan Cepat, mewakili tindakan, yang dapat diketuk pengguna untuk menyelesaikan tugas berulang dengan cepat. Aplikasi Anda dapat menyediakan kartu kustom kepada pengguna melalui TileService , dan gunakan objek Tile untuk melacak status kartu. Misalnya, Anda dapat membuat kartu yang memungkinkan pengguna mengaktifkan VPN yang disediakan oleh aplikasi Anda atau nonaktif.

Panel Setelan Cepat dengan kartu VPN diaktifkan
  dan dinonaktifkan
Gambar 1. Panel Setelan Cepat dengan kartu VPN diaktifkan dan dinonaktifkan.

Menentukan kapan harus membuat kartu

Sebaiknya buat kartu untuk fungsi tertentu yang Anda harapkan sering diakses pengguna atau memerlukan akses cepat (atau keduanya). Kartu yang paling efektif adalah kartu yang cocok dengan kedua kualitas ini, yang memberikan akses cepat ke tindakan yang sering dilakukan.

Misalnya, Anda dapat membuat kartu untuk aplikasi kebugaran yang memungkinkan pengguna memulai sesi latihan dengan cepat. Namun, sebaiknya jangan membuat kartu untuk aplikasi yang sama yang akan memungkinkan pengguna meninjau seluruh riwayat olahraga mereka.

Kasus penggunaan kartu aplikasi kebugaran
Gambar 2. Contoh kartu yang direkomendasikan versus tidak direkomendasikan untuk aplikasi kebugaran.

Untuk membantu meningkatkan visibilitas dan kemudahan penggunaan kartu Anda, sebaiknya menghindari praktik-praktik tertentu:

  • Hindari penggunaan kartu untuk meluncurkan aplikasi. Sebagai gantinya, gunakan pintasan aplikasi atau peluncur standar.

  • Hindari penggunaan kartu untuk tindakan pengguna satu kali. Sebagai gantinya, gunakan pintasan aplikasi atau notifikasi.

  • Hindari membuat terlalu banyak kartu. Sebaiknya gunakan maksimal dua per aplikasi. Sebagai gantinya, gunakan pintasan aplikasi.

  • Hindari penggunaan ubin yang menampilkan informasi, tetapi tidak interaktif untuk pengguna. Sebagai gantinya, gunakan notifikasi atau widget.

Membuat kartu

Untuk membuat kartu, Anda harus membuat ikon kartu yang sesuai terlebih dahulu, lalu membuat dan mendeklarasikan TileService di file manifes aplikasi.

Contoh Setelan Cepat memberikan contoh cara membuat dan mengelola kartu.

Membuat ikon kustom

Anda harus menyediakan ikon khusus, yang akan ditampilkan pada kartu di Panel setelan. (Anda akan menambahkan ikon ini saat mendeklarasikan TileService, yang akan dijelaskan di bagian berikutnya.) Ikon harus berwarna putih solid dengan latar belakang transparan, berukuran 24 x 24dp, dan dalam bentuk VectorDrawable

Contoh vektor drawable
Gambar 3. Contoh vektor drawable.

Buat ikon yang secara visual mengisyaratkan tujuan kartu Anda. Hal ini membantu pengguna mengidentifikasi dengan mudah apakah kartu Anda sesuai dengan kebutuhan mereka. Misalnya, Anda dapat membuat ikon stopwatch untuk kartu aplikasi kebugaran yang memungkinkan pengguna memulai sesi olahraga.

Membuat dan mendeklarasikan TileService Anda

Buat layanan untuk kartu Anda yang memperluas class TileService.

Kotlin

class MyQSTileService: TileService() {

  // Called when the user adds your tile.
  override fun onTileAdded() {
    super.onTileAdded()
  }
  // Called when your app can update your tile.
  override fun onStartListening() {
    super.onStartListening()
  }

  // Called when your app can no longer update your tile.
  override fun onStopListening() {
    super.onStopListening()
  }

  // Called when the user taps on your tile in an active or inactive state.
  override fun onClick() {
    super.onClick()
  }
  // Called when the user removes your tile.
  override fun onTileRemoved() {
    super.onTileRemoved()
  }
}

Java

public class MyQSTileService extends TileService {

  // Called when the user adds your tile.
  @Override
  public void onTileAdded() {
    super.onTileAdded();
  }

  // Called when your app can update your tile.
  @Override
  public void onStartListening() {
    super.onStartListening();
  }

  // Called when your app can no longer update your tile.
  @Override
  public void onStopListening() {
    super.onStopListening();
  }

  // Called when the user taps on your tile in an active or inactive state.
  @Override
  public void onClick() {
    super.onClick();
  }

  // Called when the user removes your tile.
  @Override
  public void onTileRemoved() {
    super.onTileRemoved();
  }
}

Deklarasikan TileService di file manifes aplikasi Anda. Tambahkan nama dan label TileService, ikon kustom yang Anda buat di bagian sebelumnya, dan izin yang sesuai.

 <service
     android:name=".MyQSTileService"
     android:exported="true"
     android:label="@string/my_default_tile_label"  // 18-character limit.
     android:icon="@drawable/my_default_icon_label"
     android:permission="android.permission.BIND_QUICK_SETTINGS_TILE">
     <intent-filter>
         <action android:name="android.service.quicksettings.action.QS_TILE" />
     </intent-filter>
 </service>

Mengelola TileService Anda

Setelah membuat dan mendeklarasikan TileService di manifes aplikasi, Anda harus mengelola statusnya.

TileService adalah layanan terikat. TileService Anda terikat saat diminta oleh aplikasi atau jika sistem perlu berkomunikasi dengannya. Karakteristik Siklus proses layanan terikat berisi empat metode callback berikut: onCreate(), onBind(), onUnbind(), dan onDestroy(). Metode ini dipanggil oleh sistem setiap kali layanan memasuki fase siklus proses baru.

Ringkasan siklus proses TileService

Selain callback yang mengontrol siklus proses layanan terikat, Anda harus menerapkan metode lain yang khusus untuk siklus proses TileService. Metode ini dapat dipanggil di luar onCreate() dan onDestroy() karena Service metode siklus proses dan metode siklus proses TileService dipanggil dalam dua dan thread asinkron yang terpisah.

Siklus proses TileService berisi metode berikut, yang dipanggil oleh sistem setiap kali TileService Anda memasuki fase siklus proses baru:

  • onTileAdded(): Metode ini hanya dipanggil saat pengguna menambahkan kartu Anda untuk pertama kalinya, dan jika pengguna menghapus dan menambahkan kartu Anda lagi. Ini adalah waktu terbaik untuk melakukan inisialisasi satu kali. Namun, hal ini mungkin tidak memenuhi semua inisialisasi yang diperlukan.

  • onStartListening() dan onStopListening(): Metode ini dipanggil setiap kali aplikasi Anda memperbarui kartu, dan sering dipanggil. Tujuan TileService tetap terikat antara onStartListening() dan onStopListening(), yang memungkinkan aplikasi Anda mengubah kartu dan mengirim update.

  • onTileRemoved(): Metode ini hanya dipanggil jika pengguna menghapus kartu.

Memilih mode mendengarkan

TileService Anda memproses dalam mode aktif atau mode tidak aktif. Sebaiknya gunakan mode aktif, yang harus Anda deklarasikan dalam manifes aplikasi. Jika tidak, TileService adalah mode standar dan tidak perlu dideklarasikan.

Jangan berasumsi TileService akan aktif di luar onStartListening() dan Pasangan metode onStopListening().

Gunakan mode aktif untuk TileService yang memproses dan memantau statusnya di proses itu sendiri. TileService dalam mode aktif terikat untuk onTileAdded(), onTileRemoved(), peristiwa ketuk, dan jika diminta oleh proses aplikasi.

Kami merekomendasikan mode aktif jika TileService diberi tahu saat kartu Anda berstatus harus diperbarui oleh prosesnya sendiri. Kartu aktif membatasi beban pada sistem karena tidak perlu terikat setiap kali panel Setelan Cepat terlihat oleh pengguna.

Metode TileService.requestListeningState() statis dapat dipanggil untuk meminta awal status pemrosesan dan menerima callback ke onStartListening().

Anda dapat mendeklarasikan mode aktif dengan menambahkan META_DATA_ACTIVE_TILE ke elemen file manifes aplikasi Anda.

<service ...>
    <meta-data android:name="android.service.quicksettings.ACTIVE_TILE"
         android:value="true" />
    ...
</service>

Mode non-aktif

Mode nonaktif adalah mode standar. TileService berada dalam mode nonaktif jika itu akan terikat setiap kali kartu Anda dapat dilihat oleh pengguna. Artinya, TileService Anda mungkin dibuat dan terikat lagi pada waktu yang di luar kendalinya. Elemen ini juga dapat di-unbound dan dihancurkan saat pengguna tidak melihat kartu.

Aplikasi Anda menerima callback ke onStartListening() setelah pengguna membuka Panel Setelan Cepat. Anda dapat memperbarui objek Tile sebanyak yang Anda inginkan antara onStartListening() dan onStopListening().

Anda tidak perlu mendeklarasikan mode non-aktif—cukup jangan tambahkan META_DATA_ACTIVE_TILE ke file manifes aplikasi Anda.

Ringkasan status kartu

Setelah pengguna menambahkan kartu, kartu tersebut akan selalu berada dalam salah satu status berikut.

  • STATE_ACTIVE: Menunjukkan status aktif atau diaktifkan. Pengguna dapat berinteraksi dengan kartu Anda saat dalam status ini.

    Misalnya, untuk kartu aplikasi kebugaran yang memungkinkan pengguna memulai sesi olahraga berdurasi, STATE_ACTIVE akan berarti bahwa pengguna telah memulai sesi olahraga dan timer sedang berjalan.

  • STATE_INACTIVE: Menunjukkan status nonaktif atau dijeda. Pengguna dapat berinteraksi dengan kartu Anda saat dalam status ini.

    Untuk menggunakan contoh kartu aplikasi kebugaran lagi, kartu di STATE_INACTIVE akan berarti bahwa pengguna belum memulai sesi olahraga, tetapi dapat melakukannya jika ingin.

  • STATE_UNAVAILABLE: Menunjukkan status tidak tersedia untuk sementara. Pengguna tidak dapat berinteraksi dengan kartu Anda saat dalam status ini.

    Misalnya, kartu di STATE_UNAVAILABLE berarti kartu tersebut saat ini tidak tersedia untuk pengguna karena alasan tertentu.

Sistem hanya menetapkan status awal objek Tile Anda. Anda menetapkan status objek Tile sepanjang siklus prosesnya.

Sistem dapat memberikan warna pada ikon kotak dan latar belakang untuk mencerminkan status Objek Tile. Objek Tile yang ditetapkan ke STATE_ACTIVE adalah yang paling gelap, dengan STATE_INACTIVE dan STATE_UNAVAILABLE yang semakin terang. Rona yang tepat spesifik untuk produsen dan versinya.

Kartu VPN diberi tint untuk mencerminkan status objek
Gambar 4. Contoh kartu yang diberi warna untuk mencerminkan status kartu (masing-masing status aktif, tidak aktif, dan tidak tersedia).

Memperbarui kartu

Anda dapat memperbarui kartu setelah menerima callback ke onStartListening(). Tergantung pada mode kartu, kotak Anda bisa diperbarui setidaknya sekali sampai menerima callback ke onStopListening().

Dalam mode aktif, Anda bisa memperbarui kotak tepat satu kali sebelum menerima callback ke onStopListening(). Dalam mode nonaktif, Anda dapat memperbarui kartu sebagai sesering yang Anda inginkan antara onStartListening() dan onStopListening().

Anda dapat mengambil objek Tile dengan memanggil getQsTile(). Untuk memperbarui kolom tertentu dari objek Tile Anda, panggil metode berikut:

Anda harus memanggil updateTile() untuk memperbarui kartu setelah selesai menyetel kolom objek Tile ke nilai yang benar. Hal ini akan membuat sistem mengurai data kartu yang diupdate dan mengupdate UI.

Kotlin

data class StateModel(val enabled: Boolean, val label: String, val icon: Icon)

override fun onStartListening() {
  super.onStartListening()
  val state = getStateFromService()
  qsTile.label = state.label
  qsTile.contentDescription = tile.label
  qsTile.state = if (state.enabled) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.icon = state.icon
  qsTile.updateTile()
}

Java

public class StateModel {
  final boolean enabled;
  final String label;
  final Icon icon;

  public StateModel(boolean e, String l, Icon i) {
    enabled = e;
    label = l;
    icon = i;
  }
}

@Override
public void onStartListening() {
  super.onStartListening();
  StateModel state = getStateFromService();
  Tile tile = getQsTile();
  tile.setLabel(state.label);
  tile.setContentDescription(state.label);
  tile.setState(state.enabled ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setIcon(state.icon);
  tile.updateTile();
}

Menangani ketukan

Pengguna dapat mengetuk kartu untuk memicu tindakan jika kartu Anda berada STATE_ACTIVE atau STATE_INACTIVE. Sistem kemudian memanggil callback onClick() aplikasi Anda.

Setelah menerima callback ke onClick(), aplikasi Anda dapat meluncurkan dialog atau aktivitas, memicu pekerjaan latar belakang, atau mengubah status kartu.

Kotlin

var clicks = 0
override fun onClick() {
  super.onClick()
  counter++
  qsTile.state = if (counter % 2 == 0) Tile.STATE_ACTIVE else Tile.STATE_INACTIVE
  qsTile.label = "Clicked $counter times"
  qsTile.contentDescription = qsTile.label
  qsTile.updateTile()
}

Java

int clicks = 0;

@Override
public void onClick() {
  super.onClick();
  counter++;
  Tile tile = getQsTile();
  tile.setState((counter % 2 == 0) ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE);
  tile.setLabel("Clicked " + counter + " times");
  tile.setContentDescription(tile.getLabel());
  tile.updateTile();
}

Meluncurkan dialog

showDialog() menciutkan panel Setelan Cepat dan menampilkan dialog. Gunakan dialog untuk menambahkan konteks ke tindakan Anda jika memerlukan input tambahan atau izin pengguna.

Meluncurkan aktivitas

startActivityAndCollapse() memulai aktivitas saat menciutkan panel. Aktivitas akan berguna jika ada informasi yang lebih detail untuk ditampilkan daripada dalam dialog, atau jika tindakan Anda sangat interaktif.

Jika aplikasi Anda memerlukan interaksi pengguna yang signifikan, aplikasi hanya boleh meluncurkan aktivitas sebagai upaya terakhir. Sebagai gantinya, pertimbangkan untuk menggunakan dialog atau tombol.

Mengetuk lama kartu akan menampilkan layar Info Aplikasi untuk pengguna. Untuk mengganti perilaku ini dan sebagai gantinya meluncurkan aktivitas untuk menyetel preferensi, tambahkan <intent-filter> ke salah satu aktivitas Anda dengan ACTION_QS_TILE_PREFERENCES.

Mulai Android API 28, PendingIntent harus memiliki Intent.FLAG_ACTIVITY_NEW_TASK:

if (Build.VERSION.SDK_INT >= 28) {
    intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}

Atau, Anda dapat menambahkan tanda di AndroidManifest.xml di bagian Activity tertentu.

Menandai kartu Anda sebagai dapat diaktifkan/dinonaktifkan

Sebaiknya tandai kartu Anda sebagai dapat diaktifkan/dinonaktifkan jika kartu tersebut berfungsi terutama sebagai tombol dua status (yang merupakan perilaku kartu yang paling umum). Hal ini membantu memberikan informasi tentang perilaku kartu ke sistem operasi dan meningkatkan aksesibilitas secara keseluruhan.

Setel metadata TOGGLEABLE_TILE ke true untuk menandai kartu Anda sebagai dapat diganti-ganti.

<service ...>
  <meta-data android:name="android.service.quicksettings.TOGGLEABLE_TILE"
    android:value="true" />
</service>

Hanya melakukan tindakan yang aman pada perangkat yang terkunci dengan aman

Kartu Anda mungkin ditampilkan di atas layar kunci pada perangkat yang terkunci. Jika ubin berisi informasi sensitif, periksa nilai isSecure() untuk tentukan apakah perangkat dalam status aman, dan TileService Anda harus mengubah perilakunya secara tepat.

Jika tindakan kartu aman untuk dilakukan saat terkunci, gunakan startActivity() untuk meluncurkan aktivitas di atas layar kunci.

Jika tindakan kartu tidak aman, gunakan unlockAndRun() untuk meminta pengguna membuka kunci perangkat mereka. Jika berhasil, sistem akan menjalankan objek Runnable yang Anda teruskan ke metode ini.

Meminta pengguna untuk menambahkan kartu Anda

Untuk menambahkan kartu secara manual, pengguna harus mengikuti beberapa langkah:

  1. Geser ke bawah untuk membuka panel Setelan Cepat.
  2. Ketuk tombol edit.
  3. Scroll semua kartu di perangkatnya hingga menemukan kartu Anda.
  4. Tahan kartu, lalu tarik ke daftar kartu yang aktif.

Pengguna juga dapat memindahkan atau menghapus kartu Anda kapan saja.

Mulai Android 13, Anda dapat menggunakan metode requestAddTileService() untuk memudahkan pengguna menambahkan kartu Anda ke perangkat. Metode ini akan meminta pengguna untuk menambahkan kartu Anda dengan cepat langsung ke panel Setelan Cepat mereka. Perintah ini menyertakan nama aplikasi, label yang diberikan, dan ikon.

Perintah Quick Settings Placement API
Gambar 5. Dialog Quick Settings Placement API.
public void requestAddTileService (
  ComponentName tileServiceComponentName,
  CharSequence tileLabel,
  Icon icon,
  Executor resultExecutor,
  Consumer<Integer> resultCallback
)

Callback berisi informasi tentang apakah kartu ditambahkan atau tidak, tidak ditambahkan, apakah sudah ada, atau apakah terjadi error.

Gunakan pertimbangan Anda saat menentukan waktu dan frekuensi untuk meminta izin kepada pengguna. Rab sebaiknya panggil requestAddTileService() hanya dalam konteks, seperti saat pengguna pertama kali berinteraksi dengan fitur yang difasilitasi kartu Anda.

Sistem dapat memilih untuk berhenti memproses permintaan untuk ComponentName jika telah ditolak oleh pengguna cukup kali sebelumnya. Pengguna ditentukan dari Context yang digunakan untuk mengambil layanan ini—pengguna harus cocok dengan pengguna saat ini.