尝试从字符串路径解析Uri时为Null [英] Null when trying to parse Uri from String path

查看:101
本文介绍了尝试从字符串路径解析Uri时为Null的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用此 FileUtils 类来处理 Uri :

I'm using this FileUtils class to handle the Uri:

public class FileUtils {
private FileUtils() {
}

private static final String TAG = "FileUtils";
private static final boolean DEBUG = false;

private static boolean isExternalStorageDocument(Uri uri) {
    return "com.android.externalstorage.documents".equals(uri.getAuthority());
}

private static boolean isDownloadsDocument(Uri uri) {
    return "com.android.providers.downloads.documents".equals(uri.getAuthority());
}

private static boolean isMediaDocument(Uri uri) {
    return "com.android.providers.media.documents".equals(uri.getAuthority());
}


private static boolean isGooglePhotosUri(Uri uri) {
    return "com.google.android.apps.photos.content".equals(uri.getAuthority());
}

private static String getDataColumn(Context context, Uri uri, String selection,
                                    String[] selectionArgs) {

    Cursor cursor = null;
    final String column = "_data";
    final String[] projection = {
            column
    };

    try {
        cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs,
                null);
        if (cursor != null && cursor.moveToFirst()) {
            if (DEBUG)
                DatabaseUtils.dumpCursor(cursor);

            final int column_index = cursor.getColumnIndexOrThrow(column);
            return cursor.getString(column_index);
        }
    } finally {
        if (cursor != null)
            cursor.close();
    }
    return null;
}

@RequiresApi(api = Build.VERSION_CODES.KITKAT)
public static String getPath(final Context context, final Uri uri) {

    if (DEBUG)
        Log.d(TAG + " File -",
                "Authority: " + uri.getAuthority() +
                        ", Fragment: " + uri.getFragment() +
                        ", Port: " + uri.getPort() +
                        ", Query: " + uri.getQuery() +
                        ", Scheme: " + uri.getScheme() +
                        ", Host: " + uri.getHost() +
                        ", Segments: " + uri.getPathSegments().toString()
        );

    final boolean isKitKat = Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT;

    // DocumentProvider
    if (isKitKat && DocumentsContract.isDocumentUri(context, uri)) {
        if (isExternalStorageDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            if ("primary".equalsIgnoreCase(type)) {
                return Environment.getExternalStorageDirectory() + "/" + split[1];
            }

        }
        // DownloadsProvider
        else if (isDownloadsDocument(uri)) {

            final String id = DocumentsContract.getDocumentId(uri);
            final Uri contentUri = ContentUris.withAppendedId(
                    Uri.parse("content://downloads/public_downloads"), Long.valueOf(id));

            return getDataColumn(context, contentUri, null, null);
        }
        // MediaProvider
        else if (isMediaDocument(uri)) {
            final String docId = DocumentsContract.getDocumentId(uri);
            final String[] split = docId.split(":");
            final String type = split[0];

            Uri contentUri = null;
            if ("image".equals(type)) {
                contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
            } else if ("video".equals(type)) {
                contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
            } else if ("audio".equals(type)) {
                contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
            }

            final String selection = "_id=?";
            final String[] selectionArgs = new String[]{
                    split[1]
            };

            return getDataColumn(context, contentUri, selection, selectionArgs);
        }
    }
    // MediaStore (and general)
    else if ("content".equalsIgnoreCase(uri.getScheme())) {

        // Return the remote address
        if (isGooglePhotosUri(uri))
            return uri.getLastPathSegment();

        return getDataColumn(context, uri, null, null);
    }
    // File
    else if ("file".equalsIgnoreCase(uri.getScheme())) {
        return uri.getPath();
    }

    return null;
}

从设备中选择视频后,我在 onActivityResult 内部的 MainActivity 中调用它:

I call it in my MainActivity, inside onActivityResult, after selecting a video from the device:

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    if (requestCode == SELECT_VIDEO_REQUEST && resultCode == RESULT_OK) {

        if (Build.VERSION.SDK_INT >= 19) {
            
            //Calling FileUtils class
            String sourcePath = FileUtils.getPath(getApplicationContext(), data.getData());
          
            Intent intent = new Intent();
            intent.setClass(MainActivity.this, PlayerActivity.class);
            intent.putExtra("videoUri", sourcePath);
            startActivity(intent);

        } else {
            //Not relevant to the question
            .......

        }
    }
    if (requestCode == SELECT_VIDEO_REQUEST && resultCode != RESULT_OK) {
        Toast.makeText(getApplicationContext(), "Failed to select video", Toast.LENGTH_LONG).show();
    } else {
        super.onActivityResult(requestCode, resultCode, data);
    }


}

在我的 PlayerActivity 中,我得到了 String 并尝试解析 Uri ,如下所示:

In my PlayerActivity I get the String and try to parse the Uri, like this:

//Getting String from Intent
mStringFilePath = getIntent().getStringExtra("videoUri");
//Parse Uri from String
mVideoUri = Uri.parse(mStringFilePath);

在我的设备上进行测试时,我没有任何问题.我得到正确的路径,并且 Uri.parse 正常工作.但是我在Crashlytics上看到了很多崩溃,说-第59行的 nullpointerexception ,指的是 mVideoUri = Uri.parse(mStringFilePath);

When testing on my device, I have no issues. I get the correct path and the Uri.parse works fine. But I see a lot of crashes on my Crashlytics saying - nullpointerexception at line 59, referring to mVideoUri = Uri.parse(mStringFilePath);

我做错了什么?为什么它可以在我的设备上运行,而在其他一些设备上返回null?

What am I doing wrong? Why is it working on my device and returning null on some other devices?

我忘记添加< uses-permission android:name =" android.permission.READ_EXTERNAL_STORAGE"/> 在我的清单中.我至少没有得到 nullpointerexception ,但是得到了以下内容-

I forgot to add <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> in my Manifest. I'm at a point where I atleast don't get a nullpointerexception, but I get the following -

java.io.FileNotFoundException:找不到(没有这样的文件或目录)

当我从SD卡中选择文件时, Uri 为何不正确?

Somehow the Uri is incorrect when I select a file from my SD Card, any reason why?

推荐答案

崩溃可能是由于 mStringFilePath = getIntent().getStringExtra("videoUri"); 上的空字符串引起的,因为 getIntent().getStringExtras()如果没有所请求的Extras的值,则不会抛出nullpointerexception异常,但也不会将数据赋予 mStringFilePath 为null来解决此问题,请确保将uri解析的给定字符串包装在以下位置:

The Crash is probably occurred due to null String on mStringFilePath = getIntent().getStringExtra("videoUri"); since getIntent().getStringExtras() won't throw nullpointerexception if there isn't a value for the requested Extras but also won't give a data to the assigned variable the final result of the mStringFilePath will be null to fix this issue make sure that the given String for the uri parse is wrapped in:

if(mStringFilePath!= null){mVideoUri = Uri.parse(mStringFilePath);}

if(mStringFilePath != null){ mVideoUri = Uri.parse(mStringFilePath); }

这篇关于尝试从字符串路径解析Uri时为Null的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆