NetworkImageView#setImageUrl(String, ImageLoader)はfileスキームに未対応なので扱えるように改造してみました
BasicNetwork#performRequest()メソッドをOverrideしてfile schemeの場合はFileInputStream経由でデータを取得するようにしたらあっさりできました。
CustomNetwork.java
package com.example.volleysample;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import org.apache.http.HttpStatus;
import android.net.Uri;
import android.util.Log;
import com.android.volley.NetworkError;
import com.android.volley.NetworkResponse;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import com.android.volley.toolbox.BasicNetwork;
import com.android.volley.toolbox.ByteArrayPool;
import com.android.volley.toolbox.HttpStack;
import com.example.volleysample.BuildConfig;
public class CustomNetwork extends BasicNetwork {
private static final String TAG = CustomNetwork.class.getSimpleName();
public CustomNetwork(HttpStack stack) {
super(stack);
}
public CustomNetwork(HttpStack stack, ByteArrayPool pool) {
super(stack, pool);
}
@Override
public NetworkResponse performRequest(Request<?> request)
throws VolleyError {
// file schemeの場合は自前で処理
Uri uri = Uri.parse(request.getUrl());
if (uri != null && "file".equals(uri.getScheme())) {
return performFileRequest(uri);
}
// file scheme以外の処理は親クラスに丸投げ
return super.performRequest(request);
}
private NetworkResponse performFileRequest(Uri uri) throws VolleyError {
File file = new File(uri.getPath());
NetworkResponse response;
if (file.exists()) {
byte[] data = readBytes(file);
response = new NetworkResponse(data);
} else {
// 404エラーを返す
if (BuildConfig.DEBUG)
Log.w(TAG, "performFileRequest: file not found: " + file);
response = new NetworkResponse(HttpStatus.SC_NOT_FOUND, null,
Collections.<String, String> emptyMap(), false);
}
return response;
}
private byte[] readBytes(File file) throws VolleyError {
if (BuildConfig.DEBUG) Log.d(TAG, "readBytes: reading data from " + file);
byte[] data = null;
try {
ByteArrayOutputStream out = new ByteArrayOutputStream();
InputStream in = null;
try {
in = new FileInputStream(file);
byte[] buf = new byte[1024];
int len = 0;
while ((len = in.read(buf, 0, buf.length)) >= 0) {
out.write(buf, 0, len);
}
data = out.toByteArray();
if (BuildConfig.DEBUG) Log.d(TAG, "readBytes: read " + data.length + " bytes.");
} finally {
if (in != null) in.close();
if (out != null) out.close();
}
} catch (IOException e) {
if (BuildConfig.DEBUG) Log.w(TAG, "readBytes: failed to read data", e);
throw new NetworkError(e);
}
return data;
}
}
実際に使う場合にはRequestQueueのコンストラクターにCustomNetworkのインスタンスを渡します。
public static RequestQueue createRequestQueue(Context context, HttpStack stack, int maxCacheSizeInBytes) {
File cacheDir = new File(context.getCacheDir(), DEFAULT_CACHE_DIR);
String userAgent = "volley/0";
try {
String packageName = context.getPackageName();
PackageInfo info = context.getPackageManager().getPackageInfo(packageName, 0);
userAgent = packageName + "/" + info.versionCode;
} catch (NameNotFoundException e) {
}
if (stack == null) {
if (Build.VERSION.SDK_INT >= 9) {
stack = new HurlStack();
} else {
// Prior to Gingerbread, HttpUrlConnection was unreliable.
// See: http://android-developers.blogspot.com/2011/09/androids-http-clients.html
stack = new HttpClientStack(AndroidHttpClient.newInstance(userAgent));
}
}
// Network network = new BasicNetwork(stack);
Network network = new CustomNetwork(stack); // ここだけ修正
RequestQueue queue = new RequestQueue(new DiskBasedCache(cacheDir, maxCacheSizeInBytes), network);
queue.start();
return queue;
}