סקירה כללית על ניהול המכשירים

הוצאה משימוש של מנהל המכשיר. החל מ-Android 9 (רמת API 28), חלק מכללי המדיניות של האדמין יסומנו ככאלה שהוצאו משימוש כשמפעילים את האדמין במכשיר. מומלץ להתחיל להתכונן לשינוי הזה כבר עכשיו. למידע נוסף ולהצגת אפשרויות ההעברה, כדאי לקרוא את המאמר הוצאה משימוש של מנהלי מכשירים.

Android כולל תמיכה באפליקציות עסקיות באמצעות Android Device Administration API. Device Administration API מספק תכונות לניהול המכשיר ברמת המערכת. ממשקי ה-API האלה מאפשרים ליצור אפליקציות עם אבטחה מובנית שמועילות בסביבות ארגוניות, שבהן אנשי IT צריכים שליטה רחבה במכשירי העובדים. לדוגמה, באפליקציית האימייל המובנית ל-Android נעשה שימוש בממשקי ה-API האלה כדי לשפר את התמיכה ב-Exchange. באמצעות אפליקציית האימייל, אדמינים של Exchange יכולים לאכוף את מדיניות הסיסמאות – כולל סיסמאות אלפאנומריות או קודי אימות מספריים – בכל המכשירים. אדמינים יכולים גם למחוק מרחוק את נתוני הטלפונים הניידים שאבדו או נגנבו (כלומר, לשחזר את הגדרות ברירת המחדל של היצרן). משתמשי Exchange יכולים לסנכרן את נתוני האימייל והיומן שלהם.

המסמך הזה מיועד למפתחים שרוצים לפתח פתרונות ארגוניים למכשירים עם Android. במאמר הזה נסביר על התכונות השונות של Device Administration API שמספקות אבטחה חזקה יותר למכשירי Android של העובדים.

הערה למידע על פיתוח בקר של מדיניות העבודה לפריסות של Android for Work, ראו פיתוח בקר לניהול מדיניות המכשירים.

מצב 'בעלי מכשיר ללא ממשק משתמש גרפי'

ב-Android 14 (רמת API 34) מופיע המצב Headless System User Mode (מכשירים שבהם UserManager.isHeadlessSystemUserMode מחזיר את הערך true). במצב Headless System User Mode, משתמש המערכת הוא משתמש ברקע, והוא מסתמך על משתמשים נוספים בחזית לצורך אינטראקציה עם משתמש הקצה. ב-Android 14 נוסף גם מצב שיוך לבעלי מכשיר ללא GUI, שמוסיף בעלים של פרופיל לכל המשתמשים המשויכים מלבד משתמש המערכת שבו מוגדר בעלי המכשיר.

במכשירים שהוגדרו עם משתמש מערכת ללא גוף (שבו משתמש המערכת פועל ברקע), רק כללי מדיניות המכשיר ברמת הכלל (כללי מדיניות שחלים על כל המשתמשים) חלים על המשתמש או המשתמשים בחזית. לפרטים נוספים, ראו addUserRestriction.

יצרני מכשירי Android יכולים להיעזר בהנחיות שפורסמו בכתובת source.android.com.

סקירה כללית על Device Administration API

ריכזנו כאן דוגמאות לסוגי האפליקציות שעשויות להשתמש ב-Device Administration API:

  • לשלוח אימיילים ללקוחות.
  • אפליקציות אבטחה שמבצעות איפוס מרחוק.
  • אפליקציות ושירותים לניהול מכשירים.

איך זה עובד?

משתמשים ב-Device Administration API כדי לכתוב אפליקציות אדמין של מכשירים שהמשתמשים מתקינים במכשירים שלהם. אפליקציית ניהול המכשיר אוכפת את כללי המדיניות הרצויים. כך זה עובד:

  • אדמין כותב אפליקציה לניהול המכשיר שאוכפת מדיניות אבטחת מכשיר מרחוק או מקומי. כללי המדיניות האלה יכולים להיות מוטמעים באפליקציה, או שהאפליקציה יכולה לאחזר אותם באופן דינמי משרת של צד שלישי.
  • האפליקציה מותקנת במכשירים של המשתמשים. בשלב הזה אין ל-Android פתרון אוטומטי להקצאה. אלה כמה מהדרכים שבהן מנהל מערכת יכול להפיץ את האפליקציה למשתמשים:
    • Google Play.
    • הפעלת האפשרות להתקנה מחנות אחרת.
    • הפצת האפליקציה באמצעים אחרים, כמו אימייל או אתרים.
  • המערכת מבקשת מהמשתמש להפעיל את אפליקציית הניהול של המכשיר. האופן והמועד שבו זה קורה תלוי באופן ההטמעה של האפליקציה.
  • אחרי שהמשתמשים מפעילים את אפליקציית האדמין של המכשיר, הם כפופים לכללי המדיניות שלה. בדרך כלל, ציות למדיניות הזו מביא יתרונות, כמו גישה למערכות ולנתונים רגישים.

אם המשתמשים לא יפעילו את אפליקציית ניהול המכשיר, היא תישאר במכשיר אך במצב לא פעיל. המשתמשים לא יהיו כפופים למדיניות של האפליקציה, ובתמורה הם לא יקבלו את היתרונות של האפליקציה – למשל, יכול להיות שהם לא יוכלו לסנכרן נתונים.

אם משתמש לא מציית למדיניות (לדוגמה, אם משתמש מגדיר סיסמה שמפירה את ההנחיות), הבעלים של האפליקציה מחליט איך לטפל בבעיה. עם זאת, בדרך כלל המשתמש לא יוכל לסנכרן נתונים.

אם מכשיר ינסה להתחבר לשרת שדורש מדיניות שלא נתמכת ב-Device Administration API, החיבור לא יאושר. בשלב זה, Device Administration API לא מאפשר הקצאה חלקית. במילים אחרות, אם מכשיר (למשל, מכשיר מדור קודם) לא תומך בכל כללי המדיניות שצוינו, אי אפשר לאפשר למכשיר להתחבר.

אם מכשיר מכיל כמה אפליקציות ניהול מופעלות, המדיניות המחמירה ביותר היא זו שתואכף. אין דרך לטרגט לאפליקציית ניהול מסוימת.

כדי להסיר אפליקציית אדמין קיימת במכשיר, המשתמשים צריכים לבטל את הרישום שלה כאדמין.

מדיניות

בסביבה ארגונית, לרוב המכשירים של העובדים צריכים לעמוד בסט של כללי מדיניות מחמירים ששולטים בשימוש במכשיר. ממשק Device Administration API תומך בכללי המדיניות שמפורטים בטבלה 1. הערה: נכון לעכשיו, Device Administration API תומך רק בסיסמאות לנעילה של המסך:

טבלה 1. כללי המדיניות שנתמכים על ידי Device Administration API.

מדיניות תיאור
הסיסמה מופעלת המכשירים צריכים לבקש קוד אימות או סיסמאות.
האורך המינימלי של הסיסמה מגדירים את מספר התווים הנדרש בסיסמה. לדוגמה, אפשר לדרוש שקודי אימות או סיסמאות יהיו באורך של שישה תווים לפחות.
נדרשת סיסמה אלפאנומרית הסיסמאות צריכות להיות משולבות של אותיות ומספרים. הם יכולים לכלול תווים סמליים.
נדרשת סיסמה מורכבת הסיסמה חייבת להכיל לפחות אות אחת, ספרה אחת ותו מיוחד אחד. התכונה הושקה ב-Android 3.0.
מספר האותיות המינימלי שנדרש בסיסמה מספר האותיות המינימלי שנדרש בסיסמה לכל האדמינים או לאדמין מסוים. הופיעה לראשונה ב-Android 3.0.
מספר מינימלי של אותיות קטנות הנדרש לסיסמה מספר האותיות הקטנות המינימלי שנדרש בסיסמה לכל האדמינים או לאדמין מסוים. הופיעה לראשונה ב-Android 3.0.
צריך להזין לפחות תווים שאינם אותיות המספר המינימלי של תווים שאינם אותיות שנדרש בסיסמה לכל האדמינים או לחשבון מסוים. הופיעה לראשונה ב-Android 3.0.
מספר הספרות המינימלי שנדרש בסיסמה מספר הספרות המספריות המינימלי שנדרש בסיסמה לכל האדמינים או לאדמין מסוים. הופיעה לראשונה ב-Android 3.0.
מספר הסימנים המינימלי שנדרש בסיסמה מספר הסימנים המינימלי שנדרש בסיסמה לכל האדמינים או לאדמין מסוים. הופיעה לראשונה ב-Android 3.0.
מספר אותיות רישיות מינימלי שנדרש בסיסמה מספר האותיות הרישיות המינימלי שנדרש בסיסמה לכל האדמינים או לאדמין מסוים. הופיעה לראשונה ב-Android 3.0.
זמן קצוב לתפוגת תוקף הסיסמה מתי יפוג התוקף של הסיסמה, כפי שהוא מחושב כדלתא באלפיות שנייה מהמועד שבו האדמין של המכשיר מגדיר את זמן התפוגה. הופיעה לראשונה ב-Android 3.0.
הגבלת היסטוריית הסיסמאות המדיניות הזו מונעת ממשתמשים לעשות שימוש חוזר ב-n הסיסמאות הייחודיות האחרונות. בדרך כלל משתמשים במדיניות הזו בשילוב עם המדיניות setPasswordExpirationTimeout(), שמאלצת את המשתמשים לעדכן את הסיסמאות שלהם אחרי פרק זמן מסוים. הופיעה לראשונה ב-Android 3.0.
מספר הניסיונות המקסימלי להזנת סיסמה מציינת כמה פעמים משתמש יכול להזין סיסמה שגויה לפני שהמכשיר מוחק את הנתונים שלו. Device Administration API מאפשר גם לאדמינים לאפס את המכשיר מרחוק להגדרות ברירת המחדל של היצרן. כך תוכלו לאבטח את הנתונים במקרה שהמכשיר יאבד או ייגנב.
נעילה לאחר זמן חוסר פעילות מקסימלי ההגדרה קובעת את משך הזמן מהפעם האחרונה שהמשתמש נגע במסך או לחץ על לחצן עד שהמסך יינעל. במצב כזה, המשתמשים יצטרכו להזין שוב את קוד האימות או את הסיסמאות כדי להשתמש במכשירים שלהם ולגשת לנתונים. הערך יכול להיות בין דקה אחת ל-60 דקות.
דרישה להצפנת אחסון מציין שצריך להצפין את אזור האחסון, אם המכשיר תומך בכך. הופיעה לראשונה ב-Android 3.0.
השבתת המצלמה מציין שצריך להשבית את המצלמה. חשוב לדעת שההשבתה לא חייבת להיות סופית. אפשר להפעיל או להשבית את המצלמה באופן דינמי על סמך הקשר, זמן וכו'. הופיעה לראשונה ב-Android 4.0.

תכונות אחרות

בנוסף לתמיכה במדיניות שמפורטת בטבלה שלמעלה, Device Administration API מאפשר לבצע את הפעולות הבאות:

  • מבקשים מהמשתמש להגדיר סיסמה חדשה.
  • נועלים את המכשיר באופן מיידי.
  • מאפסים את נתוני המכשיר (כלומר, לשחזר את המכשיר להגדרות ברירת המחדל שלו).

אפליקציה לדוגמה

הדוגמאות שמוצגות בדף הזה מבוססות על הדוגמה של Device Administration API, שכלולה בדוגמאות ל-SDK (שזמינות דרך Android SDK Manager) וממוקמת במערכת בתור <sdk_root>/ApiDemos/app/src/main/java/com/example/android/apis/app/DeviceAdminSample.java.

האפליקציה לדוגמה מציעה הדגמה של תכונות ניהול המכשיר. הוא מציג למשתמשים ממשק משתמש שמאפשר להם להפעיל את אפליקציית האדמין של המכשיר. אחרי שהם מפעילים את האפליקציה, הם יכולים להשתמש בלחצנים בממשק המשתמש כדי לבצע את הפעולות הבאות:

  • הגדרת איכות הסיסמה.
  • מציינים את הדרישות לסיסמה של המשתמש, כמו אורך מינימלי, מספר תווים מספריים מינימלי שהיא צריכה להכיל וכו'.
  • מגדירים את הסיסמה. אם הסיסמה לא עומדת בדרישות המדיניות שצוינו, המערכת מחזירה שגיאה.
  • מגדירים כמה ניסיונות כושלים להזנת סיסמה יכולים להתרחש לפני שמכשיר יימחק (כלומר, יוחזר להגדרות המקוריות).
  • מגדירים את התאריך שבו תוקף הסיסמה יפוג.
  • מגדירים את אורך היסטוריית הסיסמאות (length מתייחס למספר הסיסמאות הישנות ששמורות בהיסטוריה). הפעולה הזו מונעת מהמשתמשים לעשות שימוש חוזר באחת מ-n הסיסמאות האחרונות שבהן הם השתמשו בעבר.
  • מציינים שצריך להצפין את אזור האחסון, אם המכשיר תומך בכך.
  • מגדירים את משך הזמן המקסימלי ללא פעילות שיכול לחלוף לפני שהמכשיר ננעל.
  • לנעול את המכשיר באופן מיידי.
  • למחוק את הנתונים במכשיר (כלומר, לשחזר את הגדרות המקור).
  • להשבית את המצלמה.

איור 1. צילום מסך של האפליקציה לדוגמה

פיתוח אפליקציה לניהול מכשירים

אדמינים יכולים להשתמש ב-Device Administration API כדי לכתוב אפליקציה לאכיפת מדיניות אבטחה של מכשירים מרחוק או באופן מקומי. בקטע הזה מופיע סיכום של השלבים ליצירת אפליקציה לניהול המכשיר.

יצירת המניפסט

כדי להשתמש ב-Device Administration API, המניפסט של האפליקציה צריך לכלול את הפרטים הבאים:

  • תת-סוג של DeviceAdminReceiver שכולל את הפריטים הבאים:
  • הצהרה על כללי מדיניות האבטחה שמשמשים במטא-נתונים.

הנה קטע מתוך המניפסט לדוגמה של ניהול המכשיר:

<activity android:name=".app.DeviceAdminSample"
            android:label="@string/activity_sample_device_admin">
    <intent-filter>
        <action android:name="android.intent.action.MAIN" />
        <category android:name="android.intent.category.SAMPLE_CODE" />
    </intent-filter>
</activity>
<receiver android:name=".app.DeviceAdminSample$DeviceAdminSampleReceiver"
        android:label="@string/sample_device_admin"
        android:description="@string/sample_device_admin_description"
        android:permission="android.permission.BIND_DEVICE_ADMIN">
    <meta-data android:name="android.app.device_admin"
            android:resource="@xml/device_admin_sample" />
    <intent-filter>
        <action android:name="android.app.action.DEVICE_ADMIN_ENABLED" />
    </intent-filter>
</receiver>

חשוב לזכור:

  • המאפיינים הבאים מתייחסים למשאבי מחרוזות שבאפליקציה לדוגמה נמצאים ב-ApiDemos/res/values/strings.xml. מידע נוסף על משאבים זמין במאמר משאבי אפליקציה.
    • android:label="@string/activity_sample_device_admin" מתייחס לתווית של הפעילות שגלויה למשתמשים.
    • android:label="@string/sample_device_admin" מתייחס לתווית של ההרשאה שקריאה למשתמשים.
    • android:description="@string/sample_device_admin_description" מתייחס לתיאור של ההרשאה שגלוי למשתמש. בדרך כלל, תיאור ארוך יותר ומכיל יותר מידע מתוויות.
  • android:permission="android.permission.BIND_DEVICE_ADMIN" היא הרשאה שדרושה למחלקת משנה של DeviceAdminReceiver כדי לוודא שרק המערכת יכולה לקיים אינטראקציה עם המקלט (אי אפשר להעניק את ההרשאה הזו לאף אפליקציה). כך תוכלו למנוע מאפליקציות אחרות לנצל לרעה את האפליקציה לניהול המכשיר.
  • android.app.action.DEVICE_ADMIN_ENABLED הוא הפעולה הראשית שמחלקה משנית DeviceAdminReceiver צריכה לבצע כדי לקבל הרשאה לנהל מכשיר. הערך הזה מוגדר לנמען כשהמשתמש מפעיל את אפליקציית האדמין של המכשיר. בדרך כלל הקוד מטפל בכך ב-onEnabled(). כדי לקבל תמיכה, הנמען צריך גם לדרוש את ההרשאה BIND_DEVICE_ADMIN כדי שאפליקציות אחרות לא יוכלו לנצל לרעה את ההרשאה הזו.
  • כשמשתמש מפעיל את אפליקציית האדמין של המכשיר, הוא מעניק למכשיר המקבל הרשאה לבצע פעולות בתגובה לשידור של אירועי מערכת מסוימים. כשמתרחש אירוע מתאים, האפליקציה יכולה לאכוף מדיניות. לדוגמה, אם המשתמש מנסה להגדיר סיסמה חדשה שלא עומדת בדרישות המדיניות, האפליקציה יכולה להציג למשתמש בקשה לבחור סיסמה אחרת שעומדת בדרישות.
  • מומלץ לא לשנות את שם הנמען אחרי פרסום האפליקציה. אם השם במניפסט ישתנה, ניהול המכשיר יושבת כשהמשתמשים מעדכנים את האפליקציה. למידע נוסף, ראו <receiver>.
  • android:resource="@xml/device_admin_sample" מגדיר את כללי מדיניות האבטחה שמשמשים במטא-נתונים. המטא-נתונים מספקים מידע נוסף ספציפי למנהל המכשיר, כפי שהוא מנותח על ידי הכיתה DeviceAdminInfo. הנה התוכן של device_admin_sample.xml:
<device-admin xmlns:android="http://schemas.android.com/apk/res/android">
  <uses-policies>
    <limit-password />
    <watch-login />
    <reset-password />
    <force-lock />
    <wipe-data />
    <expire-password />
    <encrypted-storage />
    <disable-camera />
  </uses-policies>
</device-admin>

כשאתם מתכננים את האפליקציה לניהול המכשיר, אתם לא צריכים לכלול את כל כללי המדיניות, אלא רק את אלה שרלוונטיים לאפליקציה.

מידע נוסף על קובץ המניפסט זמין במדריך למפתחי Android.

הטמעת הקוד

Device Administration API כולל את הכיתות הבאות:

DeviceAdminReceiver
השכבה הבסיסית להטמעת רכיב לניהול מכשירים. הכיתה הזו מאפשרת לפרש בקלות את פעולות הכוונה הגולמיות שנשלחות על ידי המערכת. האפליקציה לניהול המכשיר חייבת לכלול מחלקה משנית DeviceAdminReceiver.
DevicePolicyManager
כיתה לניהול כללי המדיניות שחלים על מכשיר. רוב הלקוחות מהסוג הזה חייבים לפרסם DeviceAdminReceiver שהמשתמש הפעיל כרגע. DevicePolicyManager מנהלת את כללי המדיניות של מכונה אחת או יותר של DeviceAdminReceiver
DeviceAdminInfo
הקלאס הזה משמש לציון מטא-נתונים של רכיב אדמין של מכשיר.

המחלקות האלה מספקות את הבסיס לאפליקציה לניהול מכשירים שפועלת באופן מלא. בשאר ההוראות בקטע הזה נסביר איך משתמשים בממשקי ה-API של DeviceAdminReceiver ו-DevicePolicyManager כדי לכתוב אפליקציה לניהול מכשירים.

יצירת מחלקה משנית של DeviceAdminReceiver

כדי ליצור אפליקציית ניהול מכשירים, צריך לתת מחלקה משנית DeviceAdminReceiver. הכיתה DeviceAdminReceiver מורכבת מסדרה של קריאות חזרה (callbacks) שמופעלות כשאירועים מסוימים מתרחשים.

בתת-הסוג DeviceAdminReceiver, האפליקציה לדוגמה מציגה פשוט התראה מסוג Toast בתגובה לאירועים מסוימים. לדוגמה:

Kotlin

class DeviceAdminSample : DeviceAdminReceiver() {

    private fun showToast(context: Context, msg: String) {
        context.getString(R.string.admin_receiver_status, msg).let { status ->
            Toast.makeText(context, status, Toast.LENGTH_SHORT).show()
        }
    }

    override fun onEnabled(context: Context, intent: Intent) =
            showToast(context, context.getString(R.string.admin_receiver_status_enabled))

    override fun onDisableRequested(context: Context, intent: Intent): CharSequence =
            context.getString(R.string.admin_receiver_status_disable_warning)

    override fun onDisabled(context: Context, intent: Intent) =
            showToast(context, context.getString(R.string.admin_receiver_status_disabled))

    override fun onPasswordChanged(context: Context, intent: Intent, userHandle: UserHandle) =
            showToast(context, context.getString(R.string.admin_receiver_status_pw_changed))
...
}

Java

public class DeviceAdminSample extends DeviceAdminReceiver {

    void showToast(Context context, String msg) {
        String status = context.getString(R.string.admin_receiver_status, msg);
        Toast.makeText(context, status, Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onEnabled(Context context, Intent intent) {
        showToast(context, context.getString(R.string.admin_receiver_status_enabled));
    }

    @Override
    public CharSequence onDisableRequested(Context context, Intent intent) {
        return context.getString(R.string.admin_receiver_status_disable_warning);
    }

    @Override
    public void onDisabled(Context context, Intent intent) {
        showToast(context, context.getString(R.string.admin_receiver_status_disabled));
    }

    @Override
    public void onPasswordChanged(Context context, Intent intent, UserHandle userHandle) {
        showToast(context, context.getString(R.string.admin_receiver_status_pw_changed));
    }
...
}

הפעלת האפליקציה

אחד מהאירועים העיקריים שאפליקציית אדמין של מכשיר צריכה לטפל בהם הוא הפעלת האפליקציה על ידי המשתמש. המשתמש צריך להפעיל את האפליקציה באופן מפורש כדי שהמדיניות תוכל להיות נאכפת. אם המשתמש יבחר שלא להפעיל את האפליקציה, היא עדיין תופיע במכשיר, אבל המדיניות לא תיאכף והמשתמש לא ייהנה מהטבות האפליקציה.

תהליך הפעלת האפליקציה מתחיל כשהמשתמש מבצע פעולה שמפעילה את הכוונה ACTION_ADD_DEVICE_ADMIN. באפליקציה לדוגמה, מצב זה קורה כשהמשתמש לוחץ על תיבת הסימון Enable Admin (הפעלת אדמין).

כשהמשתמש לוחץ על תיבת הסימון Enable Admin, המסך משתנה ומופיעה בקשה להפעיל את אפליקציית האדמין של המכשיר, כפי שמוצג באיור 2.

איור 2. אפליקציה לדוגמה: הפעלת האפליקציה

הקוד הבא מופעל כשהמשתמש לוחץ על תיבת הסימון Enable Admin. כתוצאה מכך, המערכת תיצור את הקריאה החוזרת (callback) של onPreferenceChange(). פונקציית ה-callback הזו מופעלת כשהמשתמש משנה את הערך של Preference והוא עומד להגדיר אותו ו/או לשמור אותו. אם המשתמש מפעיל את האפליקציה, המסך משתנה כדי להנחות אותו להפעיל את אפליקציית האדמין של המכשיר, כפי שמוצג באיור 2. אחרת, האפליקציה לניהול המכשיר מושבתת.

Kotlin

override fun onPreferenceChange(preference: Preference, newValue: Any): Boolean {
    if (super.onPreferenceChange(preference, newValue)) return true
    val value = newValue as Boolean
    if (preference == enableCheckbox) {
        if (value != adminActive) {
            if (value) {
                // Launch the activity to have the user enable our admin.
                val intent = Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN).apply {
                    putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceAdminSample)
                    putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                            activity.getString(R.string.add_admin_extra_app_text))
                }
                startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN)
                // return false - don't update checkbox until we're really active
                return false
            } else {
                dpm.removeActiveAdmin(deviceAdminSample)
                enableDeviceCapabilitiesArea(false)
                adminActive = false
            }
        }
    } else if (preference == disableCameraCheckbox) {
        dpm.setCameraDisabled(deviceAdminSample, value)
    }
    return true
}

Java

@Override
public boolean onPreferenceChange(Preference preference, Object newValue) {
    if (super.onPreferenceChange(preference, newValue)) {
        return true;
    }
    boolean value = (Boolean) newValue;
    if (preference == enableCheckbox) {
        if (value != adminActive) {
            if (value) {
                // Launch the activity to have the user enable our admin.
                Intent intent = new Intent(DevicePolicyManager.ACTION_ADD_DEVICE_ADMIN);
                intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, deviceAdminSample);
                intent.putExtra(DevicePolicyManager.EXTRA_ADD_EXPLANATION,
                        activity.getString(R.string.add_admin_extra_app_text));
                startActivityForResult(intent, REQUEST_CODE_ENABLE_ADMIN);
                // return false - don't update checkbox until we're really active
                return false;
            } else {
                dpm.removeActiveAdmin(deviceAdminSample);
                enableDeviceCapabilitiesArea(false);
                adminActive = false;
            }
        }
    } else if (preference == disableCameraCheckbox) {
        dpm.setCameraDisabled(deviceAdminSample, value);
    }
    return true;
}

בשורה intent.putExtra(DevicePolicyManager.EXTRA_DEVICE_ADMIN, mDeviceAdminSample) מצוין ש-mDeviceAdminSample (רכיב של DeviceAdminReceiver) הוא מדיניות היעד. השורה הזו מפעילה את ממשק המשתמש שמוצג באיור 2, שמנחה את המשתמשים להוסיף את האדמין של המכשיר למערכת (או מאפשרת להם לדחות אותו).

כשהאפליקציה צריכה לבצע פעולה שתלויה בהפעלת האפליקציה לניהול המכשיר, היא מאשרת שהאפליקציה פעילה. לשם כך, הוא משתמש ב-method‏ DevicePolicyManager isAdminActive(). שימו לב שהשיטה DevicePolicyManagerisAdminActive() מקבלת רכיב DeviceAdminReceiver כארגומנטים שלה:

Kotlin

private lateinit var dpm: DevicePolicyManager
...
private fun isActiveAdmin(): Boolean = dpm.isAdminActive(deviceAdminSample)

Java

DevicePolicyManager dpm;
...
private boolean isActiveAdmin() {
    return dpm.isAdminActive(deviceAdminSample);
}

ניהול המדיניות

DevicePolicyManager היא כיתה ציבורית לניהול כללי מדיניות שחלים על מכשיר. DevicePolicyManager מנהל את כללי המדיניות למופע אחד או יותר של DeviceAdminReceiver.

מקבלים את ה-handle של DevicePolicyManager באופן הבא:

Kotlin

dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager

Java

DevicePolicyManager dpm =
    (DevicePolicyManager)getSystemService(Context.DEVICE_POLICY_SERVICE);

בקטע הזה מוסבר איך משתמשים ב-DevicePolicyManager כדי לבצע משימות ניהוליות:

הגדרת מדיניות סיסמאות

DevicePolicyManager כולל ממשקי API להגדרה ולאכיפה של מדיניות הסיסמאות במכשיר. ב-Device Administration API, הסיסמה רלוונטית רק לנעילת המסך. בקטע הזה מתוארות משימות נפוצות שקשורות לסיסמאות.

הגדרת סיסמה למכשיר

הקוד הזה מציג ממשק משתמש שמבקש מהמשתמש להגדיר סיסמה:

Kotlin

Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD).also { intent ->
    startActivity(intent)
}

Java

Intent intent = new Intent(DevicePolicyManager.ACTION_SET_NEW_PASSWORD);
startActivity(intent);
הגדרת איכות הסיסמה

איכות הסיסמה יכולה להיות אחת מהקבועות הבאות של DevicePolicyManager:

PASSWORD_QUALITY_ALPHABETIC
המשתמש חייב להזין סיסמה שמכילה לפחות תווים אלפביתיים (או תווים אחרים).
PASSWORD_QUALITY_ALPHANUMERIC
המשתמש חייב להזין סיסמה שמכילה לפחות גם תווים מספריים וגם תווים אלפביתיים (או סמלים אחרים).
PASSWORD_QUALITY_NUMERIC
המשתמש חייב להזין סיסמה שמכילה לפחות תווים מספריים.
PASSWORD_QUALITY_COMPLEX
המשתמש חייב להזין סיסמה שמכילה לפחות אות אחת, ספרה אחת ותו מיוחד אחד.
PASSWORD_QUALITY_SOMETHING
המדיניות מחייבת סיסמה כלשהי, אבל לא משנה מהי.
PASSWORD_QUALITY_UNSPECIFIED
אין בדרישות המדיניות דרישות לגבי הסיסמה.

לדוגמה, כך מגדירים את מדיניות הסיסמאות כך שתחייב סיסמה אלפאנומרית:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
...
dpm.setPasswordQuality(deviceAdminSample, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
...
dpm.setPasswordQuality(deviceAdminSample, DevicePolicyManager.PASSWORD_QUALITY_ALPHANUMERIC);
הגדרת דרישות תוכן לסיסמה

החל מ-Android 3.0, המחלקה DevicePolicyManager כוללת שיטות שמאפשרות לכוונן את תוכן הסיסמה. לדוגמה, אפשר להגדיר מדיניות שמציינת שסיסמאות חייבות להכיל לפחות n אותיות רישיות. אלה השיטות לכוונון עדין של תוכן הסיסמה:

לדוגמה, קטע הקוד הזה קובע שהסיסמה חייבת להכיל לפחות 2 אותיות גדולות:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val pwMinUppercase = 2
...
dpm.setPasswordMinimumUpperCase(deviceAdminSample, pwMinUppercase)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
int pwMinUppercase = 2;
...
dpm.setPasswordMinimumUpperCase(deviceAdminSample, pwMinUppercase);
הגדרת האורך המינימלי של הסיסמה

אפשר לציין שאורך הסיסמה חייב להיות לפחות באורך המינימלי שצוין. לדוגמה:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val pwLength: Int = ...
...
dpm.setPasswordMinimumLength(deviceAdminSample, pwLength)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
int pwLength;
...
dpm.setPasswordMinimumLength(deviceAdminSample, pwLength);
הגדרת מספר מקסימלי של ניסיונות כושלים להזנת סיסמה

אתם יכולים להגדיר את המספר המקסימלי של ניסיונות כושלים להזנת סיסמה לפני שמכשיר יימחק (כלומר, יאופס להגדרות המקוריות). לדוגמה:

Kotlin

val dPM:DevicePolicyManager
private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val maxFailedPw: Int = ...
...
dpm.setMaximumFailedPasswordsForWipe(deviceAdminSample, maxFailedPw)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
int maxFailedPw;
 ...
dpm.setMaximumFailedPasswordsForWipe(deviceAdminSample, maxFailedPw);
הגדרת זמן קצוב לתפוגת התוקף של סיסמה

החל מגרסה 3.0 של Android, אפשר להשתמש ב-method‏ setPasswordExpirationTimeout() כדי להגדיר מתי תוקף הסיסמה יפוג. הערך מחושב כדלתא באלפיות שנייה מהרגע שבו האדמין של המכשיר מגדיר את הזמן הקצוב לתפוגה. לדוגמה:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val pwExpiration: Long = ...
...
dpm.setPasswordExpirationTimeout(deviceAdminSample, pwExpiration)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
long pwExpiration;
...
dpm.setPasswordExpirationTimeout(deviceAdminSample, pwExpiration);
הגבלת הסיסמה על סמך היסטוריה

החל מ-Android 3.0, אפשר להשתמש בשיטה setPasswordHistoryLength() כדי להגביל את היכולת של משתמשים לעשות שימוש חוזר בסיסמאות ישנות. השיטה מקבלת פרמטר length שמציין כמה סיסמאות ישנות יישמרו. כשהמדיניות הזו פעילה, המשתמשים לא יכולים להזין סיסמה חדשה שתואמת ל-n הסיסמאות האחרונות. כך המשתמש לא יוכל להשתמש באותה סיסמה שוב ושוב. בדרך כלל משתמשים במדיניות הזו בשילוב עם המדיניות setPasswordExpirationTimeout(), שמאלצת את המשתמשים לעדכן את הסיסמאות שלהם אחרי פרק זמן מסוים.

לדוגמה, קטע הקוד הזה אוסר על משתמשים לעשות שימוש חוזר באחת מ-5 הסיסמאות האחרונות שלהם:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val pwHistoryLength = 5
...
dpm.setPasswordHistoryLength(deviceAdminSample, pwHistoryLength)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
int pwHistoryLength = 5;
...
dpm.setPasswordHistoryLength(deviceAdminSample, pwHistoryLength);

הגדרת נעילת המכשיר

אתם יכולים להגדיר את פרק הזמן המקסימלי של חוסר פעילות של המשתמש שיכול להתרחש לפני שהמכשיר נעול. לדוגמה:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
private val timeMs: Long = 1000L * timeout.text.toString().toLong()
...
dpm.setMaximumTimeToLock(deviceAdminSample, timeMs)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
...
long timeMs = 1000L*Long.parseLong(timeout.getText().toString());
dpm.setMaximumTimeToLock(deviceAdminSample, timeMs);

ניתן גם להורות למכשיר להינעל באופן מיידי:

Kotlin

private lateinit var dpm: DevicePolicyManager
dpm.lockNow()

Java

DevicePolicyManager dpm;
dpm.lockNow();

איפוס הנתונים

אפשר להשתמש בשיטה DevicePolicyManager wipeData() כדי לאפס את המכשיר להגדרות המקוריות. האפשרות הזו שימושית אם המכשיר אבד או נגנב. לעיתים קרובות, ההחלטה לאפס את הנתונים במכשיר היא תוצאה של עמידה בתנאים מסוימים. לדוגמה, אפשר להשתמש ב-setMaximumFailedPasswordsForWipe() כדי לציין שצריך למחוק מכשיר אחרי מספר ניסיונות כושלים ספציפיים להזנת סיסמה.

איך מוחקים את הנתונים:

Kotlin

private lateinit var dpm: DevicePolicyManager
dpm.wipeData(0)

Java

DevicePolicyManager dpm;
dpm.wipeData(0);

השיטה wipeData() מקבלת כפרמטר שלה מסיכת ביט של אפשרויות נוספות. בשלב זה, הערך חייב להיות 0.

השבתת המצלמה

החל מ-Android 4.0 אפשר להשבית את המצלמה. חשוב לדעת שההשבתה לא חייבת להיות סופית. אפשר להפעיל או להשבית את המצלמה באופן דינמי על סמך הקשר, זמן וכו'.

אתם קובעים אם המצלמה תהיה מושבתת באמצעות השיטה setCameraDisabled(). לדוגמה, קטע הקוד הזה מגדיר את המצלמה כפעילה או כמושבתת על סמך הגדרת תיבת סימון:

Kotlin

private lateinit var disableCameraCheckbox: CheckBoxPreference
private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
...
dpm.setCameraDisabled(deviceAdminSample, mDisableCameraCheckbox.isChecked)

Java

private CheckBoxPreference disableCameraCheckbox;
DevicePolicyManager dpm;
ComponentName deviceAdminSample;
...
dpm.setCameraDisabled(deviceAdminSample, mDisableCameraCheckbox.isChecked());

הצפנת האחסון

החל מ-Android 3.0, אפשר להשתמש ב-method‏ setStorageEncryption() כדי להגדיר מדיניות שמחייבת הצפנה של אזור האחסון, אם יש תמיכה בכך.

לדוגמה:

Kotlin

private lateinit var dpm: DevicePolicyManager
private lateinit var deviceAdminSample: ComponentName
...
dpm.setStorageEncryption(deviceAdminSample, true)

Java

DevicePolicyManager dpm;
ComponentName deviceAdminSample;
...
dpm.setStorageEncryption(deviceAdminSample, true);

בדוגמה של Device Administration API מוסבר איך מפעילים הצפנת אחסון.

דוגמאות קוד נוספות

בדוגמאות Android AppRestrictionEnforcer ו-DeviceOwner מוסבר בהרחבה איך משתמשים בממשקי ה-API שמפורטים בדף הזה.