I have an associated activity for opening a type of file, using a file explorer, when selecting the document and that opens with my app, sometimes I receive:
Caused by: java.lang.SecurityException: Permission Denial: reading nextapp.fx.fileprovider.FileProvider uri content: //nextapp.fx.FileProvider/storage/emulated/0/Documents/Untitled4.md from pid = 31631, uid = 10442 requires the provider to be exported, or grantUriPermission ()
The code where it jumps:
public static String getFileName(Context context, @NonNull Uri uri) {
String displayName = null;
String uriString = uri.toString();
if (uriString.startsWith("content://")) {
try (Cursor cursor = context.getContentResolver().query(uri, null, null, null, null)) {
if (cursor != null && cursor.moveToFirst()) {
displayName = cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
}
}
} else if (uriString.startsWith("file://")) {
File myFile = new File(uriString);
displayName = myFile.getName();
}
return displayName;
}
When trying to resolve the content provider: context.getContentResolver()
AndroidManifest.xml
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
And the permission granted Android M > of WRITE_EXTERNAL_STORAGE
set by the user dynamically.
Should other permissions be granted in order to use content providers?
Definition of content provider
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="${applicationId}.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
</provider>
Solution ??
Searching for SO I have fixed the error, before getting the name of the file , to intercept the opening intent:
List<ResolveInfo> resInfoList = getPackageManager().queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY);
for (ResolveInfo resolveInfo : resInfoList) {
String packageName = resolveInfo.activityInfo.packageName;
grantUriPermission(packageName, markDownFile, Intent.FLAG_GRANT_WRITE_URI_PERMISSION | Intent.FLAG_GRANT_READ_URI_PERMISSION);
}
I understand that this code what it does is grant reading and writing permission to all installed apps can use the uri
of the content provider.
But is there a way to only grant permission to the concrete URL of the content provider, but only for the app that asks to open it?