Android Studio,Kiosk模式,单用途设备,锁定任务模式

时间:2016-12-04 16:11:10

标签: android-studio kiosk-mode

我正在尝试创建一个单一用途的应用。 所以我创建了一个BaseActivity,我的所有活动都从它继承。

看起来像

公共类LockDeviceActivity扩展了AppCompatActivity {

@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);


}




private void startLock() {


    if(mDevicePolicyManager.isLockTaskPermitted(getPackageName())) {
        /**
         * If lock task is permitted, we can lock the task. We can use an external DPM like
         * TestDPC provided by Google to manage lock task list.
         *
         * If the lock is obtained using TestDPC, features like status bar, home button, recent
         * apps, etc is disabled.
         *
         * To unlock we can programatically call stopLockTask() when users taps a button. But
         * in practice this should be done using a separate admin console or Confirm Credential.
         *
         * For API 23+ you can check if the lock is active by checking if
         * activityManager.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_NONE
         */
        Log.d(TAG, "startLock() called");
        this.startLockTask();
    } else {
        /**
         * The device is not whitelisted.
         */
        Toast.makeText(this, "The app is not whitelisted for lock", Toast.LENGTH_SHORT).show();
    //    Timber.d("The app is not whitelisted for lock task");


        /**
         * We can still pin the app but it will not be locked.
         *
         * We can simply unlock by pressing recent and back button together.
         *
         * Unlocking by calling stopLockTask() on button click can be achieved as well.
         */
     //   Timber.d("just pinning the app");
        this.startLockTask();
    }

}

所以当我第一次进入应用程序时,我可以看到一些固定的消息,我没关系。 问题是,当我从一个活动到包含Fragment的其他Activity的Intent时,我得到以下图像:

Annyoing Message

加上我得到一些系统干杯消息: “该应用不会被列入白名单”

我该如何避免这种行为? 谢谢你们 。

1 个答案:

答案 0 :(得分:4)

1)将设备重置为出厂默认设置 2)跳过账户注册 3)安装应用程序然后关闭它 4)运行adb shell dpm set-device-owner <app-package-name>/.<AppAdminReceiver> 5)确保获得成功的结果。 6)重新启动应用程序。

必须满足以下条件:

AndroidManifest.xml标记内的

application

<activity
            android:name=".AppActivity"
            android:label="Locked Activity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN"/>
                <category android:name="android.intent.category.LAUNCHER" />
                <category android:name="android.intent.category.HOME"/>
                <category android:name="android.intent.category.DEFAULT"/>
            </intent-filter>
</activity>


<receiver
            android:name=".AppAdminReceiver"
            android:description="@string/app_name"
            android:label="@string/app_name"
            android:permission="android.permission.BIND_DEVICE_ADMIN">
            <meta-data
                android:name="android.app.device_admin"
                android:resource="@xml/device_admin_receiver" />
            <intent-filter>
                <action android:name="android.intent.action.DEVICE_ADMIN_ENABLED"/>
                <action android:name="android.intent.action.PROFILE_PROVISIONING_COMPLETE"/>
                <action android:name="android.intent.action.BOOT_COMPLETED"/>
            </intent-filter>
</receiver>

创建一个名为AppAdminReceiver.java的新Java类(可以将其留空)

public class AppAdminReceiver extends android.app.admin.DeviceAdminReceiver {
    
}

device_admin_receiver.xml目录

中添加/res/xml

<?xml version="1.0" encoding="utf-8"?>
<device-admin>
    <uses-policies>
        <disable-keyguard-features/>
    </uses-policies>
</device-admin>

AppActivity.java致电startLockTask()stopLockTask()

private ComponentName mAdminComponentName;
private DevicePolicyManager mDevicePolicyManager;
...

... onCreate(){

// Retrieve Device Policy Manager so that we can check whether we can
// lock to screen later
  mAdminComponentName = new ComponentName(this,AppAdminReceiver.class);
  mDevicePolicyManager = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);
  if(mDevicePolicyManager.isDeviceOwnerApp(getPackageName())){
            // App is whitelisted
            setDefaultCosuPolicies(true);
  }
  else {
           // did you provision the app using <adb shell dpm set-device-owner ...> ?
  }
}

... onStart(){
// Consider locking your app here or by some other mechanism
// Active Manager is supported on Android M
  if(mDevicePolicyManager.isLockTaskPermitted(this.getPackageName())){
            ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
            if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_NONE) {
                setDefaultCosuPolicies(true);
                startLockTask();
            }
    }
}


... unlockApp(){
  ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);

  if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED) {
    stopLockTask();
  }
  setDefaultCosuPolicies(false);

}

private void setDefaultCosuPolicies(boolean active){

        // Set user restrictions
        setUserRestriction(UserManager.DISALLOW_SAFE_BOOT, active);
        setUserRestriction(UserManager.DISALLOW_FACTORY_RESET, active);
        setUserRestriction(UserManager.DISALLOW_ADD_USER, active);
        setUserRestriction(UserManager.DISALLOW_MOUNT_PHYSICAL_MEDIA, active);
        setUserRestriction(UserManager.DISALLOW_ADJUST_VOLUME, active);

        // Disable keyguard and status bar
        mDevicePolicyManager.setKeyguardDisabled(mAdminComponentName, active);
        mDevicePolicyManager.setStatusBarDisabled(mAdminComponentName, active);

        // Enable STAY_ON_WHILE_PLUGGED_IN
        enableStayOnWhilePluggedIn(active);

        // Set system update policy
        if (active){
            mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName,SystemUpdatePolicy.createWindowedInstallPolicy(60, 120));
        } else {
            mDevicePolicyManager.setSystemUpdatePolicy(mAdminComponentName,null);
        }

        // set this Activity as a lock task package
        mDevicePolicyManager.setLockTaskPackages(mAdminComponentName,active ? new String[]{getPackageName()} : new String[]{});

        IntentFilter intentFilter = new IntentFilter(Intent.ACTION_MAIN);
        intentFilter.addCategory(Intent.CATEGORY_HOME);
        intentFilter.addCategory(Intent.CATEGORY_DEFAULT);

        if (active) {
            // set Cosu activity as home intent receiver so that it is started
            // on reboot
            mDevicePolicyManager.addPersistentPreferredActivity(mAdminComponentName, intentFilter, new ComponentName(getPackageName(), AppActivity.class.getName()));
        } else {
            mDevicePolicyManager.clearPackagePersistentPreferredActivities(mAdminComponentName, getPackageName());
        }
    }

    private void setUserRestriction(String restriction, boolean disallow){
        if (disallow) {
            mDevicePolicyManager.addUserRestriction(mAdminComponentName,restriction);
        } else {
            mDevicePolicyManager.clearUserRestriction(mAdminComponentName,restriction);
        }
    }

    private void enableStayOnWhilePluggedIn(boolean enabled){
        if (enabled) {
            mDevicePolicyManager.setGlobalSetting(mAdminComponentName,Settings.Global.STAY_ON_WHILE_PLUGGED_IN,Integer.toString(BatteryManager.BATTERY_PLUGGED_AC| BatteryManager.BATTERY_PLUGGED_USB| BatteryManager.BATTERY_PLUGGED_WIRELESS));
        } else {
            mDevicePolicyManager.setGlobalSetting(mAdminComponentName,Settings.Global.STAY_ON_WHILE_PLUGGED_IN,"0");
        }
    }
}

Similar tutorial on setting up kiosk mode