Android: остановить новую активность, выводя приложение на передний план

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

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

Приложение также должно перейти на страницу входа в систему, когда нажата кнопка «все открытые приложения» (не уверен в имени), так как это не должно отображать снимок экрана с текущим открытым действием, но должно отображать действие входа в систему.

Я играл с вариантами кода ниже:

@Override
public void onTrimMemory(int level) {
    super.onTrimMemory(level);

    if(level >= TRIM_MEMORY_UI_HIDDEN && ((!isInputtingPIN && !isLoggedIn) || isLoggedIn)) {

        Log.d("AppGlobalData:", "*************** APP WINDOW IS BEING OBSCURED ***************");
        Intent login = new Intent(this.currentContext, AppEntryPoint.class);
        startActivity(login);
    }
}

Это работает, но проблема в том, что при нажатии кнопки «Домой» приложение переходит в фоновый режим, но это срабатывание нового намерения возвращает приложение на передний план. Это также происходит в представлении «все приложения».

Если я отложу срабатывание этого намерения до тех пор, пока приложение не вернется на передний план, это нормально, но приложение не перейдет на страницу входа, пока не вернется в фокус, это означает, что приложение было на странице, показывающей конфиденциальные данные и все приложения кнопка нажата, приложение показывает конфиденциальные данные.

Это было достигнуто в IOS простой реализацией одного метода...

Может ли кто-нибудь сказать мне, как я могу получить намерение изменить действие, но оставить приложение в фоновом режиме?


person berimbolo    schedule 08.12.2015    source источник


Ответы (2)


Вы можете обнаружить, что ваша активность переходит в фоновый режим с помощью обратного вызова жизненного цикла onPause. Простым/наивным решением было бы установить логический флаг в значение true в onPause и в onResume проверить этот флаг и отправить пользователя в вашу активность входа, если флаг установлен.

Чтобы обойти кнопку «все приложения», вы можете удалить содержимое или очистить представления в onPause.

person Florian Barth    schedule 08.12.2015
comment
Эй, спасибо, я на самом деле делаю что-то именно так, как вы описываете, пытаясь использовать переменную отслеживания состояния и onWindowFocusChanged, а затем накладываю представление содержимого моих текущих действий на конкретное для скрытия содержимого экрана в onPause. Затем после этого я всегда отправляю пользователя обратно для входа в систему, когда приложение восстанавливает фокус. Хотя это был метод проб и ошибок, спасибо! - person berimbolo; 08.12.2015

Мне удалось заставить все работать для моего варианта использования довольно упрощенным способом, это может оказаться полезным для всех, кто захочет сделать это в будущем, я больше не использую onTrimMemory():

1) Когда пользователь вошел в систему, я устанавливаю глобальную переменную isLoggedIn, у меня есть переменная, которая устанавливается всякий раз, когда я вызываю новое намерение на другой экран в своем приложении:

public class GlobalData extends Application

public static boolean inTransition = false;
public static boolean isLoggedIn = false;

2) Создано 2 метода, которые будут реализованы в рамках каждого действия onPause() и onResume():

public static void onResumeHandler(Context context) {
    inTransition = false;

    if(!isLoggedIn) {
        Intent login = new Intent(context, AppEntryPoint.class);
        context.startActivity(login);
    }
}

public static void onPauseHandler() {
    if(!inTransition) {
        isLoggedIn = false;
    }
}

3) Каждый раз, когда я запускаю новое намерение в своем приложении, устанавливаю переменную индикатора перехода:

case R.id.map_settings:
     GlobalData.inTransition = true;
     intent = new Intent(this, MapPreference.class);
     this.startActivity(intent);
     break;

4) В действиях вызываем обработчики:

@Override
public void onResume() {
    GlobalData.onResumeHandler(this);

    super.onResume();
}

@Override
public void onPause() {
    GlobalData.onPauseHandler();

    super.onPause();
}

5) В действиях с настройками мне также приходилось обрабатывать onBackPressed(), потому что в этих случаях я не запускаю новое намерение уйти от экрана настроек, а вместо этого нажимается кнопка «Назад»:

@Override
public void onBackPressed() {
    GlobalData.inTransition = true;

    super.onBackPressed();
}

Судя по небольшому количеству проведенных мной тестов, это, похоже, обрабатывает нажатие кнопки «Домой» и нажатие кнопки «Все запущенные приложения» и перенаправляет на экран входа в систему.

6) Последнее, что я сделал, конкретно для моего варианта использования, это то, что я не хотел, чтобы кнопка «Все запущенные приложения» показывала снимок экрана при нажатии, поэтому в каждом действии я добавил следующую строку в метод onCreate() для отключения снимков экрана:

getWindow().setFlags(WindowManager.LayoutParams.FLAG_SECURE,WindowManager.LayoutParams.FLAG_SECURE);    
person berimbolo    schedule 09.12.2015