AlarmManagerに問題があります。繰り返しアラームをスケジュールするためのコードを設定し、アプリケーションを実行した後、アラームは正常に実行されます。ホームボタンをクリックしても(そしてアプリケーションが一時停止していても)、アラームはその間隔で実行されます。
問題は、タスクマネージャーを開いてアプリケーションを強制的に閉じると、アラームの実行が停止することです。
これは正常な動作ですか?これを回避し、アプリケーションを閉じた後もアラームを実行し続ける方法はありますか?
コードは次のとおりです。メソッドはApplicationContextクラスonCreate()によって呼び出されます。
private void scheduleAlarm() {
if (alarmScheduled == true) { return; } // we only need to schedule once.
int alarmInterval = Def.pref(getApplicationContext()).getInt("alarmInterval", 30);
final Intent intent = new Intent(getApplicationContext(), CollectorAlarmReceiver.class);
final PendingIntent pending = PendingIntent.getBroadcast(getApplicationContext(), 0, intent, 0);
AlarmManager alarmMgr = (AlarmManager) getApplicationContext().getSystemService(Context.ALARM_SERVICE);
alarmMgr.cancel(pending); // cancel others.
alarmMgr.setRepeating(AlarmManager.RTC_WAKEUP, System.currentTimeMillis()+1000,
alarmInterval*1000, pending);
Def.log(TAG,"scheduleAlarm(): alarm scheduled, interval: "+alarmInterval+" seconds");
alarmScheduled = true;
}
受信者コード:
public void onReceive(Context context, Intent intent) {
Log.i(TAG, "CollectorAlarmReceiver invoked, starting CollectorService in background");
context.startService(new Intent(context, CollectorService.class));
Intent collectorService = new Intent(context,CollectorService.class);
collectorService.putExtra("action", CollectorService.ACTION_BACKGROUND_REQUEST_MESSAGES);
context.sendBroadcast(collectorService);
}
ありがとう!
これは正常な動作です。ユーザーが自発的にアプリケーションを強制的に停止する場合は、アプリケーションを停止する必要があります。それ以外の場合は、アプリケーションのようなウイルスを作成しています。
本当に必要な場合は、他のサービスが実行されているかどうかを監視し、実行されていない場合はサービスを実行する別のサービスを作成できます。しかし、これは別のアプリケーションになり、(あなたが望む)ユーザーはタスクマネージャーを使用してこのアプリを強制終了しません。
個人的には心配しません。ユーザーがそれを止めた場合、彼らはそれを止めたかったのです。ユーザーを悩ませないでください。
@GSreeは間違っていると思います。これを実現する簡単な方法があります。カスタムアクションを使用するだけです。方法は次のとおりです。
まず、次のようなカスタムアクション名を定義します。
public static final String MY_ACTION = "com.sample.myaction"
次に、BroadcastReceiverを作成します。
public class MyAlarmReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MY_ACTION)) {
// Do something here
}
}
}
AndroidManifest.xmlにレシーバーを登録します。
<receiver Android:name="com.sample.MyAlarmReceiver">
<intent-filter>
<action Android:name="com.sample.myaction"/>
</intent-filter>
</receiver>
次に、アラームを設定するには、次のPendingIntentを使用します。
Intent i = new Intent(MY_ACTION);
PendingIntent pi = PendingIntent.getBroadcast(getApplicationContext(), 0, i, 0);
他の方法もあるかもしれませんが、このソリューションを試したところ、シェルからアプリを強制終了しても、BroadcastReceiverが呼び出されました。
このソリューションでは、サービスを作成する必要がないことに注意してください。
これは正常な動作です。アプリがonDestroy()に移行すると、アラームは機能しなくなります。
私はこれを数回行いましたが、なぜyaがrequestCode0を割り当てるのか疑問に思います。アラームに一意の番号を付けると大いに役立つと思います。
追加
<receiver Android:name=".AlarmReceiver" Android:process=":remote" />
マニフェストファイル内。アプリが強制終了されても、アラームは機能します。
アプリケーションを強制的に閉じることは、アプリを閉じる正しい方法ではなく、誤った動作をする可能性があります。
この 質問 も役立つかもしれません。
私はあなたが必要なことを正確に行うことができました。アプリケーションマネージャツールの[実行中]タブからアプリケーションを停止しても、サービスは自動的に再起動します。それを強制終了する唯一の方法は、アプリケーションマネージャのアンインストールオプションの横にある強制停止ボタンを使用することです。基本的には、サービスを直接呼び出します。これが私のコードです:
public class TestService extends Service {
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Toast.makeText(this, "Ejecutando Servicio ...", Toast.LENGTH_SHORT).show();
return Service.START_NOT_STICKY;
}
@Override
public void onCreate() {
super.onCreate();
Toast.makeText(this, "Iniciando Servicio ...", Toast.LENGTH_SHORT).show();
}
@Override
public void onDestroy() {
super.onDestroy();
Toast.makeText(this, "Deteniendo Servicio ...", Toast.LENGTH_SHORT).show();
}
クライアントアクティビティで、次のコードを記述します。
Calendar cal = Calendar.getInstance();
Intent intent = new Intent(this,TestService.class);
PendingIntent pIntent = PendingIntent.getService(this.getApplicationContext(), 0, intent, 0);
alarm= (AlarmManager) getSystemService(Context.ALARM_SERVICE);
alarm.setRepeating(AlarmManager.RTC_WAKEUP,cal.getTimeInMillis(), 3*1000, pIntent);
そして、マニフェストでサービスを宣言します。
<service
Android:name="TestService"
Android:icon="@drawable/ic_launcher"
Android:label="TestService"
>
</service>