Wakeful IntentService工作不完整,在睡眠模式下通知

时间:2012-07-13 21:47:50

标签: android notifications commonsware-cwac

我为测试模式设置了1分钟的AlarmManager。它向OnAlarmReceiver发送广播。 OnAlarmReceiver启动sendWakefulWork(context,TaskService);并且在doWakefulWork()方法的TaskService中,我发送了一个fireOrderedBroadcast来激活通知。 这很好用^通知声音和振动出现。但只有当手机处于活动模式时。当手机处于睡眠模式(屏幕关闭)时,通知期间仅振动和闪光工作。在睡眠模式下通知没有声音,只有振动。有时它会发出声音,但有时只会发出声音,例如每小时发出1声,但它应该每分钟发出声音。当手机连接到计算机时,它也会在睡眠模式下每分钟发出声音但是当我从计算机上拔下手机时,它只会振动。当我打开屏幕时,一切都变得正常:通知播放声音+振动。

所以我不知道我的代码或手机是否有问题(HTC Desire Android 2.2)

我已经尝试了很多东西来解决它:

  • 默认和自定义声音
  • notification.audioStreamType = AudioManager.STREAM_SYSTEM和其他
  • 带闪光灯且无闪光灯
  • 振动且无振动

无。只有声音在睡眠模式下消失,振动才能完美。

public class OnBootReceiver extends BroadcastReceiver {

public static void setAlarm(Context ctxt) {

           AlarmManager mgr = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
   mgr.setRepeating(AlarmManager.RTC_WAKEUP,
           System.currentTimeMillis()+1000,
           1*60*1000,
           getPendingIntent(ctxt));
}

public static void cancelAlarm(Context ctxt) {
   AlarmManager mgr = (AlarmManager) ctxt.getSystemService(Context.ALARM_SERVICE);
   mgr.cancel(getPendingIntent(ctxt));
}

private static PendingIntent getPendingIntent(Context ctxt) {
   Intent i=new Intent(ctxt, OnAlarmReceiver.class);
   return PendingIntent.getBroadcast(ctxt, 0, i, PendingIntent.FLAG_CANCEL_CURRENT);
}

@Override
public void onReceive(Context ctxt, Intent intent) {
   setAlarm(ctxt);
}
}

我在TaskService类中的doWakefulWork方法:

protected void doWakefulWork(Intent intent) {
Intent mIntent = new Intent(EXERCISE_EVENT);
   mIntent.putExtra(StringUtils.PARAM_NEXT_TASK_TIME, nextStringTime);
   mIntent.putExtra(StringUtils.PARAM_TASK_NUMBER, taskNumber);

   sendOrderedBroadcast(mIntent, null);
}

这是我的NotificationBrodcastReceiver:

public class NotificationBrodcastReceiver extends android.content.BroadcastReceiver {

public void onReceive(Context ctx, Intent intent) {

           String ns = Context.NOTIFICATION_SERVICE;
           NotificationManager mNotificationManager = (NotificationManager) ctx.getSystemService(ns);

           int icon = R.drawable.notif_icon;
           CharSequence tickerText = ctx.getResources().getString(R.string.notification_ticker);
           long when = System.currentTimeMillis();

           Notification notification = new Notification(icon, tickerText, when);
           notification.flags |= Notification.FLAG_AUTO_CANCEL;

           notification.defaults |= Notification.DEFAULT_SOUND;
           notification.defaults |= Notification.DEFAULT_VIBRATE;

           Intent notificationIntent = new Intent(ctx, MainActivity.class);
           PendingIntent contentIntent = PendingIntent.getActivity(ctx, 0, notificationIntent, 0);
           notification.setLatestEventInfo(ctx, "contentTitle", "contentText", contentIntent);
           mNotificationManager.notify(NOTIFICATION_ID, notification);
}
}

1 个答案:

答案 0 :(得分:2)

您正在使用有序广播来举起Notification。据推测,您这样做是因为如果活动位于前台并且此广播具有更高优先级BroadcastReceiver,您希望活动处理请求。

这种模式适用于非故障情况。但是,一旦doWakefulWork()结束,没有任何东西可以让设备保持唤醒状态,因此设备会重新入睡。您订购的Broadcast异步发生,因此其工作将在doWakefulWork()结束后发生,因此您的Notification可能根本不会发生。如果Notification部分正在发生,正如您所描述的那样,我个人认为这种行为是Android中的一个错误(它应该保留自己的WakeLock以播放铃声),但它完全有可能你的BroadcastReceiver根本无法控制,因为设备在广播传送之前就已经睡着了。

你持有 - { - 1}} - 两秒钟的解决方法会增加成功几率,但这也无法保证。确保您有机会提升WakeLock的唯一有保证的方法是:

  1. Notification

  2. 内完成这项工作
  3. 按住doWakefulWork()直到广播完成并且WakeLock被提升。

  4. 我将来会在Notification框架中添加其他功能来更好地处理您的场景,因为您似乎想要做的是合理的,并且有一个共同的实现图案。但是,您要做的事情肯定超出WakefulIntentService的当前范围。