Android Kiosk Mode - Предотвращение пользователей от "несанкционированного" открепления приложения

Я довольно новичок в Android, и в настоящее время я разрабатываю приложение для Android, которое должно работать в KioskMode, чтобы обычный пользователь не мог выйти из приложения или сделать что-либо вне его.
Что я уже сделал:

  • Я установил свое приложение в качестве владельца устройства
  • Я "прикрепляю экран" к приложению в методе onCreate() в MainActivity как владелец устройства
  • У меня есть кнопка в MainActivity, которая позже позволяет администратору выйти, введя пароль. Вызывает stopLockTask()

Проблема, с которой я столкнулся сейчас, заключается в том, что любой пользователь может выйти из функции закрепления экрана, просто нажав и удерживая одновременно кнопки "назад" и "многозадачность", потому что на планшете, на котором должно запускаться приложение, есть аппаратные кнопки, которые я не могу просто отключить. (по крайней мере, я не знаю, как это сделать без рута устройства)
Так есть ли способ отключить эту комбинацию кнопок для выхода из закрепления экрана, или какой-то аккуратный обходной путь? Один из подходов, о котором я подумал, - это повторное добавление приложения в мой класс AdminReceiver в onLockTaskModeExiting(), но я все еще застрял на том, как это сделать.

Вот некоторые фрагменты кода моего класса MainActivity и класса AdminReceiver:
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();
        }
    });}

Любая помощь высоко ценится. Спасибо!

4 ответа

Если активность установлена ​​как 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>

каждый раз, когда пользователь нажимает кнопку "Домой", действие может снова включить блокировку onCreate, onResume или же onStart, Если приложение было принудительно откреплено с помощью кнопок обзора и возврата, а список последних действий пуст, пользователь может нажать только кнопку "Домой", которая снова включит блокировку.

Поскольку этому вопросу 12 месяцев, я все еще ищу более эффективное решение.

Просто перезапустите свою деятельность и повторно закрепите экран, если режим блокировки задачи вышел без намерения.

@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));
    }
}

У меня была эта проблема, и я попробовал ответы в этой теме. Я не рекомендовал бы ответ Ксавье Лин, так как в итоге создается несколько экземпляров вашего приложения.

К счастью, я нашел собственное решение.

В вашем классе, который расширяет DeviceAdminReceiver, переопределите onLockTaskModeExiting и запустите там пин-код.

public class AdminReceiver extends DeviceAdminReceiver{

    @Override
    public void onLockTaskModeExiting(Context context, Intent intent) {
        super.onLockTaskModeExiting(context, intent);

        // Run pinning code here
    }
}

Закрепление экрана не является правильным способом реализации режима киоска, потому что его можно легко открепить. Если вы хотите внедрить режим киоска, тогда перейдите по этой ссылке https://github.com/googlesamples/android-testdpc

Другие вопросы по тегам