David Faizulaev
David Faizulaev

Reputation: 5721

Android M - camera permissions issue

I'm encountering the known issue of permissions in Android M. When attempting the open the camera it get the following exception:

java.lang.SecurityException: Permission Denial: starting Intent 
{ act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } 
from ProcessRecord{834e30b 8608:il.ac.shenkar.david.todolistex2/u0a126} (pid=8608, uid=10126) with revoked permission android.permission.CAMERA

Here is my complete code, it includes a workaround that I've found here and worked for others, but for some reason fails for me.

public class ReportTaskStatus extends AppCompatActivity{

private Task tastToEdit;
private RadioButton acceptrb;
private RadioButton statusrb;
private TextView label;
private List<ParseObject> tsks=null;

public Uri fileUri;
private int CAMERA_REQUEST = 100;
private int Gallary_REQUEST = 101;
public static final int MY_PERMISSIONS_REQUEST_CAMERA = 0;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_report_task_status);
    Toolbar toolbar = (Toolbar) findViewById(R.id.toolbar);
    setSupportActionBar(toolbar);
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);

    Intent i = getIntent();


    tastToEdit = (Task)i.getSerializableExtra("task");
    label = (TextView)findViewById(R.id.categorylabel);
    label.append(" "+tastToEdit.getTask_catg().toString());

    label = (TextView)findViewById(R.id.prioritylabel);
    label.append(" "+tastToEdit.getPriority().toString());

    label = (TextView)findViewById(R.id.locationlabel);
    label.append(" " + Location.fromInteger(tastToEdit.getTsk_location()).toString());

    label = (TextView)findViewById(R.id.duetimelabel);

    if(tastToEdit.getDueDate()!=null)
    {
        SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
        SimpleDateFormat sdft = new SimpleDateFormat("HH:mm");
        label.append(" " + (sdf.format(tastToEdit.getDueDate())));
        label.append(" " + (sdft.format(tastToEdit.getDueDate())));
    }

    Task_Status tsk_stts = tastToEdit.getTask_sts();

    if(tsk_stts==Task_Status.WAITING)
    {
        statusrb = (RadioButton) findViewById(R.id.waitingstatusRBtn);
        statusrb.setChecked(true);
    }
    if(tsk_stts==Task_Status.INPROGESS)
    {
        statusrb = (RadioButton) findViewById(R.id.inprogstatusRBtn);
        statusrb.setChecked(true);
    }
    if(tsk_stts==Task_Status.DONE)
    {
        statusrb = (RadioButton) findViewById(R.id.donestatusRBtn);
        statusrb.setChecked(true);
    }
    //Get a Tracker (should auto-report)
    ((MyApplication) getApplication()).getTracker(MyApplication.TrackerName.APP_TRACKER);

    RadioGroup radioGroup = (RadioGroup) findViewById(R.id.statusgroup);
    radioGroup.setOnCheckedChangeListener(new RadioGroup.OnCheckedChangeListener() {
        @Override
        public void onCheckedChanged(RadioGroup group, int checkedId)
        {
            RadioButton rb = (RadioButton) findViewById(R.id.donestatusRBtn);
            if(rb.isChecked())
            {
                Log.w("donestatusRBtn","donestatusRBtn");
                openCamera();
            }
        }
    });
}

private void Camerapermission() {
    // Here, thisActivity is the current activity
    if (ContextCompat.checkSelfPermission(ReportTaskStatus.this
            ,
            Manifest.permission.CAMERA)
            != PackageManager.PERMISSION_GRANTED) {

        // Should we show an explanation?
        if (ActivityCompat.shouldShowRequestPermissionRationale(ReportTaskStatus.this,
                Manifest.permission.CAMERA)) {

            // Show an expanation to the user *asynchronously* -- don't block
            // this thread waiting for the user's response! After the user
            // sees the explanation, try again to request the permission.

        } else {

            // No explanation needed, we can request the permission.

            ActivityCompat.requestPermissions(ReportTaskStatus.this,
                    new String[]{Manifest.permission.CAMERA},
                    MY_PERMISSIONS_REQUEST_CAMERA);

            // MY_PERMISSIONS_REQUEST_READ_CONTACTS is an
            // app-defined int constant. The callback method gets the
            // result of the request.
        }
    }
}

void openCamera() {
    try {
        Intent cameraIntent = new Intent(
        android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
        startActivityForResult(cameraIntent, CAMERA_REQUEST);
    } catch (Exception e) {
        e.printStackTrace();
    }
}

@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
    switch ( requestCode ) {
        case MY_PERMISSIONS_REQUEST_CAMERA: {
            for( int i = 0; i < permissions.length; i++ ) {
                if( grantResults[i] == PackageManager.PERMISSION_GRANTED ) {
                    Log.d( "Permissions", "Permission Granted: " + permissions[i] );
                } else if( grantResults[i] == PackageManager.PERMISSION_DENIED ) {
                    Log.d( "Permissions", "Permission Denied: " + permissions[i] );
                }
            }
        }
        break;
        default: {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
        }
    }
}
}

Permissions for manifest.xml

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_CALENDAR" />
<uses-permission android:name="android.permission.WRITE_CALENDAR" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />

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

Please assist.

Upvotes: 1

Views: 1955

Answers (3)

vnj
vnj

Reputation: 74

Maybe you are using device with Android M, so give the appropriate permissions to the app: Settings -> Apps -> your app

If this does not help look at this workaround.

Upvotes: 1

JYA
JYA

Reputation: 100

Add this to your manifest:

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

Reference in doc:

http://developer.android.com/guide/topics/manifest/uses-feature-element.html#permissions

Upvotes: 1

CommonsWare
CommonsWare

Reputation: 1006584

First, you are not calling your Camerapermission() method, at least in terms of the code shown in your question.

Second, you are allowing the user to do something strange with a RadioButton that triggers a call to openCamera(), without checking to see that you have permission to use the camera. For example, you could use checkSelfPermission() to see if you have permission, and only enable that RadioButton if you do.

You may wish to read more about the runtime permission system.

Upvotes: 2

Related Questions