gpt4 book ai didi

java - 使用 JobScheduler 进行基于时间的通知

转载 作者:行者123 更新时间:2023-11-29 02:30:22 25 4
gpt4 key购买 nike

我需要在每天的同一时间向用户显示通知(基于用户选择的显示时间)。使用 API 25 及更早版本,我可以毫无问题地使用 AlarmManager。但是,对于 API 26 (Oreo),如果应用程序在后台运行超过几分钟,它会使我的应用程序崩溃。我所做的一切似乎都无法阻止 AlarmManager 在应用程序在后台运行大约一分钟后崩溃。

根据我在网上看到的内容,唯一的解决方案是使用 JobScheduler,但似乎并没有让 JobScheduler 在特定时间启动然后每天重复的方法。 (我可以通过调用 setOverrideDeadline 让它在特定时间运行,或者我可以通过调用 setPeriodic 让它重复运行,但同时调用 throws 和 exception。)

这是我的 JobScheduler 代码(我将它设置为每 15 秒重复一次以进行测试,但我也希望能够在特定时间启动它):

private void setReminders(){
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.RECEIVE_BOOT_COMPLETED) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.RECEIVE_BOOT_COMPLETED }, 613);
return;
}

SharedPreferences sharedPreferences = this.getSharedPreferences(getString(R.string.shared_pref_file_name), ContextWrapper.MODE_PRIVATE);
boolean showReminder = sharedPreferences.getBoolean(getString(R.string.shared_pref_reminder_active_key), false);
int hour = sharedPreferences.getInt(getString(R.string.shared_pref_reminder_hour_key), 21);
int minute = sharedPreferences.getInt(getString(R.string.shared_pref_reminder_minute_key), 0);

Calendar calendar = Calendar.getInstance();
calendar.set(Calendar.HOUR_OF_DAY, hour);
calendar.set(Calendar.MINUTE, minute);
calendar.set(Calendar.SECOND, 0);
long startUpTime = Calendar.getInstance().getTimeInMillis() + 10000; //calendar.getTimeInMillis() + 10000;

JobInfo.Builder builder = new JobInfo.Builder( 613, new ComponentName(getPackageName(), SefiraReminderJobService.class.getName()));
builder.setRequiredNetworkType(JobInfo.NETWORK_TYPE_NONE)
.setOverrideDeadline(15000)
.setRequiresDeviceIdle(false)
.setRequiresCharging(false)
.setPersisted(true);
builder.setPeriodic(Math.max(15000, JobInfo.getMinPeriodMillis()));
JobScheduler jobScheduler = (JobScheduler) getSystemService( Context.JOB_SCHEDULER_SERVICE );
if(jobScheduler.schedule(builder.build()) == JobScheduler.RESULT_FAILURE ) {
Log.w("MainActivity.setReminders", "Something went wrong when scheduling the reminders" );
}
}

这是我的 JobIntentService 类:

public final class ReminderJobService extends JobIntentService {

private NotificationManager notificationManager;
private PendingIntent pendingIntent;
private static int NOTIFICATION_ID = 1234;
private static String NOTIFICATION_CHANNEL_ID = "my-reminder-channel";
private Notification notification;

@Override
protected void onHandleWork(@NonNull Intent intent) {
Context context = this.getApplicationContext();
notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
Intent mIntent = new Intent(this, MainActivity.class);
pendingIntent = PendingIntent.getActivity(context, 0, mIntent, PendingIntent.FLAG_UPDATE_CURRENT);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
NotificationChannel notificationChannel = new NotificationChannel(NOTIFICATION_CHANNEL_ID, "My Reminders", NotificationManager.IMPORTANCE_DEFAULT);

// Configure the notification channel.
notificationChannel.setDescription("My Reminders");
notificationChannel.enableLights(true);
notificationChannel.setLightColor(Color.RED);
notificationChannel.setVibrationPattern(new long[]{0, 1000, 500, 1000});
notificationChannel.enableVibration(true);
notificationManager.createNotificationChannel(notificationChannel);
}


NotificationCompat.Builder builder = new NotificationCompat.Builder(this);
notification = new NotificationCompat.Builder(this, NOTIFICATION_CHANNEL_ID)
.setContentIntent(pendingIntent)
.setSmallIcon(R.drawable.ic_launcher_foreground)
//.setLargeIcon(BitmapFactory.decodeResource(res, R.drawable.ic_launcher))
//.setTicker("ticker value")
.setAutoCancel(true)
.setPriority(NotificationCompat.PRIORITY_DEFAULT)
.setSound(RingtoneManager.getDefaultUri(RingtoneManager.TYPE_ALARM))
.setContentTitle("Reminder")
.setContentText("Reminder Message").build();
notification.flags |= Notification.FLAG_AUTO_CANCEL | Notification.FLAG_SHOW_LIGHTS;
notification.defaults |= Notification.DEFAULT_SOUND | Notification.DEFAULT_VIBRATE;
notification.ledARGB = 0xFFFFA500;
notification.ledOnMS = 800;
notification.ledOffMS = 1000;
notificationManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
try {
notificationManager.notify(NOTIFICATION_ID, notification);
} catch (Exception ex){
ex.printStackTrace();
}
}
}

我的 AndroidManifest 包含以下内容:

<service android:name="ReminderJobService"
android:permission="android.permission.BIND_JOB_SERVICE"></service>

还有:

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />

即使应用程序处于后台,如何在 Android 26/8.0/Oreo 上每天的特定时间发送定期通知?

最佳答案

这个可行的决定,但逻辑已弃用:

public scheduleEvent(int id, long scheduleTime) {
final PendingIntent pendingIntent = pendingIntent(id);
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, scheduleTime, pendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarmManager.setExact(AlarmManager.RTC_WAKEUP, scheduleTime, pendingIntent);
} else {
alarmManager.set(AlarmManager.RTC_WAKEUP, scheduleTime, pendingIntent);
}

private PendingIntent pendingIntent(int id) {
final Intent intent = new Intent(app, EventReceiver.class);
intent.setAction("some event " + id);
return PendingIntent.getBroadcast(context, 10, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}

创建EventReceiver 不要忘记将它添加到AndroidManifest

public class EventReceiver extends WakefulBroadcastReceiver {
@Override
public void onReceive(final Context context, final Intent intent) {
final ComponentName comp = new ComponentName(context.getPackageName(), EventService.class.getName());
startWakefulService(context, intent.setComponent(comp));
}
}

创建EventService,同时添加到AndroidManifest

public class EventService extends IntentService {
@Override
protected void onHandleIntent(final Intent intent) {
//Your logic here
}
}

关于java - 使用 JobScheduler 进行基于时间的通知,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49848316/

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