I'm having a rather strange problem with an Android app I'm writing.
In my app, I use an intent to tell the phone's camera app to take a picture for me. After I take this picture, I want to register the newly taken photo with the device's MediaStore content provider in order to make it show up in the regular "gallery" app.
To do this, I know I need the WRITE_EXTERNAL_STORAGE permission, but even when it's in my manifest I get a permission denied exception. What do I have to do to get this permission? I'm running Android 6.0.1.
Here's my permissions XML in the manifest:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Here's the code that causes the exception:
// insert photo into phone's main photo content provider
ContentResolver cr = getActivity().getContentResolver();
try {
MediaStore.Images.Media.insertImage(cr, photoFile.getPath(),
"Image Capture", "Custom Image capture");
} catch (FileNotFoundException foe) {
Log.e(DEBUG, foe.getMessage());
}
And here's the exception I get:
java.lang.SecurityException: Permission Denial: writing com.android.providers.media.MediaProvider uri content://media/external/images/media from pid=2436, uid=10041 requires android.permission.WRITE_EXTERNAL_STORAGE, or grantUriPermission()
EDIT: I should probably mention:
Right now my app uses getExternalFilesDir(Environment.DIRECTORY_PICTURES), which returns the path /sdcard/Android/data/<package>/files/Pictures to save it's photos. I want them to go where the camera app normally puts them, in /sdcard/DCIM/Camera.
You should add the android:maxSdkVersion="18" to the WRITE_EXTERNAL_STORAGE as well. Your code should look like this:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
android:maxSdkVersion="18" />
This may be a problem with respect to you requesting the permission but not being granted the permission by the user. Have a look at my answer # https://stackoverflow.com/a/35574084/529691
And see if that helps.
You should promt the user to provide you permission:
int externalPermissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE);
if (externalPermissionCheck==-1){
askPermissionStorage();
}
private void askPermissionStorage() {
//for media
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.
WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
//insert explanation
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
//if you want to explaian to the user
} else {//if no explanation needed
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_WRITE_EXTERNAL_STORAGE);
}
}
}
The above is for save the picture\video
and this is for the camera permission:
int cameraPermissionCheck = ContextCompat.checkSelfPermission(this,
Manifest.permission.CAMERA);
if (cameraPermissionCheck == -1) {
askPermissionCamera();
}
private void askPermissionCamera() {
//for camera
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.
CAMERA) != PackageManager.PERMISSION_GRANTED) {
//insert explanation
if (ActivityCompat.shouldShowRequestPermissionRationale(this,
Manifest.permission.CAMERA)) {
//if you want to explaian to the user
} else {//if no explanation needed
ActivityCompat.requestPermissions(this, new
String[]{Manifest.permission.CAMERA},
MY_PERMISSIONS_REQUEST_CAMERA);
}
}
}
Related
I am attempting to request background location permission for my app, but the locations permission dialog doesn't appear at all if I ask for background location.
If I just ask for coarse location and fine location, the permissions dialog appears as it should.
Manifest:
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
code:
requestPermissionsIfNecessary(new String[]{
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION,
Manifest.permission.RECEIVE_BOOT_COMPLETED
});
...
...
private void requestPermissionsIfNecessary(String[] permissions) {
ArrayList<String> permissionsToRequest = new ArrayList<>();
for (String permission : permissions) {
if (ContextCompat.checkSelfPermission(this, permission)
!= PackageManager.PERMISSION_GRANTED) {
// Permission is not granted
permissionsToRequest.add(permission);
}
}
if (permissionsToRequest.size() > 0) {
ActivityCompat.requestPermissions(
this,
permissionsToRequest.toArray(new String[0]),
REQUEST_PERMISSIONS_REQUEST_CODE);
}
}
No permissions dialog appears with this code. But if I comment out the 'background' permission lines, the dialog appears and the user can choose permissions.
Same result whether targeting Android 11 or 12. So what am I missing here?
This is expected behavior from android 10. Background location permission can not be granted from application as user permission. Instead you should tell user with some kind of pop up and redirect user to setting page.
OK, with help from #alokHarman and other threads here I have arrived at the following (in OnCreate):
if (ActivityCompat.checkSelfPermission(this,Manifest.permission.ACCESS_BACKGROUND_LOCATION) != PackageManager.PERMISSION_GRANTED) {
Intent intent = new Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
intent.setData(Uri.fromParts("package", getPackageName(), null));
startActivity(intent);
}
PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
if (!pm.isIgnoringBatteryOptimizations(getPackageName())) {
Intent intent = new Intent(Settings.ACTION_IGNORE_BATTERY_OPTIMIZATION_SETTINGS);
startActivity(intent);
}
I have also directed the user to change the power settings for this app, because if the app is allowed to go into deep sleep than it matters not whether background location is activaed or not.
My internal android application worked fine on Samsung Tab S2 and it automatically got permissions to access 'storage' and 'location' of the device. But, when I am installing the application on newer Samsung Galaxy Tab S7, I have to manually provide permission for the app in settings. By default it is set to "No permissions allowed" How cam I automate this.
AndroidManifest.xml has following settings
<uses-sdk
android:minSdkVersion="21"
android:targetSdkVersion="22"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.CALL_PHONE"/>
<uses-permission android:name="android.permission.READ_SMS"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Android permissions went through a radical change after android M was released. before that, developers can simply jam all the permissions in the AndroidManifesto file, and before the user installs the app, he/she has to approve all the permissions to run the app.
However, things are different now. Android expects that these permissions will be granted at rather runtime, i.e. when a feature that needs that permission is executed, it first requests for that permission, and based on user's reply handle that. If permission is granted, then good. If not, then simply display a message maybe stating that this feature will not work in the absence of that permission. In which case, because the user has already declined the permission, he/she now has to go to the settings to enable the previously declined permission.
You have to grant permission from the user. You can use it inside Fragment:
Java:
if (ActivityCompat.checkSelfPermission(getContext(),
android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(getActivity(),
new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
REQUEST_LOCATION);
} else {
Log.e("DB", "PERMISSION GRANTED");
}
Kotlin:
if (ActivityCompat.checkSelfPermission(getContext(),
Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(getActivity(), arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
REQUEST_LOCATION)
} else {
Log.e("DB", "PERMISSION GRANTED")
}
and inside Activity:
Java:
int checkPermission= ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA);
if (checkPermission!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions((Activity)getContext(), new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, REQUEST_LOCATION);
}
else {
Log.e("DB", "PERMISSION GRANTED")
}
Kotlin:
val checkPermission = ContextCompat.checkSelfPermission(getContext(), Manifest.permission.CAMERA)
if (checkPermission != PackageManager.PERMISSION_GRANTED)
{
ActivityCompat.requestPermissions(getContext() as Activity, arrayOf<String>(Manifest.permission.ACCESS_FINE_LOCATION), REQUEST_LOCATION)
}
else
{
Log.e("DB", "PERMISSION GRANTED")
}
I need to open a pdf using a uri.
I have the code in place to open the pdf.
My code works fine on Api greater than 23.
I get the following SecurityException when I try to download the file on a Samsung Galaxy device with Api 23 and version 6.
Here is the exception:
01-25 19:28:38.723 6655-6667/android.process.media E/DatabaseUtils: Writing exception to parcel
java.lang.SecurityException: No permission to write to /storage/emulated/0/Download/Canto Quick Start Guide.pdf: Neither user 10022 nor current process has android.permission.WRITE_EXTERNAL_STORAGE.
at android.app.ContextImpl.enforce(ContextImpl.java:1438)
at android.app.ContextImpl.enforceCallingOrSelfPermission(ContextImpl.java:1470)
at android.content.ContextWrapper.enforceCallingOrSelfPermission(ContextWrapper.java:675)
at com.android.providers.downloads.DownloadProvider.checkFileUriDestination(DownloadProvider.java:724)
at com.android.providers.downloads.DownloadProvider.insert(DownloadProvider.java:558)
at android.content.ContentProvider$Transport.insert(ContentProvider.java:263)
at android.content.ContentProviderNative.onTransact(ContentProviderNative.java:163)
at android.os.Binder.execTransact(Binder.java:507)
I have setup the required permission in manifest file
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.CALL_PHONE" />
<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_EXTERNAL_STORAGE" />
I have the following check in place to test if the user does not have WRITE_EXTERNAL_STORAGE permission then ask the user for granting access.
int PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE = 2;
// Check whether this app has write external storage permission or not.
int writeExternalStoragePermission = ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE);
// If do not grant write external storage permission.
if (writeExternalStoragePermission != PackageManager.PERMISSION_GRANTED) {
// Request user to grant write external storage permission.
((MainActivity)activity).getSharedPreferenceManager().add(PreferenceConstants.SHAREPOINT_FILE_URI, getUrl((SharepointFile) object, activity));
ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE);
} else {
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(getUrl((SharepointFile) object, activity)));
intent.setDataAndType(Uri.parse(getUrl((SharepointFile) object, activity)), "application/pdf");
activity.startActivity(intent);
}
I override the onRequestPermissionResult in MainActivity.java so that as soon as the user grants permission then the download can be initiated.
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case PermissionConstants.PERMISSION_REQUEST_WRITE_EXTERNAL_STORAGE:
// If request is cancelled, the result arrays are empty.
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
String fileUri = getSharedPreferenceManager().get(PreferenceConstants.SHAREPOINT_FILE_URI);
Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(fileUri));
startActivity(intent);
} else {
getSharedPreferenceManager().remove(PreferenceConstants.SHAREPOINT_FILE_URI);
}
break;
}
}
I have the code to ask the user for permission. I do get the dialog/alert to allow access. Once the user clicks allow, I see that it still gives the above exception. I went in settings to check my app's permission and see that it is turned "on" for storage. Why would I still get permission issue? Any pointers on what I could be missing here? Appreciate your help!
It is just an assumption but i see you have declared both
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
But docs says:
Any app that declares the WRITE_EXTERNAL_STORAGE permission is implicitly granted this (READ_EXTERNAL_STORAGE) permission.
Try to remove
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I'm trying to start a ACTION_IMAGE_CAPTURE activity in order to take a picture in my app and I'm getting the error in the subject.
Stacktrace:
FATAL EXCEPTION: main
Process: il.ac.shenkar.david.todolistex2, PID: 3293
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{22b0eb2 3293:il.ac.shenkar.david.todolistex2/u0a126} (pid=3293, uid=10126)
with revoked permission android.permission.CAMERA
The camera permissions is added to the manifest.xml fie:
<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.VIBRATE" />
<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" />
Here is the call to open the camera:
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())
{
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
});
Remove this permission
<uses-permission android:name="android.permission.CAMERA"/>
I faced this error executing my app in android 7. After tests I noticed user permission wasn't in project A but it was in project B, that I only tested in android 5 devices. So I remove that permission in project B in order to run it on other device that targets android 7 and it finally could open.
In adittion I added the fileprovider code that Android suggests here https://developer.android.com/training/camera/photobasics.html
Hope this helps.
hi you can use these permission in your manifest file with other permission,
<uses-feature
android:name="android.hardware.camera.any"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
Now we have very sorted way for permission handling. So,here is the steps. I have added here for kotlin.
Step 1. Declare this as global variable or any where.
private val permissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { granted ->
granted.entries.forEach {
when (it.value) {
true -> {
// Call whatever you want to do when someone allow the permission.
}
false -> {
showPermissionSettingsAlert(requireContext())
}
}
}
}
Step 2.
// You can put this line in constant.
val storagePermission = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE
)
// You can put this in AppUtil.
fun checkPermissionStorage(context: Context): Boolean {
val result =
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)
return result == PackageManager.PERMISSION_GRANTED
}
// Put this where you need Permission check.
if (!checkPermissionStorage(requireContext())) {
permissions.launch(
storagePermission
)
} else {
// Permission is already added.
}
Step 3. Permission rejection Dialog. If you want you can use this.
fun showPermissionSettingsAlert(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Grant Permission")
builder.setMessage("You have rejected the Storage permission for the application. As it is absolutely necessary for the app to perform you need to enable it in the settings of your device. Please select \"Go to settings\" to go to application settings in your device.")
builder.setPositiveButton("Allow") { dialog, which ->
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
val uri = Uri.fromParts("package", context.packageName, null)
intent.data = uri
context.startActivity(intent)
}
builder.setNeutralButton("Deny") { dialog, which ->
dialog.dismiss()
}
val dialog = builder.create()
dialog.show()
}
Thankyou
hope this will help you (Y).
Here is how I solved mine:
First of all I think the issue arises when you try to use your device Camera on (SDK < 26) without FULL permissions.
Yes, even though you have already included this permission:
<uses-permission android:name="android.permission.CAMERA"/>
To solve this issue I changed that to this:
<uses-permission android:name="android.permission.CAMERA"
android:required="true"
android:requiredFeature="true"/>
This information from the Android Docs, might be really helpful
If your application uses, but does not require a camera in order to function, instead set android:required to false. In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). If a camera is not available, you should then disable your camera features.
In my case the problem was related to my emulator permissions ,
To fix the issue :
1- Go to Settings of your emulator.
2- Look for Apps and Notifications.
3- Click on Add Permission.
see the pic : https://i.stack.imgur.com/z4GfK.png
4- Select Camera of the list.
5- Look for your Application in the provided list.
6- Enable Camera.
see the pic : https://i.stack.imgur.com/dJ8wG.pngEnjoy
Now you can use your camera on your emulator :)
private String [] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE", "android.permission.SYSTEM_ALERT_WINDOW","android.permission.CAMERA"};
on your OnCreate add this:
int requestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, requestCode);
}
As some have pointed out, one solution is removing the Camera Permission from AndroidManifest.xml, i.e., remove this line:
<uses-permission android:name="android.permission.CAMERA" />
However, that was not enough for me, as I needed the Camera Permission for something else in my app. So what worked for me was tagging that permission as not required, like this:
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
short answer ...its looking for permissions , upon failing permissions it throws exception ; moreover in this case its looking for Two Permissions i.e. first Storage and second Camera.
long answer.....Give it the permissions write way to work on all Versions of Android.I am looping to get both permissions Storage and Camera, So that it will work with Intent.
maintain in AndroidManifest.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.WRITE_EXTERNAL_STORAGE" />
check or request permissions by
private void myStoragePermission() {
if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
myCameraPermission();
} else {
//changed here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
}
}
//+10 changed its sinature as Fragment; without it onRequestPermissionsResult won't bbe called
private void myCameraPermission() {
if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
takePicture();
} else {
//changed here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}
}
add onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_WRITE_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
myStoragePermission();
} else {
showSnackbar(R.string.act_ScanQR_txt13, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
case REQUEST_CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePicture();
} else {
showSnackbar(R.string.act_ScanQR_txt14, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
in above code takePicture(); is where I call for intent (start intent) , upon getting both the Storage and Camera permissions.
Don't get confused by reading a lot on error ;)
For future references, if someone encounters the problem in flutter related android projects:
https://github.com/apptreesoftware/flutter_barcode_reader/issues/32#issuecomment-420516729
In case anyone else get's this issue, my problem was that the app wasn't requesting any permissions when I ran it. It seems xiaomi devices automatically deny permissions to apps installed through adb. I just enabled the permissions through settings and it worked.
In case you need to keep
<uses-permission android:name="android.permission.CAMERA" />
permission in manifest, just make sure it is granted before opening system camera.
In modern android, you can do that like this:
val cameraPermissionResult =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { permitted ->
if (permitted) {
openSystemCamera()
}
}
You can use cameraPermissionResult as follows:
cameraPermissionResult.launch(Manifest.permission.CAMERA)
If your app has already that permission granted it will just call openSystemCamera() without any user action required.
In other case permission dialog will be shown and system camera will be opened based on permission user chooses.
I'm quite late but please check this because there's always some update
As per official developer page - https://developer.android.com/training/camera/photobasics, you don't need to use uses-permission in Manifest.xml instead use uses-feature :
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
Notice - it's uses-feature, not uses-permission ,
Check properly, if you are using uses-permission and uses-feature both at the same, possibly you will the same crash (this note is most important then updated content from official page, because i used both of the params at the same time and faced this crash, also when i started working on camera module in my app, i don't know why i wasn't faced this issue but now app just started crashing suddenly)
more info about android:required from developer page :
If your application uses, but does not require a camera in order to function, instead set android:required to false. In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). If a camera is not available, you should then disable your camera features.
in your androidManifest, you have to add :
<uses-feature android:name="android.hardware.camera" />
here is an full Manifest example of android camera project
I'm trying to start a ACTION_IMAGE_CAPTURE activity in order to take a picture in my app and I'm getting the error in the subject.
Stacktrace:
FATAL EXCEPTION: main
Process: il.ac.shenkar.david.todolistex2, PID: 3293
java.lang.SecurityException: Permission Denial: starting Intent { act=android.media.action.IMAGE_CAPTURE cmp=com.google.android.GoogleCamera/com.android.camera.CaptureActivity } from ProcessRecord{22b0eb2 3293:il.ac.shenkar.david.todolistex2/u0a126} (pid=3293, uid=10126)
with revoked permission android.permission.CAMERA
The camera permissions is added to the manifest.xml fie:
<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.VIBRATE" />
<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" />
Here is the call to open the camera:
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())
{
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
}
});
Remove this permission
<uses-permission android:name="android.permission.CAMERA"/>
I faced this error executing my app in android 7. After tests I noticed user permission wasn't in project A but it was in project B, that I only tested in android 5 devices. So I remove that permission in project B in order to run it on other device that targets android 7 and it finally could open.
In adittion I added the fileprovider code that Android suggests here https://developer.android.com/training/camera/photobasics.html
Hope this helps.
hi you can use these permission in your manifest file with other permission,
<uses-feature
android:name="android.hardware.camera.any"
android:required="true" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
Now we have very sorted way for permission handling. So,here is the steps. I have added here for kotlin.
Step 1. Declare this as global variable or any where.
private val permissions = registerForActivityResult(ActivityResultContracts.RequestMultiplePermissions()) { granted ->
granted.entries.forEach {
when (it.value) {
true -> {
// Call whatever you want to do when someone allow the permission.
}
false -> {
showPermissionSettingsAlert(requireContext())
}
}
}
}
Step 2.
// You can put this line in constant.
val storagePermission = arrayOf(
Manifest.permission.READ_EXTERNAL_STORAGE
)
// You can put this in AppUtil.
fun checkPermissionStorage(context: Context): Boolean {
val result =
ContextCompat.checkSelfPermission(context, Manifest.permission.READ_EXTERNAL_STORAGE)
return result == PackageManager.PERMISSION_GRANTED
}
// Put this where you need Permission check.
if (!checkPermissionStorage(requireContext())) {
permissions.launch(
storagePermission
)
} else {
// Permission is already added.
}
Step 3. Permission rejection Dialog. If you want you can use this.
fun showPermissionSettingsAlert(context: Context) {
val builder = AlertDialog.Builder(context)
builder.setTitle("Grant Permission")
builder.setMessage("You have rejected the Storage permission for the application. As it is absolutely necessary for the app to perform you need to enable it in the settings of your device. Please select \"Go to settings\" to go to application settings in your device.")
builder.setPositiveButton("Allow") { dialog, which ->
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
val uri = Uri.fromParts("package", context.packageName, null)
intent.data = uri
context.startActivity(intent)
}
builder.setNeutralButton("Deny") { dialog, which ->
dialog.dismiss()
}
val dialog = builder.create()
dialog.show()
}
Thankyou
hope this will help you (Y).
Here is how I solved mine:
First of all I think the issue arises when you try to use your device Camera on (SDK < 26) without FULL permissions.
Yes, even though you have already included this permission:
<uses-permission android:name="android.permission.CAMERA"/>
To solve this issue I changed that to this:
<uses-permission android:name="android.permission.CAMERA"
android:required="true"
android:requiredFeature="true"/>
This information from the Android Docs, might be really helpful
If your application uses, but does not require a camera in order to function, instead set android:required to false. In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). If a camera is not available, you should then disable your camera features.
In my case the problem was related to my emulator permissions ,
To fix the issue :
1- Go to Settings of your emulator.
2- Look for Apps and Notifications.
3- Click on Add Permission.
see the pic : https://i.stack.imgur.com/z4GfK.png
4- Select Camera of the list.
5- Look for your Application in the provided list.
6- Enable Camera.
see the pic : https://i.stack.imgur.com/dJ8wG.pngEnjoy
Now you can use your camera on your emulator :)
private String [] permissions = {"android.permission.WRITE_EXTERNAL_STORAGE", "android.permission.ACCESS_FINE_LOCATION", "android.permission.READ_PHONE_STATE", "android.permission.SYSTEM_ALERT_WINDOW","android.permission.CAMERA"};
on your OnCreate add this:
int requestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(permissions, requestCode);
}
As some have pointed out, one solution is removing the Camera Permission from AndroidManifest.xml, i.e., remove this line:
<uses-permission android:name="android.permission.CAMERA" />
However, that was not enough for me, as I needed the Camera Permission for something else in my app. So what worked for me was tagging that permission as not required, like this:
<uses-permission android:name="android.permission.CAMERA" android:required="false" />
short answer ...its looking for permissions , upon failing permissions it throws exception ; moreover in this case its looking for Two Permissions i.e. first Storage and second Camera.
long answer.....Give it the permissions write way to work on all Versions of Android.I am looping to get both permissions Storage and Camera, So that it will work with Intent.
maintain in AndroidManifest.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.WRITE_EXTERNAL_STORAGE" />
check or request permissions by
private void myStoragePermission() {
if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
myCameraPermission();
} else {
//changed here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_WRITE_PERMISSION);
}
}
}
//+10 changed its sinature as Fragment; without it onRequestPermissionsResult won't bbe called
private void myCameraPermission() {
if (ContextCompat.checkSelfPermission(Activity_Scan_QR.this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED) {
takePicture();
} else {
//changed here
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
requestPermissions(new String[]{Manifest.permission.CAMERA}, REQUEST_CAMERA_PERMISSION);
}
}
}
add onRequestPermissionsResult
#Override
public void onRequestPermissionsResult(int requestCode, #NonNull String[] permissions, #NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case REQUEST_WRITE_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
myStoragePermission();
} else {
showSnackbar(R.string.act_ScanQR_txt13, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
case REQUEST_CAMERA_PERMISSION:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
takePicture();
} else {
showSnackbar(R.string.act_ScanQR_txt14, R.string.settings,
new View.OnClickListener() {
#Override
public void onClick(View view) {
// Build intent that displays the App settings screen.
Intent intent = new Intent();
intent.setAction(
Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
Uri uri = Uri.fromParts("package",
BuildConfig.APPLICATION_ID, null);
intent.setData(uri);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
}
});
}
}
}
in above code takePicture(); is where I call for intent (start intent) , upon getting both the Storage and Camera permissions.
Don't get confused by reading a lot on error ;)
For future references, if someone encounters the problem in flutter related android projects:
https://github.com/apptreesoftware/flutter_barcode_reader/issues/32#issuecomment-420516729
In case anyone else get's this issue, my problem was that the app wasn't requesting any permissions when I ran it. It seems xiaomi devices automatically deny permissions to apps installed through adb. I just enabled the permissions through settings and it worked.
In case you need to keep
<uses-permission android:name="android.permission.CAMERA" />
permission in manifest, just make sure it is granted before opening system camera.
In modern android, you can do that like this:
val cameraPermissionResult =
registerForActivityResult(ActivityResultContracts.RequestPermission()) { permitted ->
if (permitted) {
openSystemCamera()
}
}
You can use cameraPermissionResult as follows:
cameraPermissionResult.launch(Manifest.permission.CAMERA)
If your app has already that permission granted it will just call openSystemCamera() without any user action required.
In other case permission dialog will be shown and system camera will be opened based on permission user chooses.
I'm quite late but please check this because there's always some update
As per official developer page - https://developer.android.com/training/camera/photobasics, you don't need to use uses-permission in Manifest.xml instead use uses-feature :
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
Notice - it's uses-feature, not uses-permission ,
Check properly, if you are using uses-permission and uses-feature both at the same, possibly you will the same crash (this note is most important then updated content from official page, because i used both of the params at the same time and faced this crash, also when i started working on camera module in my app, i don't know why i wasn't faced this issue but now app just started crashing suddenly)
more info about android:required from developer page :
If your application uses, but does not require a camera in order to function, instead set android:required to false. In doing so, Google Play will allow devices without a camera to download your application. It's then your responsibility to check for the availability of the camera at runtime by calling hasSystemFeature(PackageManager.FEATURE_CAMERA_ANY). If a camera is not available, you should then disable your camera features.
in your androidManifest, you have to add :
<uses-feature android:name="android.hardware.camera" />
here is an full Manifest example of android camera project