1

電話が再起動された後、削除されたアラームを再起動する方法を学ぶチュートリアルとしてアプリを作成しました。再起動後、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; 
} 
} 

それは既に大部分のコードです。しかし、あなたが私のアプリの他の部分を必要とするなら、私はそれらを含めるでしょう。

ありがとうございます!

答えて

1

START_STICKYのためだと思います。私はその日にシステムがリソースを解放するために実行中のサービスを終了し、START_STICKYが強制的に再起動すると思います。再起動時にはonStartCommand()が再度トリガされます。

代わりに、IntentServiceを使用することができます。私はここでサービスを使う必要はないと思う。

+0

START_STICKYで返される理由( 'onStartCommand()')が正しいのであれば、解決策はインテントをチェックすることです。サービスが強制終了された後にサービスが再開されると、nullになります。 – 0X0nosugar

+0

少なくともインテントをチェックしています。しかし、まだここにサービスを実行し続ける必要はありません –

+0

はい、あなたはそこにあります。私はこの場合、あなたのようなIntentServiceを推奨したいと思います。または、サービスが終了するとすぐに 'stopSelf()'を呼び出す必要があります。 – 0X0nosugar

関連する問題