Sunday, July 27, 2014

Android-Universal-Image-Loaderの日本語ファイルの扱いでハマる

Android-Universal-Image-Loaderはとっても高機能で積極的に使っているのですが、ファイルは存在するのエラーがでていて困っていました。
下記はそのときのエラーログです。

07-27 13:11:40.254  11037-11104/? E/ImageLoader﹕ /sdcard/Music/supercell%20Discography/supercell%20Discography/1st%20single%20%5B%E5%90%9B%E3%81%AE%E7%9F%A5%E3%82%89%E3%81%AA%E3%81%84%E7%89%A9%E8%AA%9E%5D/cover.jpg: open failed: ENOENT (No such file or directory)
    java.io.FileNotFoundException: /sdcard/Music/supercell%20Discography/supercell%20Discography/1st%20single%20%5B%E5%90%9B%E3%81%AE%E7%9F%A5%E3%82%89%E3%81%AA%E3%81%84%E7%89%A9%E8%AA%9E%5D/cover.jpg: open failed: ENOENT (No such file or directory)
            at libcore.io.IoBridge.open(IoBridge.java:456)
            at java.io.FileInputStream.(FileInputStream.java:76)
            at java.io.FileInputStream.(FileInputStream.java:103)
            at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStreamFromFile(BaseImageDownloader.java:158)
            at jp.co.kayo.android.localplayer.MyApplication$MyImageDownloader.getStreamFromFile(MyApplication.java:176)
            at com.nostra13.universalimageloader.core.download.BaseImageDownloader.getStream(BaseImageDownloader.java:86)
            at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.downloadImage(LoadAndDisplayImageTask.java:290)
            at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryCacheImageOnDisk(LoadAndDisplayImageTask.java:273)
            at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.tryLoadBitmap(LoadAndDisplayImageTask.java:229)
            at com.nostra13.universalimageloader.core.LoadAndDisplayImageTask.run(LoadAndDisplayImageTask.java:135)
            at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
            at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
            at java.lang.Thread.run(Thread.java:818)

これは、ファイル名の取得処理で日本語処理に誤りがあったからなので修正方法をメモしておきます。



BaseImageDownloaderクラスの以下の処理

 protected InputStream getStreamFromFile(String imageUri, Object extra) throws IOException {
  String filePath = Scheme.FILE.crop(imageUri);
  return new ContentLengthInputStream(new BufferedInputStream(new FileInputStream(filePath), BUFFER_SIZE),
    (int) new File(filePath).length());
 }

Uriからファイルパスを取得してるのだけど、日本語ファイルの場合デコードがされていないので、FileNotFoundになってしまいます。

なので、以下の箇所を

String filePath = Scheme.FILE.crop(imageUri);

下記のようにDecode処理するようにすると治ります。

String filePath = Uri.decode(Scheme.FILE.crop(imageUri));

修正自体は、BaseImageDownloaderをOverrideし、上記メソッドを修正し

ImageLoaderConfiguration config = new ImageLoaderConfiguration.Builder(context)
                .threadPriority(Thread.NORM_PRIORITY - 2)
                .denyCacheImageMultipleSizesInMemory()
                .diskCacheFileNameGenerator(new Md5FileNameGenerator())
                .tasksProcessingOrder(QueueProcessingType.LIFO)
                .imageDecoder(new MyImageDecoder(false))
                .imageDownloader(new MyImageDownloader(context))
                .diskCache(new MyDiscCache(Environments.getCacheDir(context), 3600*24*7))
                .writeDebugLogs() // Remove for release app
                .build();

上記の様にBuilderのimageDownloaderで指定してください。。

No comments:

Post a Comment