Reputation: 1839
I created an app where I have a place to put profile picture and it looks as follows:
When the camera button is click there are two options:
Now, I had like my app to ask the users if they allow me to grant camera permissions once they click on the "Camera" option but I can't figure out how to do it.
Currently, the app asks for permission at the first time the user enters this activity.
How can I make the grant permission to pop up only after this Cemra button is clicked?
My code is:
private void showPictureDialog(){
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle("Select Action");
String[] pictureDialogItems = {"Photo Gallery", "Camera" };
pictureDialog.setItems(pictureDialogItems,
(dialog, which) -> {
switch (which) {
case 0:
choosePhotoFromGallary();
break;
case 1:
takePhotoFromCamera();
break;
}
} );
pictureDialog.show();
}
public void choosePhotoFromGallary() {
Intent galleryIntent = new Intent(Intent.ACTION_PICK,
android.provider.MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(galleryIntent, AppConstants.GALLERY);
}
private void takePhotoFromCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, AppConstants.CAMERA);
}
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_CANCELED) {
return;
}
Bitmap fixBitmap;
if (requestCode == AppConstants.GALLERY) {
if (data != null) {
Uri contentURI = data.getData();
try {
DOES SOMETHING
} catch (IOException ignored) {
}
}
} else if (requestCode == AppConstants.CAMERA) {
DOES SOMETHING
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 5) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
}
}
}
Thank you
Upvotes: 2
Views: 6952
Reputation: 1669
The idea for your problem is: You should request camera permission when user click on "Camera" option on your dialog NOT when the activity is created.
And below is my solution:
First remove your current "request camera permission" code
private void showPictureDialog(){
...
case 1:
checkPermissionAndOpenCamera();
break;
...
}
/**
* This will check your app camera permission.
* If its granted, open camera
* else request camera permission then open it later.
*/
void checkPermissionAndOpenCamera() {
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA)
== PackageManager.PERMISSION_DENIED) {
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, 5);
} else {
takePhotoFromCamera();
}
}
private void takePhotoFromCamera() {
Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, AppConstants.CAMERA);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == 5) {
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePhotoFromCamera();
}
}
}
Upvotes: 2
Reputation: 1609
For requesting permissions I use great library Dexter from Karumi:
https://github.com/Karumi/Dexter
I have the same case as you, and what I do is simply this:
txt_choose_from_gallery.setOnClickListener {
checkPhotoPermissions {
choosePictureFromGallery()
}
}
txt_take_picture.setOnClickListener {
checkPhotoPermissions {
takePictureWithCamera()
}
}
private fun checkPhotoPermissions(onPermissionGranted: () -> Unit) {
Dexter.withActivity(activity)
.withPermissions(
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE
)
.withListener(object : BaseMultiplePermissionsListener() {
override fun onPermissionsChecked(response: MultiplePermissionsReport) {
if (response.areAllPermissionsGranted()) {
onPermissionGranted()
}
}
})
.check()
}
You can easily use convert it to Java, just change the higher order function onPermissionGranted: () -> Unit
to interface, so you have for example:
interface OnPermissionGrantedListner {
void onPermissionGranted();
}
private void checkPhotoPermission(OnPermissionGrantedListener listener) {
// Dexter code for checking permission, invoke listener in overridden onPermissionChecked method in BaseMultiplePermissionsListener
listener.onPermissionGranted()
}
private void showPictureDialog(){
AlertDialog.Builder pictureDialog = new AlertDialog.Builder(this);
pictureDialog.setTitle("Select Action");
String[] pictureDialogItems = {"Photo Gallery", "Camera" };
pictureDialog.setItems(pictureDialogItems,
(dialog, which) -> {
switch (which) {
case 0:
checkPhotoPermission(new OnPermissionGrantedListener {
@Override
void onPermissionGranted() {
choosePhotoFromGallery();
}
}
break;
case 1:
checkPhotoPermission(new OnPermissionGrantedListener {
@Override
void onPermissionGranted() {
takePhotoFromCamera();
}
}
break;
}
} );
pictureDialog.show();
}
Upvotes: 0