Android RemoteView的AppWidget刷新Uri

Android RemoteView的AppWidget刷新Uri,android,uri,android-appwidget,remoteview,Android,Uri,Android Appwidget,Remoteview,我创建了一个Appwidget,它显示一个图像文件(test.png),该文件通过Uri提供给它的RemoteView。 在onUpdate中,我运行了一个更改文件内容的服务。我还为图像设置了一个onClickListener,它将调用onUpdate public class CCWidgetProvider extends AppWidgetProvider { @Override public void onUpdate(Context context, AppWidgetMan

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

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);
    }
 }
} 
-如果我创建AppWidget的实例,它将显示Uri文件的最新更改版本

-如果我单击小部件,我的服务会对文件进行相应的更改(我可以使用文件浏览器进行验证),但它不会更新AppWidget中显示的图像

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

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

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);
    }
 }
} 
问题:

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

谢谢你的时间

更新:

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


当然不优雅,也不节省内存,但我发现如果复制我的RemoteView

RemoteViews remoteViews = new RemoteViews(context.getPackageName(),R.layout.widget_layout01);
RemoteViews remoteViews2 = new RemoteViews(context.getPackageName(),R.layout.widget_layout02);
复制它们周围的代码,并在图像更新之间间歇性地交换它们(有点像缓冲区),每次强制更新其内容时重置RemoteView


现在对我有效,请随意加入一个更正确的解决方案。

我发现有各种各样的东西可以让小部件变得困难

A.onUpdate实际上不是一种更新机制

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

  • 创建小部件时
  • 每当更新周期时间(
    updateMillis
    在小部件的xml定义文件中定义)过去时
  • 关键点:
    onUpdate
    在其他时间不会被调用。(据我在实践中所见)

    如果您希望小部件在另一时间更新,则有必要创建一个单独的机制,了解小部件和要触发的容量。通常,这将是一个
    服务
    ,您可以在
    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!!
    }
    
    然后,该服务设置小部件的内容,并根据需要通过内部计时或使用
    广播
    机制进行更新

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


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

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

    与我的另一个回答一样,它还消除了循环使用RemoteView的需要。

    感谢您抽出时间查看所有这些内容。让onUpdate与OnClickPendingEvent一起正确运行是这里的首要任务,现在看来一切都正常了。再次感谢!远程视图真是让人讨厌!我认为这里的要点是,您每次都在创建一个新的RemoteView,而不是URI更改。我发现在某些设备上,当使用.setImageViewUri方法时,content://style URI被呈现为白色图像。创建图像的位图,然后使用.setImageViewBitmap解决了此问题。@PeteH use setImageViewUri将显示白色图像