将活动始终放在堆栈顶部,还是在恶意应用启动活动时集中精力? [英] Keep activity always on top of stack, or in focus when rogue apps launch activities?

查看:62
本文介绍了将活动始终放在堆栈顶部,还是在恶意应用启动活动时集中精力?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a fullscreen immersive activity that has to stay fullscreen until the user explicitly exits. (For example, think of something like watching a Youtube video full screen).

但是,我最近注意到,许多不必要的活动启动会破坏我的应用程序的行为。例如,许多阴暗的免费应用往往会生成全屏透明活动并显示广告,从而立即打乱用户。某些实际上是全屏活动的应用程序的全屏通知弹出窗口也会立即中断我的活动。

However, I've noticed recently that a lot of unwanted activities launching can break my app's behaviour. For example, many shady "free apps" tend to generate full-screen transparent activities and show ads, disrupting the user immediately. "Full screen" notification popups from certain apps which are actually full-screen activities also instantly disrupt my activity.

有没有办法避免这些活动夺走焦点,还是有办法让它们落后于我的全屏活动,以免破坏我的全屏模式?换句话说,每当某个恶意应用决定在我的网站上发起活动时,如何保持活动始终排在首位?

Is there a way to avoid these activities stealing focus, or a way to keep them behind my fullscreen activity so it doesn't break my full screen mode? In other words, how do I keep my activity always on top whenever some rogue app decides to launch an activity over mine?

不需要取消它们,而是暂时放弃,直到用户退出全屏活动为止。

They don't need to be canceled, but "put behind for the moment" until the user exits the full screen activity.

想到的一种方法是在失去焦点时,用 FLAG_ACTIVITY_REORDER_TO_FRONT 重新启动我的活动,但是对用户来说不会很漂亮:(

A method that comes to mind would be to relaunch my activity with FLAG_ACTIVITY_REORDER_TO_FRONT the moment it loses focus, but that won't look pretty to the user :(

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

Note: If you would like to try it yourself, I've found an app that "simulates" these rogue activities launching. Download this - https://play.google.com/store/apps/details?id=com.nlucas.popupnotificationslite&hl=en

无论何时收到通知,它都会启动全屏透明活动。 YouTube视频并收到某人的10条通知,并想象它会分散注意力。

Whenever you receive notifications, it launches a full screen transparent activity. Try watching a Youtube video and getting 10 notifications from someone and imagine how distracting it would be.

更新:这样做似乎不起作用:

UPDATE: Doing this doesn't seem to work:

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


推荐答案

您可以在以下位置运行服务经常检查的背景将使您的应用程序保持领先:

You can run a service in the background that checks every so often that will keep your app on top:

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

这篇关于将活动始终放在堆栈顶部,还是在恶意应用启动活动时集中精力?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆