and*_*ers 1 android alarmmanager
我正在尝试在我的Android应用中实现"每日提醒"功能,该功能应该在设定的时间每天触发一次.我试过的第一个实现适用于大多数人,但是一些用户(包括至少一个在三星的Android 4.3上运行的人)报告说警报更频繁地发射,例如每10分钟一次,每个他们打开应用程序的时间,并且通常非常讨厌.
以下是启用警报的方式:
Intent myIntent = new Intent(ctx, AlarmReceiver.class);
PendingIntent pendingIntent = PendingIntent.getBroadcast(ctx, 0, myIntent,0);
AlarmManager alarmManager = (AlarmManager)ctx.getSystemService(Service.ALARM_SERVICE);
alarmManager.cancel(pendingIntent);
alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, sched,
AlarmManager.INTERVAL_DAY,
pendingIntent);
Run Code Online (Sandbox Code Playgroud)
然后就是这个AlarmReceiver类:
public class AlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
Intent service1 = new Intent(context, AlarmService.class);
context.startService(service1);
}
}
Run Code Online (Sandbox Code Playgroud)
这在AndroidManifest中注册为接收者: <receiver android:name=".AlarmReceiver"/>
最后是AlarmService,过去看起来像这样:
public class AlarmService extends Service {
@Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
@Override
public void onCreate()
{
// TODO Auto-generated method stub
super.onCreate();
}
@SuppressWarnings("static-access")
@Override
public void onStart(Intent intent, int startId)
{
super.onStart(intent, startId);
Log.v("pm", "about to notify");
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
intent1.setAction(Intent.ACTION_MAIN);
intent1.addCategory(Intent.CATEGORY_LAUNCHER);
//intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity( this.getApplicationContext(),0, intent1,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this.getApplicationContext())
.setContentTitle("My App")
.setContentText("Don't forget that thing!")
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingNotificationIntent)
.getNotification();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
NotificationManager nManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nManager.notify(0, notification);
}
@Override
public void onDestroy()
{
// TODO Auto-generated method stub
super.onDestroy();
}
}
Run Code Online (Sandbox Code Playgroud)
但是,正如我所说的那样,人们报告说每十分钟左右就会发射一次!因此,我尝试将AlarmService更改为较少弃用的实现,但在此过程中,现在人们说它只会触发一次,然后再也不会!
我换成onStart了这个:
@Override
public int onStartCommand(Intent intent, int flags, int startId)
{
Log.v("pm", "about to notify");
if (intent != null) {
Intent intent1 = new Intent(this.getApplicationContext(), MainActivity.class);
intent1.setAction(Intent.ACTION_MAIN);
intent1.addCategory(Intent.CATEGORY_LAUNCHER);
//intent1.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP| Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingNotificationIntent = PendingIntent.getActivity( this.getApplicationContext(),0, intent1,PendingIntent.FLAG_UPDATE_CURRENT);
Notification notification = new Notification.Builder(this.getApplicationContext())
.setContentTitle("My App")
.setContentText("Don't forget that thing!")
.setSmallIcon(R.drawable.ic_launcher)
.setWhen(System.currentTimeMillis())
.setContentIntent(pendingNotificationIntent)
.getNotification();
notification.flags |= Notification.FLAG_AUTO_CANCEL;
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;
NotificationManager nManager =
(NotificationManager) getSystemService(NOTIFICATION_SERVICE);
nManager.notify(0, notification);
} else {
Log.v("pm", "Null Intent");
}
return START_STICKY;
}
Run Code Online (Sandbox Code Playgroud)
由于我无法在我的设备上重现原始问题,因此测试起来有点困难!我的两个理论是:
intent在我的onStartCommand函数中排除空值我只是有点紧张尝试2号,以防它导致人们的设备再次惹恼他们!
以下是警报的启用方式
请注意,即使您正在使用setRepeating(),一旦将您提高android:targetSdkVersion到19或更高,这将在Android 4.4+上不准确.
然后就是这个AlarmReceiver类
对于a- _WAKEUPalarm警报,这将是不可靠的.设备在startService()呼叫之间以及当您的服务实际上有机会执行某些操作时,可能会显而易见.如果您要使用委托到服务模式,请使用WakefulBroadcastReceiver或我的WakefulIntentService for- _WAKEUPstyle警报.
但在这个过程中,现在人们说它每天只发射一次!
既然这就是你想要的,我认为这是件好事.
我用这个替换了onStart:
我不知道为什么你使用的是Service代替IntentService.无论如何,请stopSelf()在onStartCommand()方法的底部打电话,这样服务就会消失.完成此工作后,此服务没有理由继续运行.另外,替换START_STICKY为START_NOT_STICKY.
而且,如果这是您打算在服务中完成的所有工作,您可以完全转储服务并将您的onStartCommand()内心转移到服务onReceive()中BroadcastReceiver.
当工作花费太长时间来冒险占用主应用程序线程(例如,> 1ms)时,使用从接收器委托工作到服务的模式......但是那时你的服务需要一个你没有的后台线程.由于我希望您的代码在执行时间不到1毫秒,您可以直接执行此操作onReceive()并简化您的应用程序,您将不再需要单独的Service,也不需要Wakeful*我之前提到的任何内容.
问题在于AlarmReceiver,就像它不应该启动一项全新的服务,而是使用现有服务做一些事情
如果这只每天运行一次,那么最好不要成为"现有服务".没有必要让你有一个正在运行的进程,占用系统RAM,只需等待时钟滴答.
我不应该在onStartCommand函数中排除null intent值
你会得到一个null Intentif:
你的过程完成服务之前终止onStartCommand()了startService()通话,并
您的服务已成功运行onStartCommand()并返回START_STICKY
我越来越想知道为什么我的AlarmReceiver会创建一个服务,而不是直接显示通知.
同意.如果你计划更多的工作,涉及磁盘或网络I/O,那么使用IntentService(后台线程,服务自动停止).否则,我只是把onReceive()它放进去并称之为好.
| 归档时间: |
|
| 查看次数: |
3293 次 |
| 最近记录: |