ตำราอาหารสำหรับอุปกรณ์โดยเฉพาะ

ตำราอาหารนี้ช่วยให้นักพัฒนาซอฟต์แวร์และผู้ผสานรวมระบบเพิ่มประสิทธิภาพ โซลูชันอุปกรณ์ ทำตามสูตรอาหารแสดงวิธีการเพื่อค้นหาโซลูชันสำหรับอุปกรณ์เฉพาะ พฤติกรรมของคุณ ตำราอาหารนี้ทำงานได้ดีที่สุดสำหรับนักพัฒนาซอฟต์แวร์ที่มี แอปจัดการอุปกรณ์ หากคุณเพิ่งเริ่มต้นใช้งาน โปรดอ่านอุปกรณ์เฉพาะ ภาพรวม

แอปหน้าแรกที่กำหนดเอง

สูตรอาหารเหล่านี้มีประโยชน์หากคุณกำลังพัฒนาแอปเพื่อแทนที่หน้าแรกของ Android และ Launcher

เป็นแอปหน้าแรก

คุณตั้งค่าแอปเป็นแอปหน้าแรกของอุปกรณ์เพื่อให้เปิดแอปได้ โดยอัตโนมัติเมื่ออุปกรณ์เริ่มทำงาน และคุณสามารถเปิดใช้งานหน้าแรก ซึ่งนำแอปในรายการที่อนุญาตไปยังเบื้องหน้าโดยมีการล็อกไว้ โหมดงาน

แอปหน้าแรกทั้งหมดจะจัดการหมวดหมู่ Intent CATEGORY_HOME ซึ่งเท่ากับ คือวิธีที่ระบบจดจำแอปหน้าแรก หากต้องการเป็นแอปหน้าแรกเริ่มต้น ให้ตั้งค่ารายการหนึ่ง ของกิจกรรมของแอปเป็นเครื่องจัดการ Intent ของ Home ที่ต้องการด้วยการเรียกใช้ DevicePolicyManager.addPersistentPreferredActivity() ดังที่ปรากฏในตัวอย่างต่อไปนี้

Kotlin

// Create an intent filter to specify the Home category.
val filter = IntentFilter(Intent.ACTION_MAIN)
filter.addCategory(Intent.CATEGORY_HOME)
filter.addCategory(Intent.CATEGORY_DEFAULT)

// Set the activity as the preferred option for the device.
val activity = ComponentName(context, KioskModeActivity::class.java)
val dpm = context.getSystemService(Context.DEVICE_POLICY_SERVICE)
        as DevicePolicyManager
dpm.addPersistentPreferredActivity(adminName, filter, activity)

Java

// Create an intent filter to specify the Home category.
IntentFilter filter = new IntentFilter(Intent.ACTION_MAIN);
filter.addCategory(Intent.CATEGORY_HOME);
filter.addCategory(Intent.CATEGORY_DEFAULT);

// Set the activity as the preferred option for the device.
ComponentName activity = new ComponentName(context, KioskModeActivity.class);
DevicePolicyManager dpm =
    (DevicePolicyManager) context.getSystemService(Context.DEVICE_POLICY_SERVICE);
dpm.addPersistentPreferredActivity(adminName, filter, activity);

คุณยังคงต้องประกาศตัวกรองความตั้งใจ ในไฟล์ Manifest ของแอปตามที่แสดงในข้อมูลโค้ด XML ต่อไปนี้

<activity
        android:name=".KioskModeActivity"
        android:label="@string/kiosk_mode"
        android:launchMode="singleInstance"
        android:excludeFromRecents="true">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
        <category android:name="android.intent.category.DEFAULT"/>
    </intent-filter>
</activity>

โดยปกติแล้วคุณไม่ต้องการให้แอป Launcher ปรากฏในหน้าจอภาพรวม แต่ไม่จําเป็นต้องเพิ่ม excludeFromRecents ลงใน การประกาศกิจกรรมเนื่องจาก Launcher ของ Android ซ่อนการเปิดตัวครั้งแรก กิจกรรมเมื่อระบบทำงานในโหมดล็อกงาน

แสดงงานแยกกัน

FLAG_ACTIVITY_NEW_TASK อาจเป็นการแจ้งที่มีประโยชน์สำหรับ แอปประเภท Launcher เนื่องจากงานใหม่แต่ละงานจะปรากฏเป็นรายการแยกกันใน หน้าจอภาพรวม หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับงานในหน้าจอภาพรวม โปรดอ่านหัวข้อล่าสุด หน้าจอ

ตู้สาธารณะ

สูตรอาหารเหล่านี้เหมาะอย่างยิ่งสำหรับอุปกรณ์ที่ไม่มีคนดูแลในพื้นที่สาธารณะ แต่ก็สามารถ ช่วยให้ผู้ใช้อุปกรณ์โดยเฉพาะจำนวนมากมีสมาธิกับงานที่ทำ

ล็อกอุปกรณ์

เพื่อช่วยให้แน่ใจว่าจะมีการใช้อุปกรณ์ตามวัตถุประสงค์ที่ออกแบบมา คุณสามารถเพิ่ม ข้อจำกัดผู้ใช้ที่แสดงในตาราง 1

ตาราง 1 ข้อจำกัดผู้ใช้สำหรับอุปกรณ์คีออสก์
ข้อจำกัดของผู้ใช้ คำอธิบาย
DISALLOW_FACTORY_RESET ป้องกันไม่ให้ผู้ใช้อุปกรณ์รีเซ็ตอุปกรณ์เป็นค่าเริ่มต้นจากโรงงาน ผู้ดูแลระบบอุปกรณ์ที่มีการจัดการครบวงจรและผู้ใช้หลักเป็นผู้ตั้งค่านี้ได้ ข้อจำกัด
DISALLOW_SAFE_BOOT ป้องกันไม่ให้ผู้ใช้อุปกรณ์เริ่มต้นอุปกรณ์ใหม่ โหมดปลอดภัย ที่ระบบจะไม่เปิดแอปของคุณโดยอัตโนมัติ ผู้ดูแลระบบ อุปกรณ์ที่มีการจัดการและผู้ใช้หลักจะกำหนดข้อจำกัดนี้ได้
DISALLOW_MOUNT_PHYSICAL_MEDIA ป้องกันไม่ให้ผู้ใช้อุปกรณ์ต่อเชื่อมวอลุ่มพื้นที่เก็บข้อมูลที่อาจใช้ได้ ต่อกับอุปกรณ์ ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรและผู้ใช้หลัก สามารถตั้งค่าข้อจำกัดนี้ได้
DISALLOW_ADJUST_VOLUME ปิดเสียงอุปกรณ์และป้องกันไม่ให้ผู้ใช้อุปกรณ์เปลี่ยนเสียง การตั้งค่าระดับเสียงและการสั่น ตรวจสอบว่าคีออสก์ไม่ต้องใช้เสียง สำหรับฟีเจอร์การเล่นสื่อหรือการช่วยเหลือพิเศษ ผู้ดูแลระบบของ ที่มีการจัดการครบวงจร ผู้ใช้หลัก ผู้ใช้รอง และโปรไฟล์งานสามารถตั้งค่านี้ ข้อจำกัด
DISALLOW_ADD_USER ป้องกันไม่ให้ผู้ใช้อุปกรณ์เพิ่มผู้ใช้ใหม่ เช่น ผู้ใช้รองหรือ ผู้ใช้ที่ถูกจำกัด ระบบจะเพิ่มข้อจำกัดผู้ใช้นี้ไปยัง อุปกรณ์ที่มีการจัดการครบวงจรแต่อุปกรณ์อาจล้างไปแล้ว ผู้ดูแลระบบ อุปกรณ์ที่มีการจัดการและผู้ใช้หลักจะกำหนดข้อจำกัดนี้ได้

ตัวอย่างต่อไปนี้แสดงวิธีตั้งข้อจำกัด

Kotlin

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
arrayOf(
        UserManager.DISALLOW_FACTORY_RESET,
        UserManager.DISALLOW_SAFE_BOOT,
        UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
        UserManager.DISALLOW_ADJUST_VOLUME,
        UserManager.DISALLOW_ADD_USER).forEach { dpm.addUserRestriction(adminName, it) }

Java

// If the system is running in lock task mode, set the user restrictions
// for a kiosk after launching the activity.
String[] restrictions = {
    UserManager.DISALLOW_FACTORY_RESET,
    UserManager.DISALLOW_SAFE_BOOT,
    UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA,
    UserManager.DISALLOW_ADJUST_VOLUME,
    UserManager.DISALLOW_ADD_USER};

for (String restriction: restrictions) dpm.addUserRestriction(adminName, restriction);

คุณอาจต้องนำข้อจำกัดเหล่านี้ออกเมื่อแอปอยู่ในโหมดผู้ดูแลระบบ ผู้ดูแลระบบไอทีจะยังคงใช้ฟีเจอร์เหล่านี้เพื่อบำรุงรักษาอุปกรณ์ได้ หากต้องการล้างข้อมูล ข้อจำกัด, โทร DevicePolicyManager.clearUserRestriction()

ระงับกล่องโต้ตอบข้อผิดพลาด

ในบางสภาพแวดล้อม เช่น การสาธิตในร้านค้าปลีกหรือข้อมูลสาธารณะ คุณอาจไม่ต้องการแสดงกล่องโต้ตอบข้อผิดพลาดต่อผู้ใช้ ใน Android 9.0 (API ระดับ 28) ขึ้นไป คุณสามารถระงับกล่องโต้ตอบข้อผิดพลาดของระบบสำหรับ แอปที่ไม่ตอบสนองด้วยการเพิ่ม ผู้ใช้ DISALLOW_SYSTEM_ERROR_DIALOGS ข้อจำกัด ระบบจะรีสตาร์ทแอปที่ไม่ตอบสนองราวกับว่าผู้ใช้อุปกรณ์ปิดไปแล้ว จากกล่องโต้ตอบ ตัวอย่างต่อไปนี้แสดงวิธีดำเนินการดังกล่าว

Kotlin

override fun onEnabled(context: Context, intent: Intent) {
    val dpm = getManager(context)
    val adminName = getWho(context)

    dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS)
}

Java

public void onEnabled(Context context, Intent intent) {
  DevicePolicyManager dpm = getManager(context);
  ComponentName adminName = getWho(context);

  dpm.addUserRestriction(adminName, UserManager.DISALLOW_SYSTEM_ERROR_DIALOGS);
}

หากผู้ดูแลระบบของผู้ใช้หลักหรือผู้ใช้รองตั้งค่าข้อจำกัดนี้ไว้ ระงับกล่องโต้ตอบข้อผิดพลาดเฉพาะสำหรับผู้ใช้รายนั้น หากผู้ดูแลระบบของ อุปกรณ์จะตั้งค่าข้อจำกัดนี้ ระบบจะระงับกล่องโต้ตอบสำหรับผู้ใช้ทุกคน

เปิดหน้าจอไว้

หากคุณกำลังสร้างคีออสก์ คุณสามารถหยุดอุปกรณ์ที่จะ สลีปขณะเรียกใช้กิจกรรมของแอป เพิ่ม ธงเลย์เอาต์ FLAG_KEEP_SCREEN_ON ลงในแอป ตามที่แสดงในตัวอย่างต่อไปนี้

Kotlin

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    // Keep the screen on and bright while this kiosk activity is running.
    window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
}

Java

@Override
protected void onCreate(Bundle savedInstanceState) {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_main);

  // Keep the screen on and bright while this kiosk activity is running.
  getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
}

คุณอาจต้องตรวจสอบว่าอุปกรณ์เสียบกับ AC, USB หรือระบบไร้สาย ที่ชาร์จ ลงทะเบียนประกาศการเปลี่ยนแบตเตอรี่และใช้ BatteryManager ค่าต่างๆ เพื่อดูสถานะการชาร์จ คุณยังส่งการแจ้งเตือนระยะไกลให้กับฝ่ายไอทีได้อีกด้วย ผู้ดูแลระบบหากอุปกรณ์ถอดปลั๊กออก สำหรับวิธีการทีละขั้นตอน โปรดอ่าน ตรวจสอบระดับแบตเตอรี่และการชาร์จ รัฐ

คุณยังสามารถตั้งค่าSTAY_ON_WHILE_PLUGGED_IN การตั้งค่าส่วนกลางเพื่อให้อุปกรณ์เปิดอยู่เสมอขณะเชื่อมต่อกับแหล่งจ่ายไฟ ผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรใน Android 6.0 (API ระดับ 23) ขึ้นไปสามารถ โทรหา DevicePolicyManager.setGlobalSetting() ตามที่แสดง ในตัวอย่างต่อไปนี้

Kotlin

val pluggedInto = BatteryManager.BATTERY_PLUGGED_AC or
        BatteryManager.BATTERY_PLUGGED_USB or
        BatteryManager.BATTERY_PLUGGED_WIRELESS
dpm.setGlobalSetting(adminName,
        Settings.Global.STAY_ON_WHILE_PLUGGED_IN, pluggedInto.toString())

Java

int pluggedInto = BatteryManager.BATTERY_PLUGGED_AC |
    BatteryManager.BATTERY_PLUGGED_USB |
    BatteryManager.BATTERY_PLUGGED_WIRELESS;
dpm.setGlobalSetting( adminName,
    Settings.Global.STAY_ON_WHILE_PLUGGED_IN, String.valueOf(pluggedInto));

แพ็กเกจแอป

ส่วนนี้ประกอบด้วยสูตรอาหารสำหรับการติดตั้งแอปบนอุปกรณ์เฉพาะอย่างมีประสิทธิภาพ

แคชแพ็กเกจแอป

หากผู้ใช้อุปกรณ์ที่แชร์ใช้ชุดแอปเดียวกันร่วมกัน แอปดังกล่าวจะมีประสิทธิภาพ ควรหลีกเลี่ยงการดาวน์โหลดแอปทุกครั้งที่ทำได้ เพื่อช่วยเพิ่มประสิทธิภาพของผู้ใช้ การจัดสรรในอุปกรณ์ที่แชร์กับกลุ่มผู้ใช้แบบคงที่ เช่น อุปกรณ์สำหรับ กะการทำงานใน Android 9.0 (API ระดับ 28) ขึ้นไป คุณสามารถแคชแอปได้ แพ็กเกจ (APK) ที่จำเป็นสำหรับเซสชันที่มีผู้ใช้หลายคน

การติดตั้ง APK ที่แคชไว้ (ซึ่งติดตั้งไว้แล้วในอุปกรณ์) จะเกิดขึ้นใน 2 ระยะดังนี้

  1. องค์ประกอบผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจร (หรือผู้ที่ได้รับมอบสิทธิ์) โปรดดู ต่อไปนี้) กำหนดรายการ APK ที่จะเก็บไว้ในอุปกรณ์
  2. องค์ประกอบผู้ดูแลระบบของผู้ใช้รองที่เชื่อมโยง (หรือผู้ที่ได้รับมอบสิทธิ์) สามารถ ติดตั้ง APK ที่แคชไว้ในนามของผู้ใช้ ผู้ดูแลระบบของ อุปกรณ์ ผู้ใช้หลัก หรือโปรไฟล์งานที่เชื่อมโยง (หรือ ผู้ที่ได้รับมอบสิทธิ์) จะติดตั้งแอปที่แคชไว้ได้ หากจำเป็น

ผู้ดูแลระบบจะโทรหาเพื่อกำหนดรายการ APK ที่จะเก็บไว้ในอุปกรณ์ DevicePolicyManager.setKeepUninstalledPackages() วิธีการนี้จะไม่ตรวจสอบว่ามีการติดตั้ง APK ในอุปกรณ์แล้วหรือไม่ ซึ่งมีประโยชน์หากคุณ ต้องการติดตั้งแอปก่อนที่จะให้ผู้ใช้ใช้งาน หากต้องการรับรายการ แพ็กเกจที่กำหนดไว้ก่อนหน้านี้ คุณสามารถเรียกใช้ DevicePolicyManager.getKeepUninstalledPackages() หลังจากโทรหา setKeepUninstalledPackages() โดยมีการเปลี่ยนแปลง หรือเมื่อ ลบผู้ใช้แล้ว ระบบจะลบ APK ที่แคชไว้ซึ่งไม่จำเป็นต้องใช้อีกต่อไป

หากต้องการติดตั้ง APK ที่แคชไว้ โปรดโทร DevicePolicyManager.installExistingPackage() วิธีนี้สามารถติดตั้งได้เฉพาะแอปที่ระบบแคชข้อมูลไว้แล้วเท่านั้น โซลูชันสำหรับอุปกรณ์โดยเฉพาะ (หรือผู้ใช้อุปกรณ์) จะต้องติดตั้งแอปใน อุปกรณ์ก่อนที่จะเรียกใช้เมธอดนี้

ตัวอย่างต่อไปนี้แสดงวิธีที่คุณสามารถใช้การเรียก API เหล่านี้ในผู้ดูแลระบบของ อุปกรณ์ที่มีการจัดการครบวงจรและผู้ใช้รอง

Kotlin

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
val cachedAppPackageName = "com.example.android.myapp"
dpm.setKeepUninstalledPackages(adminName, listOf(cachedAppPackageName))

// ...

// The admin of a secondary user installs the app.
val success = dpm.installExistingPackage(adminName, cachedAppPackageName)

Java

// Set the package to keep. This method assumes that the package is already
// installed on the device by managed Google Play.
String cachedAppPackageName = "com.example.android.myapp";
List<String> packages = new ArrayList<String>();
packages.add(cachedAppPackageName);
dpm.setKeepUninstalledPackages(adminName, packages);

// ...

// The admin of a secondary user installs the app.
boolean success = dpm.installExistingPackage(adminName, cachedAppPackageName);

มอบสิทธิ์แอป

คุณมอบสิทธิ์ให้แอปอื่นเพื่อจัดการการแคชแอปได้ คุณอาจดำเนินการนี้เพื่อ แยกฟีเจอร์ของโซลูชันหรือให้ผู้ดูแลระบบไอทีใช้งานได้ แอปของตนเองได้อีกด้วย แอปที่มอบสิทธิ์จะได้รับสิทธิ์เดียวกันกับผู้ดูแลระบบ คอมโพเนนต์ ตัวอย่างเช่น ผู้รับมอบสิทธิ์แอปของผู้ดูแลระบบของผู้ใช้รองสามารถโทรหา installExistingPackage() แต่โทรหา setKeepUninstalledPackages() ไม่ได้

วิธีโทรออกผ่านผู้รับมอบสิทธิ์ DevicePolicyManager.setDelegatedScopes() และมี DELEGATION_KEEP_UNINSTALLED_PACKAGES ในอาร์กิวเมนต์ขอบเขต ตัวอย่างต่อไปนี้แสดงวิธีสร้างแอปอีกแอปหนึ่ง ผู้รับมอบสิทธิ์:

Kotlin

var delegatePackageName = "com.example.tools.kept_app_assist"

// Check that the package is installed before delegating.
try {
    context.packageManager.getPackageInfo(delegatePackageName, 0)
    dpm.setDelegatedScopes(
            adminName,
            delegatePackageName,
            listOf(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES))
} catch (e: PackageManager.NameNotFoundException) {
    // The delegate app isn't installed. Send a report to the IT admin ...
}

Java

String delegatePackageName = "com.example.tools.kept_app_assist";

// Check that the package is installed before delegating.
try {
  context.getPackageManager().getPackageInfo(delegatePackageName, 0);
  dpm.setDelegatedScopes(
      adminName,
      delegatePackageName,
      Arrays.asList(DevicePolicyManager.DELEGATION_KEEP_UNINSTALLED_PACKAGES));
} catch (PackageManager.NameNotFoundException e) {
  // The delegate app isn't installed. Send a report to the IT admin ...
}

หากทุกอย่างเป็นไปด้วยดี แอปที่ได้รับมอบสิทธิ์จะได้รับ ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED ออกอากาศและกลายเป็นผู้รับมอบอำนาจ แอปเรียกใช้เมธอดในคู่มือนี้ได้ ราวกับว่าเป็นเจ้าของอุปกรณ์หรือเจ้าของโปรไฟล์ เมื่อโทร DevicePolicyManager เมธอด ผู้รับมอบสิทธิ์ผ่าน null สำหรับผู้ดูแลระบบ ของคอมโพเนนต์

ติดตั้งแพ็กเกจแอป

บางครั้งการติดตั้งแอปพลิเคชันที่กำหนดเองแบบแคชในเครื่องลงใน อุปกรณ์ เช่น อุปกรณ์เฉพาะมักจะติดตั้งใช้งาน สภาพแวดล้อมหรือพื้นที่ที่จำกัดแบนด์วิดท์ซึ่งไม่มีการเชื่อมต่ออินเทอร์เน็ต บัญชี โซลูชันอุปกรณ์เฉพาะควรคำนึงถึงแบนด์วิดท์ของลูกค้า บัญชี สามารถเริ่มการติดตั้งแพ็กเกจแอป (APK) อื่นโดยใช้ PackageInstaller ชั้นเรียน

แม้ว่าแอปจะติดตั้ง APK ได้ แต่ผู้ดูแลระบบในอุปกรณ์ที่มีการจัดการครบวงจรสามารถติดตั้งได้ ติดตั้ง (หรือถอนการติดตั้ง) แพ็กเกจได้โดยไม่ต้องมีการโต้ตอบของผู้ใช้ ผู้ดูแลระบบอาจจัดการ อุปกรณ์ ผู้ใช้รองที่เกี่ยวข้อง หรือโปรไฟล์งานที่เชื่อมโยง หลัง เมื่อเสร็จสิ้นการติดตั้ง ระบบจะโพสต์การแจ้งเตือนว่า ผู้ใช้อุปกรณ์ทุกคน ดู การแจ้งเตือนจะแจ้งให้ผู้ใช้อุปกรณ์ทราบว่ามีการติดตั้งแอปแล้ว (หรือ อัปเดต) โดยผู้ดูแลระบบ

ตาราง 2 เวอร์ชัน Android ที่รองรับการติดตั้งแพ็กเกจ โดยไม่ต้องมีการโต้ตอบของผู้ใช้
เวอร์ชัน Android คอมโพเนนต์ของผู้ดูแลระบบสำหรับติดตั้งและถอนการติดตั้ง
Android 9.0 (API ระดับ 28) ขึ้นไป ผู้ใช้รองที่เกี่ยวข้องและโปรไฟล์งาน ทั้งที่มีการจัดการครบวงจร อุปกรณ์
Android 6.0 (API ระดับ 23) ขึ้นไป อุปกรณ์ที่มีการจัดการเต็มรูปแบบ

วิธีเผยแพร่สำเนาของ APK อย่างน้อย 1 รายการไปยังอุปกรณ์เฉพาะจะ ขึ้นอยู่กับว่าอุปกรณ์อยู่ห่างกันแค่ไหน หรือโดยระยะห่างระหว่างอุปกรณ์ เป็นของกันและกัน โซลูชันของคุณต้องเป็นไปตามแนวทางปฏิบัติแนะนำด้านความปลอดภัย ก่อนติดตั้ง APK ลงในอุปกรณ์เฉพาะ

คุณสามารถใช้ PackageInstaller.Session เพื่อสร้างเซสชันที่อยู่ในคิว 1 รายการ APK สำหรับติดตั้งอย่างน้อย 1 รายการ ในตัวอย่างต่อไปนี้ เราได้รับสถานะ ความคิดเห็นเกี่ยวกับกิจกรรมของเรา (โหมด singleTop) แต่คุณสามารถใช้ บริการหรือ Broadcast Receiver:

Kotlin

// First, create a package installer session.
val packageInstaller = context.packageManager.packageInstaller
val params = PackageInstaller.SessionParams(
        PackageInstaller.SessionParams.MODE_FULL_INSTALL)
val sessionId = packageInstaller.createSession(params)
val session = packageInstaller.openSession(sessionId)

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
// The I/O streams can't be open when installation begins.
session.openWrite("apk", 0, -1).use { output ->
    getContext().resources.openRawResource(R.raw.app).use { input ->
        input.copyTo(output, 2048)
    }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
val intent = Intent(context, activity.javaClass)
intent.action = "com.android.example.APK_INSTALLATION_ACTION"
val pendingIntent = PendingIntent.getActivity(context, 0, intent, 0)
val statusReceiver = pendingIntent.intentSender

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver)

Java

// First, create a package installer session.
PackageInstaller packageInstaller = context.getPackageManager().getPackageInstaller();
PackageInstaller.SessionParams params = new PackageInstaller.SessionParams(
    PackageInstaller.SessionParams.MODE_FULL_INSTALL);
int sessionId = packageInstaller.createSession(params);
PackageInstaller.Session session = packageInstaller.openSession(sessionId);

// Add the APK binary to the session. The APK is included in our app binary
// and is read from res/raw but file storage is a more typical location.
try (
    // These I/O streams can't be open when installation begins.
    OutputStream output = session.openWrite("apk", 0, -1);
    InputStream input = getContext().getResources().openRawResource(R.raw.app);
) {
  byte[] buffer = new byte[2048];
  int n;
  while ((n = input.read(buffer)) >= 0) {
    output.write(buffer, 0, n);
  }
}

// Create a status receiver to report progress of the installation.
// We'll use the current activity.
// Here we're requesting status feedback to our Activity but this can be a
// service or broadcast receiver.
Intent intent = new Intent(context, getActivity().getClass());
intent.setAction("com.android.example.APK_INSTALLATION_ACTION");
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, intent, 0);
IntentSender statusReceiver = pendingIntent.getIntentSender();

// Start the installation. Because we're an admin of a fully managed device,
// there isn't any user interaction.
session.commit(statusReceiver);

เซสชันจะส่งความคิดเห็นสถานะเกี่ยวกับการติดตั้งโดยใช้ Intent ตรวจสอบ EXTRA_STATUS ของแต่ละ Intent เพื่อรับ status โปรดทราบว่าผู้ดูแลระบบจะไม่ได้รับ การอัปเดตสถานะ STATUS_PENDING_USER_ACTION เนื่องจากผู้ใช้อุปกรณ์ไม่จำเป็นต้องอนุมัติการติดตั้ง

หากต้องการถอนการติดตั้งแอป คุณสามารถโทรหา PackageInstaller.uninstall ผู้ดูแลระบบอุปกรณ์ที่มีการจัดการครบวงจร ผู้ใช้ และโปรไฟล์งานสามารถถอนการติดตั้งแพ็กเกจได้ โดยไม่ต้องมีการโต้ตอบของผู้ใช้ในการเรียกใช้ Android เวอร์ชันที่รองรับ (ดู ตาราง 2)

หยุดการอัปเดตระบบ

อุปกรณ์ Android ได้รับการอัปเดตผ่านอากาศ (OTA) ไปยังระบบและแอปพลิเคชัน ซอฟต์แวร์ เมื่อต้องการหยุดเวอร์ชันระบบปฏิบัติการในช่วงเวลาสำคัญ เช่น วันหยุดเทศกาลหรือ สำหรับเวลาที่มีการใช้งานอื่นๆ อุปกรณ์เฉพาะสามารถระงับการอัปเดตระบบของ OTA ได้สูงสุด 90 วัน หากต้องการดูข้อมูลเพิ่มเติม โปรดอ่านจัดการการอัปเดตระบบ

การกำหนดค่าระยะไกล

การกำหนดค่าที่มีการจัดการของ Android ช่วยให้ผู้ดูแลระบบไอทีดำเนินการต่อไปนี้ได้ กำหนดค่าแอปของคุณจากระยะไกล คุณอาจต้องแสดงการตั้งค่า เช่น รายการที่อนุญาต โฮสต์เครือข่าย หรือ URL เนื้อหาเพื่อให้แอปของคุณมีประโยชน์ต่อฝ่ายไอทีมากขึ้น

หากแอปแสดงการกำหนดค่า อย่าลืมรวมการตั้งค่าไว้ใน เอกสารประกอบ หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับการเปิดเผยการกำหนดค่าของแอปและการตอบสนองต่อ การเปลี่ยนแปลงในการตั้งค่า โปรดดูที่หัวข้อตั้งค่าการกำหนดค่าที่มีการจัดการ

การตั้งค่าการพัฒนา

ขณะที่คุณกำลังพัฒนาโซลูชันสำหรับอุปกรณ์เฉพาะ มีประโยชน์ในการตั้งแอปของคุณเป็นผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจรโดยไม่ต้องเริ่มต้นจากโรงงาน รีเซ็ต หากต้องการกำหนดผู้ดูแลระบบของอุปกรณ์ที่มีการจัดการครบวงจร ให้ทำตามขั้นตอนต่อไปนี้

  1. สร้างและติดตั้งแอปเครื่องมือควบคุมนโยบายด้านอุปกรณ์ (DPC) บนอุปกรณ์
  2. ตรวจสอบว่าไม่มีบัญชีในอุปกรณ์
  3. เรียกใช้คำสั่งต่อไปนี้ในเชลล์ Android Debug Bridge (adb) คุณ ต้องแทนที่ com.example.dpc/.MyDeviceAdminReceiver ในตัวอย่างด้วย ชื่อคอมโพเนนต์ผู้ดูแลระบบของแอป

    adb shell dpm set-device-owner com.example.dpc/.MyDeviceAdminReceiver

คุณจะต้องตรวจสอบการลงทะเบียนอื่นๆ เพื่อช่วยลูกค้าในการทำให้โซลูชันของคุณใช้งานได้ วิธีการ เราขอแนะนำให้ลงทะเบียนด้วยคิวอาร์โค้ดสำหรับ อุปกรณ์เฉพาะ

แหล่งข้อมูลเพิ่มเติม

หากต้องการดูข้อมูลเพิ่มเติมเกี่ยวกับอุปกรณ์เฉพาะ โปรดอ่านเอกสารต่อไปนี้