Menyiapkan konfigurasi terkelola

Jika mengembangkan aplikasi untuk pasar perusahaan, Anda mungkin perlu memenuhi persyaratan tertentu yang ditetapkan oleh kebijakan organisasi. Konfigurasi terkelola, yang sebelumnya dikenal sebagai pembatasan aplikasi, memungkinkan admin IT organisasi untuk menentukan setelan aplikasi dari jarak jauh. Kemampuan ini sangat berguna untuk aplikasi yang disetujui organisasi yang di-deploy ke profil kerja.

Misalnya, organisasi mungkin mengharuskan aplikasi yang disetujui mengizinkan admin IT untuk:

  • Mengizinkan atau memblokir URL untuk browser web
  • Konfigurasi apakah aplikasi diizinkan untuk menyinkronkan konten melalui seluler, atau hanya dengan Wi-Fi
  • Mengonfigurasi setelan email aplikasi

Panduan ini menunjukkan cara menerapkan setelan konfigurasi terkelola di aplikasi Anda. Untuk melihat aplikasi contoh dengan konfigurasi terkelola, lihat ManagedConfigurations. Jika Anda adalah developer pengelolaan mobilitas perusahaan (EMM), lihat panduan Android Management API.

Catatan: Karena alasan historis, setelan konfigurasi ini dikenal sebagai pembatasan, dan diimplementasikan dengan file dan class yang menggunakan istilah ini (seperti RestrictionsManager). Namun, pembatasan ini sebenarnya dapat mengimplementasikan berbagai opsi konfigurasi, bukan hanya pembatasan pada fungsi aplikasi.

Ringkasan konfigurasi jarak jauh

Aplikasi menentukan opsi konfigurasi terkelola yang dapat disetel dari jarak jauh oleh admin IT. Ini adalah setelan arbitrer yang dapat diubah oleh penyedia konfigurasi terkelola. Jika aplikasi Anda berjalan di profil kerja, admin IT dapat mengubah konfigurasi terkelola aplikasi Anda.

Penyedia konfigurasi terkelola adalah aplikasi lain yang berjalan di perangkat yang sama. Aplikasi ini biasanya dikontrol oleh admin IT. Admin IT mengomunikasikan perubahan konfigurasi ke aplikasi penyedia konfigurasi terkelola. Aplikasi tersebut kemudian akan mengubah konfigurasi pada aplikasi Anda.

Untuk memberikan konfigurasi yang dikelola secara eksternal:

  • Deklarasikan konfigurasi terkelola dalam manifes aplikasi Anda. Dengan melakukannya, admin IT dapat membaca konfigurasi aplikasi melalui Google Play API.
  • Setiap kali aplikasi dilanjutkan, gunakan objek RestrictionsManager untuk memeriksa konfigurasi terkelola saat ini, dan ubah UI serta perilaku aplikasi agar sesuai dengan konfigurasi tersebut.
  • Proses intent ACTION_APPLICATION_RESTRICTIONS_CHANGED. Saat Anda menerima siaran ini, periksa RestrictionsManager untuk melihat seperti apa konfigurasi terkelola saat ini, dan buat perubahan yang diperlukan pada perilaku aplikasi Anda.

Menentukan konfigurasi terkelola

Aplikasi Anda dapat mendukung konfigurasi terkelola apa pun yang ingin Anda tentukan. Anda mendeklarasikan konfigurasi terkelola aplikasi dalam file konfigurasi terkelola, dan mendeklarasikan file konfigurasi dalam manifes. Membuat file konfigurasi memungkinkan aplikasi lain memeriksa konfigurasi terkelola yang disediakan aplikasi Anda. Partner EMM dapat membaca konfigurasi aplikasi Anda dengan menggunakan API Google Play.

Untuk menentukan opsi konfigurasi jarak jauh aplikasi Anda, masukkan elemen berikut dalam elemen <application> manifes Anda:

<meta-data android:name="android.content.APP_RESTRICTIONS"
    android:resource="@xml/app_restrictions" />

Buat file bernama app_restrictions.xml di direktori res/xml aplikasi Anda. Struktur file tersebut dijelaskan dalam referensi untuk RestrictionsManager. File ini memiliki satu elemen <restrictions> tingkat atas, yang berisi satu elemen turunan <restriction> untuk setiap opsi konfigurasi yang dimiliki aplikasi.

Catatan: Jangan buat versi yang dilokalkan dari file konfigurasi terkelola. Aplikasi Anda hanya diizinkan memiliki satu file konfigurasi terkelola. Oleh karena itu, konfigurasi akan konsisten untuk aplikasi Anda di semua lokalitas.

Dalam lingkungan perusahaan, EMM biasanya akan menggunakan skema konfigurasi terkelola untuk membuat konsol jarak jauh bagi admin IT, sehingga admin dapat mengonfigurasi aplikasi Anda dari jarak jauh.

Penyedia konfigurasi terkelola dapat mengkueri aplikasi untuk menemukan detail tentang konfigurasi aplikasi yang tersedia, termasuk teks deskripsinya. Penyedia konfigurasi dan admin IT dapat mengubah konfigurasi terkelola aplikasi Anda kapan saja, bahkan saat aplikasi sedang tidak berjalan.

Misalnya, aplikasi Anda dapat dikonfigurasi dari jarak jauh untuk mengizinkan atau melarangnya mendownload data melalui koneksi seluler. Aplikasi Anda dapat memiliki elemen <restriction> seperti ini:

<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">

  <restriction
    android:key="downloadOnCellular"
    android:title="@string/download_on_cell_title"
    android:restrictionType="bool"
    android:description="@string/download_on_cell_description"
    android:defaultValue="true" />

</restrictions>

Anda menggunakan setiap atribut android:key konfigurasi untuk membaca nilainya dari paket konfigurasi terkelola. Karena alasan ini, setiap konfigurasi harus memiliki string kunci unik, dan string tersebut tidak dapat dilokalkan. Nilai ini harus ditentukan dengan literal string.

Catatan: Di aplikasi produksi, android:title dan android:description harus digambar dari file resource yang dilokalkan, seperti yang dijelaskan dalam Melokalkan dengan Resource.

Aplikasi menentukan batasan menggunakan paket dalam bundle_array. Misalnya, aplikasi dengan beberapa opsi koneksi VPN dapat menentukan setiap konfigurasi server VPN dalam bundle, dengan beberapa paket yang dikelompokkan bersama dalam array paket:

<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >

  <restriction
    android:key="vpn_configuration_list"
    android:restrictionType="bundle_array">
    <restriction
      android:key="vpn_configuration"
      android:restrictionType="bundle">
      <restriction
        android:key="vpn_server"
        android:restrictionType="string"/>
      <restriction
        android:key="vpn_username"
        android:restrictionType="string"/>
      <restriction
        android:key="vpn_password"
        android:restrictionType="string"/>
    </restriction>
  </restriction>

</restrictions>

Jenis yang didukung untuk elemen android:restrictionType tercantum dalam Tabel 1 dan didokumentasikan dalam referensi untuk RestrictionsManager dan RestrictionEntry.

Tabel 1. Jenis dan penggunaan entri batasan.

Jenis android:restrictionType Penggunaan standar
TYPE_BOOLEAN "bool" Nilai boolean, benar atau salah.
TYPE_STRING "string" Nilai string, seperti nama.
TYPE_INTEGER "integer" Bilangan bulat dengan nilai dari MIN_VALUE hingga MAX_VALUE.
TYPE_CHOICE "choice" Nilai string yang dipilih dari android:entryValues, biasanya disajikan sebagai daftar pilihan tunggal.
TYPE_MULTI_SELECT "multi-select" Array string dengan nilai yang dipilih dari android:entryValues. Gunakan metode ini untuk menampilkan daftar multi-pilihan tempat lebih dari satu entri dapat dipilih, misalnya untuk memilih judul tertentu ke daftar yang diizinkan.
TYPE_NULL "hidden" Jenis batasan tersembunyi. Gunakan jenis ini untuk informasi yang perlu ditransfer tetapi tidak boleh ditampilkan kepada pengguna di UI. Menyimpan nilai string tunggal.
TYPE_BUNDLE_ARRAY "bundle_array" Gunakan ini untuk menyimpan array pembatasan bundles. Tersedia di Android 6.0 (API level 23).

Catatan: android:entryValues dapat dibaca mesin dan tidak dapat dilokalkan. Gunakan android:entries untuk menampilkan nilai yang dapat dibaca manusia yang dapat dilokalkan. Setiap entri harus memiliki indeks yang sesuai di android:entryValues.

Memeriksa konfigurasi terkelola

Aplikasi Anda tidak otomatis diberi tahu saat aplikasi lain mengubah setelan konfigurasinya. Sebagai gantinya, Anda harus memeriksa konfigurasi terkelola saat aplikasi dimulai atau dilanjutkan, dan memproses intent sistem untuk mengetahui apakah konfigurasi berubah saat aplikasi berjalan.

Untuk mengetahui setelan konfigurasi saat ini, aplikasi Anda menggunakan objek RestrictionsManager. Aplikasi Anda harus memeriksa konfigurasi terkelola saat ini pada waktu-waktu berikut:

Untuk mendapatkan objek RestrictionsManager, dapatkan aktivitas saat ini dengan getActivity(), lalu panggil metode Activity.getSystemService() aktivitas tersebut:

Kotlin

var myRestrictionsMgr =
        activity?.getSystemService(Context.RESTRICTIONS_SERVICE) as RestrictionsManager

Java

RestrictionsManager myRestrictionsMgr =
    (RestrictionsManager) getActivity()
        .getSystemService(Context.RESTRICTIONS_SERVICE);

Setelah memiliki RestrictionsManager, Anda bisa mendapatkan setelan konfigurasi saat ini dengan memanggil metode getApplicationRestrictions():

Kotlin

var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions

Java

Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();

Catatan: Demi kenyamanan, Anda juga dapat mengambil konfigurasi saat ini menggunakan UserManager, dengan memanggil UserManager.getApplicationRestrictions(). Metode ini berperilaku sama persis seperti RestrictionsManager.getApplicationRestrictions().

Metode getApplicationRestrictions() memerlukan pembacaan dari penyimpanan data, jadi harus dilakukan dengan hemat. Jangan panggil metode ini setiap kali Anda perlu mengetahui konfigurasi saat ini. Sebagai gantinya, Anda harus memanggilnya satu kali saat aplikasi dimulai atau dilanjutkan, dan menyimpan paket konfigurasi terkelola yang diambil ke dalam cache. Kemudian, proses intent ACTION_APPLICATION_RESTRICTIONS_CHANGED untuk mengetahui apakah konfigurasi berubah saat aplikasi Anda aktif, seperti yang dijelaskan dalam Memproses Perubahan Konfigurasi Terkelola.

Membaca dan menerapkan konfigurasi terkelola

Metode getApplicationRestrictions() menampilkan Bundle yang berisi pasangan nilai kunci untuk setiap konfigurasi yang telah ditetapkan. Nilainya adalah semua jenis Boolean, int, String, dan String[]. Setelah memiliki konfigurasi terkelola Bundle, Anda dapat memeriksa setelan konfigurasi saat ini dengan metode Bundle standar untuk jenis data tersebut, seperti getBoolean() atau getString().

Catatan: Konfigurasi terkelola Bundle berisi satu item untuk setiap konfigurasi yang telah ditetapkan secara eksplisit oleh penyedia konfigurasi terkelola. Namun, Anda tidak dapat berasumsi bahwa suatu konfigurasi akan ada dalam paket hanya karena Anda menentukan nilai default dalam file XML konfigurasi terkelola.

Aplikasi Anda dapat mengambil tindakan yang tepat berdasarkan setelan konfigurasi terkelola saat ini. Misalnya, jika aplikasi Anda memiliki konfigurasi yang menentukan apakah aplikasi dapat mendownload data melalui koneksi seluler, dan Anda mendapati bahwa konfigurasi disetel ke false, Anda harus menonaktifkan download data kecuali jika perangkat memiliki koneksi Wi-Fi, seperti yang ditunjukkan pada kode contoh berikut:

Kotlin

val appCanUseCellular: Boolean =
        if (appRestrictions.containsKey("downloadOnCellular")) {
            appRestrictions.getBoolean("downloadOnCellular")
        } else {
            // cellularDefault is a boolean using the restriction's default value
            cellularDefault
        }

if (!appCanUseCellular) {
    // ...turn off app's cellular-download functionality
    // ...show appropriate notices to user
}

Java

boolean appCanUseCellular;

if (appRestrictions.containsKey("downloadOnCellular")) {
    appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular");
} else {
    // cellularDefault is a boolean using the restriction's default value
    appCanUseCellular = cellularDefault;
}

if (!appCanUseCellular) {
    // ...turn off app's cellular-download functionality
    // ...show appropriate notices to user
}

Untuk menerapkan beberapa pembatasan bertingkat, baca entri pembatasan bundle_array sebagai kumpulan objek Parcelable dan transmisikan sebagai Bundle. Dalam contoh ini, setiap data konfigurasi VPN diuraikan dan digunakan untuk membuat daftar pilihan koneksi server:

Kotlin

// VpnConfig is a sample class used store config data, not defined
val vpnConfigs = mutableListOf<VpnConfig>()

val parcelables: Array<out Parcelable>? =
        appRestrictions.getParcelableArray("vpn_configuration_list")

if (parcelables?.isNotEmpty() == true) {
    // iterate parcelables and cast as bundle
    parcelables.map { it as Bundle }.forEach { vpnConfigBundle ->
        // parse bundle data and store in VpnConfig array
        vpnConfigs.add(VpnConfig()
                .setServer(vpnConfigBundle.getString("vpn_server"))
                .setUsername(vpnConfigBundle.getString("vpn_username"))
                .setPassword(vpnConfigBundle.getString("vpn_password")))
    }
}

if (vpnConfigs.isNotEmpty()) {
    // ...choose a VPN configuration or prompt user to select from list
}

Java

// VpnConfig is a sample class used store config data, not defined
List<VpnConfig> vpnConfigs = new ArrayList<>();

Parcelable[] parcelables =
    appRestrictions.getParcelableArray("vpn_configuration_list");

if (parcelables != null && parcelables.length > 0) {
    // iterate parcelables and cast as bundle
    for (int i = 0; i < parcelables.length; i++) {
        Bundle vpnConfigBundle = (Bundle) parcelables[i];
        // parse bundle data and store in VpnConfig array
        vpnConfigs.add(new VpnConfig()
            .setServer(vpnConfigBundle.getString("vpn_server"))
            .setUsername(vpnConfigBundle.getString("vpn_username"))
            .setPassword(vpnConfigBundle.getString("vpn_password")));
    }
}

if (!vpnConfigs.isEmpty()) {
    // ...choose a VPN configuration or prompt user to select from list
}

Memproses perubahan konfigurasi terkelola

Setiap kali konfigurasi terkelola aplikasi berubah, sistem akan mengaktifkan intent ACTION_APPLICATION_RESTRICTIONS_CHANGED. Aplikasi Anda harus memproses intent ini agar Anda dapat mengubah perilaku aplikasi saat setelan konfigurasi berubah.

Catatan: Intent ACTION_APPLICATION_RESTRICTIONS_CHANGED hanya dikirim ke pemroses yang terdaftar secara dinamis, bukan ke pemroses yang dideklarasikan dalam manifes aplikasi.

Kode berikut menunjukkan cara mendaftarkan penerima siaran secara dinamis untuk intent ini:

Kotlin

val restrictionsFilter = IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED)

val restrictionsReceiver = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {

        // Get the current configuration bundle
        val appRestrictions = myRestrictionsMgr.applicationRestrictions

        // Check current configuration settings, change your app's UI and
        // functionality as necessary.
    }
}

registerReceiver(restrictionsReceiver, restrictionsFilter)

Java

IntentFilter restrictionsFilter =
    new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);

BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
  @Override public void onReceive(Context context, Intent intent) {

    // Get the current configuration bundle
    Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();

    // Check current configuration settings, change your app's UI and
    // functionality as necessary.
  }
};

registerReceiver(restrictionsReceiver, restrictionsFilter);

Catatan: Biasanya, aplikasi Anda tidak perlu diberi tahu tentang perubahan konfigurasi saat dijeda. Sebagai gantinya, Anda harus membatalkan pendaftaran penerima siaran saat aplikasi dijeda. Saat aplikasi dilanjutkan, Anda terlebih dahulu memeriksa konfigurasi terkelola saat ini (seperti yang dibahas dalam Memeriksa Konfigurasi Terkelola), lalu mendaftarkan penerima siaran untuk memastikan Anda diberi tahu tentang perubahan konfigurasi yang terjadi saat aplikasi aktif.

Mengirim masukan konfigurasi terkelola ke EMM

Setelah menerapkan perubahan konfigurasi terkelola ke aplikasi Anda, praktik terbaiknya adalah memberi tahu EMM tentang status perubahan tersebut. Android mendukung fitur yang disebut status aplikasi dengan kunci, yang dapat Anda gunakan untuk mengirim masukan setiap kali aplikasi Anda mencoba menerapkan perubahan konfigurasi terkelola. Masukan ini dapat bertindak sebagai konfirmasi bahwa aplikasi Anda berhasil menerapkan konfigurasi terkelola atau dapat menyertakan pesan error jika aplikasi Anda gagal menerapkan perubahan yang ditentukan.

Penyedia EMM dapat mengambil masukan ini dan menampilkannya di konsol agar dapat dilihat oleh admin IT. Lihat Mengirim masukan aplikasi ke EMM untuk mengetahui informasi selengkapnya tentang topik ini, termasuk panduan mendetail tentang cara menambahkan dukungan masukan ke aplikasi Anda.

Contoh kode lainnya

Contoh ManagedConfigurations lebih lanjut menunjukkan penggunaan API yang dibahas di halaman ini.