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

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


person Phil    schedule 27.04.2016    source источник
comment
Как вы устанавливаете свое приложение в качестве владельца устройства? Если ваше приложение на самом деле установлено как владелец устройства, кнопка «Последние» также будет скрыта. Дополнительные сведения см. в образце DPC.   -  person bmg    schedule 20.05.2016
comment
@ Фил, да, как ты установил владельца устройства?   -  person portfoliobuilder    schedule 14.07.2017


Ответы (3)


Если действие установлено как DEFAULT HOME

<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 месяцев, я все еще ищу более эффективное решение.

person hadifikri    schedule 23.04.2017
comment
Не могли бы вы привести пример с этим? Я реагирующий нативный разработчик, поэтому я немного растерялся. Спасибо! У меня есть ограничение, что я не могу установить приложение в качестве владельца устройства. - person Farid Saud Rolleri; 02.06.2018
comment
@hadifikri, ты смог найти какое-нибудь решение для этого? - person Dinesh Thiyagarajan; 16.10.2019

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

@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));
    }
}
person Xavier Lin    schedule 14.05.2016

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

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

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

public class AdminReceiver extends DeviceAdminReceiver{

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

        // Run pinning code here
    }
}
person C. Carter    schedule 08.03.2018