Виджет приложения setImageViewUri не обновляет изображение

У меня есть виджет приложения, который содержит только одно изображение. я перерисовываю это изображение и сохраняю его как png в частной памяти приложений, а затем я устанавливаю образ RemoteViews с помощью uri (widget.setImageViewUri(R.id.widget_icon, uri)) вместо отправки его растрового изображения, потому что очень редко ситуации, которые я получаю!!! НЕПРАВИЛЬНАЯ СДЕЛКА СДЕЛКИ!!!

проблема заключается в том, что по мере изменения изображения со временем изображение виджета не изменяется. Я проверил сохраненный png с помощью root explorer и обновил его правильно. но правильное изображение не отображается. каждый виджет показывает изображение с момента его добавления на главный экран. если я использую setImageViewBitmap (...), он работает правильно, за исключением редкой неудачной транзакции связующего.

i обновить виджет от службы с помощью метода ниже. он не работает на Android 2.3.7, а также с эмулятором, работающим под управлением 2.2. В чем может быть проблема? это как-то кэшировано?

public void updateWidget(Context context) {
  // redraws the widget 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 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: Я также попробовал пользовательский ContentProvider и установил urid "content://...", но с тем же результатом. виджет показывает изображение с момента его добавления на главный экран и не обновляется со временем.

logcat не показывает ошибок.

Ответ 1

Если Uri остается неизменным, похоже, что Android не будет обновлять изображение. Я нашел немного взлома, чтобы обойти это, хотя. Просто позвоните widget.setImageViewUri(R.id.widget_icon, Uri.parse("")); до widget.setImageViewUri(R.id.widget_icon, uri);.

Он дважды вызывает setImageViewUri(), но, похоже, работает нормально. Мне бы хотелось услышать лучший способ исправить это, поскольку я сам испытываю эту проблему.

Ответ 2

Ну, похоже, что 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())); 

Ответ 3

Надеюсь, это поможет кому угодно. Я пытался использовать этот метод в представлении списка удаления, но он никогда не работал. Но использование растровых изображений сработало для меня. Я смог обновить фотографии в любой из записей, и они обновлялись, и не было кеширования. Это статический метод, который я использовал.

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 );