androidandroid-intentandroid-broadcastandroid-alarmsandroid-broadcastreceiver

Alarm Manager does not work in background on Android 6.0


This is my Activity code,

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

These are all the permissions that I have in my app,

  <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"/>

This is my BroadcastReceiver code,

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

    }

I have registered my BroadcastReceiver in the manifest,

 <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>

The above code successfully executes the BroadcastReceiver on pre-MarshMallow devices in the background ,but on a MarshMallow device ,the BroadcastReceiver does not get executed. Does anyone know what could be happening here? Thanks.


Solution

  • There are a couple of things you can try which, when used in concert, should be able to cut through all of the idle/standby/doze modes (irrespective of OS version).

    1. Use a WakefulBroadcastReceiver instead of an ordinary BroadcastReceiver. Make sure you include the WAKE_LOCK permission to use it correctly.

    2. Use the setExactAndAllowWhileIdle() method (on API 23 & above) to schedule the Intent for the receiver:

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

    References:

    1. Alarm manager for background services.

    2. A flowchart for background work, alarms, and your Android app.