התכונות במדריך הזה מתארות רישות וניהול טלפוניה יכולות שניתן להטמיע במדיניות המכשיר בקר משחקים (DPC). המסמך הזה מכיל קוד לדוגמה ואפשר גם להשתמש בחלונית בדיקה אפליקציית DPC בתור מקור של קוד לדוגמה לתכונות הארגוניות של Android.
אפליקציית DPC יכולה לפעול במצב 'בעלי הפרופיל' במכשירים אישיים או אצל בעלי המכשיר במכשירים מנוהלים. בטבלה הזו מצוין אילו תכונות זמין כשה-DPC פועל במצב בעלי הפרופיל או בעלי המכשיר mode:
תכונה | הבעלים של הפרופיל | בעלי המכשיר |
גישה לאנשי קשר בעבודה בכל הפרופילים | ✓ | |
חשוב לוודא חיבור רשת מאובטח לתעבורת נתונים בעבודה | ✓ | ✓ |
להגדיר מזהה של רשת אלחוטית אחת בכמה אזורים | ✓ | ✓ |
ציון חייגן נפרד לפרופיל העבודה | ✓ |
גישה לאנשי קשר של עבודה בפרופילים שונים
EMM יכול לאפשר לפרופיל אישי של משתמש לגשת לאנשי הקשר שלו בעבודה כדי ניתן לגשת אל אנשי הקשר לשימוש אישי ולעבודה של משתמש באמצעות חיפוש מקומי חיפוש ספרייה מרוחקת. במכשירים אישיים, יש חייגן אחד פרופיל יכול לבצע ולקבל שיחות אישיות וגם שיחות עבודה. In addition, אנשי קשר בעבודה משתלבים היטב בממשק המשתמש של המערכת. אם פרופיל העבודה מוצפן, הנתונים שלו לא זמינים לפרופיל האישי.
משולב עם ממשק המשתמש של המערכת
ממשק המשתמש של המערכת מציין שיחות עבודה נכנסות באמצעות סמל של תיק מסמכים.
callLog
מציג גם את
כדי לציין שיחות עבודה נכנסות ויוצאות. החייגן האישי,
אפליקציות אנשי קשר יכולות להציג את פרטי השיחה המזוהה של איש קשר בעבודה באמצעות שלט רחוק
חיפוש הספרייה, לכן לא נדרש שאיש הקשר כבר מסונכרן
במכשיר המקומי. אפליקציית ההודעות יכולה לבצע שיחה מזוהה וחיפוש מקומי.
הגדרת התאימות ל-Android המסמך (CDD) כולל דרישות שאנשי קשר מהעבודה יוצגו בחייגן ברירת המחדל, ודרישות אנשי קשר ואפליקציות של הודעות מתויגים כדי לציין שהם הגיעו מהעבודה פרופיל.
אנשי הקשר בעבודה נגישים וניתן לחפש אותם
המשתמש יכול לגשת לאנשי קשר בעבודה ולהתקשר אליהם מהפרופיל האישי שלו. תוצג במסך החיפוש של אפליקציית החייגן. המשתמש יכול לחפש את העבודה אנשי קשר – באמצעות השלמה אוטומטית – שמסונכרנים באופן מקומי עם המכשיר ומופיעים באמצעות חיפוש בספרייה מרוחקת.
לנהל את אנשי הקשר מהעבודה בפרופיל הראשי
ה-DPC שולט בהרשאה לחפש אנשי קשר של עבודה. פועל אצל הבעלים של הפרופיל במצב, ה-DPC מנהל את החשיפה של אנשי הקשר מהעבודה בפרופיל האישי. מידע נוסף זמין במאמר פיתוח מדיניות מכשירים בקר משחקים.
כברירת מחדל, החיפוש של אנשי קשר מהעבודה לפי הפרופיל האישי מופעל.
כדי לראות איך המדיניות מוגדרת, אפשר ללחוץ על
DevicePolicyManager.getCrossProfileContactsSearchDisabled()
כדי להפעיל או להשבית את החיפוש של אנשי קשר מהעבודה לפי הפרופיל האישי, צריך להשתמש ב-
DevicePolicyManager.setCrossProfileContactsSearchDisabled()
ודאו שיש חיבור מאובטח לרשת בשביל תעבורת נתונים בעבודה
פועלות במצב 'בעלי המכשיר' או במצב 'בעלי הפרופיל', מדיניות מכשיר הבקר יכול להשתמש בחיבור רשת וירטואלית פרטית (VPN) שפועל כל הזמן כדי לאלץ אפליקציות להעביר תעבורת נתונים דרך אפליקציית VPN ספציפית שלא יכולה בוצעה עקיפה. באמצעות חיבור VPN שפועל כל הזמן, ה-DPC יכול להבטיח שהרשת תנועה מפרופיל עבודה או ממכשיר מנוהל עוברת דרך שירות VPN, ללא התערבות המשתמש. תהליך זה יוצר חיבור רשת מאובטח עבור תנועה רציפה בתוך פרופיל עבודה.
מידע על חיבורי VPN שפועלים כל הזמן
כחלק ממסגרת המערכת, ניתוב ה-VPN מנוהל באופן אוטומטי, כך
המשתמש לא יכול לעקוף את שירות ה-VPN. אם שירות ה-VPN מנותק בזמן החיבור
במצב 'ללא 'ביטול נעילה עם טביעת אצבע'', התנועה לא תוכל להדליף לאינטרנט הפתוח. לאפליקציות
בתהליך הטמעה
VpnService
,
רשת VPN שפועלת כל הזמן מספקת מסגרת לניהול חיבור VPN מאובטח באמצעות
שרת מהימן ולהמשיך לשמור עליו. שירות ה-VPN מפעיל מחדש באופן אוטומטי את
חיבור בין עדכוני אפליקציות, בין אם החיבור הוא באמצעות Wi-Fi או
סלולרי. אם המכשיר יופעל מחדש, ה-framework יפעיל מחדש את החיבור ל-VPN.
החיבור לשירות ה-VPN גלוי למשתמש. עבור במכשיר בבעלות החברה, המשתמש לא נדרש לאשר תיבת דו-שיח להבעת הסכמה VPN במצב פועל כל הזמן. הגדרות רשת ה-VPN של המשתמש מאפשרות להפעיל חיבור תמידי באופן ידני.
אם DISALLOW_CONFIG_VPN
true
, המשתמש לא יכול להגדיר את ה-VPN. אפשר
DISALLOW_DEBUGGING_FEATURES
כדי למנוע ממשתמשים לעקוף את רשת ה-VPN שפועלת כל הזמן באמצעות הפקודה adb לניפוי באגים.
כדי למנוע ממשתמש להסיר את ה-VPN, צריך להתקשר
DevicePolicyManager.setUninstallBlocked
הגדרת שירות ה-VPN
בארגון שמשתמש בפתרון הארגוני שלכם ל-Android מוגדר VPN.
- התקנה של אפליקציית VPN שמטמיעה
VpnService
אפשר למצוא שירותי VPN פעילים באמצעות מסנן Intent שתואם פעולהVpnService.SERVICE_INTERFACE
- להצהיר על
VpnService
במניפסט של האפליקציה שמוגן על ידי ההרשאהBIND_VPN_SERVICE
. - מגדירים את
VpnService
אז זה מתחיל על ידי המערכת. מומלץ לא להגדיר שאפליקציית ה-VPN תפעל באופן אוטומטי להאזין לאתחול של מערכת ולשלוט במחזור החיים שלה. - מגדירים את הערכים מנוהלים הגדרות אישיות של אפליקציית ה-VPN (דוגמה בהמשך).
הפעלת חיבור VPN שפועל כל הזמן
בקר ה-DPC יכול להגדיר חיבור VPN שפועל כל הזמן דרך אפליקציה ספציפית על ידי
שיחות
DevicePolicyManager.setAlwaysOnVpnPackage()
החיבור הזה יאושר באופן אוטומטי ויישמר אחרי הפעלה מחדש. אם המיקום
lockdownEnabled
מוגדר כ-False, תנועה ברשת עשויה להיות לא מאובטחת מרגע
הטלפון יופעל מחדש וה-VPN יתחבר אליו. האפשרות הזו שימושית אם לא רוצים להפסיק
קישוריות לרשת בכל פעם שה-VPN נכשל, או אם ה-VPN לא חיוני.
אימות של חיבור VPN שפועל כל הזמן
ה-DPC יכול לקרוא את שם החבילה שמנהלת VPN שפועל כל הזמן
חיבור עבור המשתמש הנוכחי עם
DevicePolicyManager.getAlwaysOnVpnPackage().
אם אין חבילה כזו, או שה-VPN נוצר בהגדרות המערכת.
האפליקציה, מוחזר null
.
דוגמה
באפליקציה TestDPC, AlwaysOnVpnFragment.java
משתמש בממשקי ה-API האלה כדי להפעיל את ההגדרה לחיבור VPN שפועל כל הזמן.
בדוגמה הבאה:
- הכרטיסייה המנוהלת
של ההגדרות האישיות
שירות ה-VPN מוגדר על ידי
DevicePolicyManager
באמצעותsetApplicationRestrictions()
. - בהגדרות מנוהלות נעשה שימוש בצמדי מפתח-ערך שרירותיים ובאפליקציה לדוגמה הזו משתמשת בהן במקום אחר כדי לקבוע את הגדרות הרשת של ה-VPN (ראו בדיקת ההגדרות המנוהלות).
- בדוגמה הזו, מנהל ההתקנה של חבילת Android מתווסף לרשימת הישויות שנחסמו, כך שלא לעדכן חבילות מערכת דרך ה-VPN. כל התנועה של המשתמש ברשת בתוך פרופיל העבודה או המכשיר עוברים דרך אפליקציית ה-VPN הזו, מלבד החבילה מנהל התקנה; העדכונים שלו משתמשים באינטרנט הפתוח.
- לאחר מכן,
DevicePolicyManager
מפעיל חיבור VPN שפועל כל הזמן עבור חבילת VPN באמצעותsetAlwaysOnVpnPackage()
, ולהפעיל את מצב 'ללא 'ביטול נעילה עם טביעת אצבע''.
Kotlin
// Set VPN's managed configurations val config = Bundle().apply { putString(Extras.VpnApp.ADDRESS, "192.0.2.0") putString(Extras.VpnApp.IDENTITY, "vpn.account1") putString(Extras.VpnApp.CERTIFICATE, "keystore://auth_certificate") putStringArray(Extras.VpnApp.DENYLIST, arrayOf("com.android.packageinstaller")) } val dpm = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager val admin = myDeviceAdminReceiver.getComponentName(this) // Name of package to update managed configurations val vpnPackageName = "com.example.vpnservice" // Associate managed configurations with DeviceAdminReceiver dpm.setApplicationRestrictions(admin, vpnPackageName, config) // Enable always-on VPN connection through VPN package try { val lockdownEnabled = true dpm.setAlwaysOnVpnPackage(admin, vpnPackageName, lockdownEnabled) } catch (ex: Exception) { throw PolicyException() }
Java
// Set VPN's managed configurations final Bundle config = new Bundle(); config.putString(Extras.VpnApp.ADDRESS, "192.0.2.0"); config.putString(Extras.VpnApp.IDENTITY, "vpn.account1"); config.putString(Extras.VpnApp.CERTIFICATE, "keystore://auth_certificate"); config.putStringArray(Extras.VpnApp.DENYLIST, new String[]{"com.android.packageinstaller"}); DevicePolicyManager dpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE); ComponentName admin = myDeviceAdminReceiver.getComponentName(this); // Name of package to update managed configurations final String vpnPackageName = "com.example.vpnservice"; // Associate managed configurations with DeviceAdminReceiver dpm.setApplicationRestrictions(admin, vpnPackageName, config); // Enable always-on VPN connection through VPN package try { boolean lockdownEnabled = true; dpm.setAlwaysOnVpnPackage(admin, vpnPackageName, lockdownEnabled)); } catch (Exception ex) { throw new PolicyException(...); }
הגדרת מזהה אחד של רשת אלחוטית בכמה אזורים
פועלות במצב 'בעלי המכשיר' או במצב 'בעלי הפרופיל', מדיניות מכשיר בקר (DPC) יכול לשייך אישורים מרובים של רשות אישורים (CA) באמצעות תצורת רשת אלחוטית אחת. בתצורה הזו, יכול להתחבר לנקודות גישה אלחוטיות שיש להן אותו שם רשת, או מזהה קבוצת שירות (SSID), אבל הם מוגדרים עם CA שונה אישורים. האפשרות הזו שימושית אם הרשתות האלחוטיות של הארגון נמצאים בכמה אזורים גיאוגרפיים, וכל אזור דורש רשות האישורים. לדוגמה, כדי לחתום על חתימות משפטיות, נדרש לרשות שזקוקה ל-CA אזורי.
הערה: מערכת Android תומכת
setCaCertificate
החל מ-API 18 (Jelly Bean), אבל מנהלי IT חייבים להקצות את הרשתות שלהם
בנפרד עם כל רשות אישורים, כדי להבטיח שלמכשירים יהיה אימות חלק בכל
נקודת גישה, ללא קשר לאזור שלהם.
ציון אישורי ה-CA לזיהוי השרת
כדי לציין רשימה של אישורי X.509 שמזהים את השרת באמצעות אותם
SSID, צריך לכלול את כל אישורי ה-CA הרלוונטיים בתצורת הרשת האלחוטית באמצעות WifiEnterpriseConfig.setCaCertificates()
.
האישור של השרת תקף אם ה-CA שלו תואם לאחד מהאישורים הנתונים.
שמות ברירת המחדל מוקצים באופן אוטומטי לאישורים ומשתמשים בהם
הגדרה אישית.
WifiManager
יתקין את האישור וישמור את התצורה באופן אוטומטי
רשת מופעלת, ומסיר את האישור כשהתצורה
נמחק.
כדי לקבל את כל אישורי ה-CA שמשויכים לתצורת הרשת האלחוטית, צריך להשתמש
WifiEnterpriseConfig.getCaCertificates()
כדי להחזיר רשימה של
X509Certificate
אובייקטים.
הוספת תצורה אלחוטית באמצעות מספר אישורי CA
- מאמתים את זהות השרת:
- טוענים את אישורי ה-CA מסוג X.509.
- טוענים את המפתח הפרטי והאישור של הלקוח. במאמר אבטחה עם HTTPS ו-SSL תוכלו לראות דוגמה לקריאת קובץ אישור.
- חדש
WifiConfiguration
ולהגדיר את ה-SSID ואת ניהול המפתחות שלו. - הגדרת
WifiEnterpriseConfig
ב-WifiConfiguration
הזה.- מזהים את השרת בעזרת רשימה של
X509Certificate
אובייקטים שמשתמשים בהםsetCaCertificates()
. - מגדירים את פרטי הכניסה, הזהות והסיסמה של הלקוח.
- הגדרת פרוטוקול אימות שניתן להרחבה (EAP) ושיטת שלב 2 בתור ביצירת החיבור.
- מזהים את השרת בעזרת רשימה של
- מוסיפים את הרשת עם
WifiManager
- הפעלת הרשת. WifiManager שומר את התצורה באופן אוטומטי במהלך הגדרה אישית.
בדוגמה הזו אנחנו מקשרים בין השלבים:
Kotlin
// Verify the server's identity val caCert0 = getCaCert("cert0.crt") val caCert1 = getCaCert("cert1.crt") val clientKey = getClientKey() val clientCert = getClientCert() // Create Wi-Fi configuration val wifiConfig = WifiConfiguration().apply { SSID = "mynetwork" allowedKeyManagement.set(KeyMgmt.WPA_EAP) allowedKeyManagement.set(KeyMgmt.IEEE8021X) // Set up Wi-Fi enterprise configuration enterpriseConfig.setCaCertificates(arrayOf<X509Certificate>(caCert0, caCert1)) enterpriseConfig.setClientKeyEntry(clientKey, clientCert) enterpriseConfig.setIdentity("myusername") enterpriseConfig.setEapMethod(Eap.TLS) enterpriseConfig.setPhase2Method(Phase2.NONE) } // Add network val wifiManager = getSystemService(Context.WIFI_SERVICE) as WifiManager val netId = wifiManager.addNetwork(wifiConfig) // Enable network if (netId < 0) { // Error creating new network } else { wifiManager.enableNetwork(netId, true) }
Java
// Verify the server's identity X509Certificate caCert0 = getCaCert("cert0.crt"); X509Certificate caCert1 = getCaCert("cert1.crt"); PrivateKey clientKey = getClientKey(); X509Certificate clientCert = getClientCert(); // Create Wi-Fi configuration WifiConfiguration wifiConfig = new WifiConfiguration(); wifiConfig.SSID = "mynetwork"; wifiConfig.allowedKeyManagement.set(KeyMgmt.WPA_EAP); wifiConfig.allowedKeyManagement.set(KeyMgmt.IEEE8021X); // Set up Wi-Fi enterprise configuration wifiConfig.enterpriseConfig.setCaCertificates(new X509Certificate[] {caCert0, caCert1}); wifiConfig.enterpriseConfig.setClientKeyEntry(clientKey, clientCert); wifiConfig.enterpriseConfig.setIdentity("myusername"); wifiConfig.enterpriseConfig.setEapMethod(Eap.TLS); wifiConfig.enterpriseConfig.setPhase2Method(Phase2.NONE); // Add network WifiManager wifiManager = (WifiManager) getSystemService(Context.WIFI_SERVICE); int netId = wifiManager.addNetwork(wifiConfig); // Enable network if (netId < 0) { // Error creating new network } else { wifiManager.enableNetwork(netId, true); }
ציון חייגן נפרד לפרופיל העבודה
ניתן להוסיף לרשימת ההיתרים אפליקציית חייגן נפרדת לשימוש בפרופיל העבודה.
זה יכול להיות החייגן עצמו או אפליקציה של Voiceover IP (VoIP) שמטמיעה את
ConnectionService
API לקצה העורפי של הקריאה. כך מקבלים את אותה חיוג בממשק המשתמש של המערכת המשולבת
ניסיון באפליקציות VoIP בפרופיל העבודה, וכך עובדים ביעילות
חייגן: תכונת ליבה. השיחות הנכנסות לחשבונות לשיחות לצורכי עבודה
להבדיל משיחות נכנסות לחשבונות אישיים לשיחות.
המשתמש יכול לבחור להתקשר ולקבל שיחות מחייגן העבודה שמופיע ברשימת ההיתרים
בחשבון טלפון. כל השיחות שמתקבלות מהחייגן הזה או נכנסות לעבודה
בחשבון הטלפון שלהם, רשומים בחשבון של פרופיל העבודה
CallLog
ספק. החייגן בעבודה שומר יומן שיחות של עבודה בלבד, עם גישה רק אל
אנשי קשר בעבודה. שיחות נכנסות למתג מעגל מטופלות על ידי החייגן הראשי
והם מאוחסנים ביומן שיחות אישי. אם פרופיל עבודה נמחק, יומן השיחות
שמשויכים לפרופיל העבודה הזה, יימחקו גם כל פרופילי העבודה
.
אפליקציות צד שלישי חייבות להטמיע ConnectionService
אפליקציות VoIP של צד שלישי שצריכים לבצע שיחות טלפון ולקבל את השיחות האלה
שמשולבים באפליקציית הטלפון המובנית יכולים להטמיע
ConnectionService
API. חובה לעשות את זה בכל שירות VoIP שמשמש לשיחות עבודה. האפליקציות האלה
כך שהשיחות שלהם יטופלו כמו שיחות רגילות סלולריים,
הן מופיעות בחייגן המערכת המובנה וביומן השיחות. אם
הטמעה של אפליקציה
ConnectionService
מותקנת בפרופיל העבודה, ניתן לגשת אליה רק באמצעות חייגן
שמותקן בפרופיל העבודה הזה.
לאחר שהמפתח מטמיע
ConnectionService
,
עליהם להוסיף אותו לקובץ המניפסט של האפליקציה ולרשום
PhoneAccount
עם
TelecomManager
.
חשבון טלפון מייצג שיטה ייחודית לביצוע או לקבלת שיחות טלפון,
ויכול להיות מספר PhoneAccounts
בכל פעם
ConnectionService
. אחרי רישום חשבון הטלפון, המשתמש
יכולים להפעיל אותה דרך הגדרות החייגן.
שילוב עם ממשק המשתמש של המערכת והתראות
ממשק המשתמש של המערכת מספק למשתמשים חוויית חיוג עקבית ומשולבת
לאפליקציות צד שלישי שמשתמשות
ConnectionService
API כקצה עורפי לביצוע קריאות. אם משתמשים באפליקציה בפרופיל עבודה, תיק מסמכים
מוצג סמל בשיחות נכנסות ובשורת הסטטוס. אפליקציה שבה מטמיעים
האפליקציה ConnectionService
שמותקנת בפרופיל העבודה יכולה להשתמש ב
חייגן מערכת או לבנות חייגן עבודה נפרד. האפליקציות האלה יכולות להיות אפליקציה אחת או
לאפליקציות נפרדות.
אפליקציית החייגן קובעת אם היא מבצעת או מקבלת שיחת עבודה עד
בדיקת הדגל
android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL
אם השיחה היא שיחת עבודה, החייגן מציין זאת למשתמש על ידי הוספת
תג עבודה (סמל המזוודה):
Kotlin
// Call placed through a work phone account. getCurrentCall() is defined by the // dialer. val call = getCurrentCall() if (call.hasProperty(android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL)) { // Set briefcase icon }
Java
// Call placed through a work phone account. getCurrentCall() is defined by the // dialer. Call call = getCurrentCall(); if (call.hasProperty(android.telecom.Call.Details.PROPERTY_ENTERPRISE_CALL)) { // Set briefcase icon }