#java #android #widget #android-widget
Вопрос:
Мое приложение использует виджет, который я хочу обновлять в определенное время в течение дня. Вот код:
package com.apps.app;
import android.app.AlarmManager;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.util.Log;
import android.widget.RemoteViews;
import com.snappydb.DB;
import com.snappydb.DBFactory;
import com.snappydb.SnappydbException;
import java.util.ArrayList;
import java.util.Calendar;
public class Widget extends AppWidgetProvider {
public static String ACTION_AUTO_UPDATE_WIDGET = "ACTION_AUTO_UPDATE_WIDGET";
@Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if (ACTION_AUTO_UPDATE_WIDGET.equals(intent.getAction())) {
Log.d("widget","received");
onUpdate(context, AppWidgetManager.getInstance(context),
AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, Widget.class)));
}
}
@Override
public void onDisabled(Context context) {
super.onDisabled(context);
Intent intent = new Intent(context, Widget.class);
intent.setAction(ACTION_AUTO_UPDATE_WIDGET);
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.cancel(PendingIntent.getBroadcast(context, 0, intent, 0));
}
@Override
public void onEnabled(Context context) {
super.onEnabled(context);
try {
DB db = DBFactory.open(context, "notes");
ArrayList <Note> noteArrayList = db.getObject("notes", ArrayList.class);
for(Note note: noteArrayList) {
setUpdateIntent(context, note.getHours(), note.getMinutes());
}
} catch (SnappydbException e) {
e.printStackTrace();
}
}
private void setUpdateIntent(Context context, int h, int m) {
Intent intent1 = new Intent(context, Widget.class);
intent1.setAction(ACTION_AUTO_UPDATE_WIDGET);
PendingIntent alarmIntent = PendingIntent.getBroadcast(context, h*m, intent1, 0);
Calendar c = Calendar.getInstance();
c.set(Calendar.HOUR_OF_DAY, h);
c.set(Calendar.MINUTE, m);
AlarmManager alarmMgr = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
alarmMgr.setRepeating(AlarmManager.RTC, c.getTimeInMillis(), AlarmManager.INTERVAL_DAY, alarmIntent);
}
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
super.onUpdate(context, appWidgetManager, appWidgetIds);
for (int id : appWidgetIds) {
updateWidget(context, appWidgetManager, id);
}
}
private void updateWidget(Context context, AppWidgetManager manager, int widgetId) {
RemoteViews widgetView = new RemoteViews(context.getPackageName(), R.layout.widget);
widgetView.setTextViewText(R.id.dateTextView, TimeManager.getDay());
widgetView.setTextViewText(R.id.curTimeTextView, TimeManager.getTime());
widgetView.setTextViewText(R.id.weatherTextView,
context.getSharedPreferences("weather", Context.MODE_PRIVATE).getString("weather", "default"));
Intent configIntent = new Intent(context, MainActivity.class);
configIntent.setAction(AppWidgetManager.ACTION_APPWIDGET_CONFIGURE);
configIntent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
PendingIntent pIntent = PendingIntent.getActivity(context, widgetId, configIntent, 0);
widgetView.setOnClickPendingIntent(R.id.layoutId, pIntent);
manager.updateAppWidget(widgetId, widgetView);
}
}
Основываясь на данных базы данных, она должна обновляться ровно в 17:37, 17:40 и 17:42.
А вот мой журнал обновлений:
2021-09-07 17:38:31.518 6787-6787/com.apps.app D/widget: received
2021-09-07 17:38:31.547 6787-6787/com.apps.app D/widget: received
2021-09-07 17:42:52.078 6787-6787/com.apps.app D/widget: received
2021-09-07 17:42:52.092 6787-6787/com.apps.app D/widget: received
Я действительно не понимаю, на каком алгоритме основано обновление виджета. Кто-нибудь может мне это объяснить?
Комментарии:
1. Не могли бы вы поделиться всем классом, из чего он состоит и т. Д.?
2. @DanielBeleza только что отредактировал вопрос
3. Это не вызвано обновлением виджета. На самом деле, сигнал тревоги неточен.
Ответ №1:
Если ваше приложение хочет, чтобы время доставки изменялось, чтобы гарантировать, что между сигналами тревоги всегда проходит по крайней мере определенный интервал времени, то подход, который следует использовать, заключается в использовании одноразовых сигналов тревоги, самостоятельно планируя следующий при обработке каждой доставки сигнала тревоги.
Начиная с API 19, все повторяющиеся сигналы тревоги являются неточными. Если вашему приложению требуется точное время доставки, оно должно использовать одноразовые точные сигналы тревоги, каждый раз перенося их, как описано выше. Устаревшие приложения, у которых targetSdkVersion более ранняя, чем API 19, будут по-прежнему обрабатывать все свои сигналы тревоги, включая повторяющиеся сигналы тревоги, как точные.