専用デバイス クックブック

このクックブックは、開発者やシステム インテグレータが Google Cloud の 説明しました専用デバイス向けのソリューションを見つけるには、ハウツー レシピをご覧ください サポートします。このクックブックは、Google Cloud プロダクトを 初めて使用する場合は、専用デバイス 概要をご覧ください。

カスタム Home アプリ

これらのレシピは、Android Home に代わるアプリを開発する場合に便利です。 ランチャーがあります。

Google Home アプリになる

アプリをデバイスの Google Home アプリとして設定すれば、起動できます 自動的に起動します。[Google Home アプリや ボタン: 許可リストに登録されたアプリをロック中のフォアグラウンドに表示します。 タスクモードを選択できます。

すべてのホームアプリは、CATEGORY_HOME インテント カテゴリを処理します。 システムが Home アプリを認識する方法です。デフォルトの Google Home アプリになるには、アプリを設定してください 優先される 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);

引き続きインテント フィルタを宣言する必要があります。 をアプリ マニフェスト ファイルに追加します。次の 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>

通常、ランチャー アプリは概要画面に表示されないようにする必要があります。 ただし、excludeFromRecents を アクティビティ宣言。これは、Android のランチャーでは最初に起動された ロックタスク モードで実行中のアクティビティに対して行われます。

個別のタスクを表示

FLAG_ACTIVITY_NEW_TASK は、サービス アカウント キーに関連する ランチャータイプのアプリでは、新しいタスクは個別のアイテムとして 概要画面。[概要] 画面のタスクについて詳しくは、履歴 画面

公共キオスク

これらのレシピは、公共の場で無人で設置されたデバイスに適していますが、 多くの専用デバイス ユーザーがタスクに集中できます。

デバイスをロックダウンする

デバイスが本来の用途に確実に使用されるようにするには、 ユーザー制限が適用されます。

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

アプリが管理者モードの場合は、これらの制限を解除して、 IT 管理者がこれらの機能をデバイスのメンテナンスに 引き続き使用できることを説明しました消去する 制限する場合は、 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 を使用する 充電状態を検出できます。IT 担当者にリモート アラートを送信することもできます。 管理者(デバイスが電源から外された場合)詳しい手順については、 バッテリーの残量と充電を監視する 状態

また、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);

アプリを委任する

アプリのキャッシュの管理を別のアプリに委任できます。これを使用して、 ソリューションの機能を分離するか、IT 管理者が 開発できます委任アプリには管理者と同じ権限が付与される 説明します。たとえば、セカンダリ ユーザーの管理者のアプリの委任は、 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 を渡します。 component 引数を渡します。

アプリ パッケージをインストールする

ローカルにキャッシュされたカスタムアプリを、 ダウンロードしますたとえば、専用デバイスは頻繁にデプロイされ、 帯域幅が限られている環境やインターネット接続がない場所などで、お客様の 顧客の帯域幅に配慮する必要があります。お客様の アプリは、SDK を使用して別のアプリ パッケージ(APK)のインストールを開始できます。 PackageInstaller クラス。

どのアプリでも APK をインストールできますが、完全管理対象デバイスの管理者は APK をインストールできます ユーザーの操作なしでパッケージをインストール(またはアンインストール)できます。この管理者は デバイス、関連付けられたセカンダリ ユーザー、関連付けられた仕事用プロファイルのいずれかになります。変更後 インストールを完了すると、すべてのデバイス ユーザーが 表示されます。この通知では、アプリがインストールされていること(または 管理者によって更新されます。

表 2.パッケージ インストールをサポートしている Android バージョン (ユーザーの操作なし)
Android バージョン インストールとアンインストール用の管理コンポーネント
Android 9.0(API レベル 28)以降 関連付けられたセカンダリ ユーザーと仕事用プロファイル(どちらもフルマネージド) デバイス
Android 6.0(API レベル 23)以降 完全管理対象デバイス

APK のコピーを専用デバイスに配布する方法は、 デバイスの距離に依存し、場合によってはデバイスの距離にも依存します。 あります。ソリューションはセキュリティのベスト プラクティスに従う必要があります 専用のデバイスに APK をインストールする前に、

PackageInstaller.Session を使用すると、キューに入れるセッションを作成できます。 インストール用 APK。次の例では、ステータスを受け取ります。 (singleTop モード)。ただし、 サービスまたはブロードキャスト レシーバ:

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

セッションは、インテントを使用して、インストールに関するステータス フィードバックを送信します。確認 各インテントの EXTRA_STATUS フィールドで status。なお、管理者には STATUS_PENDING_USER_ACTION のステータスの更新 これはデバイスのユーザーがインストールを承認する必要がないためです。

アプリをアンインストールするには、PackageInstaller.uninstall を呼び出します。 完全管理対象デバイス、ユーザー、仕事用プロファイルの管理者はパッケージをアンインストールできる サポートされている Android バージョンを実行している間、ユーザーの操作なしで実行可能( 表 2 をご覧ください)。

システム アップデートの凍結

Android デバイスは、システムやアプリの無線(OTA)アップデートを受信します。 ソフトウェアです。休日や祝日など、重要な期間に OS のバージョンを凍結する 専用デバイスで OTA システム アップデートを最大 90 秒間停止できます。 日詳しくは、システム アップデートを管理するをご覧ください。

Remote Config

Android の管理対象設定を使用すると、IT 管理者は次のことを行えます。 アプリをリモートで構成できますたとえば、 許可リスト、ネットワーク ホスト、コンテンツ URL を使用して、IT 部門にとってアプリの利便性を高める できます。

アプリでその設定を公開する場合は、 ご覧くださいアプリの構成の公開と 設定を変更する場合は、管理対象設定を指定するをご覧ください。

開発のセットアップ

専用デバイス向けのソリューションを開発する場合、 工場出荷状態ではない完全管理対象デバイスの管理者としてアプリを設定するのが便利 リセットできます。完全管理対象デバイスの管理者を設定する手順は次のとおりです。

  1. Device Policy Controller(DPC)アプリをビルドしてデバイスでインストールします。
  2. デバイス上にアカウントがないことを確認します。
  3. Android Debug Bridge(adb)シェルで次のコマンドを実行します。マイページ この例の com.example.dpc/.MyDeviceAdminReceiver を アプリの管理コンポーネント名を指定します。

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

お客様によるソリューションのデプロイをサポートするには、その他の登録方法を確認する必要がある メソッド。以下の場合は QR コードの登録をおすすめします。 専用のデバイスです。

参考情報

専用デバイスについて詳しくは、次のドキュメントをご覧ください。