2011/02/21

ImageView#setImageUriについて

WeatherNowのホームウィジェットで、次に実装する機能をテストしていたらどうやらIntentの転送量オーバーで表示が更新されない。うーむ...

RemoteViewsで使えるImageViewメソッド?は
setImageViewResource (アプリのリソースファイルを表示)
setImageViewBitmap (Bitmapを表示、これで転送量オーバーに)
setImageViewUri (Uriから表示)


SDカード内の画像ファイルを表示させたいので、残りのsetImageViewUriを試してみた。で、ここで問題が。
試したコード:


結果:
Uri failed on bad bitmap uri: file:///sdcard/weathernow/plugin/image/test/icon_100s
と怒られました。でも何が原因なのか、全く分からない。

2時間近く悩んだ挙句、「分からないならAndroidのソースコードを見ればいいじゃない!」という結論に

ということで、ImageView#setImageURIから見てみましょう。

なにやらresolveUri()が呼ばれている。じゃあresolveUri()の中身はというと、

ImageView#resolveUri

今回はFileを読み込みたいので、ContentResolver.SCHEME_FILEの部分

Drawable#createFromStreamが呼ばれ、更にContentResolver#openInputStreamが呼ばれているらしい

ではまずCotentResolver#openInputStreamは

UriがFileの場合、new FileInputStream(uri.getPath())が呼ばれていただけでした。

じゃあDrawable#createFromStreamというと

createFromResourceStreamが呼ばれている。見てやろうじゃないか。

Drawable#createFromResourceStream



で、更にBitmapFactory#decodeResourceStreamを見てみる。


BitmapFactory#decodeStream


...ん?w
The input stream that holds the raw data to be decoded into a bitmap.


つまりあれか。ここまで見て、BitmapのRawデータを渡さないとだめっぽいと理解。(英語の解釈を間違えているだけかもしれないけど)。


結論:
ImageView#setImageURIやRemoteViews#setImageViewUriで普通にファイルを参照することは出来ない。

まして(名前からして出来そうな) 
ウェブ上のイメージファイルなんてもってのほか 
である。


PS.
凄い誤解があるかもしれません。
間違いがあればぜひこちらまで。
次回に続く。