これが私が扱っているものです。
画面がオンの場合にのみ、10 分ごとに (現在は AlarmManager を使用して) 更新したい Android アプリに関連付けられたウィジェットがあります。画面がオフの場合、pendingIntent のアラームはキャンセルされます。画面が再びオンになったら、前回の更新と現在の時刻が 10 分以上ずれているかどうかを確認し、ずれている場合はブロードキャストを送信してウィジェットを更新します。
問題は、保留中のインテントのアラームがおそらくキャンセルされず (おそらく)、画面がオフのときに積み上げられた pendingIntent のすべてのアラームに対してウィジェットの更新が実行されることです。
ここにいくつかのコードスニペットがあります。
@Override
public void onReceive(Context context, Intent intent) {
check_intent = intent.getAction();
if(check_intent.equals("android.appwidget.action.APPWIDGET_UPDATE")){
mAppPreferences = PreferenceManager.getDefaultSharedPreferences(context);
int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0);
/*Check if there is atleast one widget on homescreen*/
if (saved_num_widgets>0){
boolean check = CheckScreenOn.check_screen_on(context);
/*Check if Screen is ON*/
if(check == true){
Intent widgetUpdate = new Intent(context, MyWidget.class);
widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
alarms = (AlarmManager)context.getSystemService(Context.ALARM_SERVICE);
newPending = PendingIntent.getBroadcast(context, 0, widgetUpdate,0);
alarms.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime()+ PERIOD, newPending);
context.startService(new Intent(context, UpdateService.class));
}
else{
alarms.cancel(newPending);
/*Screen is OFF no point updating the widget, cancel Alarms and do nothing*/
}
}
else{
int duration = Toast.LENGTH_LONG;
CharSequence text = "Please place My Widget on your home screen to keep earning money.";
Toast toast = Toast.makeText(context, text, duration);
toast.show();
}
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_ENABLED")){
this.onEnabled(context);
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_DELETED")){
this.onDeleted(context);
}
if(check_intent.equals("android.appwidget.action.APPWIDGET_DISABLED")){
this.onDisabled(context);
}
}
SCREEN_ON ブロードキャストを受信し、現在時刻 - 前回ウィジェットが更新された時間 >= 10 分である場合、ウィジェット更新の要求を送信する BroadcastReceiver を次に示します。
registerReceiver(new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
// ...
long update_interval = mAppPreferences.getLong(LASTUPDATETIME, 0);
long curtimemillis = System.currentTimeMillis();
long calculate_interval = curtimemillis - update_interval;
if(calculate_interval >= PERIOD){
int saved_num_widgets = mAppPreferences.getInt(NUM_WIDGETS, 0);
if (saved_num_widgets>0){
alarms.cancel(newPending);
Intent widgetUpdate = new Intent(context, MyWidget.class);
widgetUpdate.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
context.sendBroadcast(widgetUpdate);
}
}
}
}, new IntentFilter(Intent.ACTION_SCREEN_ON));
最後の更新が午前 10 時に行われ、画面が 30 分間オフだったとします。画面が表示されると、pendingIntent に保存されているすべてのアラームについてウィジェットが一度に更新されます。画面が再びオンになったときにウィジェットの更新が1回だけ発生するようにします。
最初に、デバイスがアイドル状態から復帰したときに AlarmManager.ELAPSED_REALTIME がトリガーされることを理解しました。
アラームキャンセルが機能しない理由がわかりません。他のすべては期待どおりに機能します。
ところで、さまざまなデバイスで 10 分間のウィジェット アップデートのパフォーマンス テストを行ったところ、利用可能なリソースに負担をかけることはまったくありませんでした。さらに、配信されたサービスは、Android デバイスのバッテリー使用量モニターにも表示されません。
どんな助けでも大歓迎です。