Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

app widget setImageViewUri does not update the image

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.

like image 626
shelll Avatar asked Oct 26 '11 09:10

shelll


2 Answers

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.

like image 92
Michell Bak Avatar answered Sep 24 '22 06:09

Michell Bak


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())); 
like image 41
Nys Avatar answered Sep 22 '22 06:09

Nys