gpt4 book ai didi

Android 每日闹钟过于频繁或仅触发一次

转载 作者:行者123 更新时间:2023-11-29 14:50:02 26 4
gpt4 key购买 nike

我正在尝试在我的 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);

然后是这个 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);
}

}

这在 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();
}
}

但是,正如我所说,人们报告说这每十分钟左右就会触发一次!因此,我尝试将 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;
}

由于我无法在我的设备上重现原始问题,因此很难测试!我的两个理论是:

  1. 问题出在 AlarmReceiver 上,好像它不应该启动一个全新的服务,而是对现有服务做一些事情
  2. 我不应该费心排除 null intent我的值 onStartCommand功能

我只是有点紧张尝试第 2 种方法,以防它会导致人们的设备再次惹恼他们!

最佳答案

Here's how the alarm is enabled

请注意,即使您正在使用 setRepeating(),一旦您将 android:targetSdkVersion 提高到 19 或更高版本,这在 Android 4.4+ 上将是不准确的。

Then there's this AlarmReceiver class

如果使用 _WAKEUP 样式的警报,那将是不可靠的。设备很可能在 startService() 调用和您的服务实际有机会做某事之间进入休眠状态。请use WakefulBroadcastReceivermy WakefulIntentService对于 _WAKEUP 样式的警报,如果您要使用委托(delegate)到服务模式。

but in the process now people are saying it only fires once per day!

既然这就是你想要的,我会认为这是一件好事。

I replaced onStart with this:

我不知道您为什么使用 Service 而不是 IntentService。无论如何,请在 onStartCommand() 方法底部调用 stopSelf(),这样服务就会消失。一旦这项工作完成,就没有理由让这项服务继续运行。此外,将 START_STICKY 替换为 START_NOT_STICKY

而且,如果这就是您打算在服务中完成的所有工作,您可以完全转储该服务并将您的 onStartCommand() 内容移动到 onReceive() BroadcastReceiver

将工作从接收者委托(delegate)给服务的模式用于当工作将花费太长时间以冒占用主应用程序线程的风险时(例如,>1ms)......但是你的服务需要一个后台线程,它你的缺乏。由于我希望您的代码的执行时间少于 1 毫秒,您可以在 onReceive() 中执行此操作并简化您的应用程序,您将不再需要单独的 Service,也不是我之前提到的任何 Wakeful* 内容。

The problem lies in AlarmReceiver, like it ought to not be starting up a brand new service but doing something with the existing service

如果它每天只运行一次,那么最好不要有“现有服务”。您无需运行进程占用系统 RAM,只需等待时钟滴答作响。

I shouldn't bother excluding null intent values in my onStartCommand function

如果满足以下条件,您将获得一个null Intent:

  • 您的进程在服务为 startService() 调用完成 onStartCommand() 之前终止,并且

  • 您的服务之前已成功运行 onStartCommand() 并返回 START_STICKY

I'm more and more wondering why my AlarmReceiver creates a service, rather than just showing the notification directly.

同意。如果您计划进行更多工作,涉及磁盘或网络 I/O,然后使用 IntentService(后台线程,服务会自动停止)。否则,我会把它放在 onReceive() 中并称它为好。

关于Android 每日闹钟过于频繁或仅触发一次,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21315543/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com