Capture image without permission with Android 6.0

12,094

Solution 1

It is possible if you on android 4.4+, you can specify MediaStore.EXTRA_OUTPUT, to be a file under your package-specific directories

Starting in Android 4.4, the owner, group and modes of files on external storage devices are now synthesized based on directory structure. This enables apps to manage their package-specific directories on external storage without requiring they hold the broad WRITE_EXTERNAL_STORAGE permission. For example, the app with package name com.example.foo can now freely access Android/data/com.example.foo/ on external storage devices with no permissions. These synthesized permissions are accomplished by wrapping raw storage devices in a FUSE daemon.

https://source.android.com/devices/storage/

Solution 2

Try this:

Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
File file = new File(getActivity().getApplicationContext().getExternalFilesDir(android.os.Environment.DIRECTORY_PICTURES).getAbsolutePath() + File.separator + "yourPicture.jpg");
Uri uri = Uri.fromFile(file);
cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, url);

This gives you access to an "external" storage writable for camera apps in this case, but the files are just visible from your app. To learn a little bit more about storage spaces in android see https://www.youtube.com/watch?v=C28pvd2plBA

Hope it helps you!

Solution 3

This is possible without either of the CAMERA and WRITE_EXTERNAL_STORAGE permissions.

You can create a temporary in your app's cache directory, and give other apps access to it. That makes the file writeable by the camera app:

File tempFile = File.createTempFile("photo", ".jpg", context.getCacheDir());
tempFile.setWritable(true, false);

Now you just need to pass this file as the output file for the camera intent:

Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(mTempFile));  // pass temp file
startActivityForResult(intent, REQUEST_CODE_CAMERA);

Note: the file Uri won't be passed to you in the Activity result, you'll have to keep a reference to the tempFile and retrieve it from there.

Solution 4

Since the camera app cannot access to the private dirs of your app, It's your applications duty to write the photo file to that directory. I'm not really sure about this but this works for me:

private File createImageFile() throws IOException {
    // Create an image file name
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss", Locale.getDefault())
            .format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);
    return File.createTempFile(
            imageFileName,  /* prefix */
            ".jpg",         /* suffix */
            storageDir      /* directory */
    );
}

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
    // Create the File where the photo should go
    File photoFile = null;
    try {
        photoFile = createImageFile();
        takePictureIntent.putExtra("PhotoPath", mCameraPhotoPath);
    } catch (IOException ex) {
        // Error occurred while creating the File
        Log.e(TAG, "Unable to create Image File", ex);
    }

    // Continue only if the File was successfully created
    if (photoFile != null) {
        takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,
                Uri.fromFile(photoFile));
    } else {
        takePictureIntent = null;
    }
}

But you still need WRITE_EXTERNAL_STORAGE permission before KITKAT:

<uses-permission
    android:name="android.permission.WRITE_EXTERNAL_STORAGE"
    android:maxSdkVersion="18" />
Share:
12,094

Related videos on Youtube

stankocken
Author by

stankocken

Updated on July 09, 2022

Comments

  • stankocken
    stankocken almost 2 years

    I need to let the user take a picture (from the gallery or from a camera app) with Android 6.0.

    Because I don't need to control the camera, I wanted to use an intent as describe here:

    However, if you don't need such control, you can just use an ACTION_IMAGE_CAPTURE intent to request an image. When you start the intent, the user is prompted to choose a camera app (if there isn't already a default camera app), and that app takes the picture. The camera app returns the picture to your app's onActivityResult() method.

    https://developer.android.com/preview/features/runtime-permissions.html

    But for this ACTION_IMAGE_CAPTURE, you need to fill the extra "MediaStore.EXTRA_OUTPUT" which is an Uri to a temp file (without this param I will have only a thumbnail). This temp file must be into the external storage (to be accessible by the camera app). You need the permission WRITE_EXTERNAL_STORAGE to create a file on the external storage.

    So it's not possible to capture an image through native dialogs/apps without the permission android.permission.CAMERA or android.permission.WRITE_EXTERNAL_STORAGE. Is that correct?

    Thanks

  • Greg Ennis
    Greg Ennis over 8 years
    Have you actually tried this? This gives YOUR app access to the directory, but not the CAMERA app, which is the problem.
  • Vinil Chandran
    Vinil Chandran about 8 years
    @Derek Fung can you share an example project?
  • wiradikusuma
    wiradikusuma about 8 years
    Doesn't seem to work anymore when targeting Marshmallow.
  • Andrea Lazzarotto
    Andrea Lazzarotto over 7 years
    This is the only working solution I found so far that doesn't break on Android 6. :)
  • Zapnologica
    Zapnologica over 7 years
    this option seems promising, anyone have any feedback with regards to compatibility?
  • Makalele
    Makalele over 7 years
    Doesn't work. Camera app doesn't have access to app cache dir.
  • Makalele
    Makalele over 7 years
    Working! No need for WRITE_EXTERNAL_STORAGE or READ_EXTERNAL_STORAGE.
  • Makalele
    Makalele over 7 years
    Camera doesn't have access to app private cache dir directory. @Jonathan Aste's solution is working.
  • CoolMind
    CoolMind about 6 years
    Thanks! In onActivityResult you will get RESULT_OK and data == null. In this case you should either read a file from path (variable uri), or see stackoverflow.com/questions/32043222/…. You have to get permission for file reading on API >= 23.