Android 11/12图片上传报错java.lang.NullPointerException: uriString求助
Android 11/12下Matisse图片上传出现
NullPointerException: uriString问题解决 问题现象
仅在Android 11、12系统中使用Matisse库实现图片上传时出现java.lang.NullPointerException: uriString错误,其他Android版本可正常上传。
错误日志
2022-11-15 12:27:13.220 25887-24114/com.app.zeis E/sqlite3_android: [IKR-38846] ONEPLUS_NAME_PARTS_MATCH SQLITE_OK 2022-11-15 12:27:15.951 25887-25887/com.app.zeis E/AndroidRuntime: FATAL EXCEPTION: main Process: com.app.zeis, PID: 25887 java.lang.RuntimeException: Failure delivering result ResultInfo{who=null, request=22, result=-1, data=Intent { act=inline-data (has extras) }} to activity {com.app.zeis/com.app.zeis.UploadPanActivity}: java.lang.NullPointerException: uriString at android.app.ActivityThread.deliverResults(ActivityThread.java:5220) at android.app.ActivityThread.handleSendResult(ActivityThread.java:5261) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:245) at android.app.ActivityThread.main(ActivityThread.java:8024) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978) Caused by: java.lang.NullPointerException: uriString at android.net.Uri$StringUri.<init>(Uri.java:496) at android.net.Uri$StringUri.<init>(Uri.java:486) at android.net.Uri.parse(Uri.java:458) at com.app.zeis.UploadPanActivity.getImageUri(UploadPanActivity.java:314) at com.app.zeis.UploadPanActivity.onActivityResult(UploadPanActivity.java:233) at android.app.Activity.dispatchActivityResult(Activity.java:8316) at android.app.ActivityThread.deliverResults(ActivityThread.java:5213) at android.app.ActivityThread.handleSendResult(ActivityThread.java:5261) at android.app.servertransaction.ActivityResultItem.execute(ActivityResultItem.java:51) at android.app.servertransaction.TransactionExecutor.executeCallbacks(TransactionExecutor.java:135) at android.app.servertransaction.TransactionExecutor.execute(TransactionExecutor.java:95) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2253) at android.os.Handler.dispatchMessage(Handler.java:106) at android.os.Looper.loop(Looper.java:245) at android.app.ActivityThread.main(ActivityThread.java:8024) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:631) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:978) 2022-11-15 12:27:16.086 25887-24114/com.app.zeis E/sqlite3_android: [IKR-38846] ONEPLUS_NAME_PARTS_MATCH SQLITE_OK
问题代码
图片选择代码
Matisse.from(UploadPanActivity.this) .choose(MimeType.ofImage()) .countable(true).capture(false) .maxSelectable(1) .gridExpectedSize(300) .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED) .thumbnailScale(0.85f) .imageEngine(new GlideEngine()) .showPreview(false) // Default is `true` .forResult(21);
结果回调代码
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); System.out.println("AAkash " + requestCode); Bitmap photo = (Bitmap) data.getExtras().get("data"); Uri tempUri = getImageUri(getApplicationContext(), photo); // CALL THIS METHOD TO GET THE ACTUAL PATH File finalFile = new File(getRealPathFromURI(tempUri)); if (requestCode == 21 && resultCode == RESULT_OK) { sendPan(userDetails.getuserid(), "8", Matisse.obtainPathResult(data).get(0), "pan_photo"); } }
获取图片URI方法
public Uri getImageUri(Context inContext, Bitmap inImage) { Bitmap OutImage = Bitmap.createScaledBitmap(inImage, 1000, 1000, true); String path = MediaStore.Images.Media.insertImage(inContext.getContentResolver(), OutImage, "easy_loan_profile_pic", null); return Uri.parse(path); }
通过URI获取真实路径方法
public String getRealPathFromURI(Uri uri) { String path = ""; if (getContentResolver() != null) { Cursor cursor = getContentResolver().query(uri, null, null, null, null); if (cursor != null) { cursor.moveToFirst(); int idx = cursor.getColumnIndex(MediaStore.Images.ImageColumns.DATA); path = cursor.getString(idx); cursor.close(); } } return path; }
问题原因
MediaStore.Images.Media.insertImage()高版本失效:该方法在Android 10及以上版本(尤其是11/12)因存储权限模型变更,会返回null,导致Uri.parse(path)触发空指针异常。- 冗余代码引发崩溃:你在
onActivityResult中额外处理的Bitmap获取、MediaStore插入逻辑完全多余——Matisse已经直接返回了选中图片的路径(Matisse.obtainPathResult(data).get(0)),这部分代码反而触发了高版本兼容性问题。 data.getExtras().get("data")不可靠:该方法返回的是缩略图Bitmap,并非原图,且在高版本系统中大概率返回null,进一步导致后续逻辑崩溃。
修复方案
直接移除冗余的Bitmap、Uri转换逻辑,使用Matisse提供的路径直接上传,同时适配Android 11+存储规则:
修正后的onActivityResult代码
@Override protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { super.onActivityResult(requestCode, resultCode, data); System.out.println("AAkash " + requestCode); // 仅在请求码匹配、结果成功且data不为空时处理 if (requestCode == 21 && resultCode == RESULT_OK && data != null) { // 直接使用Matisse返回的图片路径 String imagePath = Matisse.obtainPathResult(data).get(0); sendPan(userDetails.getuserid(), "8", imagePath, "pan_photo"); } }
额外注意事项
- 权限适配:AndroidManifest.xml中需声明必要权限,Android 11+如需访问公共存储,需添加
android.permission.MANAGE_EXTERNAL_STORAGE权限并引导用户手动授权;若使用拍照功能,配合Matisse的capture()方法并通过MediaStore存储即可。 - 避免依赖
DATA列:Android 10+中MediaStore.Images.ImageColumns.DATA列可能无法获取真实路径,推荐使用ContentResolver直接读取文件流上传:
// 示例:通过ContentResolver获取输入流上传 Uri imageUri = Matisse.obtainResult(data).get(0); InputStream inputStream = getContentResolver().openInputStream(imageUri); // 使用inputStream执行上传操作
内容的提问来源于stack exchange,提问作者MARSH
相关产品推荐
相关产品推荐

