保持活动始终在堆栈之上,或在流氓应用程序启动活动时保持焦点?

时间:2016-02-07 17:42:45

标签: android dialog fullscreen

我有一个全屏沉浸式活动,必须保持全屏直到用户明确退出。 (例如,想想像全屏观看Youtube视频一样)。

但是,我最近注意到很多不必要的活动启动可能会破坏我应用的行为。例如,许多阴暗的“免费应用”倾向于生成全屏透明活动和展示广告,立即扰乱用户。某些应用程序实际上是全屏活动的“全屏”通知弹出窗口也会立即中断我的活动。

有没有办法避免这些活动窃取焦点,或者一种方法让它们落后于我的全屏活动,这样就不会破坏我的全屏模式?换句话说,每当一些流氓应用程序决定在我的活动上发起一项活动时,如何让我的活动始终保持在最顶层?

他们不需要取消,但“暂时搁置”直到用户退出全屏活动。

我想到的一种方法是在失去焦点的时候用FLAG_ACTIVITY_REORDER_TO_FRONT重新启动我的活动,但这对用户来说并不美观:(

注意:如果您想自己尝试一下,我发现了一个“模拟”这些流氓活动的应用程序。下载此内容 - https://play.google.com/store/apps/details?id=com.nlucas.popupnotificationslite&hl=en

每当您收到通知时,它都会启动全屏透明活动。尝试观看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);
}

2 个答案:

答案 0 :(得分:4)

您可以在后台运行一项经常检查的服务,以保持您的应用程序在最前面:

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

答案 1 :(得分:1)

您最好的选择是使用“屏幕固定”(如在Android L中引入的here)。其他任何东西都是无法向前兼容的黑客或解决方法。

坦率地说,Android并非真正意图让应用程序无条件地完全接管设备。 Android旨在成为响应用户意愿的用户工具。如果他们希望留下一个应用程序,为什么要这么难?此外,如果用户希望有阴影应用程序意外启动活动,那么就这样吧。每个人都遵循由系统建立的相同规则。