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

הוצאה משימוש של 'אדמין המכשיר' החל מגרסה 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 יש גם מצב משויך של בעל מכשיר ללא גוף, שמוסיף בעל פרופיל לכל המשתמשים המשויכים, מלבד משתמש המערכת שבו מוגדר בעל המכשיר.

במכשירים שהוגדרו עם משתמש מערכת ללא גוף (שבו משתמש המערכת פועל ברקע), רק כללי מדיניות המכשיר ברמת הכלל (כללי מדיניות שחלים על כל המשתמשים) חלים על המשתמש או המשתמשים בחזית. לפרטים נוספים, ראו 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. הפעולה הזו תגרום להפעלה של פונקציית הקריאה החוזרת 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);
הגבלת הסיסמה על סמך היסטוריה

החל מגרסה 3.0 של Android, אפשר להשתמש בשיטה 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.

השבתת המצלמה

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

אתם קובעים אם המצלמה תהיה מושבתת באמצעות השיטה 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 שמפורטים בדף הזה.