電話が再起動された後、削除されたアラームを再起動する方法を学ぶチュートリアルとしてアプリを作成しました。再起動後、BroadcastReceiverはBOOT_COMPLETEDアクションを受信し、すべてのアラームを再開するサービスを起動します。アラームは、呼び出されたときに通知を作成します。最初のテストの後、私は予期された時間に通知を受け取った後、このチュートリアルアプリを忘れて電話をオフにしませんでした。アプリはBOOT_COMPLETEDを何度も受信し、アラームは再び再作成されます
しかし、私はまだアプリがアラームを再開したかのように画面上に通知を受けています。私は2回受け取りましたが、そのすべてはなぜ不明です。再起動アラームを起動できるのはBOOT_COMPLETEDアクションだけです。ここで何がうまくいかないの?
マニフェスト:
<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;
}
}
それは既に大部分のコードです。しかし、あなたが私のアプリの他の部分を必要とするなら、私はそれらを含めるでしょう。
ありがとうございます!
START_STICKYで返される理由( 'onStartCommand()')が正しいのであれば、解決策はインテントをチェックすることです。サービスが強制終了された後にサービスが再開されると、nullになります。 – 0X0nosugar
少なくともインテントをチェックしています。しかし、まだここにサービスを実行し続ける必要はありません –
はい、あなたはそこにあります。私はこの場合、あなたのようなIntentServiceを推奨したいと思います。または、サービスが終了するとすぐに 'stopSelf()'を呼び出す必要があります。 – 0X0nosugar