1

Ich habe eine App als Lernprogramm gemacht, um zu lernen, wie gelöschte Alarme nach dem Neustart des Telefons neu gestartet werden. Nach dem Neustart empfängt BroadcastReceiver die Aktion BOOT_COMPLETED und startet einen Dienst, der alle Alarme neu startet. Alarme erstellen Benachrichtigungen, wenn sie angerufen werden. Nach ersten Tests habe ich Benachrichtigungen zur erwarteten Zeit erhalten und dann diese Tutorial-App vergessen und das Telefon nicht ausgeschaltet.App empfängt BOOT_COMPLETED mehrmals und Alarme werden erneut erstellt

Ich bekomme jedoch immer noch Benachrichtigungen auf meinem Bildschirm, als ob die App erneut Alarme ausgelöst hat. Während des Tages habe ich zweimal erhalten und alle sind unklar, warum. Das einzige, was den Neustart von Alarmen auslösen kann, ist die Aktion BOOT_COMPLETED. Was läuft hier falsch?

Manifest:

<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
package="com.example.marat.recyclerviewtutorial"> 

<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity 

    // list of activities 

    <service android:name=".BootService"/> 

    <receiver android:name=".AlarmBroadcastReceiver"/> 

    <receiver android:name=".RestartAlarmsReceiver" android:enabled="true"> 
     <intent-filter> 
      <action android:name="android.intent.action.BOOT_COMPLETED" /> 
     </intent-filter> 
    </receiver> 

</application> 

</manifest> 

RestartAlarmsReceiver.java

public class RestartAlarmsReceiver extends BroadcastReceiver { 

private static final String TAG = "myTag"; 

@Override 
public void onReceive(Context context, Intent intent) { 

    if ("android.intent.action.BOOT_COMPLETED".equals(intent.getAction())) { 

     Intent i = new Intent(context, BootService.class); 
     ComponentName service = context.startService(i); 

     if (null == service) { 
      // something really wrong here 
      Log.e(TAG, "Could not start service "); 
     } 
     else { 
      Log.e(TAG, "Successfully started service "); 
     } 

    } else { 
     Log.e(TAG, "Received unexpected intent " + intent.toString()); 
    } 
} 
} 

BootService.java

public class BootService extends Service { 

private static final String TAG = "myTag"; 

@Nullable 
@Override 
public IBinder onBind(Intent intent) { 
    return null; 
} 

@Override 
public int onStartCommand(Intent intent, int flags, int startId) { 

    Log.d(TAG, "onStartCommand"); 

    Database db = new Database(this); 
    db.open(); 
    ArrayList<ArrayList<String>> data = new ArrayList<ArrayList<String>>(); 
    data = db.getData(); 
    db.close(); 

    Log.d(TAG, "db is openned"); 

    for (int i=0; i<data.size(); i++) { 

     Intent notif = new Intent(this, AlarmBroadcastReceiver.class); 
     notif.putExtra("Text", data.get(i).get(2)); 
     notif.putExtra("Position", data.get(i).get(0)); 

     int sec = Integer.parseInt(data.get(i).get(3)); 

     Log.d(TAG, "intent is openned"); 

     PendingIntent pendingIntent = PendingIntent.getBroadcast(this, Integer.parseInt(data.get(i).get(0)), notif, PendingIntent.FLAG_CANCEL_CURRENT); 
     AlarmManager am = (AlarmManager) this.getSystemService(Context.ALARM_SERVICE); 
     am.set(AlarmManager.RTC_WAKEUP, System.currentTimeMillis() + (sec * 1000), pendingIntent); 

     Log.d(TAG, "Alarm is restarted"); 
    } 

    Log.d(TAG, "before returning service"); 

    return Service.START_STICKY; 
} 
} 

Es ist bereits eine riesige Portion Code. Aber wenn Sie andere Teile meiner App benötigen, werde ich sie einschließen.

Vielen Dank im Voraus!

Antwort

1

Ich denke, das ist wegen START_STICKY. Ich denke während des Tages schließt das System Ihren laufenden Dienst, um Ressourcen freizugeben, und START_STICKY zwingt es zum Neustart. Und beim Neustart wird onStartCommand() erneut ausgelöst.

Die Entscheidung kann stattdessen IntentService verwendet werden. Ich sehe nicht die Notwendigkeit, Service hier zu verwenden.

+0

Wenn Sie mit dem Grund recht haben ('onStartCommand()' kehrt mit START_STICKY zurück), dann wäre die Lösung, die Absicht zu prüfen: Es wird null sein, wenn der Dienst nach dem Absturz neu gestartet wird. – 0X0nosugar

+0

zumindest Überprüfung Intent. Aber trotzdem - es ist nicht nötig, den Service hier weiter zu betreiben. –

+0

Ja, du bist genau da. Ich denke, in diesem Fall würde ich einen IntentService wie Sie vorgeschlagen bevorzugen. Oder der Dienst sollte 'stopSelf()' aufrufen, sobald es fertig ist. – 0X0nosugar