应用程序小部件 setImageViewUri 不更新图像

发布于 2024-12-11 17:20:50 字数 2133 浏览 0 评论 0原文

我有一个应用程序小部件,其中仅包含一个图像视图。我重新绘制该图像并将其以 png 形式存储在应用程序的私有内存中,然后我使用 uri (widget.setImageViewUri(R.id.widget_icon, uri)) 设置 RemoteViews 的图像,而不是自行发送位图,因为这种情况非常罕见我得到的情况!活页夹交易失败!!!

问题是,随着图像随时间的变化,小部件的图像不会改变。我用 root explorer 检查了保存的 png,它已正确更新。但没有显示正确的图像。每个小部件都会显示添加到主屏幕后的图像。如果我使用 setImageViewBitmap(...) 它可以正常工作,除了罕见的失败活页夹事务。

我使用下面的方法从服务更新小部件。它不适用于 android 2.3.7 以及运行 2.2 的模拟器。可能是什么问题?它是否以某种方式被缓存?

public void updateWidget(Context context) {
  // redraws the widget's image
  updateIcon();

  OutputStream stream;
  try {
    stream = context.openFileOutput("icon.png", Context.MODE_WORLD_READABLE);
  }
  catch (FileNotFoundException ex) {
    ex.printStackTrace();
    return;
  }

  m_Icon.compress(CompressFormat.PNG, 100, stream);

  try {
    stream.close();
  }
  catch (IOException ex) {
    ex.printStackTrace();
  }

  AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
  int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetProvider.class));

  Intent intent = new Intent(context, MyDialog.class);
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

  PendingIntent clickIntent = PendingIntent.getActivity(context, 0, intent, 0);

  File file = new File(context.getFilesDir().getAbsolutePath() + File.separator + "icon.png");
//      Uri uri = Uri.fromFile(file);

  // update all widgets on home screen
  for (int wid : appWidgetIds) {
    RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget);
    widget.setOnClickPendingIntent(R.id.widget_layout, clickIntent);

    // === EDIT ===
    // Uri.fromFile(file); does not work correctly on android 2.1, only 2.2 and up
    // widget's image will disappear
//        widget.setImageViewUri(R.id.widget_icon, uri);
    widget.setImageViewUri(R.id.widget_icon, Uri.parse(file.getPath()));

    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, wid);

    appWidgetManager.updateAppWidget(wid, widget);
  }
}

编辑: 我还尝试了自定义 ContentProvider 并设置“content://...”uri,但结果相同。该小部件显示自添加到主屏幕以来的图像,并且不会随着时间的推移而更新。

logcat 不显示任何错误。

i have an app widget, which contains only one imageview. i redraw that image and store it as png in apps's private memory and then i set the RemoteViews' image with the uri (widget.setImageViewUri(R.id.widget_icon, uri)) instead of sendding the bitmap it self, because in very rare situations i get !!! FAILED BINDER TRANSACTION !!!

the problem is, that as the image changes over time, the widget's image does not change. i checked the saved png with root explorer and it is updated correctly. but the correct image is not displayed. each widget shows the image from the time it was added to the home screen. if i use setImageViewBitmap(...) it works correctly, except the rare failed binder transaction.

i update the widget from a service with the method below. it does not work on android 2.3.7 and also with emulator running 2.2. what could be the problem? is it somehow cached?

public void updateWidget(Context context) {
  // redraws the widget's image
  updateIcon();

  OutputStream stream;
  try {
    stream = context.openFileOutput("icon.png", Context.MODE_WORLD_READABLE);
  }
  catch (FileNotFoundException ex) {
    ex.printStackTrace();
    return;
  }

  m_Icon.compress(CompressFormat.PNG, 100, stream);

  try {
    stream.close();
  }
  catch (IOException ex) {
    ex.printStackTrace();
  }

  AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(context);
  int[] appWidgetIds = appWidgetManager.getAppWidgetIds(new ComponentName(context, WidgetProvider.class));

  Intent intent = new Intent(context, MyDialog.class);
  intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);

  PendingIntent clickIntent = PendingIntent.getActivity(context, 0, intent, 0);

  File file = new File(context.getFilesDir().getAbsolutePath() + File.separator + "icon.png");
//      Uri uri = Uri.fromFile(file);

  // update all widgets on home screen
  for (int wid : appWidgetIds) {
    RemoteViews widget = new RemoteViews(context.getPackageName(), R.layout.widget);
    widget.setOnClickPendingIntent(R.id.widget_layout, clickIntent);

    // === EDIT ===
    // Uri.fromFile(file); does not work correctly on android 2.1, only 2.2 and up
    // widget's image will disappear
//        widget.setImageViewUri(R.id.widget_icon, uri);
    widget.setImageViewUri(R.id.widget_icon, Uri.parse(file.getPath()));

    intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, wid);

    appWidgetManager.updateAppWidget(wid, widget);
  }
}

EDIT:
i also tried a custom ContentProvider and setting "content://..." uri, but with the same result. the widget shows the image from the time it was added to the home screen and does not update over time.

logcat does not show any errors.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

又爬满兰若 2024-12-18 17:20:50

如果 Uri 保持不变,Android 似乎不会更新图像。不过,我发现了一些技巧来解决这个问题。只需在 widget.setImageViewUri(R.id.widget_icon, uri); 之前调用 widget.setImageViewUri(R.id.widget_icon, Uri.parse("")); 即可。

它调用 setImageViewUri() 两次,但似乎工作正常。我很想听到更好的解决方法,因为我自己也遇到过这个问题。

If the Uri remains unchanged, it seems Android won't update the image. I've found a bit of a hack to get around this though. Just call widget.setImageViewUri(R.id.widget_icon, Uri.parse("")); before widget.setImageViewUri(R.id.widget_icon, uri);.

It calls setImageViewUri() twice, but seems to be working OK. I'd love to hear a better way to fix it though, as I'm experiencing this issue myself.

梦巷 2024-12-18 17:20:50

好吧,看起来 setImageViewUri 会缓存图像,并且如果它们具有相同的名称,则不会刷新它们。

这不是最优雅的解决方案,但它有效,每隔一次它就会使用不同的文件名。

String filename = new String("bitmap-1.png");
// rotate files, due to not being refreshed if same name 
if ( context.deleteFile(filename) ) {
   filename = new String("bitmap-0.png");
}
FileOutputStream out = context.openFileOutput(filename, Context.MODE_WORLD_READABLE);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, out);
file = context.getFileStreamPath(filename);
out.close();
updateViews.setImageViewUri(R.id.image1,Uri.parse(file.toString())); 

Well it looks like setImageViewUri caches images and does not refresh them if the have the same name.


Not the most elegant solution but it works, every second time it will use a different file name.

String filename = new String("bitmap-1.png");
// rotate files, due to not being refreshed if same name 
if ( context.deleteFile(filename) ) {
   filename = new String("bitmap-0.png");
}
FileOutputStream out = context.openFileOutput(filename, Context.MODE_WORLD_READABLE);
bitmap.compress(Bitmap.CompressFormat.PNG, 80, out);
file = context.getFileStreamPath(filename);
out.close();
updateViews.setImageViewUri(R.id.image1,Uri.parse(file.toString())); 
月野兔 2024-12-18 17:20:50

我希望这对其他人有帮助。我试图在删除列表视图中使用该方法,但它从未起作用。但使用位图对我有用。我能够更新任何记录中的图片,并且它们正在更新并且没有缓存。这是我使用的静态方法。

public static Bitmap getBitmap( String imageLocation ) {

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;

    return BitmapFactory.decodeFile(imageLocation, options);
}

然后

bitmap = BitmapUtils.getBitmap( address.getPhotoLocation() );
row.setImageViewBitmap( R.id.row_image, bitmap );

I hope this helps anyone else. I was trying to use that method in a remove list view but it never worked. But using bitmaps worked for me. I was able to update pictures in any of the records and they were updating and there was no caching. This is the static method I used.

public static Bitmap getBitmap( String imageLocation ) {

    BitmapFactory.Options options = new BitmapFactory.Options();
    options.inPreferredConfig = Bitmap.Config.ARGB_8888;

    return BitmapFactory.decodeFile(imageLocation, options);
}

then

bitmap = BitmapUtils.getBitmap( address.getPhotoLocation() );
row.setImageViewBitmap( R.id.row_image, bitmap );
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文