Alarm Service не работает на версиях андроид выше 7.1.2

224
02 августа 2021, 18:00

я пытаюсь сделать так чтобы после закрытия приложения свайпом из списка приложений, появлялись уведомления в заданное время. Я подправил манифест и сделал Alarm Service системным процессом чтобы он не удалялся после закрытия приложения

<service
        android:name=".Alarm.ReminderAlarmService"
        android:exported="true"
        android:process=":ServiceProcess"/>

И все отлично работает на версиях Android ниже 7.1 на версиях с ОС выше 7.1 данная хитрость не работает. Подскажите пожалуйста как решить данную проблему? Ниже прилагаю код из AlarmManagerProvider

private int updateReminder(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    if (values.size() == 0) {
        return 0;
    }
    SQLiteDatabase database = dbHelper.getWritableDatabase();
    int rowsUpdated = database.update(ConstantsDB.DB_TABLE_NAME, values, selection, selectionArgs);
    if (rowsUpdated != 0) {
        getContext().getContentResolver().notifyChange(uri, null);
    }
    return rowsUpdated;
}
static synchronized AlarmManager getAlarmManager(Context context) {
    if (sAlarmManager == null) {
        sAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
    }
    return sAlarmManager;
}

AlarmHelper

public class AlarmHelper {
public void setAlarm(Context context, long alarmTime, Uri uri) {
AlarmManager alarmManager = AlarmReminderProvider.getAlarmManager(context);
PendingIntent pendingIntent = ReminderAlarmService.getReminderPendingIntent(context, uri);
    if (Build.VERSION.SDK_INT >= 23) {
        alarmManager.setExactAndAllowWhileIdle(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
    } else if (Build.VERSION.SDK_INT >= 19) {
        alarmManager.setExact(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
    } else {
        alarmManager.set(AlarmManager.RTC_WAKEUP, alarmTime, pendingIntent);
    }
}

ReminderAlarmService

public class ReminderAlarmService extends IntentService {
    private static final String TAG = ReminderAlarmService.class.getSimpleName();
    private static final int NOTIFICATION_ID = 100;
    PendingIntent operation;
    NotificationManager notificationManager;
    static final String LOG_TAG = "myLog";

    // Это намерение с глубокими ссылками, для которого требуется стек задач
    public static PendingIntent getReminderPendingIntent(Context context, Uri uri) {
        Intent action = new Intent(context, ReminderAlarmService.class);
        action.setData(uri);
        return PendingIntent.getService(context, 0, action, PendingIntent.FLAG_UPDATE_CURRENT);
    }
    public ReminderAlarmService() {
        super(TAG);
    }

    @Override
    protected void onHandleIntent(@Nullable Intent intent) {
        notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        Uri uri = intent.getData();
        // Отображение уведомления для просмотра деталей задачи
        Intent action = new Intent(this, DetailsActivity.class);
        action.setData(uri);

        operation = TaskStackBuilder.create(this)
                .addNextIntentWithParentStack(action)
                .getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
        // Получить описание задачи
        Cursor cursor = getContentResolver().query(uri, null, null, null, null);

        String description = "";
       try {
            if (cursor != null && cursor.moveToFirst()) {
                description = ConstantsDB.getColumnString(cursor, ConstantsDB.KEY_NAME);
            }
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        Notification notification = new Notification.Builder(this)
                .setContentTitle(getString(R.string.app_name))
                .setContentText(description)
                .setSmallIcon(R.drawable.ic_notification)
                .setContentIntent(operation)
                .setVibrate(new long[]{1000, 1000, 1000, 1000, 1000})
                .setSound(Settings.System.DEFAULT_NOTIFICATION_URI)
                .setAutoCancel(true)
                .build();
        notificationManager.notify(NOTIFICATION_ID, notification);
    }
}

Буду признателен за любую помощь, ломаю голову уже целую неделю

Answer 1

Зачем все так сложно у вас? Схема такая: создаем приемник (BroadcastReceiver), при получении сигнала он будет посылать уведомление (Notification), а Alarm Manager уже в заданное время пошлет сигнал в приемник. Не забываем приемник указать в манифесте.

<receiver android:name=".AlarmBroadcastReceiver"/>
public class AlarmBroadcastReceiver extends BroadcastReceiver {
    @Override
    public void onReceive(Context context, Intent intent) {
        //посылаем уведомление здесь
    }
}
//в Alarm Manager помещаем следующий PendingIntent
PendingIntent.getBroadcast( context, 1, new Intent( context, AlarmBroadcastReceiver.class), 0);

Теперь про уведомление, начиная с 26 API нужно использовать каналы (NotificationChannel), иначе вы ничего не увидите.

Notification.Builder builder = new Notification.Builder(this)
                    .setSmallIcon( R.mipmap.ic_launcher )
                    .setContentTitle( title )
                    .setContentText( message )
                    .setContentIntent( pendingIntent );
                NotificationChannel channel = new NotificationChannel( channel_id, title, NotificationManager.IMPORTANCE_DEFAULT);
                notificationManager.createNotificationChannel(channel);
                builder.setChannelId( channel_id );
                Notification notification = builder.build();
                notificationManager.notify(1, notification);
READ ALSO
Не переносится текст у CheckBox (Programmatically (Android))

Не переносится текст у CheckBox (Programmatically (Android))

При динамическом создании CheckBox, не переносится текстДобавляю следующим образом:

340
Настройка виртуальных хостов Tomcat

Настройка виртуальных хостов Tomcat

Есть имя хоста testmydomain

214
HashMap.merge() через Stream API

HashMap.merge() через Stream API

Есть метод, в котором алгоритм прописан через обычную итерацию по List:

225
Как получить одно из двух значений Object из Map&lt;String, Object&gt; и поместить его в List&lt;&gt;?

Как получить одно из двух значений Object из Map<String, Object> и поместить его в List<>?

От сервера с помощью Retrofit я получаю данные в виде:

227