我有一个应用程序,允许使用外部应用程序选择照片。然后我从uri拍摄照片的路径并将其用于内部动作。
当用户使用Google Photo选择照片时,如果图片是本地存储的,则下一个代码可以正常工作。但如果图片在云端,则 cursor.getString(index)的结果为空。
我搜索了一些信息,但不确定解决方案
final String[] projection = { "_data" };
Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
final int index = cursor.getColumnIndexOrThrow("_data");
return cursor.getString(index);
}
谢谢!
答案 0 :(得分:14)
最后,根据@CommonsWare的回答和之前关于这个问题的帖子,我解决了从uri获取InputStream,处理新的临时文件并将路径传递给我需要使用的函数。
这是简化的代码:
public String getImagePathFromInputStreamUri(Uri uri) {
InputStream inputStream = null;
String filePath = null;
if (uri.getAuthority() != null) {
try {
inputStream = getContentResolver().openInputStream(uri); // context needed
File photoFile = createTemporalFileFrom(inputStream);
filePath = photoFile.getPath();
} catch (FileNotFoundException e) {
// log
} catch (IOException e) {
// log
}finally {
try {
inputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return filePath;
}
private File createTemporalFileFrom(InputStream inputStream) throws IOException {
File targetFile = null;
if (inputStream != null) {
int read;
byte[] buffer = new byte[8 * 1024];
targetFile = createTemporalFile();
OutputStream outputStream = new FileOutputStream(targetFile);
while ((read = inputStream.read(buffer)) != -1) {
outputStream.write(buffer, 0, read);
}
outputStream.flush();
try {
outputStream.close();
} catch (IOException e) {
e.printStackTrace();
}
}
return targetFile;
}
private File createTemporalFile() {
return new File(getExternalCacheDir(), "tempFile.jpg"); // context needed
}
答案 1 :(得分:1)
当用户使用Google Photo选择照片时,如果图片是本地存储的,则下一个代码可以正常运行。
不一定。 Uri
没有要求_data
列回复query()
。它不需要返回的值对您有用(例如,您无法访问的内部存储或可移动存储上的文件)。
如果您需要将照片加载到ImageView
,请将Uri
传递给an image-loading library,例如Picasso。
如果您需要照片的字节,请使用openInputStream()
与ContentResolver
一起获取InputStream
标识的内容Uri
。请打开并阅读后台主题InputStream
。