我有一个全屏沉浸式活动,必须保持全屏直到用户明确退出。 (例如,想想像全屏观看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);
}
答案 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旨在成为响应用户意愿的用户工具。如果他们希望留下一个应用程序,为什么要这么难?此外,如果用户希望有阴影应用程序意外启动活动,那么就这样吧。每个人都遵循由系统建立的相同规则。