0

I'm developing app in which we pick image from Camera OR Gallery using intents and set to ImageView. The camera button feature is working perfect. The problem is when first time I click Gallery button it asks permission when I allow the permission it the app crashes but gallery opens. Then second time when I open app and click the Gallery button again then works fine. Here is my code: The WRITE_EXTERNAL_STORAGE permission is used for both taking image from camera intent and also taking image from Galley intent may be that is causing the problem. But I'm new in android development so don't know how to solve it.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.blogspot.atifsoftwares.myapplication">

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

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>
    </application>

</manifest>

activity_main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageIv"
        android:layout_width="match_parent"
        android:layout_height="300dp"
        android:scaleType="fitCenter"
        android:src="@drawable/ic_launcher_background" />
    <Button
        android:id="@+id/galleryBtn"
        android:text="Gallery"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />
    <Button
        android:id="@+id/cameraBtn"
        android:text="Camera"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

</LinearLayout>

MainActivity.java

package com.blogspot.atifsoftwares.myapplication;

import android.Manifest;
import android.content.ContentValues;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.NonNull;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

public class MainActivity extends AppCompatActivity {

    private static final int IMAGE_PICK_GALLERY_CODE = 1000;
    private static final int IMAGE_PICK_CAMERA_CODE = 1001;
    private static final int PERMISSION_WRITE_STORAGE_CODE = 1002;
    private static final int PERMISSION_CAMERA_CODE = 1003;

    Uri image_uri;

    ImageView mImageView;
    Button mGalleryBtn, mCameraBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = findViewById(R.id.imageIv);
        mGalleryBtn = findViewById(R.id.galleryBtn);
        mCameraBtn = findViewById(R.id.cameraBtn);

        //Gallery button click listener to pick image from gallery
        mGalleryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                    //System OS is Marshmallow or above
                    if (checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE)
                            == PackageManager.PERMISSION_DENIED){
                        //permission not granted, request it.
                        String[] permissions = {Manifest.permission.WRITE_EXTERNAL_STORAGE};
                        //show popup for runtime permission
                        requestPermissions(permissions, PERMISSION_WRITE_STORAGE_CODE);
                    }
                    else {
                        //permission already granted
                        pickGallery();
                    }
                }
                else {
                    //System OS is less then Marshmallow
                    pickGallery();
                }
            }
        });
        //Camera button click listener to pick image from gallery
        mCameraBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                    //System OS is Marshmallow or above
                    if (checkSelfPermission(Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED ||
                            checkSelfPermission(Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_DENIED){
                        //permission not granted, request it.
                        String[] permissions = {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
                        //show popup for runtime permission
                        requestPermissions(permissions, PERMISSION_CAMERA_CODE);
                    }
                    else {
                        //permission already granted
                        pickCamera();
                    }
                }
                else {
                    //System OS is less than Marshmallow
                    pickCamera();
                }
            }
        });

    }

    public void pickCamera(){
        //take image from default camera
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "New Picture");
        values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
        image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
        startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
    }

    public void pickGallery(){
        //pick image from gallery
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
    }


    //handle result of runtime permission
    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode){
            case PERMISSION_WRITE_STORAGE_CODE:{
                if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //permission was granted
                    Toast.makeText(this, "Gallery Granted", Toast.LENGTH_SHORT).show();
                    pickGallery();
                }
                else {
                    //permission was denied
                    Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
                }
            }
            case PERMISSION_CAMERA_CODE:{
                if (grantResults.length >0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                    //permission was granted
                    Toast.makeText(this, "Camera Granted", Toast.LENGTH_SHORT).show();
                    pickCamera();
                }
                else {
                    //permission was denied
                    Toast.makeText(this, "Permission denied...!", Toast.LENGTH_SHORT).show();
                }

            }
        }
    }

    //handle result of picked image
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == RESULT_OK){
            if (requestCode == IMAGE_PICK_GALLERY_CODE){
                //set image to image view
                mImageView.setImageURI(data.getData());
            }
            if (requestCode == IMAGE_PICK_CAMERA_CODE){
                //set image to image view
                mImageView.setImageURI(image_uri);
            }
        }

    }


}

Here is logcat report:

FATAL EXCEPTION: main
    Process: com.blogspot.atifsoftwares.myapplication, PID: 24672
    java.lang.RuntimeException: Failure delivering result ResultInfo{who=@android:requestPermissions:, request=1002, result=-1, data=Intent { act=android.content.pm.action.REQUEST_PERMISSIONS (has extras) }} to activity {com.blogspot.atifsoftwares.myapplication/com.blogspot.atifsoftwares.myapplication.MainActivity}: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4339)
        at android.app.ActivityThread.handleSendResult(ActivityThread.java:4382)
        at android.app.ActivityThread.-wrap20(ActivityThread.java)
        at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1679)
        at android.os.Handler.dispatchMessage(Handler.java:102)
        at android.os.Looper.loop(Looper.java:186)
        at android.app.ActivityThread.main(ActivityThread.java:6509)
        at java.lang.reflect.Method.invoke(Native Method)
        at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:914)
        at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:804)
     Caused by: java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE flg=0x3 cmp=com.oppo.camera/.Camera clip={text/uri-list U:content://media/external/images/media/58337} (has extras) } from ProcessRecord{f4a4aee 24672:com.blogspot.atifsoftwares.myapplication/u0a427} (pid=24672, uid=10427) with revoked permission android.permission.CAMERA
        at android.os.Parcel.readException(Parcel.java:1702)
        at android.os.Parcel.readException(Parcel.java:1655)
        at android.app.ActivityManagerProxy.startActivity(ActivityManagerNative.java:3229)
        at android.app.Instrumentation.execStartActivity(Instrumentation.java:1520)
        at android.app.Activity.startActivityForResult(Activity.java:4434)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767)
        at android.app.Activity.startActivityForResult(Activity.java:4369)
        at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754)
        at com.blogspot.atifsoftwares.myapplication.MainActivity.pickCamera(MainActivity.java:98)
        at com.blogspot.atifsoftwares.myapplication.MainActivity.onRequestPermissionsResult(MainActivity.java:128)
        at android.app.Activity.dispatchRequestPermissionsResult(Activity.java:7404)
        at android.app.Activity.dispatchActivityResult(Activity.java:7256)
        at android.app.ActivityThread.deliverResults(ActivityThread.java:4335)
  • Can you provide Manifest code? – itsmysterybox Sep 25 '18 at 17:57
  • Possible duplicate of [Android: Permission Denial: starting Intent with revoked permission android.permission.CAMERA](https://stackoverflow.com/questions/35973235/android-permission-denial-starting-intent-with-revoked-permission-android-perm) – Marcos Vasconcelos Sep 25 '18 at 18:05

1 Answers1

0

Your app is crashed when we click on camera button and it asks for camera permission and storage permissions. And we allow camera permission but deny the storage permission. The reason for crash is this: We allowed camera permission to capture image but we also have to give permission to store that image as well. Otherwise it crashes..

I tried to rewrite code to take permissions effectively. Try this code and tell me if it works.

MainActivity.java

public class MainActivity extends AppCompatActivity {

    public static final int CAMERA_REQUEST_CODE = 200;
    public static final int STORAGE_REQUEST_CODE = 400;
    private static final int IMAGE_PICK_GALLERY_CODE = 1000;
    private static final int IMAGE_PICK_CAMERA_CODE = 1001;

    Uri image_uri;

    ImageView mImageView;
    Button mGalleryBtn, mCameraBtn;
    String cameraPermission[];
    String storagePermission[];

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mImageView = findViewById(R.id.imageIv);
        mGalleryBtn = findViewById(R.id.galleryBtn);
        mCameraBtn = findViewById(R.id.cameraBtn);

        cameraPermission = new String [] {Manifest.permission.CAMERA, Manifest.permission.WRITE_EXTERNAL_STORAGE};
        storagePermission = new String[] {Manifest.permission.WRITE_EXTERNAL_STORAGE};


        //Gallery button click listener to pick image from gallery
        mGalleryBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!checkStoragePermission()) {
                    requestStoragePermission();

                } else {
                    pickGallery();
                }
            }
        });
        //Camera button click listener to pick image from gallery
        mCameraBtn.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                if (!checkCameraPermission()) {
                    requestCameraPermission();

                } else {
                    pickCamera();
                }
            }
        });

    }

    public void pickCamera() {
        //take image from default camera
        ContentValues values = new ContentValues();
        values.put(MediaStore.Images.Media.TITLE, "New Picture");
        values.put(MediaStore.Images.Media.DESCRIPTION, "From Camera");
        image_uri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
        Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
        cameraIntent.putExtra(MediaStore.EXTRA_OUTPUT, image_uri);
        startActivityForResult(cameraIntent, IMAGE_PICK_CAMERA_CODE);
    }

    public void pickGallery() {
        //pick image from gallery
        Intent intent = new Intent(Intent.ACTION_PICK);
        intent.setType("image/*");
        startActivityForResult(intent, IMAGE_PICK_GALLERY_CODE);
    }

    public boolean checkStoragePermission() {
        boolean result = ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
        return result;
    }

    public void requestStoragePermission() {
        ActivityCompat.requestPermissions(this, storagePermission, STORAGE_REQUEST_CODE);
    }

    public boolean checkCameraPermission() {
        boolean result = ContextCompat.checkSelfPermission(this,
                Manifest.permission.CAMERA) == (PackageManager.PERMISSION_GRANTED);
        boolean result1 = ContextCompat.checkSelfPermission(this,
                Manifest.permission.WRITE_EXTERNAL_STORAGE) == (PackageManager.PERMISSION_GRANTED);
        return result && result1;
    }

    public void requestCameraPermission() {
        ActivityCompat.requestPermissions(this,cameraPermission, CAMERA_REQUEST_CODE);
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
        switch (requestCode) {
            case CAMERA_REQUEST_CODE:
                if (grantResults.length > 0) {
                    boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    boolean writeStorageAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
                    if (cameraAccepted && writeStorageAccepted) {
                        Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
 pickCamera();
                    }
                    else {
                        Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            if (shouldShowRequestPermissionRationale(Manifest.permission.CAMERA)) {
                                showMessageOkCancel("You need to allow storage permissions.",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                                    requestPermissions(cameraPermission, CAMERA_REQUEST_CODE);
                                                }
                                            }
                                        });
                                return;
                            }
                        }
                    }
                }
                break;
            case STORAGE_REQUEST_CODE:
                if (grantResults.length > 0) {
                    boolean writeStorageAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
                    if (writeStorageAccepted) {
                        Toast.makeText(this, "Thank you", Toast.LENGTH_SHORT).show();
pickGallery();
                    }
                    else {
                        Toast.makeText(this, "Permission denied", Toast.LENGTH_SHORT).show();
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                            if (shouldShowRequestPermissionRationale(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                                showMessageOkCancel("You need to allow storage permissions.",
                                        new DialogInterface.OnClickListener() {
                                            @Override
                                            public void onClick(DialogInterface dialog, int which) {
                                                if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                                                    requestPermissions(storagePermission, STORAGE_REQUEST_CODE);
                                                }
                                            }
                                        });
                                return;
                            }
                        }
                    }
                }
                break;
        }
    }
    private void showMessageOkCancel(String message, DialogInterface.OnClickListener okListener) {
        new AlertDialog.Builder(this).setMessage(message).setPositiveButton("OK", okListener)
                .setNegativeButton("Cancel", null).create().show();
    }

    //handle result of picked image
    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {

        if (resultCode == RESULT_OK) {
            if (requestCode == IMAGE_PICK_GALLERY_CODE) {
                //set image to image view
                mImageView.setImageURI(data.getData());
            }
            if (requestCode == IMAGE_PICK_CAMERA_CODE) {
                //set image to image view
                mImageView.setImageURI(image_uri);
            }
        }

     }
    }

Hopefully app should run this time! Now whenever you click gallery button, app asks for Storage Permission and when click camera button, app will ask for both camera and storage permissions.

AtifSayings
  • 756
  • 14
  • 23
itsmysterybox
  • 2,748
  • 3
  • 21
  • 26
  • This code is working fine. I have checked it on Jellybean and oreo. – itsmysterybox Sep 25 '18 at 17:56
  • 1
    in my case WRITE_EXTERNAL_STORAGE permission is used in both cases whether to import image from Camera or from Gallery may be that's the cause of error –  Sep 25 '18 at 18:30
  • 1
    but this is not the right way, I mean if I want to pick image from gallery why I'm asking Camera permission? –  Sep 26 '18 at 05:02
  • 1
    Yes, you are right! I have updated the code. Please try again. It should work now as expected. – itsmysterybox Sep 26 '18 at 08:41
  • 1
    Thanks for contributing. That's working perfect now and I also checked by calling pickCamera(); , pickGallery(); methods instead of Thank you toasts. –  Sep 26 '18 at 18:06