I'm developing an application that recieves a file from the user and inserts the URI into a SQLite db:
public void getBook(){ // called when the user wants to give a file to the app
Intent chooseFile = new Intent(Intent.ACTION_OPEN_DOCUMENT);
chooseFile.setType("text/plain");
chooseFile = Intent.createChooser(chooseFile, "Choose a file");
startActivityForResult(chooseFile, FILE_CHOOSER_REQUEST_CODE);
}
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == FILE_CHOOSER_REQUEST_CODE && resultCode == Activity.RESULT_OK) {
Uri u = data.getData();
addBook(u); // addBook adds u.toString() to the db
}
}
My application uses the following code to read the file (it gets u
by using Uri.parse()
on the string from the db):
private void readFile(Uri u, String lang, String name){
try {
InputStream is = getContentResolver().openInputStream(u); //the code crashes on this line
\\ some code...
}
catch(java.io.IOException e){
Toast.makeText(MainActivity.this, R.string.file_not_found, Toast.LENGTH_SHORT).show();
}
}
This works fine even when I reopen the app, but after the phone gets restarted I'm getting the following error:
2020-03-06 11:31:49.687 5664-5664/com.example.android.readme E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.example.android.readme, PID: 5664
java.lang.SecurityException: Permission Denial: opening provider com.android.providers.downloads.DownloadStorageProvider from ProcessRecord{93bfa52 5664:com.example.android.readme/u0a163} (pid=5664, uid=10163) requires that you obtain access using ACTION_OPEN_DOCUMENT or related APIs
at android.os.Parcel.readException(Parcel.java:2013)
at android.os.Parcel.readException(Parcel.java:1959)
at android.app.IActivityManager$Stub$Proxy.getContentProvider(IActivityManager.java:4758)
at android.app.ActivityThread.acquireProvider(ActivityThread.java:5836)
at android.app.ContextImpl$ApplicationContentResolver.acquireUnstableProvider(ContextImpl.java:2526)
at android.content.ContentResolver.acquireUnstableProvider(ContentResolver.java:1780)
at android.content.ContentResolver.openTypedAssetFileDescriptor(ContentResolver.java:1394)
at android.content.ContentResolver.openAssetFileDescriptor(ContentResolver.java:1247)
at android.content.ContentResolver.openInputStream(ContentResolver.java:967)
at com.example.android.readme.MainActivity.readFile(MainActivity.java:162)
at com.example.android.readme.MainActivity.access$300(MainActivity.java:25)
at com.example.android.readme.MainActivity$1.onItemClick(MainActivity.java:84)
at android.widget.AdapterView.performItemClick(AdapterView.java:318)
at android.widget.AbsListView.performItemClick(AbsListView.java:1158)
at android.widget.AbsListView$PerformClick.run(AbsListView.java:3127)
at android.widget.AbsListView$3.run(AbsListView.java:4042)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Why does it happen? (I do use ACTION_OPEN_DOCUMENT
in my code.)
Thanks in advance for any help!
addBook(u); // addBook adds u.toString() to the db
By default, your rights to access the content identified by the Uri
is limited to the activity instance that was given the Uri
via onActivityResult()
. In particular, your rights go away when your process does.
If you are going to persist the Uri
from ACTION_OPEN_DOCUMENT
and try to use that Uri
again the next day/week/month/year, you need to call takePersistableUriPermission()
on ContentResolver
first, before saving your Uri
to the database.