Alarm Manager не работает в фоновом режиме на Android 6.0

Это мой код Activity,

Long time = new GregorianCalendar().getTimeInMillis()+20000;//Setting alarm after 20 sec
Intent intentAlarm = new Intent("alarm");
intentAlarm.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
intentAlarm.putExtra("req_code",10);
PendingIntent pendingIntent = PendingIntent.getBroadcast(context,10, intentAlarm, PendingIntent.FLAG_UPDATE_CURRENT);
AlarmManager alarmManager = (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarmManager.set(AlarmManager.RTC_WAKEUP, time, pendingIntent);

Это все разрешения, которые у меня есть в моем приложении,

  <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.INTERNET"/>
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.GET_ACCOUNTS"/>
    <uses-permission android:name="com.myapp.pack.permission.SET_ALARM"/>
    <uses-permission android:name="android.permission.WAKE_LOCK" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>

Это мой код BroadcastReceiver,

@Override
public void onReceive(Context context, Intent intent) {
        SharedPreferences sharedPreferences =
        context.getSharedPreferences( "mydata", Context.MODE_PRIVATE);
        SharedPreferences.Editor editor = sharedPreferences.edit();
        editor.putBoolean("elligible",true);
        editor.apply();

    }

Я зарегистрировал свой BroadcastReceiver в манифесте,

 <receiver android:name="com.myapp.pack.AlarmReciever" android:enabled="true">
        <intent-filter>
            <action android:name="android.intent.action.BOOT_COMPLETED" />
            <action android:name="alarm" />
        </intent-filter>
    </receiver>

Вышеупомянутый код успешно выполняет BroadcastReceiver на устройствах pre-MarshMallow в фоновом режиме, но на устройстве MarshMallow BroadcastReceiver не выполняется. Кто-нибудь знает, что может происходить здесь? Спасибо.

Ответ 1

Есть несколько вещей, которые вы можете попробовать, которые при совместном использовании должны иметь возможность разрезать все режимы бездействия/ожидания/доза (независимо от версии ОС).

1. Используйте WakefulBroadcastReceiver вместо обычного BroadcastReceiver. Убедитесь, что вы включили разрешение WAKE_LOCK, чтобы использовать его правильно.

2. Используйте метод setExactAndAllowWhileIdle() (по API 23 и выше), чтобы запланировать Intent для получателя:

if(Build.VERSION.SDK_INT < 23){
    if(Build.VERSION.SDK_INT >= 19){
        setExact(...);
    }
    else{
        set(...);
    }
}
else{
    setExactAndAllowWhileIdle(...);
}

Литература:

1. Менеджер аварийных сигналов для фоновых служб.

2. Блок-схема фоновой работы, аварийных сигналов и вашего приложения для Android.

Ответ 2

Причиной может быть Режим Doze, представленный в Android 6.0 Marshmallow. Используйте setAlarmclock() вместо set(). Он разработан специально для будильников и может прорезать дозу. Есть несколько команд adb, которые вы можете использовать для ручного перевода телефона в режим ожидания или ожидания приложения:

https://developer.android.com/preview/features/power-mgmt.html

Если это не способно разбудить ваше приложение, то метод surefire setExactAndAllowWhileIdle() предназначен для пробуждения телефона от доза не важно что. В худшем случае вы можете разбудить свое приложение с помощью этого метода и использовать пробуждение для планирования следующего аварийного сигнала.

Справка: Как заставить Alarm Manager работать, когда Android 6.0 в режиме Doze?