Device Policy Controller を構築する

このガイドでは、Android エンタープライズ デプロイメントのデバイス向けにデバイス ポリシー コントローラ(DPC)を開発する方法について説明します。DPC アプリ(以前は仕事用ポリシー コントローラと呼ばれていました)は、デバイス上のローカル デバイス ポリシーとシステムアプリを制御します。

DPC について

Android エンタープライズ環境では、企業はユーザーのデバイスのさまざまな側面を管理できます。たとえば、仕事関連の情報をユーザーの個人データから分離したり、環境用に承認済みアプリを事前設定したり、デバイスの機能(カメラなど)を無効にしたりできます。

EMM は、EMM コンソールとサーバーと組み合わせて顧客が使用できる DPC アプリを開発します。お客様が管理するユーザー デバイスに DPC をデプロイします。DPC は、EMM コンソール(およびサーバー)とデバイスの間のブリッジとして機能します。管理者は EMM コンソールを使用して、デバイスの設定やアプリの設定など、さまざまなタスクを実行します。

DPC は、インストールされているデバイスで仕事用プロファイルを作成して管理します。仕事用プロファイルは、仕事関連の情報を暗号化し、ユーザーの個人用アプリやデータとは別に保持します。DPC は、仕事用プロファイルを作成する前に、デバイスで使用する managed Google Play アカウントをプロビジョニングすることもできます。

このガイドでは、仕事用プロファイルを作成および管理できる DPC を開発する方法について説明します。

EMM 向けの DPC サポート ライブラリ

EMM 向けの DPC サポート ライブラリは、企業環境での Android デバイスのプロビジョニングと管理を容易にするユーティリティ クラスとヘルパークラスで構成されています。このライブラリを使用すると、DPC アプリで重要な機能を活用できます。

  • managed Google Play アカウントのプロビジョニングのサポート: DPC アプリから managed Google Play アカウントをプロビジョニングするには、Google Play アプリと Google Play 開発者サービス アプリが最小バージョン要件を満たしている必要があります。ただし、これらのアプリの更新は複雑になる可能性があります。DPC サポート ライブラリは、これらのアプリの更新を処理し、管理対象の Google Play アカウントのプロビジョニング プロセスの将来の更新との互換性も確保します。詳しくは、managed Google Play アカウントのプロビジョニングのサポートをご覧ください。
  • 管理対象設定のサポート: Play EMM API を使用して承認済みアプリの管理対象設定を処理することは、DPC に管理対象設定を実装する最も簡単な方法です。DPC サポート ライブラリを使用すると、EMM コンソールを使用して管理者が設定した管理対象構成(以前のアプリの制限)を適用するタスクを Google Play に委任できます。Play EMM API を使用してマネージド構成を処理すると、インストール中にアプリの構成をアトミックに適用できます。DPC でこの機能を有効にする方法について詳しくは、仕事用アプリに管理対象の設定を適用するをご覧ください。

ライブラリをダウンロードする手順は次のとおりです。このガイドで説明するタスクは、DPC サポート ライブラリの使用を前提としています。

DPC サポート ライブラリをダウンロードする

DPC サポート ライブラリを使用するには、Android Enterprise EMM プロバイダ コミュニティからライブラリをダウンロードします。DPC アプリをビルドする際は、ライブラリを build.gradle ファイルに追加し、他の依存関係を処理する必要があります。たとえば、ライブラリには 11.4.0 の Google Play 開発者サービス認証クライアント ライブラリが必要です。

  1. build.gradle ファイルにライブラリを追加します。

    Groovy

    implementation(name:'dpcsupport-yyyymmdd', ext:'aar')

    Kotlin

    implementation(name = "dpcsupport-yyyymmdd", ext = "aar")
  2. 11.4.0 Google Play 開発者サービス認証クライアント ライブラリを build.gradle ファイルに追加します。

    Groovy

    implementation 'com.google.android.gms:play-services-auth:11.4.0'

    Kotlin

    implementation("com.google.android.gms:play-services-auth:11.4.0")

ライブラリを実行するには特定の権限が必要なため、Google Play にアップロードする際に、これらの権限を DPC アプリのマニフェストに追加する必要があります。

  <uses-permission android:name=
      "android.permission.DOWNLOAD_WITHOUT_NOTIFICATION"/>
  <uses-permission android:name=
      "android.permission.GET_ACCOUNTS"/>
  <uses-permission android:name=
      "android.permission.MANAGE_ACCOUNTS"/>
  <uses-permission android:name=
      "android.permission.WRITE_SYNC_SETTINGS"/>
  <uses-permission android:name=
      "com.google.android.providers.gsf.permission.READ_GSERVICES"/>

これらの事前設定とデプロイの手順に加えて、実装する機能に応じて、DPC コードで特定のライブラリ機能を初期化する必要があります。詳細は、以下の関連セクションをご覧ください。

DPC を作成する

デバイス管理アプリケーションで使用されている既存のモデルに基づいて DPC を構築します。具体的には、 デバイス管理の説明に沿って、アプリで DeviceAdminReceiverandroid.app.admin パッケージのクラス)をサブクラス化する必要があります。

仕事用プロファイルの作成

基本的な仕事用プロファイルを作成する方法を示すサンプルについては、GitHub の BasicManagedProfile をご覧ください。

すでに個人用プロファイルが設定されているデバイスに仕事用プロファイルを作成するには、まず FEATURE_MANAGED_USERS システム機能の有無を確認して、デバイスが仕事用プロファイルをサポートできるかどうかを調べます。

Kotlin

if (!packageManager.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
    // This device does not support work profiles!
}

Java

PackageManager pm = getPackageManager();
if (!pm.hasSystemFeature(PackageManager.FEATURE_MANAGED_USERS)) {
    // This device does not support work profiles!
}

デバイスが仕事用プロファイルに対応している場合は、ACTION_PROVISION_MANAGED_PROFILE アクションでインテントを送信して、仕事用プロファイルを作成します。(一部のドキュメントでは、管理対象プロファイルは、企業向け Android のコンテキストで仕事用プロファイルと同じ意味の一般的な用語です)。デバイス管理パッケージ名をエクストラとして含めます。

Kotlin

val provisioningActivity = getActivity()

// You'll need the package name for the DPC app.
val myDPCPackageName = "com.example.myDPCApp"

// Set up the provisioning intent
val adminComponent = ComponentName(provisioningActivity.applicationContext, MyAdminReceiver::class.java)
provisioningIntent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, adminComponent.flattenToString())
if (provisioningIntent.resolveActivity(provisioningActivity.packageManager) == null) {
    // No handler for intent! Can't provision this device.
    // Show an error message and cancel.
} else {
    // REQUEST_PROVISION_MANAGED_PROFILE is defined
    // to be a suitable request code
    startActivityForResult(provisioningIntent,
            REQUEST_PROVISION_MANAGED_PROFILE)
    provisioningActivity.finish()
}

Java

Activity provisioningActivity = getActivity();
// You'll need the package name for the DPC app.
String myDPCPackageName = "com.example.myDPCApp";
// Set up the provisioning intent
Intent provisioningIntent =
        new Intent("android.app.action.PROVISION_MANAGED_PROFILE");
ComponentName adminComponent = new ComponentName(provisioningActivity.getApplicationContext(), MyAdminReceiver.class);
provisioningIntent.putExtra(EXTRA_PROVISIONING_DEVICE_ADMIN_COMPONENT_NAME, adminComponent.flattenToString());
if (provisioningIntent.resolveActivity(provisioningActivity.getPackageManager())
         == null) {
    // No handler for intent! Can't provision this device.
    // Show an error message and cancel.
} else {
    // REQUEST_PROVISION_MANAGED_PROFILE is defined
    // to be a suitable request code
    startActivityForResult(provisioningIntent,
            REQUEST_PROVISION_MANAGED_PROFILE);
    provisioningActivity.finish();
}

システムは、次の処理を行ってこのインテントに応答します。

  • デバイスが暗号化されていることを確認します。暗号化されていない場合は、続行する前にデバイスを暗号化するよう求めるメッセージがシステムに表示されます。
  • 仕事用プロファイルを作成します。
  • 仕事用プロファイルから必須ではないアプリケーションを削除します。
  • DPC アプリを仕事用プロファイルにコピーし、DPC 自体をプロファイル所有者として設定します。

onActivityResult() をオーバーライドして、プロビジョニングが成功したかどうかを確認します。

Kotlin

override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
    // Check if this is the result of the provisioning activity
    if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {
        // If provisioning was successful, the result code is
        // Activity.RESULT_OK
        if (resultCode == Activity.RESULT_OK) {
            // Work profile created and provisioned.
        } else {
            // Provisioning failed.
        }
        return
    } else {
        // This is the result of some other activity. Call the superclass.
        super.onActivityResult(requestCode, resultCode, data)
    }
}

Java

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    // Check if this is the result of the provisioning activity
    if (requestCode == REQUEST_PROVISION_MANAGED_PROFILE) {
        // If provisioning was successful, the result code is
        // Activity.RESULT_OK
        if (resultCode == Activity.RESULT_OK) {
            // Work profile created and provisioned.
        } else {
            // Provisioning failed.
        }
        return;
    } else {
        // This is the result of some other activity. Call the superclass.
        super.onActivityResult(requestCode, resultCode, data);
    }
}

仕事用プロファイルの有効化を完了する

プロファイルがプロビジョニングされると、システムは DPC アプリの DeviceAdminReceiver.onProfileProvisioningComplete() メソッドを呼び出します。このコールバック メソッドをオーバーライドして、仕事用プロファイルの有効化を完了します。

一般的な DeviceAdminReceiver.onProfileProvisioningComplete() コールバック実装では、次の処理が行われます。

仕事用プロファイルを有効にする

これらのタスクが完了したら、デバイス ポリシー マネージャーの setProfileEnabled() メソッドを呼び出して仕事用プロファイルを有効にします。

Kotlin

// Get the device policy manager
val myDevicePolicyMgr = getSystemService(Context.DEVICE_POLICY_SERVICE) as DevicePolicyManager
val componentName = myDeviceAdminReceiver.getComponentName(this)
// Set the name for the newly created work profile.
myDevicePolicyMgr.setProfileName(componentName, "My New Work Profile")
// ...and enable the profile
myDevicePolicyMgr.setProfileEnabled(componentName)

Java

// Get the device policy manager
DevicePolicyManager myDevicePolicyMgr =
        (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
ComponentName componentName = myDeviceAdminReceiver.getComponentName(this);
// Set the name for the newly created work profile.
myDevicePolicyMgr.setProfileName(componentName, "My New Work Profile");
// ...and enable the profile
myDevicePolicyMgr.setProfileEnabled(componentName);

デバイス ポリシーを設定する

DPC アプリは、組織の要件と制約を満たすために管理者が設定したデバイス ポリシーを適用します。たとえば、セキュリティ ポリシーで、パスワードの入力失敗が一定回数を超えたらデバイスをロックすることが求められる場合があります。DPC は EMM コンソールに現在のポリシーを問い合わせ、デバイス管理 API を使用してポリシーを適用します。

デバイス ポリシーの適用方法については、 ポリシーをご覧ください。

仕事用アプリに管理対象設定を適用する

管理対象設定を使用すると、お客様はデプロイ用に承認したアプリを事前設定し、構成の変更が必要になったときにアプリを簡単に更新できます。デプロイ前にアプリを構成すると、ターゲット デバイスにアプリをインストールしたときに、組織のセキュリティ ポリシーなどのポリシーが確実に適用されます。

アプリの機能は、アプリ デベロッパーが XML スキーマ(管理対象設定のスキーマ)で定義します。このスキーマは、Google Play にアップロードされるアプリに付随します(アプリ デベロッパーは、管理対象設定を設定するで詳細を確認してください)。

このスキーマをアプリから取得して、EMM コンソールでお客様の管理者に表示し、スキーマで定義されたさまざまなオプションが表示される UI を提供して、管理者がアプリの設定を事前構成できるようにします。管理者が設定した管理対象構成は通常、EMM サーバーに保存され、Play EMM API を使用して Managedconfigurationsfordevice または Managedconfigurationsforuser を設定します。詳しくは、Google Play を介した管理対象の設定をご覧ください。

管理対象構成は、Play EMM API(推奨アプローチ)を使用するか、DPC から直接(DPC から管理対象構成を直接適用するで説明)アプリに適用できます。Play EMM API を使用すると、DPC サポート ライブラリを使用して DPC タスクを簡素化できるため、実装が容易になるなど、いくつかのメリットがあります。また、Play EMM API は次のことを行います。

  • 新しいアプリがインストールされたときに構成をアトミックに設定し、ユーザーがアプリを初めて起動したときにアプリが準備できているようにします。
  • ユーザー単位で構成を管理できるため、デバイス単位でモニタリングのプロビジョニングを行う必要がなくなります。

Play EMM API を使用して管理対象構成を適用する

管理対象構成に Play EMM API を使用するには、DPC で Google Play が構成を設定できるようにする必要があります。DPC サポート ライブラリは、Google Play から送信された構成をプロキシすることで、このタスクを処理します。

Play EMM API を使用するには、DPC サポート ライブラリをダウンロードしてから、DPC でマネージド構成のサポートを有効にします。

DPC でマネージド構成のサポートを有効にする

このクラスを DPC にインポートします。

com.google.android.apps.work.dpcsupport.ManagedConfigurationsSupport

管理対象設定ライブラリを初期化します。この例では、DeviceAdminReceiver の ComponentName は「admin」です。

Kotlin

var managedConfigurationsSupport = ManagedConfigurationsSupport(context, admin)

Java

ManagedConfigurationsSupport managedConfigurationsSupport =
    new ManagedConfigurationsSupport(context, admin);

管理対象設定を有効にします。

Kotlin

managedConfigurationsSupport.enableManagedConfigurations()

Java

managedConfigurationsSupport.enableManagedConfigurations();

このライブラリを DPC で初期化すると、EMM コンソールとサーバーで Google Play EMM API を使用して、承認済みアプリに管理対象構成を適用できます。これらのタスクを DPC で直接コーディングする必要はありません。詳しくは、 Google Play を介した管理対象の設定をご覧ください。

DPC から直接管理対象構成を適用する

DPC からアプリの構成設定を直接変更するには、DevicePolicyManager.setApplicationRestrictions() メソッドを呼び出し、DPC アプリの DeviceAdminReceiver、ターゲット アプリのパッケージ名、管理者が設定したアプリの管理対象構成を含む Bundle のパラメータを渡します。詳しくは、DPC と EMM コンソールの連携方法マネージド構成を設定するをご覧ください。ただし、managed Google Play アカウントのデプロイでは、管理対象の設定を適用するこの代替アプローチは推奨されません。

managed Google Play アカウントのプロビジョニングのサポート

DPC サポート ライブラリには、managed Google Play アカウントのプロビジョニングのサポートが含まれています。このサポートを使用するには、まずライブラリを初期化する必要があります。その後、動作環境を確認したり、managed Google Play アカウントを追加したりできます。

DPC で managed Google Play アカウントのサポートを初期化する

このクラスを DPC にインポートします。

com.google.android.apps.work.dpcsupport.AndroidForWorkAccountSupport

プロビジョニング互換性ライブラリを初期化します。この例では、「admin」は DeviceAdminReceiverComponentName です。

Kotlin

var androidForWorkAccountSupport = AndroidForWorkAccountSupport(context, admin)

Java

AndroidForWorkAccountSupport androidForWorkAccountSupport =
    new AndroidForWorkAccountSupport(context, admin);

managed Google Play アカウントの動作環境を確認する

DPC がプロファイル所有者モード(ACTION_PROVISION_MANAGED_PROFILE)またはデバイス所有者モード(ACTION_PROVISION_MANAGED_DEVICE)でデバイスをプロビジョニングした後、次の呼び出しによって、デバイスが管理対象 Google Play アカウントをサポートできることを確認します。

Kotlin

androidForWorkAccountSupport.ensureWorkingEnvironment(callback)

Java

androidForWorkAccountSupport.ensureWorkingEnvironment(callback);

コールバックは、このプロセスの成功または失敗を報告します。コールバックが正常に返されると、managed Google Play アカウントを追加できます。コールバックがエラーを報告した場合は、デバイスがネットワークに接続されていることを確認するようユーザーに促します(ダウンロードが失敗した場合など)。それ以外の場合は、Google に障害を報告してください。

Kotlin

object : WorkingEnvironmentCallback() {
    override fun onSuccess() {
        // Can now provision the managed Google Play Account
    }
    override fun onFailure(error: Error) {
        // Notify user, handle error (check network connection)
    }
}

Java

new WorkingEnvironmentCallback() {
    @Override
    public void onSuccess() {
        // Can now provision the managed Google Play Account
    }

    @Override
    public void onFailure(Error error) {
        // Notify user, handle error (check network connection)
    }
}

managed Google Play アカウントを追加する

Android フレームワークの AccountManager は、管理対象の Google Play アカウントをデバイスに追加できます。AccountManager とのやり取りを簡素化するには、DPC サポート ライブラリのヘルパー関数(以下の例を参照)を使用します。この関数は、Google Play サーバーから返されたトークンを処理し、managed Google Play アカウントのプロビジョニングを容易にします。この関数は、管理対象の Google Play アカウントが有効な状態になると返されます。

Kotlin

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback)

Java

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback);
  • token - Google Play EMM API の Users.generateAuthenticationToken() 呼び出しによって生成されたユーザー認証トークン。
  • accountAddedCallback - デバイスに正常に追加された管理対象 Google Play アカウントを返します。このコールバックには、onAccountReady() メソッドと onFailure() メソッドを含める必要があります。

Kotlin

val workAccountAddedCallback = object : WorkAccountAddedCallback() {
    override fun onAccountReady(account: Account, deviceHint: String) {
        // Device account was successfully added to the device
        // and is ready to be used.
    }

    override fun onFailure(error: Error) {
        // The account was not successfully added. Check that the token
        // provided was valid (it expires after a certain period of time).
    }
}

Java

WorkAccountAddedCallback workAccountAddedCallback =
    new WorkAccountAddedCallback() {
        @Override
        public void onAccountReady(Account account, String deviceHint) {
            // Device account was successfully added to the device
            // and is ready to be used.
        }

        @Override
        public void onFailure(Error error) {
            // The account was not successfully added. Check that the token
            // provided was valid (it expires after a certain period of time).
        }
};
  • Device Administration API について詳しくは、デバイス管理をご覧ください。
  • Android Enterprise のプロビジョニング方法については、Android Enterprise デベロッパー ガイドのデバイスをプロビジョニングするをご覧ください。
  • 基本的な仕事用プロファイルを作成する方法を示す GitHub サンプルについては、BasicManagedProfile をご覧ください。
  • プロファイル オーナーとして他のアプリに構成を設定する方法を示す GitHub サンプルについては、AppRestrictionEnforcer をご覧ください。