如何在ACTION_SCREEN_OFF时停止服务

时间:2010-12-23 22:24:43

标签: android service

我正在尝试让我的数字时钟小部件的UpdateService在屏幕关闭以节省电池时停止,然后在屏幕激活时重新启动。我目前在我的AppWidgetProvider中的onReceive()中有它,但我也在BroadcastReciever中尝试过它。

我目前的代码是:

public static boolean wasScreenOn = true;

public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
    Log.d("Screen switched on. ", "Starting DigiClock UpdateService.");
    context.startService(new Intent(UpdateService2by2.ACTION_UPDATE));
    wasScreenOn = false;
} else if (intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
    Log.d("Screen switched off. ", "Stopping DigiClock UpdateService.");
    context.stopService(new Intent(context, UpdateService2by2.class));
    wasScreenOn = true;
}

任何人都可以帮助我吗?我很难过。

4 个答案:

答案 0 :(得分:3)

我很确定你必须在ACTION_SCREEN_OFF/ON的代码中注册接收器。我不认为在清单中注册它们会起作用。

答案 1 :(得分:1)

似乎您无法在清单中使用过滤器注册ACTION_SCREEN_ON / OFF意图。您必须在代码中注册您的BroadcastReceiver。有关活动和服务的示例,请参阅here

如果您的服务或活动正在运行,您将只收到意图。与其他广播事件相比,系统不会启动您的进程来处理SCREEN_ON意图。在这方面类似于ACTION_BATTERY_CHANGED。

要使用窗口小部件处理此意图,我认为您必须启动一个侦听意图的服务,然后通知您的窗口小部件。

答案 2 :(得分:1)

从Jens对这个问题的回答中链接的文章提供了关于这个主题的精彩演讲。我用它来实现一个对我有用的解决方案。

关键的见解是您的BroadcastReceiver只能在代码中注册;你既不想要也不需要你的清单中的条目。

我推荐这篇文章,但对于那些匆忙的人来说,最简单的功能方法就是将这样的东西粘贴到你的活动的onCreate()方法中:

IntentFilter filter = new IntentFilter(Intent.ACTION_SCREEN_ON);
filter.addAction(Intent.ACTION_SCREEN_OFF);
BroadcastReceiver screenoffReceiver = new BroadcastReceiver() {
  @Override
  public void onReceive(Context context, Intent intent) {
    if(intent.getAction().equals(Intent.ACTION_SCREEN_OFF)) {
      Log.v("screenoffReceiver", "SCREEN OFF");
    }
    else if(intent.getAction().equals(Intent.ACTION_SCREEN_ON)) {
      Log.v("screenoffReceiver", "SCREEN ON");
    }
    return;
  }
};      
registerReceiver(screenoffReceiver, filter);

正如文章指出的那样,对于正在运行的活动,当电源按钮用于清空/取消显示时,总是调用onPause()/ onResume(),所以如果你有什么东西你不介意做甚至如果电源按钮 onPause()或onResume()调用的原因,您可以在这些方法中执行此操作,从而捕获用于空白的电源按钮的每个实例或者取消屏幕(以及由于其他原因引起的调用),而不会产生创建BroadcastReceiver的开销。

对我来说就是这样;我有一个按钮,当按下按钮时,我的活动的主视图不可见,当被释放时可见,如果用户按住按钮然后在隐藏应用程序时点击电源按钮,当屏幕被另一个屏幕取消时,它将永久隐藏点击电源按钮。所以在我的情况下,我只需要在我的活动的onResume()覆盖中为我的主视图调用setVisibility(VISIBLE)。

事实上,正如文章所示,即使您只想响应电源按钮事件,正确的方法是在BroadcastReceiver中设置一个标志,然后在onPause()和/或中测试该标志onResume()查看电源按钮是否是调用这些方法的具体原因。

答案 3 :(得分:0)

也许你应该使用

public class MyReceiver extends BroadcastReceiver {..}

然后在清单

中使用此类名