如何将网址中的图像加载到小部件的Android远程视图中

时间:2013-12-28 18:34:55

标签: android android-widget android-xml android-image

我有一个图像网址,我解析形式json,我想加载到主屏幕上的Android小部件。现在我正试图这样做,但错了:

ImageDownloadTask imageD = new ImageDownloadTask(image);
            views.setImageViewBitmap(R.id.image, imageD.execute(image));

图片是一个字符串,其中包含需要下载的图片的网址,我正在尝试将其设置为R.id.image

我找到了另一个堆栈问题并尝试了这个结果:

views.setBitmap(R.id.image, "setImageBitmap",BitmapFactory.decodeStream(new URL(image).openStream()));

当我使用应用程序中没有任何东西加载时,没有任何文本视图被设置。

我的第三次尝试是这样的:

 //get beer data
            JSONObject o = new JSONObject(result);
            String name = getName(o);
            String image = getImage(o);
            String abv = getABV(o);
            String ibu = getIBU(o);
            String glass = getGlass(o);
            String beerBreweryName = getBreweryName(o);
            String beerBreweryStyle = getBreweryStyle(o);
            String beerDescription = getDescription(o);

            InputStream in = new java.net.URL(image).openStream();
            Bitmap bitmap = BitmapFactory.decodeStream(in);



            views.setTextViewText(R.id.beerTitle, name);
            views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
            views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);
            views.setImageViewBitmap(R.id.image, bitmap);

这给出了与上次尝试相同的结果,它甚至不会设置任何文本视图....

在下面发布的一个答案之后尝试了另一次尝试:

RemoteViews views = new RemoteViews(c.getPackageName(), R.layout.widget_test);

            //get beer data
            JSONObject o = new JSONObject(result);
            String name = getName(o);
            String imageURL = getImage(o);
            String abv = getABV(o);
            String ibu = getIBU(o);
            String glass = getGlass(o);
            String beerBreweryName = getBreweryName(o);
            String beerBreweryStyle = getBreweryStyle(o);
            String beerDescription = getDescription(o);

            Log.d("widgetImage" , imageURL);
            views.setImageViewUri(R.id.image, Uri.parse(imageURL));

            views.setTextViewText(R.id.beerTitle, name);
            views.setTextViewText(R.id.beerBreweryName, beerBreweryName);
            views.setTextViewText(R.id.beerStyleName, beerBreweryStyle);




            mgr.updateAppWidget(appWidgetIds, views);

此尝试允许加载所有文本视图,但不会显示任何图像。

2 个答案:

答案 0 :(得分:4)

可靠地执行此操作的方法是在远程setImageViewURI上使用ImageView。诀窍在于,您提供的URI是content:// URI,然后指向您从应用程序导出的内容提供程序。在您的内容提供商中,您可以执行任何操作以提供图像字节。

例如,在你的清单中:

<provider android:name=".ImageContentProvider" android:authorities="com.example.test" android:exported="true" />

您的提供者:

public class ImageContentProvider extends ContentProvider {

    // (Removed overrides that do nothing) 

    @Override
    public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException {
        List<String> segs = uri.getPathSegments();

        // Download the image content here, get the info you need from segs

        return ParcelFileDescriptor.open(new File(path), ParcelFileDescriptor.MODE_READ_ONLY);
    }
}

然后您的网址如下:

content://com.example.test/something-you-can-define/here

这是必要的,因为您的远程图像视图未在您的进程中运行。您可以做的事情更加局限,因为所有事项都必须在整个流程边界上进行序列化。 URI可以很好地序列化,但如果你尝试用setImageViewBitmap发送一兆字节的图像数据,它可能会失败(取决于可用的设备内存)。

答案 1 :(得分:0)

从这个问题的多个来源获得了很多帮助。对我来说最大的问题是为什么我上面列出的一堆尝试似乎锁定了小部件应用程序并且没有加载任何东西是因为我无法下载图像并将其设置在UI线程中。

为了实现这一点,我必须将所有内容移到我的异步任务的后台,而不是onPostExecute。