无法启动接收器,应用程序在后台。 AlarmReceiver触发通知

问题描述 投票:0回答:2

在我的应用程序中,我使用AlarmManager启动IntentService,该服务访问报价的内部数据库并随机选择一个报价,然后使用该报价触发通知。

它在我的Android 9,OnePlus6手机上正常运行。但是我从其他用户那里收到了很多crashlytics数据,说明:

Fatal Exception: java.lang.RuntimeException: Unable to start receiver com.myapp.receiver.AlarmReceiver: java.lang.IllegalStateException: Not allowed to start service Intent { cmp=com.myapp/.service.NotificationQuoteService }: app is in background uid UidRecord{e3c2e3d u0a203 TRNB idle procs:1 proclist:23491, seq(0,0,0)}
       at android.app.ActivityThread.handleReceiver(ActivityThread.java:3606)
       at android.app.ActivityThread.access$1300(ActivityThread.java:237)
       at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1796)
       at android.os.Handler.dispatchMessage(Handler.java:106)
       at android.os.Looper.loop(Looper.java:214)
       at android.app.ActivityThread.main(ActivityThread.java:7045)
       at java.lang.reflect.Method.invoke(Method.java)
       at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:493)
       at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:964)

我想,这是由于Oreo的限制所致,每个后台任务都应通过前台通知来通知自己。但是,显示前台通知以查询报价然后显示报价通知是不是很荒谬?有很多应用程序在做类似的事情,它们查询内部数据并在通知中显示它,而在查询数据时不显示任何前台通知。

我将如何做,有人能指出我正确的方向吗?

添加了编辑代码:

AlarmManager在上午9点起飞。在早上。

    private void prepareAlarmManager() {

        Intent intent = new Intent(context, AlarmReceiver.class);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context, AlarmReceiver.REQUEST_CODE, intent, PendingIntent.FLAG_UPDATE_CURRENT);

        AlarmManager alarmManager = (AlarmManager) getSystemService(ALARM_SERVICE);
        if (alarmManager != null) {

            Calendar calendar = Calendar.getInstance();
            calendar.setTimeInMillis(System.currentTimeMillis());
            calendar.set(Calendar.HOUR_OF_DAY, 9);
            calendar.set(Calendar.MINUTE, 0);
            calendar.set(Calendar.SECOND, 0);

            alarmManager.setRepeating(AlarmManager.RTC_WAKEUP, calendar.getTimeInMillis(), 24 * 60 * 60 * 1000, pendingIntent);
        }
    }

BroadcastReceiver处理AlarmManager

public class AlarmReceiver extends BroadcastReceiver {

    public static final int REQUEST_CODE = 10;

    @Override
    public void onReceive(Context context, Intent intent) {
        Intent serviceIntent = new Intent(context, NotificationQuoteService.class);
        context.startService(serviceIntent);
    }
}

用于查询内部SQLite数据库和火灾通知的IntentService

public class NotificationQuoteService extends IntentService {

    private Context mContext;
    private DatabaseHelper mDatabaseHelper;

    public NotificationQuoteService() {
        super("quote service");
    }

    @Override
    public void onCreate() {
        super.onCreate();
        mContext = getApplicationContext();
        mDatabaseHelper = DatabaseHelper.getInstance(mContext);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        List<Quote> quoteList = mDatabaseHelper.getAllQuotes();
        int size = quoteList.size();
        int randomIndex = (int) (Math.random() * size);
        Quote quote = quoteList.get(randomIndex);
        NotificationHelper.showDefaultNotification(mContext, quote);
    }

    @Override
    public void onDestroy() {
        super.onDestroy();
        L.e("hop", "service is destroyed");
    }
}
android android-service android-notifications android-intentservice
2个回答
0
投票

您无法在Android 8或更高版本的后台启动服务。

context.startService(serviceIntent);

您可以以startForegroundService()身份启动服务。


0
投票

在onReceive()启动服务中:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
   context.startForegroundService(intent);
 } else {
  context.startService(intent); 
 }

并且在服务中onCreate()会产生类似的结果:

 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  startForeground(1, new Notification());
 }
© www.soinside.com 2019 - 2024. All rights reserved.