Активность PIN-кода Android при загрузке

У меня есть приложение, которое регистрируется как средство запуска по умолчанию и автоматически прикрепляется при запуске.

Все это прекрасно работает при установке приложения. Сам прикалывается и видна только кнопка назад.

Проблема в том, что при первой загрузке устройство не фиксируется должным образом. Я вижу серию тостов "Экран закреплен" и "Экран откреплен" несколько раз. Кнопки «Домой» и «Недавние задачи» также по-прежнему видны.

--

Запуск «деятельности adb shell dumpsys» — последние строки указывают, что он не закреплен:

mLockTaskModeState=NONE mLockTaskPackages (userId:packages)=
0:[com.example.myapp]
mLockTaskModeTasks[]

--

Тестовое устройство Asus ZenPad под управлением Marshmallow/6.0/23

Я полагаюсь на атрибут манифеста MainActivity "lockTaskMode" для закрепления (а не на activity.startLockTask()):

<activity
    android:name=".MainActivity"
    android:configChanges="keyboardHidden|orientation|screenSize"
    android:label="@string/launcher_main"
    android:launchMode="singleTask"
    android:lockTaskMode="if_whitelisted"
    android:screenOrientation="landscape">
    <intent-filter>
        <action android:name="android.intent.action.MAIN"/>
        <category android:name="android.intent.category.HOME"/>
        <category android:name="android.intent.category.DEFAULT"/>
        <category android:name="android.intent.category.LAUNCHER"/>
    </intent-filter>
</activity>

Любая помощь или указатели будут оценены


person Greg T    schedule 10.10.2016    source источник
comment
Что произойдет, если вы используете значение по умолчанию lockTaskMode и вызываете startLockTask()?   -  person Kevin Krumwiede    schedule 10.10.2016
comment
Вроде ведет себя так же   -  person Greg T    schedule 10.10.2016
comment
Интересно, есть ли состояние гонки между запуском программы запуска и установлением разрешений на закрепление задач. Я написал приложение, которое автоматически прикрепляется при запуске, но вместо запуска оно запускается в ответ на BOOT_COMPLETED. Это транслируется через несколько секунд после появления лаунчера.   -  person Kevin Krumwiede    schedule 11.10.2016
comment
Вы правы насчет задержки трансляции BOOT_COMPLETED. Кажется, сначала он доставляется системным приложениям, а через некоторое время — пользовательским приложениям. Я не уверен, что проблема именно в этом... В DeviceAdminReceiver я вижу onLockTaskModeEntering, а затем onLockTaskModeExiting. Я просто не знаю, что вызывает его вырваться   -  person Greg T    schedule 11.10.2016


Ответы (3)


У меня была такая же проблема, и я действительно мог найти только одно решение. Я не уверен, почему, но да, что-то в Android предотвращает блокировку задач при загрузке, что пугает меня, поскольку блокировка задач была разработана для создания приложений типа «киоск». Единственное решение, которое я смог найти, - это обнаружить случай, когда оно не блокируется, а затем перезапустить приложение. Это немного "хакерски", но что еще вы можете сделать?

Чтобы обнаружить случай, когда он не заблокирован, я создал переменную состояния и присвоил состояния (блокировка, блокировка, разблокировка, разблокировка). Затем в приемнике администратора устройства в onTaskModeExiting, если состояние не «Разблокировка», я знаю, что оно разблокировано само по себе. Поэтому, если в этом случае произошел сбой, я перезапускаю приложение, используя этот метод (который планирует приложение в диспетчере тревог, а затем убивает приложение):

как программно перезапустить приложение Android?

Вот пример кода:

DeviceAdminReceiver

@Override
public void onLockTaskModeEntering(Context context, Intent intent, String pkg) {
    super.onLockTaskModeEntering(context, intent, pkg);
    Lockdown.LockState = Lockdown.LOCK_STATE_LOCKED;
}

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

    if (Lockdown.LockState != Lockdown.LOCK_STATE_UNLOCKING) {
        MainActivity.restartActivity(context);
    }
    Lockdown.LockState = Lockdown.LOCK_STATE_UNLOCKED;
}

Основная деятельность

public static void restartActivity(Context context) {
    if (context != null) {
        PackageManager pm = context.getPackageManager();
        if (pm != null) {
            Intent intent = pm.getLaunchIntentForPackage(context.getPackageName());
            if (intent != null) {
                intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
                int pendingIntentId = 223344;
                PendingIntent pendingIntent = PendingIntent.getActivity(context, pendingIntentId, intent, PendingIntent.FLAG_CANCEL_CURRENT);
                AlarmManager mgr = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
                mgr.set(AlarmManager.RTC, System.currentTimeMillis() + 100, pendingIntent);
                System.exit(0);
            }
        }
    }
}

private void lock() {
    Lockdown.LockState = Lockdown.LOCK_STATE_LOCKING;
    startLockTask();
}

private void unlock() {
    ActivityManager am = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
    if (am.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED) {
        Lockdown.LockState = Lockdown.LOCK_STATE_UNLOCKING;
        stopLockTask();
    }
}

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

person Will Young    schedule 05.05.2017
comment
Не идеальное решение, но оно защищает от выхода пользователя из режима киоска. Приложение будет убито и запущено снова (при условии, что это средство запуска по умолчанию). - person Greg T; 18.05.2017
comment
Надеюсь, это будет исправлено в будущих версиях Android. - person Greg T; 18.05.2017
comment
Для меня это не работает. Моя деятельность перезагружается, как всегда, в бесконечном цикле; (Есть ли еще решения, пожалуйста? - person LionisIAm; 09.11.2017

Единственное решение, которое я нашел на данный момент: сделать другое приложение запуска без блокировки, которое будет запускать основное приложение каждый раз, когда появляется панель запуска. Это не позволяет пользователю ждать еще несколько секунд, прежде чем приложение LockTasked будет вызвано с помощью приемника BOOT_COMPLETED. Таким образом, мы можем столкнуться с этой проблемой только тогда, когда приложение lockTask имеет свойства запуска для некоторой активности в манифесте.

person LionisIAm    schedule 09.11.2017

Извините за поздний ответ, но...
Любой, у кого есть эта проблема, может выполнить эту сложную работу в первом (LAUNCHER/HOME) действии (например, MainActivity):

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

    if (mSharedPreferences.getBoolean(KEY_PREF_RECREATED, false)) {
        mSharedPreferences.edit().putBoolean(KEY_PREF_RECREATED, false).apply();

        // start LOCK TASK here
    } else {
        mSharedPreferences.edit().putBoolean(KEY_PREF_RECREATED, true).apply();

        finish(); // close the app
        startActivity(new Intent(this, MainActivity.class)); // reopen the app
        return;
    }

    setContentView(R.layout.activity_main);

    // other codes
}
person Pourqavam    schedule 02.06.2018