Невозможно запустить приемник, приложение находится в фоновом режиме. AlarmReceiver для оповещения о пожаре - PullRequest
0 голосов
/ 26 января 2020

В моем приложении я использую AlarmManager, чтобы запустить IntentService, который обращается к внутренней базе данных котировок и выбирает один случайным образом, а затем генерирует уведомление с этой цитатой.

Он отлично работает на моем телефоне, который Android 9, OnePlus6. Но я получаю много данных о сбоях от других пользователей, заявляющих:

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 для go выключен в 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);
    }
}

IntentService для запроса внутренней базы данных SQLite и уведомления о пожаре

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

Ответы [ 2 ]

0 голосов
/ 26 января 2020

в 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());
 }
0 голосов
/ 26 января 2020

вы не можете запустить службу в фоновом режиме в android 8 или выше.

context.startService(serviceIntent);

Вы можете запустить службу как startForegroundService () .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...