【发布时间】:2022-01-20 12:23:22
【问题描述】:
我想在外部 PDF 查看器中打开文件。 如果我使用“OPEN_DOCUMENT”文件选择器调用该文件,一切正常。
如果我在没有用户对话框的情况下直接使用硬编码的现有 URI 调用不同的文件,我没有权限。
得到这个错误:
Caused by: java.lang.SecurityException: UID 10153 does not have permission to content://com.android.externalstorage.documents/document/primary%3ANot%2FBar%2Ftest.pdf [user 0]; you could obtain access using ACTION_OPEN_DOCUMENT or related APIs
at android.os.Parcel.createException(Parcel.java:2071)
at android.os.Parcel.readException(Parcel.java:2039)
at android.os.Parcel.readException(Parcel.java:1987)
at android.app.IActivityManager$Stub$Proxy.grantUriPermission(IActivityManager.java:5748)
at android.app.ContextImpl.grantUriPermission(ContextImpl.java:1935)
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:805)
at android.content.ContextWrapper.grantUriPermission(ContextWrapper.java:805)
at de.temaks.stepbystep.MainActivity.grantPermissions(MainActivity.java:203)
at de.temaks.stepbystep.MainActivity.oPDF(MainActivity.java:184)
at de.temaks.stepbystep.MainActivity.my10(MainActivity.java:144)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.appcompat.app.AppCompatViewInflater$DeclaredOnClickListener.onClick(AppCompatViewInflater.java:441)
at android.view.View.performClick(View.java:7146)
at com.google.android.material.button.MaterialButton.performClick(MaterialButton.java:1119)
at android.view.View.performClickInternal(View.java:7119)
at android.view.View.access$3500(View.java:803)
at android.view.View$PerformClick.run(View.java:27533)
at android.os.Handler.handleCallback(Handler.java:883)
at android.os.Handler.dispatchMessage(Handler.java:100)
at android.os.Looper.loop(Looper.java:214)
at android.app.ActivityThread.main(ActivityThread.java:7386)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:492)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:980)
Caused by: android.os.RemoteException: Remote stack trace:
at com.android.server.uri.UriGrantsManagerService.checkGrantUriPermission(UriGrantsManagerService.java:1174)
at com.android.server.uri.UriGrantsManagerService.grantUriPermission(UriGrantsManagerService.java:767)
at com.android.server.uri.UriGrantsManagerService$LocalService.grantUriPermission(UriGrantsManagerService.java:1317)
我尝试使用 ACTION_OPEN_DOCUMENT_TREE 设置文件夹中所有文件的标志:
public void openDirectory(Uri uriToLoad) {
// Choose a directory using the system's file picker.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
// Optionally, specify a URI for the directory that should be opened in
// the system file picker when it loads.
intent.putExtra(DocumentsContract.EXTRA_INITIAL_URI, uriToLoad);
intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
startActivityForResult(intent, 3333);
} 并且在 activityRusult 尝试为该文件夹中的所有文件设置标志:
if (requestCode == 3333
&& resultCode == Activity.RESULT_OK) {
// The result data contains a URI for the document or directory that
// the user selected.
Uri uri = null;
if (resultData != null) {
uri = resultData.getData();
// Perform operations on the document using its URI.
Log.i("Verzeichnis ", "gelesen: "+uri.toString());
//take persist permission for later use
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
getContentResolver().takePersistableUriPermission(uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
int takeFlags = resultData.getFlags()& (Intent.FLAG_GRANT_READ_URI_PERMISSION
| Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
ContentResolver resolver = this.getContentResolver();
resolver.takePersistableUriPermission(resultData.getData(),takeFlags);
File directory = new File(path);
Log.i("directory.exists(): ",String.valueOf(directory.exists()));
Log.i("directory.canRead(): ",String.valueOf( directory.canRead()));
Log.i("directory.length(): ",String.valueOf( directory.length()));
/*File[] files = directory.listFiles();
Log.i("Files", "Size: " + files.length);
Toast.makeText(this,String.valueOf(files.length) +"
String[] theNamesOfFiles = new String[files.length];
for (int i = 0; i < files.length; i++) {
theNamesOfFiles[i] = files[i].getName();
}*/
这不起作用,因为之后的错误仍然相同。 也许我有错误的标志?
directory.exists() 给出“真”
directory.canRead() 给出“假”
我将标志设置为“目录树”。 我应该在每个文件上单独设置标志吗?
目前在测试用例中,我手动构建了 uri(这个 uri(文件)在我设置标志的树中)。稍后我想从数据库中调用已保存的 uri。
Uri uri2 = Uri.parse("content://com.android.externalstorage.documents/document/primary%3ANoten_MVP%2FBariton%2F0018_Wiener%20Elan-Bariton.pdf");
oPDF(uri2);
将 uri 发送到外部应用程序:
public void oPDF(Uri myUri){
Uri uri = null;
uri = myUri;
uri.getAuthority();
String mimeType = getContentResolver().getType(uri);
Log.i("mime Type ", mimeType);
//this.grantUriPermission(null, uri, Intent.FLAG_GRANT_READ_URI_PERMISSION);
Log.i("URI Import",uri.toString());
String path = uri.getLastPathSegment() ;//getEncodedPath();
path = path.substring(path.indexOf(":") + 1);
Toast.makeText(this, "importiert: " + path, Toast.LENGTH_LONG).show();
Log.i("READ_REQUEST_CODE 42: "," hier sind die Ergebnisse aus onActivityResult: " );
Log.i("uri DER: ", uri.toString());
Intent target = new Intent(Intent.ACTION_VIEW);
//target.setDataAndType(Uri.parse("content://com.android.externalstorage.documents/document/primary%3A"+ path), "application/pdf");
target.setDataAndType(uri, "application/pdf");
target.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
//Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
Intent intent = Intent.createChooser(target, "Open PDF using");
intent.setFlags(Intent.FLAG_ACTIVITY_NO_HISTORY | Intent.FLAG_GRANT_READ_URI_PERMISSION);
grantPermissions(this,target,uri,true);
try {
startActivity(intent);
} catch (ActivityNotFoundException e) {
// Instruct the user to install a PDF reader here, or something
Toast.makeText(this, "No Applications found to open pdf", Toast.LENGTH_SHORT).show();
}
}
还是一样的错误
原因:java.lang.SecurityException:UID 10153 没有对内容的权限://com.android.externalstorage.documents/document/primary%3ANoten_MVP%2FBariton%2F0010_Laridah%20Marsch-Bariton.pdf [user 0] ;您可以使用 ACTION_OPEN_DOCUMENT 或相关 API 获得访问权限
如何获取文件夹中所有文件的权限? 我能做什么?
【问题讨论】:
-
target.setDataAndType(uri, "application/pdf");你没有展示你是如何建立你的uri的。 -
我的 uri 存在且正确。
-
你应该只调用一次 takePersistableUriPermission()。
标签: java android android-studio uri permission-denied