我有一个接收屏幕广播的广播接收器,当屏幕关闭时,它会启动一个活动。我已将此活动命名为LockScreenActivity。我已在活动的getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
中添加onCreate()
,以便它显示在Android锁屏的顶部,这正是我想要的。这种方法效果很好,主要是。每当我按下主页按钮将任何应用程序发送到后台时,就会出现问题。
当我按下主页按钮从任何应用程序返回主屏幕,然后立即按电源按钮关闭屏幕,并按一下电源按钮重新打开,它显示Android锁定屏幕。我的活动在3-4秒后创建。这是一个巨大的延迟,是不可接受的。在其他情况下,这种延迟不会发生。如果我已经在主屏幕上播放了一段时间,或者某个其他应用程序已打开,并且我连续两次点击电源按钮,我会在看到Android锁屏之前看到我的LockScreenActivity。
我的应用程序还有一些其他正常活动(从App抽屉启动)和一个显示持久通知的服务。单击通知时将启动相同的LockScreenActivity。有趣的是,如果我按下主页按钮以最小化某个应用程序并立即单击我的应用程序的通知,它会毫不拖延地打开LockScreenActivity。
我经常搜索任何解决方案。这是我迄今为止尝试过的内容:
onReceive()
中获取了一个唤醒锁,并将其发布在LockScreenActivity的onResume()
这里是活动和服务的清单声明:
<activity
android:name=".LockScreenActivity"
android:label="@string/app_name"
android:excludeFromRecents="true"
android:taskAffinity="@string/task_lockscreen">
</activity>
<service
android:name=".services.BaseService"
android:enabled="true" >
</service>
广播接收器:
public class ScreenReceiver extends BroadcastReceiver {
private static final String LOG_TAG = ScreenReceiver.class.getSimpleName();
private static final String HANDLER_THREAD_NAME = "screen_receiver_thread";
public static final String WAKELOCK_TAG = "lockscreen_overlay_create_wakelock";
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
WakeLockHelper.acquireWakeLock(WAKELOCK_TAG, context);
Log.d(LOG_TAG, "Screen off");
context.startService(BaseService.getServiceIntent(context, null, BaseService.ACTION_START_LOCKSCREEN_ACTIVITY));
} else {
if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
Log.d(LOG_TAG, "Screen on");
}
}
}
public static void registerScreenReceiver(Context context){
new BroadcastReceiverRegistration().execute(context);
}
private static class BroadcastReceiverRegistration extends AsyncTask<Context, Void, Void>{
@Override
protected Void doInBackground(Context... params) {
Context context = params[0];
if(Utility.checkForNullAndWarn(context, LOG_TAG)){
return null;
}
HandlerThread handlerThread = new HandlerThread(HANDLER_THREAD_NAME);
handlerThread.start();
Looper looper = handlerThread.getLooper(); //Will block till thread is started, hence using AsyncTask
Handler handler = new Handler(looper);
IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_OFF);
filter.addAction(Intent.ACTION_SCREEN_ON);
BroadcastReceiver mReceiver = new ScreenReceiver();
context.registerReceiver(mReceiver, filter, null, handler);
return null;
}
}
}
WakeLockHelper是一个管理我应用中所有唤醒锁的类。服务启动时会调用registerScreenReceiver()
。
这里是LockScreenActivity的onCreate():
protected void onCreate(Bundle savedInstanceState) {
Log.d(LOG_TAG, "LockscreenActivity onCreate()");
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_lock_screen);
if (savedInstanceState == null) {
getFragmentManager().beginTransaction()
.add(R.id.container, new LockScreenFragment())
.commit();
}
getWindow().addFlags(WindowManager.LayoutParams.FLAG_DIM_BEHIND);
getWindow().setDimAmount((float) 0.4);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED);
int systemUiVisibilityFlags = View.SYSTEM_UI_FLAG_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_FULLSCREEN |
View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION |
View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN;
if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
systemUiVisibilityFlags = systemUiVisibilityFlags | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
}
getWindow().getDecorView().setSystemUiVisibility(systemUiVisibilityFlags);
}
这是事情按预期工作的日志:(屏幕正在开启;它已关闭然后再打开)
09-19 11:00:09.384 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen off
09-19 11:00:09.384 31226-31226/com.pvsagar.smartlockscreen D/BaseService﹕ Starting lockscreen overlay.
09-19 11:00:09.394 31226-31226/com.pvsagar.smartlockscreen D/LockScreenActivity﹕ LockscreenActivity onCreate()
09-19 11:00:09.735 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen on
屏幕关闭和发送意图之间的延迟并没有实际启动LockScreenActivity。现在屏幕最初开启;我从某个应用程序(任何应用程序,甚至我自己的应用程序的其他一些活动)按回家;屏幕关闭然后再打开:
09-19 11:02:51.557 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen off
09-19 11:02:51.557 31226-31226/com.pvsagar.smartlockscreen D/BaseService﹕ Starting lockscreen overlay.
09-19 11:02:51.708 31226-31243/com.pvsagar.smartlockscreen D/ScreenReceiver﹕ Screen on
09-19 11:02:54.851 31226-31226/com.pvsagar.smartlockscreen D/LockScreenActivity﹕ LockscreenActivity onCreate()
在这里,正如您所看到的,屏幕关闭广播是及时收到的,服务立即获得意图并将意图发送到LockScreenActivity,但LockScreenActivity的onCreate()延迟3秒。
这是服务启动LockScreenActivity的方式:
Intent lockscreenIntent = new Intent(this, LockScreenActivity.class);
lockscreenIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
Log.d(LOG_TAG, "Starting lockscreen overlay.");
startActivity(lockscreenIntent);
这是传递给通知的待处理意图(只是为了表明它做同样的事情):
Intent notificationIntent = new Intent(context, LockScreenActivity.class);
notificationIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
PendingIntent pendingIntent = PendingIntent.getActivity(context, 0, notificationIntent, 0);
notificationBuilder.setContentIntent(pendingIntent);
我不知道为什么会这样。 GC也没有运行太多。可能是什么问题呢?我能做些什么来克服这个问题? 任何建议/想法将不胜感激。
整个代码可在以下网址找到:https://github.com/aravindsagar/SmartLockScreen/tree/backend_code_strengthening
答案 0 :(得分:4)
此处有更多信息:https://code.google.com/p/android/issues/detail?id=4536
我用添加到正在运行的服务的窗口管理器的Window替换了活动。这不会造成任何延误。
答案 1 :(得分:2)
请找到解决方案here
使用Pending Intent并发出请求立即解决了我的问题,希望它也能帮到你:))