Сохранять активность всегда поверх стека или в фокусе при запуске приложений-изгоев?

У меня полноэкранная захватывающая активность, которая должна оставаться в полноэкранном режиме, пока пользователь явно не выйдет. (Например, подумайте о чем-то вроде просмотра видео в полноэкранном режиме Youtube).

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

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

Их не нужно отменять, но "поставить на место" до тех пор, пока пользователь не выйдет из полноэкранного режима.

Метод, который приходит на ум, FLAG_ACTIVITY_REORDER_TO_FRONT бы в том, чтобы возобновить мою деятельность с FLAG_ACTIVITY_REORDER_TO_FRONT тот момент, когда он теряет фокус, но это не будет выглядеть красиво для пользователя :(

Примечание. Если вы хотите попробовать самостоятельно, я нашел приложение, которое "имитирует" запуск этих запугивающих действий. Загрузить это - https://play.google.com/store/apps/details?id=com.nlucas.popupnotificationslite&hl=ru

Всякий раз, когда вы получаете уведомления, он запускает прозрачную активность в полноэкранном режиме. Попробуйте посмотреть видео Youtube и получить 10 уведомлений от кого-то и представить себе, как это будет отвлекать.

ОБНОВЛЕНИЕ: Выполнение этого не работает:

@Override
public void onWindowFocusChanged(boolean hasFocus) {
    super.onWindowFocusChanged(hasFocus);
    if (!hasFocus) {
        Intent i = new Intent(getBaseContext(), MainActivity.class);
        i.addFlags(Intent.FLAG_ACTIVITY_BROUGHT_TO_FRONT);
        startActivity(i);
}

Ответы

Ответ 1

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

public class ServiceKeepInApp extends Service {

//private static boolean sendHandler = false;
KeepInAppHandler taskHandler = new KeepInAppHandler(this);


@Override
public void onCreate() {
    super.onCreate();
    //sendHandler = true;

    taskHandler.sendEmptyMessage(0);
}

@Override
public void onDestroy() {
    super.onDestroy();
    //sendHandler = false;
    taskHandler.removeCallbacksAndMessages(0);
}

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    return START_STICKY;
}

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

private static class KeepInAppHandler extends Handler {
    private final WeakReference<ServiceKeepInApp> mService;
    private Context context;
    private boolean sendHandler = false;

    public KeepInAppHandler(ServiceKeepInApp mService) {
        this.mService = new WeakReference<ServiceKeepInApp>(mService);
        this.context = mService;
        this.sendHandler = true;

    }

    @Override
    public void handleMessage(Message msg) {
        super.handleMessage(msg);

        ActivityManager activityManager = (ActivityManager)context.getSystemService(Service.ACTIVITY_SERVICE);

        if (activityManager.getRecentTasks(2, 0).size() > 0) {
            if (activityManager.getRecentTasks(2, 0).get(0).id != GlobalVars.taskID) {
                activityManager.moveTaskToFront(GlobalVars.taskID, 0);
            }

            if (sendHandler) {
                sendEmptyMessageDelayed(0, 1000);
            }
        }


    }

}

}

Затем выполните одноэлементный класс:

public static class GlobalVars { 
   public static int taskID;
   public static Intent keepInApp;

}

Затем в вашей деятельности:

public class MyActivity extends Activity { 

     @Override
     public void onCreate(Bundle savedInstanceState) {

         super.onCreate(savedInstanceState);

         GlobalVars.taskID = getTaskId();

         GlobalVars.keepInApp = new Intent(this, ServiceKeepInApp.class);
         startService(GlobalVars.keepInApp);
     }
}

Ответ 2

Лучше всего использовать "скрининг экрана" (как это представлено здесь, новое в Android L). Все остальное - это хак или обходной путь, который не будет совместим с переходом.

Чтобы быть тупым, Android на самом деле не был разработан, чтобы приложение безоговорочно и полностью захватило устройство. Android был разработан, чтобы быть инструментом для пользователя, который отвечает их пожеланиям. Если их желание оставить приложение, почему это должно сделать это сложно? Кроме того, если пользователь хочет иметь теневые приложения, которые неожиданно запускают действия, то пусть будет так. Все играют по тем же правилам, которые установлены системой.