Android Studio,信息亭模式,单一用途设备,锁定任务模式 [英] Android Studio, Kiosk mode, Single-Purpose Devices, Lock Task mode

查看:85
本文介绍了Android Studio,信息亭模式,单一用途设备,锁定任务模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试创建一个单一用途的应用程序. 因此,我创建了一个BaseActivity,我所有的活动都继承自它.

看起来像

public class LockDeviceActivity extends 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的活动进行Intent时,我得到以下图像:

加上我收到了一些系统吐司消息: 该应用未列入锁定白名单"

如何避免这种行为? 谢谢你们 .

解决方案

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

必须满足以下条件:

标签内的

AndroidManifest.xml

 <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 {
    
} 

/res/xml目录中添加device_admin_receiver.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");
        }
    }
} 

有关设置信息亭模式的类似教程

I'm trying to create a single purpose app. So I have create an BaseActivity that all my activities inherit from it.

it's look like

public class LockDeviceActivity extends 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();
        }

    }

so when I first Enter the app, I can see some Pinned message and it's okay by me. The problem is, when I'm doing an Intent from one activity to other Activity which contain Fragment, I'm getting the following image :

plus i'm getting a some system toast message : " the app is not whitelisted for lock "

how can I avoid this kind of behavior ? thank you all .

解决方案

1) Reset device to factory default 2) Skip Account registration 3) Install the app then close it 4) Run adb shell dpm set-device-owner <app-package-name>/.<AppAdminReceiver> 5) Make sure you get a successful result. 6) Re-launch the app.

The following must be satisfied:

AndroidManifest.xml inside application tag

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

Create a new Java Class named AppAdminReceiver.java (it's fine to leave it blank)

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

Add device_admin_receiver.xml in /res/xml directory

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

In AppActivity.java calling startLockTask() and 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

这篇关于Android Studio,信息亭模式,单一用途设备,锁定任务模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆