1

First of all, I already checked out this similar question but it didn't seem to work well with my code. So here it is, my problem is that my app crashes anytime I try to open the camera in order to take a picture and store it. Here's the code I'm using:

@RequiresApi(api = Build.VERSION_CODES.M)
private void dispatchTakePictureIntent() throws IOException {

    Log.i("Debug","dispatchTakePictureIntent entered");
    checkCameraPermissions();
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Makes sure there's an activity that handles the intent
    if (takePictureIntent.resolveActivity(getContext().getPackageManager()) != null) {

        File image = null;
        try{
            image = createImageFile();
        } catch (IOException ex) {
            Log.i("Debug", "IOException: " + ex);
        }
        // Continues if the file is created correctly
        if(image != null){

            Uri imageUri = Uri.fromFile(image); // <-- Here's the error 

            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); 
            Log.i("Debug", "Photo succesfully saved " + takePictureIntent);
        }
    }
}

And also, my method createImageFile:

    private File createImageFile() throws IOException { 


    File imageRoot = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES), appDirectoryName);

    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File newFile = new File(imageRoot, imageFileName + ".jpg");
    if(!imageRoot.exists())
        if (!imageRoot.mkdirs())
            return null;

    mCurrentPhotoPath = newFile.getAbsolutePath();

    return newFile;

}

And the error I'm getting when I press the camera button I have in-app:

FATAL EXCEPTION: main
              Process: com.odoo.quipons, PID: 13976
              android.os.FileUriExposedException: file:///data/user/0/com.odoo.myApp/files/Android/data/myApp/files/Pictures/JPEG_20171122_111843_.jpg exposed beyond app through ClipData.Item.getUri()
Adrián Valero
  • 29
  • 1
  • 2
  • 9
  • You have a FileUriExposedException. And the link you refer to should be sufficient to solve your problem. So what is the problem? – greenapps Nov 22 '17 at 10:42
  • `Log.i("Debug", "Photo succesfully saved " + takePictureIntent);`. That is the wrong place for such a message. You only start the camera app there. Picture is not yet taken. Nothing saved yet. – greenapps Nov 22 '17 at 10:43
  • `if(!imageRoot.exists()) imageRoot.mkdirs();`. ImageRoot? Unknown variable! Further you should check the return value of mkdirs and not continu if it fails. Please adapt your code. – greenapps Nov 22 '17 at 10:45
  • `getContext().getFilesDir(), "Android/data/MyApp/files/Pictures");` Why creating all those subdirectories in your private internal memory? It looks to me that you are confused with getExternalFilesDir(). – greenapps Nov 22 '17 at 10:48
  • `// Continues if the file is created correctly`. You are not trying to create a file already. WHICH IS OK. You only constructed a filename in a File object. – greenapps Nov 22 '17 at 10:52
  • `you're right about imageRoot, `. Then change your code. As now it is nonsense. – greenapps Nov 22 '17 at 10:54
  • There you go then. Could you please explain a bit more in-depth what it is I'm doing wrong? I'm having a really hard time getting this to work, that's why I started this question in the first place. – Adrián Valero Nov 22 '17 at 10:56
  • I told you 'exactly' how you should change your createImageFile() code. When you are done with it and have posted the updated code we can continue. – greenapps Nov 22 '17 at 10:59
  • @greenapps Okay, I already did. I'm confused about what you said about the internal memory, wouldn't I just create the subdirectory Pictures? I'm only supposed to store a small amount of pictures in it. – Adrián Valero Nov 22 '17 at 11:31
  • You are messing around with two storage locations. File imageRoot and File imagePath. That is not ok. You should first decide which storage location you wanna use. Only one. Not two. – greenapps Nov 22 '17 at 11:36
  • Dude, I already added the variable to the method and changed all the other things you said, I just told you I'm confused about the thing you said about getExternalFilesDir(). – Adrián Valero Nov 22 '17 at 11:37
  • Sorry i overlooked that you added that variable. But does not matter. You should decide upon only one location. getFilesDir() is a differend location as getExternal.... – greenapps Nov 22 '17 at 11:38
  • Okay, I already did. Sorry if I sounded a bit harsh but this problem is just kind of ruining my day. Thanks for the help – Adrián Valero Nov 22 '17 at 11:40
  • `imageRoot.mkdirs();` Check the return value! And return `null` when it fails. Also tell if you manage the exception now. – greenapps Nov 22 '17 at 11:42
  • I just did change that, check the edited version of the question. It does not throw the exception now, since it's always returning a null value. – Adrián Valero Nov 22 '17 at 11:52
  • `Now, my code is always getting into the second condition and returning null.`. My god.. second condition ?? If mkdirs() fails then just say 'mkdirs() fails`. And do not add an extra edit code block. Just update the code in that function. Now it makes it unreadable. – greenapps Nov 22 '17 at 11:57
  • Okay then. Can you help me now? – Adrián Valero Nov 22 '17 at 12:05
  • Please adapt the code of createImageFile() first. Where is the null? And if mkdirs() fails then say so. I do not know what you mean with ' okay then'. Come to the point! – greenapps Nov 22 '17 at 12:11
  • It is now. As I said, it returns null everytime. – Adrián Valero Nov 22 '17 at 12:25
  • So the Pictures directory does not exist to begin with on your device!? Can you check using a file explorer app on your device? – greenapps Nov 22 '17 at 12:29
  • I thought that was exactly what mkdirs() did. – Adrián Valero Nov 22 '17 at 12:38
  • Sorry but i do not understand what you say. Can you just do the check i asked for? – greenapps Nov 22 '17 at 12:40
  • No it does not. I said I thought that was exactly what mkdirs did, as make a directory where there's none. – Adrián Valero Nov 22 '17 at 12:46
  • No it does not? What does that mean? My god come to the point! Make a complete sentence. Tell what you did! – greenapps Nov 22 '17 at 12:50

1 Answers1

0

Besides the solution using the- FileProvider, there is another way to work around this. Simply put in Application.onCreate(). In this way, the VM ignores the file URI exposure. Just paste the below code in Activity onCreate().

StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder(); 
 StrictMode.setVmPolicy(builder.build());
Codeplayon
  • 429
  • 1
  • 6
  • 16