【问题标题】:Android Kiosk Mode - Preventing users from "unauthorized" unpinning the applicationAndroid Kiosk 模式 - 防止用户“未经授权”取消固定应用程序
【发布时间】:2016-08-22 10:59:17
【问题描述】:

我对 android 很陌生,我目前正在开发一个应该在 KioskMode 下运行的 Android 应用程序,这样普通用户就无法退出应用程序或在它之外做任何事情。
我已经做了什么:

  • 我将我的应用设置为设备所有者
  • 我以设备所有者身份在 MainActivity 的 onCreate() 方法中“屏幕固定”应用程序
  • 我在 MainActivity 中有一个按钮,稍后允许管理员通过输入密码退出。调用 stopLockTask()

我现在遇到的问题是,任何用户都可以通过同时长按“返回”和“多任务”按钮来退出屏幕固定,因为应该运行应用程序的平板电脑有硬件按钮,我不能简单地停用这些按钮。 (至少我不知道如何在不植根设备的情况下做到这一点)
那么有什么方法可以停用此按钮组合以退出屏幕固定,或者一些巧妙的解决方法? 我想到的一种方法是在 onLockTaskModeExiting() 的 AdminReceiver 类中重新固定应用程序,但我仍然坚持如何做到这一点。

这是我的 MainActivity 和 AdminReceiver 类的一些代码 sn-ps:
AdminReceiver.java

public class AdminReceiver extends DeviceAdminReceiver{

@Override
public void onEnabled(Context context, Intent intent) {
    Toast.makeText(context, context.getString(R.string.device_admin_enabled), Toast.LENGTH_SHORT).show();
}

@Override
public CharSequence onDisableRequested(Context context, Intent intent) {
    return context.getString(R.string.device_admin_warning);
}

@Override
public void onDisabled(Context context, Intent intent) {
    Toast.makeText(context, context.getString(R.string.device_admin_disabled), Toast.LENGTH_SHORT).show();
}

@Override
public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
    Toast.makeText(context, context.getString(R.string.kiosk_mode_enabled), Toast.LENGTH_SHORT).show();
}

@Override
public void onLockTaskModeExiting(Context context, Intent intent) {
    Toast.makeText(context, context.getString(R.string.kiosk_mode_disabled), Toast.LENGTH_SHORT).show();
}

}

MainActivity.java

public class MainActivity extends Activity {

private DevicePolicyManager mDpm;


@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    ComponentName deviceAdmin = new ComponentName(this, AdminReceiver.class);
    mDpm = (DevicePolicyManager) getSystemService(Context.DEVICE_POLICY_SERVICE);

    if (!mDpm.isAdminActive(deviceAdmin)) {
        Toast.makeText(this, getString(R.string.not_device_admin), Toast.LENGTH_SHORT).show();
    }


    if (mDpm.isDeviceOwnerApp(getPackageName())) {
        Toast.makeText(this, getString(R.string.device_owner), Toast.LENGTH_SHORT).show();

        mDpm.setLockTaskPackages(deviceAdmin, new String[]{getPackageName()});
        startLockTask();
    } else {
        Toast.makeText(this, getString(R.string.not_device_owner), Toast.LENGTH_SHORT).show();
    }

    Button exit = (Button) findViewById(R.id.exit);
    exit.setOnClickListener(new View.OnClickListener(){
        @Override
        public void onClick(View v) {
            stopLockTask();
        }
    });}

非常感谢任何帮助。谢谢!

【问题讨论】:

  • 您如何将您的应用设置为设备所有者?如果您的应用实际设置为设备所有者,则最近按钮也将被隐藏。有关详细信息,请参阅示例 DPC。
  • @Phil,是的,你是如何设置设备所有者的?

标签: android android-5.0-lollipop kiosk device-owner android-screen-pinning


【解决方案1】:

如果活动设置为DEFAULTHOME

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

每次用户按下主页按钮时,活动都可以重新启用对onCreateonResumeonStart 的锁定。如果应用程序被使用概览和返回键强制取消固定并且最近的活动列表为空,用户只能按下将重新启用锁定的主页按钮。

由于这个问题已有 12 个月的历史,我仍在寻找更有效的解决方案。

【讨论】:

  • 你能举个例子吗?我是一个反应原生的开发者,所以我有点迷路了。谢谢!我有一个限制,我不能将应用程序设置为设备所有者。
  • @hadifikri 你能找到任何解决方案吗?
【解决方案2】:

如果锁定任务模式无意退出,只需重新启动您的活动并重新固定屏幕。

@Override
public void onLockTaskModeExiting(Context context, Intent intent) {
    SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context);
        if (sharedPreferences.getBoolean(PIN_SHOULD_ENABLED, false)) {
            context.startActivity(new Intent(context, YOUR_PIN_SCREEN_ACTIVITY.class).setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
    }
}

【讨论】:

    【解决方案3】:

    我遇到了这个问题,并在这个线程中尝试了答案。我不会推荐 Xavier Lin 的答案,因为它最终会创建您的应用程序的多个实例。

    幸运的是,我想出了自己的解决方案。

    在您扩展 DeviceAdminReceiver 的类中,覆盖 onLockTaskModeExiting 并在那里运行 pin 码。

    public class AdminReceiver extends DeviceAdminReceiver{
    
        @Override
        public void onLockTaskModeExiting(Context context, Intent intent) {
            super.onLockTaskModeExiting(context, intent);
    
            // Run pinning code here
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-09-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多