Android - 从URI获取文件路径

时间:2015-06-04 19:39:40

标签: java android uri

我有一个图像处理应用程序。在我的代码中,我将我的服务传递给ArrayList,服务完成其余的工作。现在我想扩展我的应用程序的功能,让用户能够去图库,选择一张图片,并使用共享按钮,将其发送到我的应用程序进行处理。 我希望尽可能多地重用代码,因此我认为一个好的方法是将send动作返回的URI转换为实际的文件路径。 我的解决方案与QuickPic一样正常工作,但不适用于Google相册。我的代码如下:

//MainFragment.onCreateView()
Intent intent = getActivity().getIntent();
if(Intent.ACTION_SEND.equals(intent.getAction()) {
    handleSingleImage(intent);
}

private void handleSingleImage(Intent intent) {
    Uri uri = intent.getParcelableExtra(Intent.EXTRA_STREAM);

    Log.d("MYURISTRING", uri.toString());
    ArrayList<String> selectedPaths = new ArrayList<String>();

    String path = Utils.getRealPathFromURI(getActivity(), uri);

    selectedPaths.add(path);

    Utils.startProcessPhotosService(getActivity(), MainFragment.this, selectedPaths);
}

//Utils
public static String getRealPathFromURI(Context context, Uri contentUri) {
    /*String[] proj = {MediaStore.Images.Media.DATA};

    CursorLoader cursorLoader = new CursorLoader(context, contentUri, proj, null, null, null);
    Cursor cursor = cursorLoader.loadInBackground();

    int columnIndex = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
    cursor.moveToFirst();

    return cursor.getString(columnIndex);*/

    ContentResolver contentResolver = context.getContentResolver();
    Cursor cursor = contentResolver.query(contentUri, null, null, null, null);
    cursor.moveToFirst();

    String path = cursor.getString(cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA));

    cursor.close();

    return path;
}

如果我使用QuickPic应用程序中的照片进行测试,一切都按预期工作,日志上的URI如下:

content://media/external/images/media/135695

但如果我使用Google相册对其进行测试,我的应用会崩溃,而URI如下:

content://com.google.android.apps.photos.contentprovider/-1/1/content%3A%2F%2Fmedia%2Fexternal%2Fimages%2Fmedia%2F135669/ACTUAL

我该如何支持两种风格的URI(可能还有更多这些风格)? 谢谢

1 个答案:

答案 0 :(得分:1)

  

所以我决定一个好的方法是将send动作返回的URI转换为实际的文件路径

那是所以不是一个好方法。

正如我今天已经指出过几次,过去几个月已经数十次,a Uri is not a file。您无法可靠地获取Uri的本地文件路径。甚至可能 本地路径,更不用说您可以访问的路径了。

如果您希望使用Uri所代表的内容,请使用getContentResolver().openInputStream()或反过来使用它的内容(例如,毕加索用于图片加载)。

相关问题