【问题标题】:Wake Lock for Alarm doesn't work in Service闹钟唤醒锁在服务中不起作用
【发布时间】:2015-07-17 20:27:35
【问题描述】:

我正在尝试创建一个警报,其中包含我已经存储在 Parse 中的时间列表。到目前为止,我可以让闹钟响起。但现在我希望它即使在设备处于睡眠状态时也能关闭。我知道我需要在我已经做过的服务中实现唤醒锁。我也明白我需要包含“FLAG_SHOW_WHEN_LOCKED | FLAG_TURN_SCREEN_ON, FLAG_FULLSCREEN”。目前我知道的唯一方法是使用 get Window。但我知道 getWindow 不是为了服务。所以,我需要一些帮助来解决这个问题。

我有一个带有此代码的 AlarmService:

@Override
public int onStartCommand(Intent intent, int flags, int startId) {
    super.onStartCommand(intent, flags, startId);
    Toast.makeText(this,"onStartCommand()",Toast.LENGTH_SHORT).show();

    //wake lock
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, "My Wake Log");
    mWakeLock.acquire();

    //This code below doesn't work because getWindow is not for Service. what is my other option?
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
                    WindowManager.LayoutParams.FLAG_FULLSCREEN |
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    setContentView(R.layout.activity_reminder_screen);

    //start alarm screen
    Intent intent = new Intent(this, AlarmScreenActivity.class);
    ReminderIntent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
    startActivity(intent);

    return flags;
}

按下添加警报活动中的保存按钮后服务关闭,如下所示:

//set time into calendar instance
Calendar calendar= Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY,mAlarmDetails.timeHour);
calendar.set(Calendar.MINUTE,mAlarmDetails.timeMinute);

AlarmManager reminder = (AlarmManager)getSystemService(Context.ALARM_SERVICE);

Intent intent = new Intent(this, AlarmService.class);
PendingIntent pendingIntent = PendingIntent.getService(this,0,intent,PendingIntent.FLAG_UPDATE_CURRENT);

reminder.set(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(),pendingIntent);

提前谢谢你

更新 我尝试将我的服务变成一个 Activity 并将此代码插入:

public class AlarmService extends Activity {
private MediaPlayer mMediaPlayer;
private PowerManager.WakeLock mWakeLock;


@Override
public void onCreate(Bundle savedInstateState) {
    super.onCreate(savedInstateState);
    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
    mWakeLock = pm.newWakeLock(/***PowerManager.FULL_WAKE_LOCK*/WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON, "My Wake Log");
    mWakeLock.acquire();
    this.requestWindowFeature(Window.FEATURE_NO_TITLE);
    this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN |
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON,
            WindowManager.LayoutParams.FLAG_FULLSCREEN |
                    WindowManager.LayoutParams.FLAG_SHOW_WHEN_LOCKED |
                    WindowManager.LayoutParams.FLAG_TURN_SCREEN_ON);
    setContentView(R.layout.activity_alarm_screen);


}

我还将待处理意图中的 getService 从按钮更改为 getActivity。但是在我改变了这些之后,什么都没有出现。闹钟没有出现。

【问题讨论】:

    标签: android service alarmmanager alarm android-wake-lock


    【解决方案1】:

    您不需要持有唤醒锁。仅当您想阻止设备进入睡眠状态时才这样做。在您的情况下,您只是希望设备唤醒您。使用 RTC_WAKEUP 或 ELAPSED_REALTIME_WAKEUP 将实现此目标。如果您要异步处理事件,您可以在唤醒时获取唤醒锁,以防止设备立即返回睡眠状态。

    RTC_WAKEUP is not working

    RTC_WAKEUP 不会在屏幕上切换,它所做的只是唤醒你 cpu,这样你的工作就完成了。要打开屏幕,您需要 要获取一个完整的唤醒锁。

    【讨论】:

    • 我希望即使设备处于睡眠状态也能响起警报。如您所见,添加警报时,我的活动中已经有 RTC_WAKEUP。它不会唤醒手机。
    • 您是否检查过您的时间计算是否正确?打印出你的闹钟时间和 System.currentTimeMillis() 看看差值是不是预期值。
    • 现在是时候了。我知道,因为如果我删除整个唤醒锁,它会正常工作。但是只有在我解锁屏幕/手机后它才会熄灭。
    • 顺便说一句,您为什么要通过服务来启动活动?您可以让待处理的意图直接启动活动。 PendingIntent pintent = PendingIntent.getActivity(SomeActivity.this, 0, intent,PendingIntent.FLAG_UPDATE_CURRENT);
    • 所以我想,如果我把这个服务变成一个活动,问题就解决了吗?我很快就会试一试。
    【解决方案2】:

    您需要 wakeful intent service 或 WakefulBroadcastReceiver - 将挂起的 Intent 更改为广播 (PendingIntent pendingIntent = PendingIntent.getBroadcast...) 设置接收器并在接收器中启动 Wakeful Intent 服务 - 或设置 WakefulBroadcastReceiver。警报管理器在 onReceive 运行时持有一个唤醒锁 - 通过使用 WIS(或 WBR,尚未使用它们),您基本上获得了一个在 onReceive 结束和您的服务启动之间处于活动状态的唤醒锁。见:https://stackoverflow.com/a/20332558/281545

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-11-02
      相关资源
      最近更新 更多