尝试从字符串路径解析Uri时为Null [英] Null when trying to parse Uri from String path
问题描述
我正在使用此 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屋!