应用程序被终止后无法使用 WorkManager 定期发送本地通知
Unable to send periodic local notifications with WorkManager after app is killed
我遇到了一个浪费我时间的问题。
我正在使用本地 SQLite
数据库构建应用程序。例如,我希望此应用每 15 分钟向用户发送一次通知,其中包含 SQLite
数据库中的一些数据。我已经成功地实现了这个 只要应用程序 运行 或没有被杀死 但是,当应用程序被杀死时,通知不再出现在用户面前。我正在两个真实设备 Samsung 和 Huawei 上测试该应用程序。
这是扩展 Worker
的通知程序 class 的代码:-
public Result doWork() {
try {
SqliteAssetHelper dbHelper = new SqliteAssetHelper(MainActivity.mcontext);
mdatabase = dbHelper.getWritableDatabase();
Cursor mCursor = mdatabase.query(BDH.BDHEntry.TABLE_NAME,
new String[]{BDH.BDHEntry.COLUMN_HADITH_ID,BDH.BDHEntry.COLUMN_BOOK_NAME,
BDH.BDHEntry.COLUMN_DOOR_NAME, BDH.BDHEntry.COLUMN_NARRATORS, BDH.BDHEntry.COLUMN_CONTEXT},
BDH.BDHEntry.COLUMN_BOOK_ID+"=?",new String[]{"1"},null,null, "RANDOM() LIMIT 1");
if (mCursor != null) {
mCursor.moveToFirst();
if (mCursor.getCount() > 0) {
while (mCursor.isAfterLast() == false) { //You need to check if cursor doesnot contain last row
hadithID = mCursor.getString(mCursor.getColumnIndex("HadithID"));
book = mCursor.getString(mCursor.getColumnIndex("BookName"));
door = mCursor.getString(mCursor.getColumnIndex("DoorName"));
mCursor.moveToNext();
}
}
}
Intent intentActivity = new Intent(MainActivity.mcontext, HadithActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intentActivity.putExtra("id", hadithID );
PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.mcontext, 0, intentActivity, PendingIntent.FLAG_UPDATE_CURRENT);
notificationManager = NotificationManagerCompat.from(MainActivity.mcontext);
Notification notification = new NotificationCompat.Builder(MainActivity.mcontext,CHANNEL_ID)
.setSmallIcon(R.drawable.book)
.setContentTitle(book)
.setContentText(door)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(contentIntent)
.build();
notificationManager.notify(notificationID, notification);
return Result.success();
}
catch (Throwable throwable)
{
return Result.retry();
}
}
在主要 Activity 中,我使用以前的通知程序每 15 分钟出现一次:-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mcontext = this;
//creating constraints
Constraints constraints = new Constraints.Builder()
.setTriggerContentMaxDelay(1, TimeUnit.MINUTES)
.build();
PeriodicWorkRequest showHadithEveryHour = new PeriodicWorkRequest.Builder(HadithNotifier.class, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build();
WorkManager.getInstance(this).enqueue(showHadithEveryHour);
}
当我更改通知程序 class 代码以显示没有任何值的日志消息时 logcat 中工作人员的结果是 Success
Log.d(TAG,"Work Manager is working");
如果我更改通知程序 class 代码以显示带有游标值的日志消息或显示硬编码通知,则它不起作用,工作人员的结果为 Retry
。
至少从 class 中删除对 MainActivity.mcontext
的所有引用。更好的办法是从应用程序中完全删除 mcontext
,因为这是内存泄漏。
Your Worker
constructor 传递了 Context
。在字段中保留它,然后使用 doWork()
方法中的 Context
。
我遇到了一个浪费我时间的问题。
我正在使用本地 SQLite
数据库构建应用程序。例如,我希望此应用每 15 分钟向用户发送一次通知,其中包含 SQLite
数据库中的一些数据。我已经成功地实现了这个 只要应用程序 运行 或没有被杀死 但是,当应用程序被杀死时,通知不再出现在用户面前。我正在两个真实设备 Samsung 和 Huawei 上测试该应用程序。
这是扩展 Worker
的通知程序 class 的代码:-
public Result doWork() {
try {
SqliteAssetHelper dbHelper = new SqliteAssetHelper(MainActivity.mcontext);
mdatabase = dbHelper.getWritableDatabase();
Cursor mCursor = mdatabase.query(BDH.BDHEntry.TABLE_NAME,
new String[]{BDH.BDHEntry.COLUMN_HADITH_ID,BDH.BDHEntry.COLUMN_BOOK_NAME,
BDH.BDHEntry.COLUMN_DOOR_NAME, BDH.BDHEntry.COLUMN_NARRATORS, BDH.BDHEntry.COLUMN_CONTEXT},
BDH.BDHEntry.COLUMN_BOOK_ID+"=?",new String[]{"1"},null,null, "RANDOM() LIMIT 1");
if (mCursor != null) {
mCursor.moveToFirst();
if (mCursor.getCount() > 0) {
while (mCursor.isAfterLast() == false) { //You need to check if cursor doesnot contain last row
hadithID = mCursor.getString(mCursor.getColumnIndex("HadithID"));
book = mCursor.getString(mCursor.getColumnIndex("BookName"));
door = mCursor.getString(mCursor.getColumnIndex("DoorName"));
mCursor.moveToNext();
}
}
}
Intent intentActivity = new Intent(MainActivity.mcontext, HadithActivity.class)
.addFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
intentActivity.putExtra("id", hadithID );
PendingIntent contentIntent = PendingIntent.getActivity(MainActivity.mcontext, 0, intentActivity, PendingIntent.FLAG_UPDATE_CURRENT);
notificationManager = NotificationManagerCompat.from(MainActivity.mcontext);
Notification notification = new NotificationCompat.Builder(MainActivity.mcontext,CHANNEL_ID)
.setSmallIcon(R.drawable.book)
.setContentTitle(book)
.setContentText(door)
.setPriority(NotificationCompat.PRIORITY_HIGH)
.setAutoCancel(true)
.setCategory(NotificationCompat.CATEGORY_CALL)
.setContentIntent(contentIntent)
.build();
notificationManager.notify(notificationID, notification);
return Result.success();
}
catch (Throwable throwable)
{
return Result.retry();
}
}
在主要 Activity 中,我使用以前的通知程序每 15 分钟出现一次:-
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mcontext = this;
//creating constraints
Constraints constraints = new Constraints.Builder()
.setTriggerContentMaxDelay(1, TimeUnit.MINUTES)
.build();
PeriodicWorkRequest showHadithEveryHour = new PeriodicWorkRequest.Builder(HadithNotifier.class, 15, TimeUnit.MINUTES)
.setConstraints(constraints)
.build();
WorkManager.getInstance(this).enqueue(showHadithEveryHour);
}
当我更改通知程序 class 代码以显示没有任何值的日志消息时 logcat 中工作人员的结果是 Success
Log.d(TAG,"Work Manager is working");
Retry
。
至少从 class 中删除对 MainActivity.mcontext
的所有引用。更好的办法是从应用程序中完全删除 mcontext
,因为这是内存泄漏。
Your Worker
constructor 传递了 Context
。在字段中保留它,然后使用 doWork()
方法中的 Context
。