Device Policy Controller を構築する

このガイドでは、Android Enterprise デプロイのデバイス向けの Device Policy Controller(DPC)を開発する方法について説明します。DPC アプリ(旧称は Work Policy Controller)は、デバイス上のローカル デバイス ポリシーとシステムアプリを制御します。

DPC について

Android Enterprise デプロイでは、企業はユーザー デバイスのさまざまな要素を制御します。たとえば、仕事に関連する情報をユーザーの個人データから分離する、環境向けに承認済みアプリを事前構成する、デバイス機能(カメラなど)を無効にするなどです。

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 サポート ライブラリによって行われ、managed 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. build.gradle ファイルに 11.4.0 Google Play 開発者サービス認証クライアント ライブラリを追加します。

    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 コンソールに現在のポリシーを照会し、Device Administration API を使用してポリシーを適用します。

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

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

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

アプリの機能は、Google Play へのアップロード時にアプリに付属する XML スキーマ(管理対象設定スキーマ)でアプリ デベロッパーが定義します(詳しくは、管理対象設定の設定をご覧ください)。

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

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

Kotlin

var managedConfigurationsSupport = ManagedConfigurationsSupport(context, admin)

Java

ManagedConfigurationsSupport managedConfigurationsSupport =
    new ManagedConfigurationsSupport(context, admin);

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

Kotlin

managedConfigurationsSupport.enableManagedConfigurations()

Java

managedConfigurationsSupport.enableManagedConfigurations();

このライブラリを DPC で初期化すると、これらのタスクを DPC で直接コーディングする代わりに、EMM コンソールとサーバーで Google Play EMM API を使用して管理対象設定を承認済みアプリに適用できます。詳しくは、 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)でプロビジョニングしたら、デバイスが managed 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 は、managed Google Play アカウントをデバイスに追加できます。AccountManager の操作を簡素化するには、DPC サポート ライブラリのヘルパー関数(下記の例を参照)を使用します。この関数は、Google Play サーバーから返されたトークンを処理し、managed Google Play アカウントのプロビジョニングを容易にします。managed Google Play アカウントが有効な状態になると、この関数が返されます。

Kotlin

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback)

Java

androidForWorkAccountSupport.addAndroidForWorkAccount(token, accountAddedCallback);
  • token - Google Play EMM API の Users.generateAuthenticationToken() 呼び出しによって生成されたユーザー認証トークン。
  • accountAddedCallback - デバイスに正常に追加された managed 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 をご覧ください。