最近有个需求:在检查到特定条件的时候,自动从后台启动页面。
很简单的功能,但是也遇到了坑,那就是:按Home键时无法从后台启动Activity。
会报以下错误:
10-22 17:31:21.897 I/ActivityManager( 664): START u0 {flg=0x14000000 meizuflg=0x200000 cmp=com.pl.getaway.getaway/com.pl.getaway.component.Activity.welcome.SplashActivity } from uid 10255
10-22 17:31:21.897 W/ActivityManager( 664): Activity start request from 10020 stopped
百度一下,很快就找到了原因,是Android系统本身的限制:
当通过 home 键将当前 activity 置于后台时,任何在后台startActivity 的操作都将会延迟 5 秒。
除非该应用获取了"android.permission.STOP_APP_SWITCHES" 权限。
关于延迟 5 秒的操作在 com.android.server.am.ActivityManagerService 中的 stopAppSwitches() 方法中。
系统级的应用当获取了 "android.permission.STOP_APP_SWITCHES" 后将不会调用到这个方法来延迟通过后台启动 activity 的操作。
事实上 android 原生的 Phone 应用就是这样的情况,它是一个获取了"android.permission.STOP_APP_SWITCHES" 权限的系统级应用。
当有来电时,一个从后台启动的 activity 将突然出现在用户的面前,警醒用户有新的来电,这样的设计是合理的。
参考自——后台启动Activity
原因是知道了,但是是文中却没有给出可行的解决办法。但我们怎么能就此放弃呢。经过一番搜索,终于在sof上找到了答案: Starting an activity from a service after HOME button pressed without the 5 seconds delay
方法很简单,也很巧妙,用PendingIntent来启动:
把:
Intent intent = new Intent(context, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(intent);
改成:
Intent intent = new Intent(context, A.class);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, 0);
try {
pendingIntent.send();
} catch (PendingIntent.CanceledException e) {
e.printStackTrace();
}
如此即可解决问题。
但是这种方案也并不完美,在pixel 2 android 9上可以完美运行,但是在小米6 miui10,android 8.0上无法运行。
再次感叹:
1、面向google和sof编程是如此重要。
2、国产ROM是多么厉害