11

Questo è il mio codice Activity,Alarm Manager non funziona in background su Android 6.0

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

Queste sono tutte le autorizzazioni che ho nella mia 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"/> 

Questo è il mio codice 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(); 

    } 

ho registrato il mio BroadcastReceiver nel manifesto,

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

Il codice di cui sopra esegue con successo il BroadcastReceiver su dispositivi pre-marshmallow sullo sfondo, ma su un dispositivo Marshmallow, il BroadcastReceiver non viene eseguito. Qualcuno sa cosa potrebbe accadere qui? Grazie.

risposta

22

Ci sono un paio di cose che si può provare che, se utilizzate in concerto, dovrebbe essere in grado di tagliare attraverso tutte le modalità di inattività/standby/Doze (a prescindere dal Versione del sistema operativo).

1. Utilizzare un WakefulBroadcastReceiver anziché un numero ordinario BroadcastReceiver. Assicurati di includere l'autorizzazione WAKE_LOCK per utilizzarlo correttamente.

2. utilizzare il metodo setExactAndAllowWhileIdle() (su API 23 & sopra) per programmare la Intent per il ricevitore:

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

Riferimenti:

1.Alarm manager for background services.

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

+1

Quindi, se uso 'setExactAndAllowWhileIdle()' dovrò cambiare la versione minima sdk della mia app a 23? –

+0

Grazie amico! you rock :) –

+1

'setExact()' è disponibile solo dall'API 19. Quindi devi farlo anche in'else if' nella condizione nello snippet. – Henry

6

Il motivo può essere Doze mode introdotto in Android 6.0 Marshmallow. Utilizzare setAlarmclock() anziché set(). È progettato specificamente per le sveglie e potrebbe essere in grado di tagliare doze. Ci sono alcuni comandi adb è possibile utilizzare per mettere manualmente un telefono in un'applicazione stand-by dormiveglia o:

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

Se questo non è in grado di riattivare l'app su, c'è il metodo infallibile setExactAndAllowWhileIdle() è stato progettato per sveglia il telefono da doze, non importa cosa. Nella peggiore delle ipotesi, puoi svegliare la tua app con questo metodo e utilizzare la sveglia per programmare l'allarme successivo.

Riferimento: How to make Alarm Manager work when Android 6.0 in Doze mode?

+0

Ok ci proverò. –