Hello everyone, I try to access the storage and select an image immediately after the app crashes me and then I get the following error:
It is important to note API 29 everything works great and only when I upload the API to version 30-31 I get this error. I have all the storage permissions
E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.pets.igloopet, PID: 9797
java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.io.File.exists()' on a null object reference
at com.pets.igloopet.activity.addpet.AddImage$1.onClick(AddImage.java:149)
at com.cocosw.bottomsheet.BottomSheet$4.onItemClick(BottomSheet.java:332)
at android.widget.AdapterView.performItemClick(AdapterView.java:330)
at android.widget.AbsListView.performItemClick(AbsListView.java:1197)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3190)
at android.widget.AbsListView$3.run(AbsListView.java:4166)
at android.os.Handler.handleCallback(Handler.java:938)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loopOnce(Looper.java:201)
at android.os.Looper.loop(Looper.java:288)
at android.app.ActivityThread.main(ActivityThread.java:7839)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
This is my code (File Addimage.java):
builder.listener(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
switch (which) {
case R.id.camera_cards:
if (ProjectUtils.hasPermissionInManifest(getActivity(), PICK_FROM_CAMERA, Manifest.permission.CAMERA)) {
if (ProjectUtils.hasPermissionInManifest(getActivity(), PICK_FROM_GALLERY, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
try {
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = getOutputMediaFile(1);
if (!file.exists()) {
try {
ProjectUtils.pauseProgressDialog();
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
//Uri contentUri = FileProvider.getUriForFile(getApplicationContext(), "com.example.asd", newFile);
picUri = FileProvider.getUriForFile(getActivity().getApplicationContext(), getActivity().getApplicationContext().getPackageName() ".fileprovider", file);
} else {
picUri = Uri.fromFile(file); // create
}
sharedPrefrence.setValue(Consts.IMAGE_URI_CAMERA, picUri.toString());
intent.putExtra(MediaStore.EXTRA_OUTPUT, picUri); // set the image file
startActivityForResult(intent, PICK_FROM_CAMERA);
} catch (Exception e) {
e.printStackTrace();
}
}
}
break;
case R.id.gallery_cards:
if (ProjectUtils.hasPermissionInManifest(getActivity(), PICK_FROM_CAMERA, Manifest.permission.CAMERA)) {
if (ProjectUtils.hasPermissionInManifest(getActivity(), PICK_FROM_GALLERY, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
File file = getOutputMediaFile(1);
if (!file.exists()) {
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
picUri = Uri.fromFile(file);
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_FROM_GALLERY);
}
}
break;
case R.id.cancel_cards:
builder.setOnDismissListener(new DialogInterface.OnDismissListener() {
@Override
public void onDismiss(DialogInterface dialog) {
dialog.dismiss();
}
});
break;
}
}
});
CodePudding user response:
you get this exception because the method "getOutputMediaFile" return null and you try to use null object.
first, add null check to file, its always good approach.
second, you have to understand why this method return null and not the file you want. if you try to use "getExternalStorageDirectory" and call mkdirs(), its depracated, you should use "getExternalFilesDir" on your context/activity.
try to do the change, if it does not help, please share with us the method "getOutputMediaFile" so we can see whats going on there and give you further help.
CodePudding user response:
You have horrible error and null handling. Things go wrong? Sod it, log nothing, do nothing, just return null
!
And now you are wondering why you get unexpected null pointer exceptions.
As homer would say, 'Duh'.
We can delve into why it happens here specifically but this is interchangible with a thousand other similar situations. The real fix is for you to stop handling errors like this.
Here's an example:
if (!mediaStorageDir.mkdirs()) { return null; }
This is silly. Don't do this. And it would directly lead to your NPE error here if indeed making the directories fails to work.
Log something if you want, but most of all, when things occur that you did not expect, and you don't quite now what it means if it happens, always throw an exception, and add details if you like. The exception means that IF the unexpected happens, at least you get a stack trace with a whole bunch of details and crucially, something pointing right at the place where the weird, unexpected, not quite understood thing happened. It would in this case be pointing right at "Weird, I can't make those dirs" - at least now you know what to investigate. Perhaps your app doesn't have the appropriate file rights, android will just fail the operation if your app doesn't have the user permission.
You pull the same stunt when type
isn't 1
- then you just go: Oh, uh, no idea, whatever - just return null. Don't. That return null;
in the else block there should be throw new IllegalArgumentException("Type " type " not implemented yet");
or whatnot.
Fix those things - and then the answer to your question will become self evident. Without fixing this - we don't know either.