#android
#Android
Вопрос:
Я хочу заблокировать свое приложение, когда оно переходит в фоновый режим, и когда оно возобновится, я хочу отобразить свой собственный экран блокировки. Экран блокировки — это действие моего приложения.
После успешного ввода пароля пользователь может видеть возобновленную активность, иначе он не сможет.
Как я могу это сделать?
Ответ №1:
Основная проблема заключается в том, что вы должны получить определенное поведение при запуске Activity
из фона. onPause()
и onResume()
вызываются при каждом переключении между Activities
ними, а не только при сворачивании приложения. Чтобы обойти это, вы можете получить текущие запущенные задачи из ActivityManager
и сравнить их имя пакета с именем вашего приложения:
private boolean isApplicationInBackground() {
final ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);
final List<RunningTaskInfo> tasks = manager.getRunningTasks(1);
if (!tasks.isEmpty()) {
final ComponentName topActivity = tasks.get(0).topActivity;
return !topActivity.getPackageName().equals(getPackageName());
}
return false;
}
Теперь вы можете сделать это:
public boolean wasPaused = false;
@Override
public void onPause() {
super.onPause();
if(isApplicationInBackground()) {
wasPaused = true;
}
}
@Override
public void onResume() {
super.onResume();
if(wasPaused) {
lockScreen();
wasPaused = false;
}
}
И это все! Я рекомендую вам реализовать это в базе Activity
, из которой исходят все ваши другие Activities
.
Комментарии:
1. Почему бы не использовать onRestart ()?
2. ActivityManager.getRunningTasks(), похоже, устарел.
3. ActivityManager.getRunningTasks() устарел от Lollipop.
Ответ №2:
Вы можете добиться этого, если у вас есть глобальная активность «MyActivity», и все действия исходят из нее.
Затем вы переопределяете методы onPause и onStop для «MyActivity»
@Override
public void onPause()
{
super.onPause();
setLockStatus(false);
}
@Override
public void onStop()
{
super.onStop();
setLockStatus(true);
}
и:
@Override
public void onResume()
{
super.onResume();
checkLockScreen();
}
РЕДАКТИРОВАТЬ: очевидно, вам нужно создать методы setLockStatus и checkLockScreen и делать все, что вы хотите (например, сохранить статус в SharedPreferences).
Комментарии:
1. Спасибо за ваш ответ. В этом случае я начинаю второе действие с первого действия, в этом случае в методе onPause () первого действия флаг будет true, и когда второе действие возобновится в это время, флаг будет true, так что он откроет экран разблокировки, что означает, что когда-либо моя активность будет приостановлена, она будет запрашивать разблокировку, поэтомуэто не решение, как мне нужно.
2. Вы хотите, чтобы ваше приложение блокировалось только тогда, когда оно работает в фоновом режиме? когда приложение переходит в фоновый режим, будут вызываться как onPause, так и onStop, оставляя значение lockStatus равным «true», но если вы переходите от одного действия к другому, будет вызываться onPause, оставляя значение lock равным false. Я вставил этот код, потому что столкнулся с той же проблемой, с которой столкнулись вы, и это было мое решение.
3. Я думаю, вы неправильно понимаете, когда начинаете другое действие, тогда 1) первое действие будет приостановлено. 2) второе действие создать, запустить и возобновить. 3) первое действие остановится и / или уничтожится
4. Вы сами ответили .. 1) onPause> блокировка выключена 2) Возобновление 2-го действия> включена ли блокировка? НЕТ 3) если вы уничтожите свое первое действие (это не обязательно), это не имеет значения, потому что ваше действие уже разблокировано.. но это хорошо, так что вы можете выбрать лучшее решение для вас между ответами..
5. Я не могу понять, как моя проблема будет решена, если я установлю флаг в методе onPause, потому что он будет вызываться 3 раза: 1) при нажатии кнопки Home 2) второе действие появляется выше первого действия 3) третье приложение появляется над моим приложением, так как я могу их отличить?
Ответ №3:
Для всех, кому интересно, если я правильно понял ваш вопрос, я изучал аналогичную функциональность и не был доволен тем, что нашел. Я хотел определить, когда действие возобновляется в фоновом режиме по сравнению с когда оно возобновлялось из вызываемого действия.
В итоге я использовал логический флаг, который устанавливается из startActivity, что позволит вызывающей активности определять, возобновляется ли она из вызываемой активности или из фона. Что-то вроде этого
private static boolean RESUME_FROM_ACTIVITY;
@Override
public void onResume(){
super.onResume();
if(!RESUME_FROM_ACTIVITY){
// do what you want like lock the screen
}
RESUME_FROM_ACTIVITY = false;
}
@Override
public void startActivity(Intent intent){
RESUME_FROM_ACTIVITY = true;
super.startActivity(intent);
}
Из-за того, как Android обрабатывает статику и стек активности (подробнее читайте в этом сообщении в блоге), это должно работать концептуально. Еще одно объяснение: статика должна быть одной из последних вещей, которые удаляются из памяти при запуске вашего приложения, если пространство кучи становится слишком большим. Действие не будет уничтожено без уничтожения самого стека, поэтому будет вызван onResume, и он проверит статический флаг, чтобы узнать, поступает ли он из другого действия или из фона.
Статика, вероятно, даже излишняя, так как опять же сама активность не будет уничтожена, и ее глобальные значения будут храниться как можно дольше. Это только концептуальный, и мы все еще находимся в процессе стресс-тестирования, но это вариант. Если мы обнаружим какие-либо проблемы, я обновлю этот пост.
Ответ №4:
Ваша активность имеет onResume()
обратный вызов в своем жизненном цикле. Просто переопределите это и сделайте то, что вам нужно.
Комментарии:
1. Но как я могу узнать, что моя активность возобновляется после фонового режима или при запуске с другого действия?
2. Что значит «после фона»? Если вы имеете в виду, что хотите узнать, приостановлено ли оно из-за запуска другого вашего собственного действия, вы должны добавить эту логику в свой код вокруг точки, в которой вы
startActivity()
находитесь… однако при этом вы также должны обмениваться данными между своими действиями, чтобы знать, когда они также приостановлены; их логика возобновления должна будет выполнять такую же повторную блокировку.
Ответ №5:
Ну, вы должны переопределить методы onResume и onPause
посмотрите это, и вы получите это 🙂
в вашей деятельности у вас может быть флаг типа boolean заблокирован;
и в onPause вы можете установить для этого значение true. И каждый раз, когда в критических местах вы можете проверить состояние этого флага, и если это правда, тогда вы показываете активность разблокировки, после успешной разблокировки установите флаг в false.
Комментарии:
1. В этом случае я начинаю второе действие с первого действия, в этом случае в методе onPause () первого действия флаг будет true, и когда второе действие возобновится в это время, флаг будет true, так что он откроет экран разблокировки, что означает, что когда-либо моя активность будет приостановлена, она будет запрашивать разблокировку, поэтомуэто не решение, как мне нужно.
2. да, если вы закодируете таким образом, вам будет предложено разблокировать каждый раз, когда будет вызываться onPause
3. Вместо этого все в порядке, если вы отключите флаг в onResume в каждом из блокируемых действий. Действие блокировки имеет свою собственную проверку и не является частью блокируемого действия, если оно запущено, это означает, что после onStop не было запущено никаких новых действий.