Using my own extented ContentProvider Google Camera refuses to use it. It directly complains: Can't save photo. Camera does not have permission to save to this location.
Log statements in the provider class show that not one function of the class is called to come to that conclusion.
Everything is ok when Open Camera is used or another app to use the uri.
ActivityResultLauncher takePicture = null;
takePicture = getActivity().registerForActivityResult(
new TakePicture(),
new ActivityResultCallback<Boolean>() {
@Override
public void onActivityResult(Boolean result) {
// code irrelevant for problem
}
});
File file = .....
//Uri uri = FileProvider.getUriForFile(getContext(), getContext().getPackageName() + ".fileprovider", file);
Uri uri = ABCContentProvider.getUriForFile(getContext(), file);
try {
takePicture.launch(uri);
} catch (ActivityNotFoundException e) {
e.printStackTrace();
toast("ActivityNotFoundException: " + e.getMessage());
}
And the code for the content provider:
public class ABCContentProvider extends ContentProvider {
static String TAG = "abccontentprovider";
public static Uri getUriForFile (Context context, File file)
{
Log.d(TAG, "getUriForFile() file: " + file.getAbsolutePath() );
return Uri.parse("content://" + context.getPackageName() + ".abcprovider" + file.getAbsolutePath());
}
@Override
public ParcelFileDescriptor openFile(Uri uri, String mode) throws FileNotFoundException
{
Log.d(TAG, "open-File() mode: " + mode ); // "r" | "w"
Log.d(TAG, "open-File() uri.getEncodedPath(): " + uri.getEncodedPath() );
String path = uri.getEncodedPath();
File f = new File(path);
if ( mode.equals("r") && ! f.exists() )
{
Log.d(TAG, "path does not exist" );
throw new FileNotFoundException(
"in ABCProvider\n"
+ path
+ "\nmode: " + mode);
}
if ( mode.equals("r") )
return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_ONLY));
if ( f.exists() )
return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_READ_WRITE));
return (ParcelFileDescriptor.open(f,ParcelFileDescriptor.MODE_CREATE));
}
@Override
public boolean onCreate() {
Log.d(TAG, "onCreate()" );
return false;
}
@Nullable
@Override
public Cursor query(@NonNull Uri uri, @Nullable String[] strings, @Nullable String s, @Nullable String[] strings1, @Nullable String s1) {
Log.d(TAG, "query() uri: " + uri.toString() );
return null;
}
@Nullable
@Override
public String getType(@NonNull Uri uri) {
Log.d(TAG, "getType() uri: " + uri.toString() );
return null;
}
@Nullable
@Override
public Uri insert(@NonNull Uri uri, @Nullable ContentValues contentValues) {
Log.d(TAG, "insert() uri: " + uri.toString() );
return null;
}
@Override
public int delete(@NonNull Uri uri, @Nullable String s, @Nullable String[] strings) {
Log.d(TAG, "delete() uri: " + uri.toString() );
return 0;
}
@Override
public int update(@NonNull Uri uri, @Nullable ContentValues contentValues, @Nullable String s, @Nullable String[] strings) {
Log.d(TAG, "update() uri: " + uri.toString() );
return 0;
}
}
And in manifest:
<provider
android:name=".ABCContentProvider"
android:authorities="${applicationId}.abcprovider"
android:enabled="true"
android:exported="true" />
The question is why Google Camera refuses to use a different FileProvider? It even refuses before a picture is taken and without using any member of the content provider.