【问题标题】:AppWidget refresh Uri for RemoteViews用于 RemoteViews 的 AppWidget 刷新 Uri
【发布时间】:2014-09-20 02:33:06
【问题描述】:

我创建了一个 Appwidget,它显示了一个通过 Uri 提供给它的 RemoteViews 的图像文件 (test.png)。 在 onUpdate 中,我运行一个更改文件内容的服务。我还为将调用 onUpdate 的图像设置了 onClickListener。

-如果我创建 AppWidget 的实例,它会显示 Uri 文件的最新更改版本。

-如果我单击小部件,我的服务会对文件进行适当的更改(我可以使用文件资源管理器进行验证),但它不会更新 AppWidget 中显示的图像。

-(最重要的是)如果我删除 AppWidget 并创建一个新的,它会显示图像文件的当前/正确版本。

我知道我的服务可能需要很长时间才能在第一次通过时生效,但它应该在下一次 onClick/onUpdate 调用时显示最新的图像。 就目前而言,AppWidget 仅显示第一次调用 onUpdate 时存在的图像文件的版本。

问题:

刷新 Appwidget 的 RemoteView 内容的正确方法是什么,我的方法中是否遗漏了什么?

感谢您的宝贵时间!

更新:

我尝试从 AppWidgetProvider.onReceive() 调用 AppWidgetManager.notifyAppWidgetViewDataChanged() 方法,在 onUpdate() 之后仍然没有更改为 RemoteViews 内容。

public class CCWidgetProvider extends AppWidgetProvider {

  @Override
  public void onUpdate(Context context, AppWidgetManager appWidgetManager,int[] appWidgetIds) 
    {

    // Get all ids
    ComponentName thisWidget = new ComponentName(context,CCWidgetProvider.class);
    int[] allWidgetIds = appWidgetManager.getAppWidgetIds(thisWidget);

    for (int widgetId : allWidgetIds)
        {
        RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout04);

        /*
         * it's here that I run a service that changes the content of the file /test/test.png
         */

        RelativeLayout RL_widget = new RelativeLayout(context);
        LayoutInflater inflater = (LayoutInflater)context.getSystemService( Context.LAYOUT_INFLATER_SERVICE );
        RL_widget = (RelativeLayout)inflater.inflate(R.layout.widget_main, null);

        Uri uri = Uri.parse(Environment.getExternalStorageDirectory().getPath()+"/test/test.png");
        remoteViews.setImageViewUri(R.id.IV_widget_image,uri);


        Intent intent = new Intent(context, CCWidgetProvider.class);
        intent.setAction(AppWidgetManager.ACTION_APPWIDGET_UPDATE);
        intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_IDS, appWidgetIds);
        //PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent, PendingIntent.FLAG_CANCEL_CURRENT);
        PendingIntent pendingIntent = PendingIntent.getBroadcast(context,0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
        remoteViews.setOnClickPendingIntent(R.id.IV_widget_image, pendingIntent);

        appWidgetManager.updateAppWidget(widgetId, remoteViews);
    }
 }
} 

【问题讨论】:

    标签: android uri android-appwidget remoteview


    【解决方案1】:

    我发现有很多事情可以使小部件变硬。

    A. onUpdate 并不是真正的更新机制

    与听起来相反,onUpdate 仅在两种情况下被调用:

    1. 小部件创建时间。
    2. 每当更新周期时间(在小部件的 xml 定义文件中定义的updateMillis)过去时。

    关键点:onUpdate 在其他时间不会被调用。 (据我在实践中所见)。

    如果您希望小部件在其他时间更新,则有必要创建一个单独的机制,了解小部件和被触发的能力。通常这将是一个Service,您从onUpdate 例程开始。这可能看起来像:

    public void onUpdate(Context context, AppWidgetManager appWidgetManager, int[] appWidgetIds )
    {       
        // start the service in case it ain't started yet, this also force a widget update to ensure correct status on them
        Intent intent = new Intent(context, MyService.class);
        intent.putExtra('service.startCode', /*A number to identify what is going on*/);
        context.startService(intent);
    
        // Everything else is triggered from the service!!
    }
    

    服务然后设置小部件的内容,并在必要时通过内部计时或通过使用Broadcast 机制更新它们。

    B.您无法真正更新一些小部件

    在您创建小部件时创建remoteViews,然后在事情发生变化时更新它或其中的视图,这似乎是合乎逻辑的。以我的经验,这无法预测。当您想更改小部件中的任何内容时,请创建一个新的remoteViews,正确填写,然后将其分配给小部件。

    【讨论】:

    • 感谢您抽出宝贵时间查看这一切。让 onUpdate 与 onClickPendingIntent 一起正确运行是这里的首要任务,而且现在似乎一切正常。再次感谢! RemoteViews 真是让人头疼!
    【解决方案2】:

    我在 RemoteView 处理 URI 的方式上遇到了一些设备依赖性,并找到了解决方案的方法,如下所示:

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout);
    Uri uri = Uri.parse("file://"+Environment.getExternalStorageDirectory().getPath()+"/test/test.png");
    
    Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.crap);
    bitmap = MediaStore.Images.Media.getBitmap(context.getContentResolver(), uri);
    remoteViews.setImageViewBitmap(R.id.IV_widget_image, bitmap);
    

    它还消除了循环 RemoteViews 的需要,就像我的其他答案一样。

    【讨论】:

    • 我认为这里的重点是您每次都在创建一个新的 RemoteViews,而不是 URI 更改。
    • 我发现在某些设备上使用 .setImageViewUri 方法时 content:// 样式的 URI 被呈现为白色图像。创建图像的位图,然后使用 .setImageViewBitmap 解决它。
    • @PeteH 使用 setImageViewUri 将显示白色图像
    【解决方案3】:

    当然不优雅,或者内存效率不高,但我发现如果我复制了我的 RemoteViews

    RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout01);
    RemoteViews remoteViews2 = new RemoteViews(context.getPackageName(),R.layout.widget_layout02);
    

    复制它们周围的代码,并在图像更新之间间歇性地交换它们(有点像缓冲区),每次重置 RemoteView 都会强制更新其内容!

    目前对我有用,请随时提出更正确的解决方案。

    【讨论】:

      猜你喜欢
      • 2013-08-09
      • 1970-01-01
      • 1970-01-01
      • 2016-06-08
      • 1970-01-01
      • 2022-10-02
      • 1970-01-01
      • 2014-02-05
      • 2012-01-30
      相关资源
      最近更新 更多