2
votes

I am trying to take photo from android device's native Camera App. For that i create a file first and then attach its URI with the intent to capture image and write output in that file. For file provider i have added the following in the AndroidManifest file

    <provider
        android:name="android.support.v4.content.FileProvider"
        android:authorities="com.example.myapp.fileprovider"
        android:exported="false"
        android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"></meta-data>
    </provider>

And the java code for capturing image is as follows

Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // Ensure that there's a camera activity to handle the intent
    if (takePictureIntent.resolveActivity(mActivity.getPackageManager()) != null) {
        // Create the File where the photo should go
        File photoFile = null;
        try {
            String imageName = "image_" + Preferences.getStringForUserId(mActivity);
            photoFile = createImageFile(imageName);
            mCurrentPhotoPath = photoFile.getAbsolutePath();

        } catch (IOException ex) {
            // Error occurred while creating the File
            ex.printStackTrace();
        }
        // Continue only if the File was successfully created
        if (photoFile != null) {
            try {
                if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                    String authorities = "com.example.myapp.fileprovider";
                    Uri photoURI = FileProvider.getUriForFile(mActivity, authorities, photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

                } else {
                    Uri photoURI = Uri.fromFile(photoFile);
                    takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);
                }
                mActivity.startActivityForResult(takePictureIntent, CAMERA_CODE);

            } catch (Exception ex) {
                // Error occurred while creating the File
                ex.printStackTrace();
                Toast.makeText(mActivity, ex.toString(), Toast.LENGTH_LONG).show();
            }
        }
    } else {
        Toast.makeText(mActivity, "No Camera App found in device", Toast.LENGTH_LONG).show();
    }

As documented in Android own documentation by Google in: https://developer.android.com/training/camera/photobasics.html I have added necessary permissions

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

But did not add permission for Camera and i am also asking for runtime permissions for Android M or higher. Getting from the Google docs it is clear that we do not need Camera Permission if we want to use native Camera App to capture photos for our App, then why does it give me this exception stated below

java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.android.camera/.Camera clip={text/uri-list U:file:///storage/emulated/0/Android/data/com.example.myapp/files/Pictures/myapp/image_20130-1383873550.jpg} (has extras) } from ProcessRecord{d82d864 6641:com.pencilinapp.pencilin/u0a63} (pid=6641, uid=10063) with revoked permission android.permission.CAMERA

So my question is that do i have to ask for both Camera and Storage permissions from now on? And why is it not stated in Google Documentation?

I have researched and checked many stackoverflow threads but none gave answer related to this issue so far.

3
"Getting from the Google docs it is clear that we do not need Camera Permission if we want to use native Camera App to capture photos for our App" - are you sure? - Shalu T D
as i have also given link please see this developer.android.com/training/camera/photobasics.html There is no mention of adding Camera permission - Faizy_Flash
Google says - If you are using the camera by invoking an existing camera app, your application does not need to request this permission. developer.android.com/guide/topics/media/camera.html - Shalu T D
@ShaluTD and in almost all blogs that i have visited for adding Image capturing feature from Camera App, i have seen that they add only Storage Permissions, i did that as well and my App was working fine for a time (maybe permission had been granted from App settings, idk..) but recently when i checked my Image Capturing feature, it started to give me this Exception - Faizy_Flash
i think u have confused it with taking Images using Camera API. No i am not using camera API, i'm just leveraging Android's Camera App. And i have seen this doc too. And yeah of course Google says that "If you are using the camera by invoking an existing camera app, your application does not need to request this permission", so they why does it give SecurityException now? thats what i wanna know - Faizy_Flash

3 Answers

2
votes

The issue is the revoked permission ("with revoked permission android.permission.CAMERA"). Normally, you do not need permission, but if you ask for permission (say, in a previous build of your app), and the user revokes that permission, then you cannot use ACTION_IMAGE_CAPTURE.

0
votes

Add below lines in your Manifest.xml :

<uses-feature
android:name="android.hardware.camera.any"
android:required="true" />

<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-permission android:name="android.permission.CAMERA" />

Please refer to this URL for more.

0
votes

However, not all Android devices actually have these hardware features. So if your app requests the CAMERA permission, it's important that you also include the <uses-feature> tag in your manifest to declare whether or not this feature is actually required. For more information, see Google Play and feature-based filtering

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="your package" >
    <uses-permission android:name="android.permission.CAMERA"/>
    <uses-permission  android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-feature android:name="android.hardware.camera2.full" />
    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >
        <activity
            android:name=".MainActivity"
            android:label="@string/app_name" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>
</manifest>

From Marshmallow, Dangerous permissions are:

  1. READ_CALENDAR
  2. WRITE_CALENDAR
  3. CAMERA
  4. READ_CONTACTS
  5. WRITE_CONTACTS
  6. GET_ACCOUNTS
  7. ACCESS_FINE_LOCATION
  8. ACCESS_COARSE_LOCATION
  9. RECORD_AUDIO
  10. READ_PHONE_STATE
  11. CALL_PHONE
  12. READ_CALL_LOG
  13. WRITE_CALL_LOG
  14. ADD_VOICEMAIL
  15. USE_SIP
  16. PROCESS_OUTGOING_CALLS
  17. BODY_SENSORS
  18. SEND_SMS
  19. RECEIVE_SMS
  20. READ_SMS
  21. RECEIVE_WAP_PUSH
  22. RECEIVE_MMS
  23. READ_EXTERNAL_STORAGE
  24. WRITE_EXTERNAL_STORAGE

SO i think Permission may be required...