views:

341

answers:

1

I have an appwidget application and would like to enable users to create skins which can be applied at runtime. My preferred solution is to use apk files with nine patch png images that stretch to fit the ImageView's of widget, however its starting to look like I might have to use another packaging technique (e.g. zip files).

What I've tried: Importing nine patch resources as Drawable with context.getResourcesForApplication(my.app).getResources..., converting them to bitmaps using a canvas and setting the bitmap to the RemoteView using setImageViewBitap. This didn't work because I needed to specify the size of the resulting view (myBitmap.setBounds(..,..)) during conversion and some of the widths/heights in my appwidget aren't fixed. Perhaps there is a way to get the heights etc that I missed.

Importing resources directly to the RemoteView using setImageViewUri() This doesn't work because the function doesn't seem to read android.resource:// Uri's anymore (I poked around in the ImageView source and it only seems to read files paths and content:// Uri's)

Importing resources directly to the RemoteView using setImageViewResource() which didn't work because the id retrieved from the external package obviously doesn't include a package reference.

What I'm trying to avoid is hard coding all my appwidget width's and height's, or using a separate packaging scheme.

Has anyone implemented appwidget skins nicely and want to share the knowledge? Alternately there might be a hole in my logic somewhere that can be pointed out.

I can provide code if required though I don't have any here right now.

A: 

Did anybody ever figure this out. I am having the same exact issue. I am thinking of getting the resource stream of the file, then using it to write out the file, and then using the Uri of that file. But it seams like overkill. SO I gave it a shot:

    String dataPath = context.getFilesDir().getParent() + "/";
    String filepath = dataPath + "afile.9.png";
    InputStream astream = res.openRawResource(resID);
    byte[] buffer = new byte[1024];
    File f = new File(filepath);
    FileOutputStream fs;
    try {
        f.createNewFile();
        fs = new FileOutputStream(f, false);
        while (astream.read(buffer) != -1)
        {
            fs.write(buffer);
        }
        fs.flush();
        fs.close();
        astream.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    Uri uri = Uri.fromFile(f);
    views.setImageViewUri(R.id.alarm, uri);

And guess what it does not work. I get this message in the logcat: INFO/System.out(138): resolveUri failed on bad bitmap uri: file:///data/data/com.smartandroidapps.audiowidgetpro/afile.9.png

So I try it again on the SDCard path to check to see if the file is good after it was written and sure enough the file was fine. So I then try a regular .png image, not a 9patch and it still does not work, same error from logcat.

Another path that I have tried and does not work was creating a custom view that abstracts from Image view and overriding one of the functions to make it do what you need. This does not work because you cannot use custom views in Remote Views.

Basically it is not possible to do this, you can only use bitmaps, not any drawable, so you must size it out somehow.

Moose
I finally came back to this problem and have found a "solution" which is similar to what you used above. Essentially I have a content provider and "Insert" the resources using openFileOutput.To retrieve the images I used views.setImageViewUri(R.id.resulting_image_view, Uri.parse("content://com.mycontentprovider/filename"));This works but you have to specify the size of the image view before you use it, so one png is stored for every widget size.Once I iron out the details (there is a view bugs at the moment) I will post the full solution.
Sam