我很抱歉提出一个常见问题, 但我做了很多研究,仍然无法找到解决方案。
我也做了一个Android测试,我设置我的服务即将被触发,但下面的代码在我的两部手机上完全不同。
其中一个7.0安卓版本永远不会工作,甚至服务从未被触发。如果我将触发时间设置为System.currentTimeMillis()
,则5.0版本的另一个成功工作,但它在当前时间之后的任何时间都不起作用(例如System.currentTimeMillis() + 2000
)。如果通知成功发送,那么它会在很短的时间内消失。
这是我的android测试方法。
@Test
public void setAlarm(){
Context context = InstrumentationRegistry.getTargetContext();
Intent intent = new Intent(context, MedicationNotificationService.class);
PendingIntent sender = PendingIntent.getService(context, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager am = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
am.setExact(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() , sender);
}
然后是我的详细服务代码。 MedicationNotification只是一个包含触发时间的POJO。 该服务发送通知并设置下一个警报。
public class MedicationNotificationService extends Service {
private static final String TAG = "MedicationNfService";
public MedicationNotificationService() {}
@Override
public IBinder onBind(Intent intent) {return null;}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
MedicationNotification notification = (MedicationNotification) intent.getSerializableExtra(NOTIFICATION);
Log.d(TAG, "Service started. notification: " + notification);
NotificationUtils.showNotification(this, getString(R.string.itsTimeToMedicate),
notification.getMedication().getName(), notification.getId());
if (notification.getMedication().getEndDate().after(new Date())) //set next notification if not expired
{
AlarmManagerUtils.arrangeMedicationNotification(this, notification);
Log.d(TAG, "Medication does not expire, set the next alarm.");
}
else
Log.d(TAG, "Medication expired, delete it.");
return START_STICKY;
}
}
我也确保我没有拼错服务的名字。
<service
android:name=".android.MedicationNotificationService">
</service>
最后,这是AlarmManager代码。它和我在测试方法中的做法一样。 PendingIndent的ID取决于MedicationNotification的id。并设置确切的时间。
public class AlarmManagerUtils {
public static void arrangeMedicationNotification(Context context, MedicationNotification notification){
AlarmManager alarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
if (alarmManager != null)
{
Intent alarmIntent = new Intent(context, MedicationNotificationService.class);
alarmIntent.putExtra(NOTIFICATION, notification);
PendingIntent pendingIntent = PendingIntent.getService(context, 50000 + notification.getId(),
alarmIntent, PendingIntent.FLAG_UPDATE_CURRENT);
alarmManager.setExact(AlarmManager.RTC_WAKEUP, notification.getNotifyTime().getTimeInMillis(), pendingIntent);
}
}
}
感谢您的耐心等待,告诉我您是否需要更多信息,我真的花了几个小时来解决这个问题。这真的很奇怪,它曾用于我的另一个项目。谢谢。
用于在代码下方设置警报
if (SDK_INT < Build.VERSION_CODES.KITKAT) {
alarmManager.set(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
else if (Build.VERSION_CODES.KITKAT <= SDK_INT && SDK_INT < Build.VERSION_CODES.M) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
else if (SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, c.getTimeInMillis(), pendingIntent);
}
通知notify
方法后添加以下行
PowerManager pm = (PowerManager) context
.getSystemService(Context.POWER_SERVICE);
boolean isScreenOn ;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT_WATCH) {
isScreenOn = pm.isInteractive();
}else {
isScreenOn=pm.isScreenOn();
}
if (!isScreenOn) {
PowerManager.WakeLock wl = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK
| PowerManager.ACQUIRE_CAUSES_WAKEUP
| PowerManager.ON_AFTER_RELEASE, "MyLock");
wl.acquire(10000);
PowerManager.WakeLock wl_cpu = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,
"MyCpuLock");
wl_cpu.acquire(10000);
}
并在清单上添加此权限
<uses-permission android:name="android.permission.WAKE_LOCK" />