تنظیمات مدیریت شده را تنظیم کنید

اگر در حال توسعه برنامه‌ها برای بازار سازمانی هستید، ممکن است لازم باشد الزامات خاصی را که توسط خط‌مشی‌های سازمان تعیین شده است، برآورده کنید. پیکربندی‌های مدیریت‌شده، که قبلاً به‌عنوان محدودیت‌های برنامه شناخته می‌شدند، به سرپرست فناوری اطلاعات سازمان اجازه می‌دهد تا تنظیمات برنامه‌ها را از راه دور مشخص کند. این قابلیت به ویژه برای برنامه‌های مورد تأیید سازمان که در نمایه کاری مستقر شده‌اند مفید است.

برای مثال، ممکن است یک سازمان از برنامه‌های تأیید شده بخواهد که به سرپرست فناوری اطلاعات اجازه دهد:

  • URL ها را برای یک مرورگر وب مجاز یا مسدود کنید
  • پیکربندی کنید که آیا یک برنامه مجاز است محتوا را از طریق تلفن همراه یا فقط از طریق Wi-Fi همگام‌سازی کند
  • تنظیمات ایمیل برنامه را پیکربندی کنید

این راهنما نحوه اجرای تنظیمات پیکربندی مدیریت شده را در برنامه خود نشان می دهد. برای مشاهده نمونه برنامه‌ها با پیکربندی مدیریت شده، به ManagedConfigurations مراجعه کنید. اگر یک توسعه‌دهنده مدیریت تحرک سازمانی (EMM) هستید، به راهنمای API مدیریت Android مراجعه کنید.

توجه: به دلایل تاریخی، این تنظیمات پیکربندی به عنوان محدودیت‌ها شناخته می‌شوند و با فایل‌ها و کلاس‌هایی که از این اصطلاح استفاده می‌کنند (مانند RestrictionsManager ) پیاده‌سازی می‌شوند. با این حال، این محدودیت‌ها در واقع می‌توانند طیف گسترده‌ای از گزینه‌های پیکربندی را اعمال کنند، نه فقط محدودیت‌هایی در عملکرد برنامه.

نمای کلی پیکربندی از راه دور

برنامه‌ها گزینه‌های پیکربندی مدیریت‌شده را تعریف می‌کنند که می‌تواند از راه دور توسط سرپرست فناوری اطلاعات تنظیم شود. اینها تنظیمات دلخواه هستند که می تواند توسط یک ارائه دهنده پیکربندی مدیریت شده تغییر یابد. اگر برنامه شما در نمایه کاری اجرا می شود، سرپرست فناوری اطلاعات می تواند پیکربندی مدیریت شده برنامه شما را تغییر دهد.

ارائه‌دهنده تنظیمات مدیریت‌شده، برنامه دیگری است که روی همان دستگاه اجرا می‌شود. این برنامه معمولاً توسط سرپرست فناوری اطلاعات کنترل می شود. سرپرست فناوری اطلاعات تغییرات پیکربندی را به برنامه ارائه‌دهنده پیکربندی مدیریت شده اطلاع می‌دهد. آن برنامه، به نوبه خود، تنظیمات برنامه شما را تغییر می دهد.

برای ارائه تنظیمات مدیریت شده خارجی:

  • پیکربندی های مدیریت شده را در مانیفست برنامه خود اعلام کنید. انجام این کار به سرپرست فناوری اطلاعات اجازه می‌دهد پیکربندی‌های برنامه را از طریق APIهای Google Play بخواند.
  • هر زمان که برنامه از سر گرفته می شود، از شی RestrictionsManager برای بررسی پیکربندی های مدیریت شده فعلی استفاده کنید و رابط کاربری و رفتار برنامه خود را تغییر دهید تا با آن پیکربندی ها مطابقت داشته باشد.
  • به هدف ACTION_APPLICATION_RESTRICTIONS_CHANGED گوش دهید. وقتی این پخش را دریافت می‌کنید، RestrictionsManager بررسی کنید تا ببینید پیکربندی‌های مدیریت‌شده فعلی چیست و هر گونه تغییر لازم را در رفتار برنامه‌تان اعمال کنید.

تنظیمات مدیریت شده را تعریف کنید

برنامه شما می تواند از هر پیکربندی مدیریت شده ای که می خواهید تعریف کنید پشتیبانی کند. پیکربندی‌های مدیریت‌شده برنامه را در فایل پیکربندی‌های مدیریت‌شده و فایل پیکربندی‌ها را در مانیفست اعلام می‌کنید. ایجاد یک فایل پیکربندی به برنامه های دیگر اجازه می دهد تا پیکربندی های مدیریت شده ای را که برنامه شما ارائه می دهد بررسی کنند. شرکای EMM می‌توانند پیکربندی‌های برنامه شما را با استفاده از APIهای Google Play بخوانند.

برای تعریف گزینه های پیکربندی راه دور برنامه، عنصر زیر را در عنصر <application> مانیفست خود قرار دهید:

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

یک فایل به نام app_restrictions.xml در فهرست برنامه خود را در res/xml ایجاد کنید. ساختار آن فایل در مرجع RestrictionsManager توضیح داده شده است. این فایل دارای یک عنصر سطح بالای <restrictions> است که شامل یک عنصر <restriction> فرزند برای هر گزینه پیکربندی برنامه است.

توجه: نسخه های بومی سازی شده فایل پیکربندی مدیریت شده را ایجاد نکنید. برنامه شما فقط مجاز است یک فایل پیکربندی مدیریت شده داشته باشد، بنابراین پیکربندی ها برای برنامه شما در همه مناطق سازگار خواهند بود.

در یک محیط سازمانی، یک EMM معمولاً از طرح پیکربندی مدیریت شده برای ایجاد یک کنسول راه دور برای سرپرستان فناوری اطلاعات استفاده می کند، بنابراین مدیران می توانند از راه دور برنامه شما را پیکربندی کنند.

ارائه‌دهنده پیکربندی مدیریت‌شده می‌تواند از برنامه درخواست کند تا جزئیات پیکربندی‌های موجود برنامه، از جمله متن توضیحات آن‌ها را بیابد. ارائه‌دهنده تنظیمات و سرپرست فناوری اطلاعات می‌توانند پیکربندی‌های مدیریت‌شده برنامه شما را در هر زمانی تغییر دهند، حتی زمانی که برنامه در حال اجرا نیست.

به عنوان مثال، فرض کنید برنامه شما می تواند از راه دور پیکربندی شود تا به آن اجازه داده یا از دانلود داده ها از طریق اتصال سلولی منع شود. برنامه شما می تواند یک عنصر <restriction> مانند این داشته باشد:

<?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>

شما از ویژگی android:key هر پیکربندی برای خواندن مقدار آن از یک بسته پیکربندی مدیریت شده استفاده می کنید. به همین دلیل، هر پیکربندی باید یک رشته کلید منحصر به فرد داشته باشد و رشته را نمی توان بومی سازی کرد. باید با یک رشته به معنای واقعی کلمه مشخص شود.

توجه: در یک برنامه تولیدی، android:title و android:description باید از یک فایل منبع بومی سازی شده ترسیم شوند، همانطور که در محلی سازی با منابع توضیح داده شده است.

یک برنامه با استفاده از بسته‌ها در یک bundle_array محدودیت‌هایی را تعریف می‌کند. به عنوان مثال، یک برنامه با چندین گزینه اتصال VPN می‌تواند هر پیکربندی سرور VPN را در یک bundle تعریف کند، با چندین بسته که در یک آرایه دسته‌بندی شده‌اند:

<?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>

انواع پشتیبانی شده برای android:restrictionType در جدول 1 فهرست شده و در مرجع RestrictionsManager و RestrictionEntry مستند شده است.

جدول 1. انواع ورود محدودیت و استفاده.

تایپ کنید android:restrictionType استفاده معمولی
TYPE_BOOLEAN "bool" یک مقدار بولی، درست یا نادرست.
TYPE_STRING "string" یک مقدار رشته، مانند یک نام.
TYPE_INTEGER "integer" یک عدد صحیح با مقدار از MIN_VALUE تا MAX_VALUE .
TYPE_CHOICE "choice" یک مقدار رشته انتخاب شده از android:entryValues ، که معمولاً به عنوان یک لیست انتخابی ارائه می شود.
TYPE_MULTI_SELECT "multi-select" یک آرایه رشته ای با مقادیر انتخاب شده از android:entryValues . از این برای ارائه یک لیست چند انتخابی استفاده کنید که در آن می توان بیش از یک ورودی را انتخاب کرد، مانند انتخاب عناوین خاص به لیست مجاز.
TYPE_NULL "hidden" نوع محدودیت پنهان از این نوع برای اطلاعاتی استفاده کنید که باید به سراسر جهان منتقل شوند اما نباید در رابط کاربری به کاربر ارائه شوند. یک مقدار رشته را ذخیره می کند.
TYPE_BUNDLE_ARRAY "bundle_array" از این برای ذخیره آرایه های bundles محدود استفاده کنید. موجود در Android 6.0 (سطح API 23).

توجه: android:entryValues ​​قابل خواندن با ماشین هستند و نمی توان آنها را محلی کرد. از android:entries برای ارائه مقادیر قابل خواندن توسط انسان که می توانند بومی سازی شوند استفاده کنید. هر ورودی باید یک شاخص مربوطه در android:entryValues ​​داشته باشد.

تنظیمات مدیریت شده را بررسی کنید

هنگامی که برنامه های دیگر تنظیمات پیکربندی آن را تغییر می دهند، برنامه شما به طور خودکار مطلع نمی شود. درعوض، باید بررسی کنید که تنظیمات مدیریت شده در زمان شروع یا از سرگیری برنامه شما چیست و به قصد سیستم گوش دهید تا متوجه شوید که آیا تنظیمات در حین اجرای برنامه شما تغییر می کند یا خیر.

برای اطلاع از تنظیمات پیکربندی فعلی، برنامه شما از یک شی RestrictionsManager استفاده می کند. برنامه شما باید پیکربندی های مدیریت شده فعلی را در زمان های زیر بررسی کند:

  • هنگامی که برنامه شروع می شود یا از سر می گیرد، در متد onResume() آن
  • هنگامی که برنامه از تغییر پیکربندی مطلع می شود، همانطور که در Listen for Managed Configuration Changes توضیح داده شده است.

برای دریافت یک شی RestrictionsManager ، اکتیویتی فعلی را با getActivity() دریافت کنید، سپس متد Activity.getSystemService() آن فعالیت را فراخوانی کنید:

کاتلین

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

جاوا

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

هنگامی که یک RestrictionsManager دارید، می توانید تنظیمات پیکربندی فعلی را با فراخوانی متد getApplicationRestrictions() آن دریافت کنید:

کاتلین

var appRestrictions: Bundle = myRestrictionsMgr.applicationRestrictions

جاوا

Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();

توجه: برای راحتی، می‌توانید پیکربندی‌های فعلی را با یک UserManager با فراخوانی UserManager.getApplicationRestrictions() واکشی کنید. این روش دقیقاً مانند RestrictionsManager.getApplicationRestrictions() عمل می کند.

متد getApplicationRestrictions() نیاز به خواندن از ذخیره داده ها دارد، بنابراین باید به اندازه کافی انجام شود. هر بار که نیاز به دانستن پیکربندی فعلی دارید، این روش را فراخوانی نکنید. در عوض، باید زمانی که برنامه شما شروع به کار کرد یا از سر گرفت، آن را یک بار فراخوانی کنید و بسته تنظیمات مدیریت شده واکشی شده را در حافظه پنهان ذخیره کنید. سپس به هدف ACTION_APPLICATION_RESTRICTIONS_CHANGED گوش دهید تا متوجه شوید که آیا پیکربندی در زمانی که برنامه شما فعال است تغییر می کند، همانطور که در Listen for Managed Configuration Changes توضیح داده شده است.

خواندن و اعمال تنظیمات مدیریت شده

متد getApplicationRestrictions() یک Bundle حاوی یک جفت کلید-مقدار برای هر پیکربندی تنظیم شده برمی گرداند. مقادیر همگی از نوع Boolean ، int ، String و String[] هستند. هنگامی که پیکربندی مدیریت شده Bundle دارید، می توانید تنظیمات پیکربندی فعلی را با روش های استاندارد Bundle برای آن نوع داده ها، مانند getBoolean() یا getString() بررسی کنید.

توجه: Bundle تنظیمات مدیریت شده شامل یک مورد برای هر پیکربندی است که به صراحت توسط یک ارائه دهنده تنظیمات مدیریت شده تنظیم شده است. با این حال، نمی‌توانید فرض کنید که پیکربندی در بسته وجود دارد، فقط به این دلیل که یک مقدار پیش‌فرض را در فایل XML پیکربندی‌های مدیریت‌شده تعریف کرده‌اید.

این به برنامه شما بستگی دارد که بر اساس تنظیمات پیکربندی مدیریت شده فعلی اقدام مناسب انجام دهد. برای مثال، اگر برنامه شما دارای پیکربندی است که مشخص می‌کند آیا می‌تواند داده‌ها را از طریق اتصال سلولی بارگیری کند یا خیر، و متوجه شدید که پیکربندی روی false تنظیم شده است، باید دانلود داده را غیرفعال کنید، مگر زمانی که دستگاه دارای اتصال Wi-Fi باشد، در کد مثال زیر نشان داده شده است:

کاتلین

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
}

جاوا

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
}

برای اعمال محدودیت های تو در تو , ورودی محدودیت bundle_array را به عنوان مجموعه ای از اشیاء Parcelable بخوانید و به صورت Bundle پخش کنید . در این مثال، داده های پیکربندی هر VPN تجزیه شده و برای ایجاد لیستی از گزینه های اتصال سرور استفاده می شود:

کاتلین

// 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
}

جاوا

// 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
}

به تغییرات پیکربندی مدیریت شده گوش دهید

هر زمان که پیکربندی های مدیریت شده یک برنامه تغییر می کند، سیستم هدف ACTION_APPLICATION_RESTRICTIONS_CHANGED را اجرا می کند. برنامه شما باید به این هدف گوش دهد تا بتوانید رفتار برنامه را هنگام تغییر تنظیمات پیکربندی تغییر دهید.

توجه: هدف ACTION_APPLICATION_RESTRICTIONS_CHANGED فقط برای شنوندگانی ارسال می شود که به صورت پویا ثبت شده اند، نه برای شنوندگانی که در مانیفست برنامه اعلام شده اند.

کد زیر نحوه ثبت پویا یک گیرنده پخش را برای این هدف نشان می دهد:

کاتلین

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)

جاوا

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);

توجه: معمولاً وقتی برنامه شما متوقف می شود، نیازی به اطلاع از تغییرات پیکربندی نیست. در عوض، زمانی که برنامه متوقف می شود، باید گیرنده پخش خود را لغو ثبت کنید. هنگامی که برنامه از سر گرفته می‌شود، ابتدا پیکربندی‌های مدیریت‌شده فعلی را بررسی می‌کنید (همانطور که در بررسی تنظیمات مدیریت‌شده توضیح داده شد)، سپس گیرنده پخش خود را ثبت می‌کنید تا مطمئن شوید در مورد تغییرات پیکربندی که هنگام فعال بودن برنامه رخ می‌دهد به شما اطلاع داده می‌شود.

بازخورد پیکربندی مدیریت شده را به EMM ارسال کنید

پس از اعمال تغییرات پیکربندی مدیریت شده در برنامه خود، بهترین کار این است که EMM ها را از وضعیت تغییر مطلع کنید. Android از ویژگی‌ای به نام حالت‌های برنامه کلیددار پشتیبانی می‌کند که می‌توانید از آن برای ارسال بازخورد هر بار که برنامه‌تان تلاش می‌کند تغییرات پیکربندی مدیریت‌شده را اعمال کند، استفاده کنید. این بازخورد می‌تواند به‌عنوان تأییدی باشد که برنامه شما پیکربندی‌های مدیریت‌شده را با موفقیت تنظیم کرده است یا اگر برنامه‌تان تغییرات مشخص‌شده را اعمال نکرد، می‌تواند شامل یک پیام خطا باشد.

ارائه دهندگان EMM قادر به بازیابی این بازخورد و نمایش آن در کنسول های خود برای مشاهده مدیران فناوری اطلاعات هستند. برای اطلاعات بیشتر در مورد موضوع، از جمله راهنمای دقیق در مورد نحوه افزودن پشتیبانی بازخورد به برنامه ، به ارسال بازخورد برنامه به EMM مراجعه کنید.

نمونه کد اضافی

نمونه ManagedConfigurations استفاده از APIهای پوشش داده شده در این صفحه را بیشتر نشان می دهد.