Reputation: 29557
I have a user who is not able to use the camera in my Android app even though she seems to have all the right permissions.
She is using a Google Pixel 6 Pro, Android 12 Build/SD1A.210817.037.
She has deleted and reinstalled the app. She has deleted storage and cache associated with the app. She is able to use the camera for other apps. She is using the default camera app.
No one else has complained about this issue, but she is using a recent build update so maybe she's just the first to see it and tell me.
The popup error message says:
Can't save photo. Camera doesn't have permission to save to this location.
In her Settings app, for App Permissions:
In her Settings app, for all permissions, :
The app permissions:
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.CAMERA" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-feature android:name="android.hardware.camera.autofocus" android:required="false" />
The app uses a webview and launches the camera from a standard HTML form. This is standard and automatically gives the user the choice of using the camera or file. The image is then normally sent to my server via the form and saved there.
<form action="upload/" method="post" enctype="multipart/form-data" > <input type="file" accept="image/*" name="image"> <input type="submit"> </form>
The user is able to upload an image if she chooses a file, but not if she chooses the camera option. I'm not sure if the error message pops up before or after taking a photo with her camera.
App code:
private int MY_PERMISSIONS_REQUEST_CAMERA = 1;
public boolean onShowFileChooser(WebView webView, ValueCallback<Uri[]> filePathCallback, WebChromeClient.FileChooserParams fileChooserParams) {
uriArrayCallback = filePathCallback;
if ( (ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
|| ActivityCompat.checkSelfPermission(getActivity(), android.Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
)) {
requestPermissions(new String[]{android.Manifest.permission.CAMERA,
android.Manifest.permission.READ_EXTERNAL_STORAGE,
android.Manifest.permission.WRITE_EXTERNAL_STORAGE},
MY_PERMISSIONS_REQUEST_CAMERA);
} else {
// has permissions
openFileChooserInternal(NEW_FILECHOOSER_REQUEST_CODE);
}
return true;
}
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
if (requestCode == MY_PERMISSIONS_REQUEST_CAMERA) {
boolean cameraAccepted = grantResults[0] == PackageManager.PERMISSION_GRANTED;
boolean readExternalAccepted = grantResults[1] == PackageManager.PERMISSION_GRANTED;
boolean writeExternalAccepted = grantResults[2] == PackageManager.PERMISSION_GRANTED;
if (cameraAccepted && readExternalAccepted && writeExternalAccepted) {
openFileChooserInternal(NEW_FILECHOOSER_REQUEST_CODE);
} else {
}
}
}
Upvotes: 9
Views: 3517
Reputation: 2724
I faced this problem in pixel 7. Solved it using provider in manifest.
Define filepaths.xml in your res/xml/filepaths.xml
<?xml version="1.0" encoding="utf-8"?>
<paths>
<external-cache-path
name="images"
path="." />
</
In your manifest,
<application>
<activity
/>
<provider
android:name="androidx.core.content.FileProvider"
android:authorities="package.fileprovider"
android:grantUriPermissions="true"
android:exported="false">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/filepaths" />
</provider>
</application>
Now use It like this
FileProvider.getUriForFile(
context,
"package.fileprovider",
createTempFile(context)
)
fun createTempFile(context: Context): File {
return File.createTempFile(
System.currentTimeMillis().toString(),
".jpg",
context.externalCacheDir
)
}
Upvotes: 1
Reputation: 5911
It's a bug specific to Pixel devices: https://issuetracker.google.com/issues/242767872?pli=1
As usual with Google, no resolution
Status: Won't Fix (Infeasible)
We are closing this issue since we didn't receive a response. If you are still facing this problem, please open a new issue and add the relevant information along with reference to this issue.
Upvotes: 0
Reputation: 241
I ran into the same issue, I used MediaStorage for the extra in my intent. Here is an example:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
ContentResolver cr = getContentResolver();
ContentValues values = new ContentValues();
values.put(MediaStore.Images.Media.DISPLAY_NAME, imageFileName);
values.put(MediaStore.Images.Media.MIME_TYPE, "image/jpeg");
values.put(MediaStore.Images.Media.RELATIVE_PATH, Environment.DIRECTORY_PICTURES);
Uri uri = cr.insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
Upvotes: 1