【问题标题】:Unable to send periodic local notifications with WorkManager after app is killed应用程序被杀死后无法使用 WorkManager 定期发送本地通知
【发布时间】:2020-04-17 21:30:12
【问题描述】:

我遇到了一个浪费我时间的问题。
我正在使用本地 SQLite 数据库构建应用程序。例如,我希望这个应用程序每 15 分钟向用户发送一次通知,其中包含来自 SQLite 数据库的一些数据。我已经成功实现了这一点只要应用程序正在运行或没有被杀死但是,当应用程序被杀死时,通知不再向用户显示。我正在两台真实设备上测试应用程序三星和华为
这是扩展 Worker 的通知程序类的代码:-

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


在主要活动中,我使用以前的通知器每 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);
    }


当我更改通知程序类代码以显示没有任何值的日志消息时,logcat 中工作人员的结果为Success

Log.d(TAG,"Work Manager is working");

如果我更改通知程序类代码以显示带有光标值的日志消息或显示硬编码通知,则它不起作用并且工作人员的结果是Retry

【问题讨论】:

  • "它不起作用并且工作人员的结果是重试" - 然后记录您正在捕获的Throwable。如果您记录它,您将看到一个堆栈跟踪,其中包含导致您进入该 catch 块并返回 Result.retry() 的任何原因。
  • 我正在处理它,一旦它出现在日志中,我会展示给你的
  • @CommonsWare 这里是可抛出的消息:-`Workerjava.lang.NullPointerException:尝试在 null 上调用虚拟方法 'android.content.pm.ApplicationInfo android.content.Context.getApplicationInfo()'对象引用`

标签: android notifications android-sqlite android-workmanager


【解决方案1】:

至少从这个类中删除所有对MainActivity.mcontext 的引用。更好的办法是从应用程序中完全删除 mcontext,因为这是内存泄漏。

Your Worker constructor 被传递一个Context。在某个字段中保留它,然后使用您的 doWork() 方法中的 Context

【讨论】:

  • 你知道它每 15 分钟运行一次,所以一旦我完成测试,我会告诉你结果。非常感谢。
  • 非常感谢。我真的很感谢你的帮助。它终于奏效了。再次感谢:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-12-20
  • 1970-01-01
  • 1970-01-01
  • 2015-07-08
  • 1970-01-01
相关资源
最近更新 更多