1

我已经为测试模式设置了 1 分钟的 AlarmManager。它向 OnAlarmReceiver 发送广播。OnAlarmReceiver 启动 sendWakefulWork(context, TaskService); 在 doWakefulWork() 方法中的 TaskService 中,我发送了触发通知的OrderedBroadcast。这很好用^出现带有声音和振动的通知。但仅当手机处于活动模式时。当手机处于睡眠模式(屏幕关闭)时,通知期间只有振动和闪光工作。睡眠模式下没有通知声音,只有振动。有时它会发出声音,但只是有时会发出声音,例如每小时发出 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);
}
}
4

1 回答 1

2

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

这种模式适用于非清醒情况。然而,一旦doWakefulWork()结束,没有什么可以让设备保持清醒,因此设备会重新进入睡眠状态。您的命令Broadcast是异步发生的,因此它的工作将在doWakefulWork()结束后发生,因此您Notification可能根本不会发生。如果Notification部分发生,正如您所描述的,我个人认为这种行为是 Android 中的一个错误(它应该拥有自己的WakeLock用于播放铃声的目的),但完全有可能您BroadcastReceiver根本无法控制完全没有,因为设备在广播发送之前就睡着了。

保持WakeLock两秒钟的解决方法会增加成功的几率,但这也不能保证。确保您有机会筹集到的唯一有保证的方法Notification是:

  1. doWakefulWork(), 或

  2. 保持 aWakeLock直到广播完成并Notification引发。

我会考虑WakefulIntentService在未来为框架添加额外的特性来更好地处理你的场景,因为你想要做的似乎是合理的,并且有一个通用的模式实现会很好。但是,您正在尝试做的事情绝对超出了当前所做的事情的范围WakefulIntentService

于 2012-07-14T10:13:18.520 回答