Va1iant
Va1iant

Reputation: 223

CAMERA_ROLL Permission return denied even though user grant it

SDK Version: 35

Platforms(Android/iOS/web/all): Android

My app is trying to get photo from user’s camera. I simply use this code in my expo App before calling ImagePicker.launchCameraAsync

const { status } = await Permissions.askAsync(Permissions.CAMERA, Permissions.CAMERA_ROLL);.
if(status !== ‘granted’) {
    dispatchMsg(‘error’, ‘We need your permission to get photo’);
    return;
}

from user perspective, they will see the system asking for permission twice

enter image description here enter image description here

The problem is… eventhough user has granted the permission for both, the status are still “denied”! and the funny thing is this only happen in standalone production app. If i’m correctly recall… this issue happen only recently. My app has been in Playstore for more than 6 months and initially there is no problem until recently.

I tried to print debug message on production and this is the result:

I was very sure I choose granting the permission… so does the users that reported to me the bug. And like i told you before this issue seem to occur only recently. Any ideas how to solve since this issue only occur in my production app.

EDIT: here is the screenshot of my app permission list from Android Setting. Doesn’t seem to show anything wrong

enter image description here

Upvotes: 2

Views: 1191

Answers (3)

Va1iant
Va1iant

Reputation: 223

Since i'm using Expo, I checked again the permission list in app.json and found WRITE_EXTERNAL_STORAGE was not there. I swore in the beginning after deploy the app to App & Play store the application worked perfectly but it seemed after certain time the problem appear. Since the modification of permissions in app.json will require full new build to be resubmitted to play/app store (instead of just publish the new build to Expo for OTA update), I did so and after that I confirmed that the problem dissappear

Upvotes: 0

Samer Kasseb
Samer Kasseb

Reputation: 192

check your Manifest file.

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

Example.

    lateinit var imageCamera: ImageView
    lateinit var captureBtn: Button

    val REQUEST_IMAGE_CAPTURE = 1


    private val PERMISSION_REQUEST_CODE: Int = 101

    private var mCurrentPhotoPath: String? = null;
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        imageCamera= findViewById(R.id.image)
        captureBtn = findViewById(R.id.captureBtn)
        captureBtn.setOnClickListener(View.OnClickListener {
            if (checkPersmission()) takePicture() else requestPermission()
        })


    }


    override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
        when (requestCode) {
            PERMISSION_REQUEST_CODE -> {

                if ((grantResults.isNotEmpty() && grantResults[0] == PackageManager.PERMISSION_GRANTED)
                        && grantResults[1] == PackageManager.PERMISSION_GRANTED) {

                    takePicture()

                } else {
                    Toast.makeText(this, "Permission Denied", Toast.LENGTH_SHORT).show()
                }
                return
            }

            else -> {

            }
        }
    }

    private fun takePicture() {

        val intent: Intent = Intent(MediaStore.ACTION_IMAGE_CAPTURE)
        val file: File = createFile()

        val uri: Uri = FileProvider.getUriForFile(
                this,
                "com.example.android.fileprovider",
                file
        )
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri)
        startActivityForResult(intent, REQUEST_IMAGE_CAPTURE)

    }

    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == Activity.RESULT_OK) {

            //To get the File for further usage
            val auxFile = File(mCurrentPhotoPath)


            var bitmap: Bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath)
            imageCamera.setImageBitmap(bitmap)

        }
    }

    private fun checkPersmission(): Boolean {
        return (ContextCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) ==
                PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this,
                android.Manifest.permission.READ_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED)
    }

    private fun requestPermission() {
        ActivityCompat.requestPermissions(this, arrayOf(READ_EXTERNAL_STORAGE, CAMERA), PERMISSION_REQUEST_CODE)
    }

    @Throws(IOException::class)
    private fun createFile(): File {
        // Create an image file name
        val timeStamp: String = SimpleDateFormat("yyyyMMdd_HHmmss").format(Date())
        val storageDir: File = getExternalFilesDir(Environment.DIRECTORY_PICTURES)
        return File.createTempFile(
                "JPEG_${timeStamp}_", /* prefix */
                ".jpg", /* suffix */
                storageDir /* directory */
        ).apply {
            // Save a file: path for use with ACTION_VIEW intents
            mCurrentPhotoPath = absolutePath
        }
    }
}

Upvotes: 1

Usama Saeed US
Usama Saeed US

Reputation: 1004

you have to regenerate the shell-bundle after adding the permissions, clear cache and expo publish.

Upvotes: 0

Related Questions