我尝试读取并更改外部存储SD卡上的文本文件。为了使示例更容易,我已经插入了从文件选择器中获取的内容URI。
我使用Android 7(SDK 24)在Nexus 5X上运行应用程序。 minSdkVersion设置为19,targetSdkVersion为23.
java.lang.SecurityException: Permission Denial: reading de.cowabuja.androidaccess uri content://com.android.externalstorage.documents/document/primary%3ADCIM%2FAny%2Dir%2FtheFile.txt from pid=1399, uid=10350 requires android.permission.MANAGE_DOCUMENTS, or grantUriPermission()
这里的日志:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="de.cowabuja.androiduriaccess">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
</application>
</manifest>
我尝试调用grantUriPermission,因为我尝试解决之前遇到的异常:
data Tree t = Leaf t | Node (Tree t) t (Tree t) deriving Show
foldTree :: (t1 -> t -> t1 -> t1) -> (t -> t1) -> Tree t -> t1
foldTree treeFn leafFn tree
| foldTree (Leaf v) = leafFn v
| foldTree (Node left v right) = treeFn left v right
的AndroidManifest.xml:
class MyClass<K> {
private final Map<K, Float> myMap;
public MyClass() {
myMap = new HashMap<>();
}
public static MyClass<Integer> create(int size) {
MyClass<Integer> result = new MyClass<>();
for(int i = 0; i < size; i++) {
Float rnd = ThreadLocalRandom.current().nextFloat();
result.myMap.put(bar,rnd);
}
return result;
}
}
答案 0 :(得分:1)
您无法将Uri
组合到这样的第三方提供商并期望它能够正常运行。该提供商未授予您使用该内容的权限。最多,以前为您提供了临时访问内容的权限,但是当您的流程过期时,这些权利就会消失。
或者:
将文件移至removable storage上getExternalFilesDirs()
,getExternalCacheDirs()
和getExternalMediaDirs()
上具有文件系统访问权限的位置之一。如果这些方法(在Context
上)返回2个以上的条目,则第二个和后续的条目是可以使用的可移动存储上的目录。然后,您可以使用普通的Java文件I / O(例如,File
,FileInputStream
)。
使用the Storage Access Framework要求用户选择要使用的文件。用户可以选择在可移动存储上选择一个,因为它是用户的设备和用户的文件。然后,您可以通过openInputStream()
。
Uri
with ContentResolver