gpt4 book ai didi

android - 通过 AlarmManager 和 BroadcastReceiver 发送通知不起作用?

转载 作者:塔克拉玛干 更新时间:2023-11-03 01:10:51 24 4
gpt4 key购买 nike

我提前 5 天安排了一个通知,所以我使用 AlarmManager 创建了一个警报,它会触发一个 PendingIntent,它会触发我的 BroadcastReceiver。

如果我尝试该代码 10 秒钟,它就会起作用。当我尝试 5 天时,没有任何反应。

NotificationScheduler 类是用于设置和更新警报的辅助类。

开火日期是正确的,因为我将它们存储在数据库中,并且我已经对其进行了校对。

list :

<receiver android:name=".reminder.ReminderReceiver" />

通知调度器:

class NotificationScheduler {

companion object {

const val NOTIFICATION_EXTRA_CLAIM_ID = "notification_extra_bookentry_id"

const val INTENT_ACTION_REMINDER = "at.guger.moneybook.reminder"

fun setReminder(context: Context, bookEntryId: Long, fireDate: Date? = null) {
val mCalendar = Calendar.getInstance()

val lFireDate = if (fireDate == null) {
mCalendar.timeInMillis += 5 * 24 * 3600 * 1000
mCalendar.set(Calendar.HOUR_OF_DAY, 12)

mCalendar.time
} else {
fireDate
}

create(context, bookEntryId, lFireDate.time)

AppDatabase.getInstance(context).reminderDao().insert(Reminder(bookEntryId, lFireDate))
}

fun updateReminder(context: Context, bookEntryId: Long) {
cancel(context, bookEntryId)

val mCalendar = Calendar.getInstance()
mCalendar.timeInMillis += 5 * 24 * 3600 * 1000
mCalendar.set(Calendar.HOUR_OF_DAY, 12)

create(context, bookEntryId, mCalendar.timeInMillis)

AppDatabase.getInstance(context).reminderDao().update(Reminder(bookEntryId, mCalendar.time))
}

fun cancelReminder(context: Context, bookEntryId: Long) {
cancel(context, bookEntryId)

AppDatabase.getInstance(context).reminderDao().delete(Reminder(bookEntryId))
}

private fun create(context: Context, bookEntryId: Long, fireDate: Long) {
val mAlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

val mComponentName = ComponentName(context, ReminderReceiver::class.java)
context.packageManager.setComponentEnabledSetting(mComponentName, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP)

val mIntent = Intent(context, ReminderReceiver::class.java)
mIntent.action = INTENT_ACTION_REMINDER
mIntent.putExtra(NOTIFICATION_EXTRA_CLAIM_ID, bookEntryId)

val mPendingIntent = PendingIntent.getBroadcast(context, bookEntryId.toInt(), mIntent, PendingIntent.FLAG_UPDATE_CURRENT)

if (Utils.isKitKat()) {
mAlarmManager.setWindow(AlarmManager.RTC, fireDate, AlarmManager.INTERVAL_HOUR, mPendingIntent)
} else {
mAlarmManager.set(AlarmManager.RTC, fireDate, mPendingIntent)
}
}

private fun cancel(context: Context, bookEntryId: Long) {
val mAlarmManager: AlarmManager = context.getSystemService(Context.ALARM_SERVICE) as AlarmManager

val mComponentName = ComponentName(context, ReminderReceiver::class.java)
context.packageManager.setComponentEnabledSetting(mComponentName, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP)

val mIntent = Intent(context, ReminderReceiver::class.java)
mIntent.putExtra(NOTIFICATION_EXTRA_CLAIM_ID, bookEntryId)

val mPendingIntent = PendingIntent.getBroadcast(context, bookEntryId.toInt(), mIntent, PendingIntent.FLAG_UPDATE_CURRENT)

mAlarmManager.cancel(mPendingIntent)
mPendingIntent.cancel()
}
}
}

广播接收者:

class ReminderReceiver : BroadcastReceiver() {

override fun onReceive(context: Context?, intent: Intent?) {
if (context != null && intent != null) {
when (intent.action) {
NotificationScheduler.INTENT_ACTION_REMINDER -> {
val mPowerManager = context.getSystemService(Context.POWER_SERVICE) as PowerManager
val mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, this::class.simpleName)

mWakeLock.acquire(WAKELOCK_TIME)

val iClaimEntryId = intent.getLongExtra(NotificationScheduler.NOTIFICATION_EXTRA_CLAIM_ID, -1)

showNotification(context, iClaimEntryId)
AppDatabase.getInstance(context).reminderDao().delete(Reminder(iClaimEntryId))

mWakeLock.release()
}
}
}
}

private fun showNotification(context: Context, claimEntryId: Long) {
val mNotificationManager: NotificationManager = context.getSystemService(Context.NOTIFICATION_SERVICE) as NotificationManager

val nBuilder: Notification.Builder

if (Utils.isOreo()) {
val mNotificationChannel = NotificationChannel(NOTIFICATIONCHANNEL_CLAIMREMINDERID, context.getString(R.string.notificationchannel_claimreminder_title), NotificationManager.IMPORTANCE_DEFAULT)
mNotificationChannel.description = context.getString(R.string.notificationchannel_claimreminder_description)

mNotificationManager.createNotificationChannel(mNotificationChannel)

nBuilder = Notification.Builder(context, NOTIFICATIONCHANNEL_CLAIMREMINDERID)
} else {
nBuilder = Notification.Builder(context)
}

val mClaimEntry: BookEntry = AppDatabase.getInstance(context).bookEntryDao().get(claimEntryId)

val mCurrencyFormatter = DecimalFormat.getCurrencyInstance(Preferences.getInstance(context).currency.locale)

nBuilder.setSmallIcon(R.drawable.ic_money)
nBuilder.setContentTitle(context.getString(R.string.notification_claimreminder_title, mCurrencyFormatter.format(mClaimEntry.dValue)))
val sContacts = mClaimEntry.getContacts(context).joinToString().takeIf { it.isNotEmpty() }
?: "-"
nBuilder.setContentText(context.getString(R.string.notification_claimreminder_content, sContacts))
nBuilder.setContentIntent(PendingIntent.getActivity(context, 0, Intent(context, MainActivity::class.java), PendingIntent.FLAG_UPDATE_CURRENT))
nBuilder.setAutoCancel(true)

mNotificationManager.notify(mClaimEntry.lId!!.toInt(), nBuilder.build())
}

companion object {
const val NOTIFICATIONCHANNEL_CLAIMREMINDERID = "notification_channel_claimreminder"

const val WAKELOCK_TIME: Long = 1000
}
}

最佳答案

我在使用 AlarmManager 时遇到了问题,所以我现在正在使用 WorkManager。

WorkManager是随 Android Jetpack/Architecture Components 引入的。

解决方案

  • 首先添加WorkManager的依赖,可以找到最新版本here .
  • 创建一个Worker 类,以及在doWork() 中显示通知的代码。

  • 在您的应用启动时安排这项工作,同时检查是否尚未安排。为了方便起见,我已经在下面的类中创建了一个名为 isWorkScheduled() 的方法。

  • 您可以通过 setInputData() 向您的任务发送额外的数据(如 putExtra()) .

  • 在第一个 Activity onCreate() 或应用程序类 onCreate 中安排您的一次性任务。

例子

public static final String TAG_WORK = "myTag";
if(!MyWork.isWorkScheduled(TAG_WORK))
MyWork.scheduleOneTimeTask(TAG_WORK, 5, TimeUnit.DAYS)

MyWork.java

public class MyWork extends Worker {
public static void scheduleOneTimeTask(String tag, long duration, TimeUnit timeUnit) {
OneTimeWorkRequest compressionWork =
new OneTimeWorkRequest.Builder(MyWork.class).setInitialDelay(duration, timeUnit).addTag(tag)
.build();
WorkManager instance = WorkManager.getInstance();
if (instance != null) {
instance.enqueue(compressionWork);
}
}

private boolean isWorkScheduled(String tag) {
WorkManager instance = WorkManager.getInstance();
if (instance == null) return false;
LiveData<List<WorkStatus>> statuses = instance.getStatusesByTag(tag);
if (statuses.getValue() == null) return false;
boolean running = false;
for (WorkStatus workStatus : statuses.getValue()) {
running = workStatus.getState() == State.RUNNING | workStatus.getState() == State.ENQUEUED;
}
return running;
}

@NonNull
@Override
public Result doWork() {
// show notification
return Result.SUCCESS;
// (Returning RETRY tells WorkManager to try this task again
// later; FAILURE says not to try again.)
}
}

I suggested you WorkManger only, because I created a sample earlier days with JobScheduler, EvernoteJobs, AlarmManager, JobService, and WorkManager. In which I started periodic task of 15 minutes with each of these. and wrote logs of each in separate file when invoked.

Conclusion of this test was that. WorkManager and EvernoteJobs were most efficient to do jobs. Now because EvernoteJobs will use WorkManager from next version. So I came up with WorkManager.

更新

调度周期性任务的最短时间为 15 分钟,因此请记住。您可以在 documentation. 中阅读更多内容

关于android - 通过 AlarmManager 和 BroadcastReceiver 发送通知不起作用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52017035/

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