AppWidget Imageview updatePeriodMillis
AppWidget Imageview updatePeriodMillis
我尝试每 30 分钟更新一次 AppWidget 中的 ImageView,但没有成功。
它使用 Glide 库加载小部件,我怀疑缓存。
我正在尽我所能防止干扰唤醒和电池。只需要时不时地更改图像。醒来就好了。
我认为 30 分钟轮询是设备处于活动状态时。比如,它睡觉的时候,不算数,错过了。
感谢您的帮助。
res/xml/widget_name.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/widget_name"
android:initialLayout="@layout/widget_name"
android:minWidth="300dp"
android:minHeight="100dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="1800000"
android:widgetCategory="home_screen"></appwidget-provider>
com/WidgetName/WidgetName.java
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_name);
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.imageView, remoteViews, appWidgetIds) {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
super.onResourceReady(resource, transition);
}
};
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.navigation_header_bg).error(R.drawable.ic_navigation_help);
// Create an Intent to launch Browser
Intent intent = new Intent(context, WidgetConfig.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, 0);
Log.i("WidgetName", "src " + src);
remoteViews.setOnClickPendingIntent(R.id.imageView, pendingIntent);
Glide.with(context.getApplicationContext())
.asBitmap()
.load(src)
.apply(options)
.into(awt);
}
在查看您的项目时,您需要进行以下更改。
在res/xml/widget_name.xml中设置android:updatePeriodMillis="0"
然后在com/WidgetName/WidgetName.java
覆盖 onReceive 方法并进行以下更改
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case AppWidgetManager.ACTION_APPWIDGET_UPDATE:
onUpdate(context, AppWidgetManager.getInstance(context), AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, LineaMeteoPremium.class)));
break;
default:
super.onReceive(context, intent);
}
}
并且由于您要更新所有小部件,因此在循环中按顺序更新它们,如下所示,使用 AlarmManager 作为刷新触发器(更好的灵活性,因为您可以允许用户设置自定义刷新时间)另一个问题是你没有使用 skipMemoryCache(true) 和 diskCacheStrategy(DiskCacheStrategy.NONE) 方法来强制滑动获取新图像而不是在缓存中查找。
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
setUpAlarm(context, widgetId);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.linea_meteo_premium);
Log.e("LineaMeteo Widget", "src " + src);
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.imageView, remoteViews, appWidgetIds);
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.navigation_header_bg).error(R.drawable.ic_navigation_help).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE);
// Create an Intent to launch Browser
Intent intent = new Intent(context, WidgetConfig.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.imageView, pendingIntent);
Glide.with(context.getApplicationContext())
.asBitmap()
.load(src)
.apply(options)
.into(awt);
}
}
使用以下代码根据您想要的时间设置刷新小部件的警报
/**
* Sets up widget refresh alarm
*
* @param context The context of widget
* @param appWidgetId Widget ID of current widget
*/
private void setUpAlarm(Context context, int appWidgetId) {
final AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
long interval = (3 * 60000); // 60000 = 1minute | Change the formula based on your refresh timing needs
PendingIntent alarmPendingIntent = getRefreshWidgetPendingIntent(context, appWidgetId);
alarm.cancel(alarmPendingIntent);
// SET NEW ALARM
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
} else {
alarm.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
}
}
/**
* Get the pending intent object for refreshing the widget
*
* @param context current Context
* @param widgetId - Current Widget ID
* @return - Pending intent for refreshing widget
*/
private PendingIntent getRefreshWidgetPendingIntent(Context context, int widgetId) {
Intent intent = new Intent(context, LineaMeteoPremium.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
// Make the pending intent unique...
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
return PendingIntent.getBroadcast(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
最重要的是,由于您的应用使用的是 ClearText HTTP 流量,并且从 Android 9.0 开始默认禁用明文支持,因此您需要在清单的 appilcation 标签中添加以下标签,以防止小部件在 android 9.+ 设备。
<application
.
.
android:usesCleartextTraffic="true">
我尝试每 30 分钟更新一次 AppWidget 中的 ImageView,但没有成功。
它使用 Glide 库加载小部件,我怀疑缓存。
我正在尽我所能防止干扰唤醒和电池。只需要时不时地更改图像。醒来就好了。
我认为 30 分钟轮询是设备处于活动状态时。比如,它睡觉的时候,不算数,错过了。
感谢您的帮助。
res/xml/widget_name.xml
<?xml version="1.0" encoding="utf-8"?>
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:initialKeyguardLayout="@layout/widget_name"
android:initialLayout="@layout/widget_name"
android:minWidth="300dp"
android:minHeight="100dp"
android:previewImage="@drawable/example_appwidget_preview"
android:resizeMode="horizontal|vertical"
android:updatePeriodMillis="1800000"
android:widgetCategory="home_screen"></appwidget-provider>
com/WidgetName/WidgetName.java
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_name);
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.imageView, remoteViews, appWidgetIds) {
@Override
public void onResourceReady(Bitmap resource, Transition<? super Bitmap> transition) {
super.onResourceReady(resource, transition);
}
};
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.navigation_header_bg).error(R.drawable.ic_navigation_help);
// Create an Intent to launch Browser
Intent intent = new Intent(context, WidgetConfig.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, 0);
Log.i("WidgetName", "src " + src);
remoteViews.setOnClickPendingIntent(R.id.imageView, pendingIntent);
Glide.with(context.getApplicationContext())
.asBitmap()
.load(src)
.apply(options)
.into(awt);
}
在查看您的项目时,您需要进行以下更改。
在res/xml/widget_name.xml中设置android:updatePeriodMillis="0"
然后在com/WidgetName/WidgetName.java
覆盖 onReceive 方法并进行以下更改
@Override
public void onReceive(Context context, Intent intent) {
switch (intent.getAction()) {
case AppWidgetManager.ACTION_APPWIDGET_UPDATE:
onUpdate(context, AppWidgetManager.getInstance(context), AppWidgetManager.getInstance(context).getAppWidgetIds(new ComponentName(context, LineaMeteoPremium.class)));
break;
default:
super.onReceive(context, intent);
}
}
并且由于您要更新所有小部件,因此在循环中按顺序更新它们,如下所示,使用 AlarmManager 作为刷新触发器(更好的灵活性,因为您可以允许用户设置自定义刷新时间)另一个问题是你没有使用 skipMemoryCache(true) 和 diskCacheStrategy(DiskCacheStrategy.NONE) 方法来强制滑动获取新图像而不是在缓存中查找。
@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds) {
for (int widgetId : appWidgetIds) {
setUpAlarm(context, widgetId);
RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.linea_meteo_premium);
Log.e("LineaMeteo Widget", "src " + src);
AppWidgetTarget awt = new AppWidgetTarget(context, R.id.imageView, remoteViews, appWidgetIds);
RequestOptions options = new RequestOptions().
override(300, 300).placeholder(R.drawable.navigation_header_bg).error(R.drawable.ic_navigation_help).skipMemoryCache(true).diskCacheStrategy(DiskCacheStrategy.NONE);
// Create an Intent to launch Browser
Intent intent = new Intent(context, WidgetConfig.class);
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, intent, 0);
remoteViews.setOnClickPendingIntent(R.id.imageView, pendingIntent);
Glide.with(context.getApplicationContext())
.asBitmap()
.load(src)
.apply(options)
.into(awt);
}
}
使用以下代码根据您想要的时间设置刷新小部件的警报
/**
* Sets up widget refresh alarm
*
* @param context The context of widget
* @param appWidgetId Widget ID of current widget
*/
private void setUpAlarm(Context context, int appWidgetId) {
final AlarmManager alarm = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
long interval = (3 * 60000); // 60000 = 1minute | Change the formula based on your refresh timing needs
PendingIntent alarmPendingIntent = getRefreshWidgetPendingIntent(context, appWidgetId);
alarm.cancel(alarmPendingIntent);
// SET NEW ALARM
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
alarm.setExactAndAllowWhileIdle(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
alarm.setExact(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
} else {
alarm.set(AlarmManager.ELAPSED_REALTIME, SystemClock.elapsedRealtime() + interval, alarmPendingIntent);
}
}
/**
* Get the pending intent object for refreshing the widget
*
* @param context current Context
* @param widgetId - Current Widget ID
* @return - Pending intent for refreshing widget
*/
private PendingIntent getRefreshWidgetPendingIntent(Context context, int widgetId) {
Intent intent = new Intent(context, LineaMeteoPremium.class);
intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, widgetId);
// Make the pending intent unique...
intent.setData(Uri.parse(intent.toUri(Intent.URI_INTENT_SCHEME)));
return PendingIntent.getBroadcast(context, 123, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
最重要的是,由于您的应用使用的是 ClearText HTTP 流量,并且从 Android 9.0 开始默认禁用明文支持,因此您需要在清单的 appilcation 标签中添加以下标签,以防止小部件在 android 9.+ 设备。
<application
.
.
android:usesCleartextTraffic="true">