我的应用在Android 5.0上运行.我用方法getExternalFilesDirs()来检查外部SD卡是否可用.如果返回超过1 File,则表示存在外部SD卡.
但是在某些设备(例如Elephone G2)上,方法getExternalFilesDirs()只返回一个主存储目录.我确定该设备有外部SD卡(/ storage/sdcard1 /).
任何人都可以给我答案吗?
我有DocumentFile以下两种定义:
DocumentFile documentFile;
Uri documentFileUri;
Run Code Online (Sandbox Code Playgroud)
我可以通过以下方法从SD卡中删除文档文件:
documentFile.delete();DocumentsContract.deleteDocument(contentResolver, documentFileUri);但以上方法均不能从中删除相应的条目MediaStore。
处理该问题的正确方法是什么?如果我使用ContentProvider删除本地文件,它将File从数据库(contentResolver.delete(localFileUri, null, null);)中删除AND行。我希望如果使用,也会发生相同的情况,DocumentsContract但不会发生...
我想要的是
我想了解一下更新MediaStore。通常我会打电话给我,contentResolver.delete(documentFileUri, null, null);但这会失败,但有一个例外,说uri不支持删除...
题
是否有比我的解决方法更有效的方法?
解决方法
目前,我在删除a后使用以下功能立即更新媒体存储DocumentFile:
public static boolean updateAfterChangeBlocking(String path, int timeToWaitToRecheckMediaScanner)
{
final AtomicBoolean changed = new AtomicBoolean(false);
MediaScannerConnection.scanFile(StorageManager.get().getContext(),
new String[]{path}, null,
new MediaScannerConnection.OnScanCompletedListener() {
public void onScanCompleted(String path, Uri uri) {
changed.set(true);
}
});
while (!changed.get()) {
try {
Thread.sleep(timeToWaitToRecheckMediaScanner);
} catch (InterruptedException e) …Run Code Online (Sandbox Code Playgroud) 我正在使用存储访问框架(SAF):
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("image/*");
startActivityForResult(intent, 0);
Run Code Online (Sandbox Code Playgroud)
我想知道是否有一个额外的启用显示SD卡选项,用户可以在溢出菜单中看到.

使用:ACTION_OPEN_DOCUMENT_TREE + DocumentFile
更多信息: 如何使用针对Android 5.0(Lollipop)推出的新SD卡访问API?
我找不到如何更改文件属性的方法.有没有?
特别是,我需要更改Last Modified属性 - 比如File Class方法:
public boolean setLastModified(long time);
Run Code Online (Sandbox Code Playgroud)
我没有找到任何替补:
https://developer.android.com/reference/android/support/v4/provider/DocumentFile.html
或者在DocumentsContract之类的相关类中,...
新API的文档几乎没用,API函数运行速度极慢,新API的代码重写非常麻烦.我很抱歉这么强硬,但Kitkat"EACCESS(Permission denied)功能"花了我几年的生命而不是解决方案我会得到这个.
似乎setLastModified(...)方法即使使用java.io.FileClass 也不起作用(至少从Android版本4.4开始):
https://code.google.com/p/android/issues/detail?id=18624
例如,如果您有一个归档应用程序,并且您想要真正的上次修改时间,而不是从归档中提取文件的时间 - 抱歉.很多同步工具变得无用......
Android 5.1(模拟器):setLastModified(long time)方法仍然不起作用.
Android 6.0(模拟器):setLastModified(long time)方法仍然无法正常工作.
在我的应用程序中,我使用以下意图获得SD卡写入权限.如果用户从系统文件资源管理器中选择sd卡文件夹,那么我有SD卡写访问权限.
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
intent.putExtra("android.content.extra.SHOW_ADVANCED", true);
startActivityForResult(intent, 42);
Run Code Online (Sandbox Code Playgroud)
之后,我可以使用DocumentFile类修改SD卡中的文件.但我在获取随机文件路径的DocumentFile时遇到问题.
Document.fromFile(new File(path));
Document.fromSingleUri(Uri.fromFile(new File(path)));
Run Code Online (Sandbox Code Playgroud)
两者都返回一个DocumentFile对象,该对象在.canWrite()上返回false.即使我已经获得SD卡许可.
所以我编写了在我的问题末尾发布的方法,以获得一个在.canWrite()上返回true的DocumentFile.但这很慢......而且感觉非常错误!必须有更好的方法来做到这一点.我还写了一个返回相同字符串的方法
String docFileUriString = docFile.getUri().toString();
Run Code Online (Sandbox Code Playgroud)
对于任何文件,其中docFile是由下面的方法返回的DocumentFile.但
DocumentFile.fromTreeUri(Uri.parse(docFileUriString ));
Run Code Online (Sandbox Code Playgroud)
返回一个DocumentFile,它指向sd卡的根,而不是DocumentFile路径.这很奇怪.有人可以提出更优雅的解决方案吗?
public static DocumentFile getDocumentFileIfAllowedToWrite(File file, Context con){
List<UriPermission> permissionUris = con.getContentResolver().getPersistedUriPermissions();
for(UriPermission permissionUri:permissionUris){
Uri treeUri = permissionUri.getUri();
DocumentFile rootDocFile = DocumentFile.fromTreeUri(con, treeUri);
String rootDocFilePath = FileUtil.getFullPathFromTreeUri(treeUri, con);
if(file.getAbsolutePath().startsWith(rootDocFilePath)){
ArrayList<String> pathInRootDocParts = new ArrayList<String>();
while(!rootDocFilePath.equals(file.getAbsolutePath())){
pathInRootDocParts.add(file.getName());
file = file.getParentFile();
}
DocumentFile docFile = null;
if(pathInRootDocParts.size()==0){
docFile = DocumentFile.fromTreeUri(con, rootDocFile.getUri());
}
else{
for(int i=pathInRootDocParts.size()-1;i>=0;i--){
if(docFile==null){docFile = rootDocFile.findFile(pathInRootDocParts.get(i));} …Run Code Online (Sandbox Code Playgroud) 我搜索了这些问题,但无法解决。请帮我解决这个问题
那是我的 mkdir 代码:
File _sdcardPath = Environment.getExternalStorageDirectory(); // sdcard path is /storage/emulate/0
File _dirPath = new File(_sdcardPath, "CreateFolder");
boolean _isCreate = _dirPath.mkdir();
if (_isCreate) {
tvResult.append(_dirPath + " mkdir success");
} else {
tvResult.append(_dirPath + " mkdir fail");
}
Run Code Online (Sandbox Code Playgroud)
我的 manifest.xml:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.createfolder"
android:versionCode="1"
android:versionName="1.0" >
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
我的设备android版本是:5.1.1,12GB可用空间,代码在5.0下正常运行
在运行应用程序时,我遇到了这个异常: …
在 Android Q 之前,如果我们想要获取有关 APK 文件的信息,我们可以使用WRITE_EXTERNAL_STORAGE和READ_EXTERNAL_STORAGE来访问存储,然后在文件路径上使用PackageManager.getPackageArchiveInfo函数。
类似的情况也存在,例如在压缩文件上使用ZipFile 类,可能还有无数的框架 API 和第三方库。
谷歌最近宣布了对 Android Q 的大量限制。
其中之一称为“范围存储”,当访问设备拥有的所有文件时,它会破坏存储权限。它可以让您处理媒体文件,或者使用非常受限的存储访问框架 ( SAF ),该框架不允许应用程序使用文件 API 和文件路径访问和使用文件。
当Android Q Beta 2发布时,它破坏了很多应用程序,包括谷歌的应用程序。原因是它默认打开,影响所有应用程序,无论它们是否针对 Android Q。
原因是许多应用程序、SDK 和 Android 框架本身 - 都经常使用文件 API。在许多情况下,它们也不支持 InputStream 或 SAF 相关的解决方案。一个例子就是我写的 APK 解析示例 (PackageManager.getPackageArchiveInfo)。
然而,在 Q beta 3 上,情况发生了一些变化,因此目标 Q 的应用程序将具有范围存储,并且有一个标志可以禁用它,但仍然像往常一样使用正常的存储权限和文件 API。遗憾的是,该标志只是暂时的(请阅读此处),因此它推迟了不可避免的事情。
我已经尝试并发现了接下来的事情:
android file storage-access-framework android-10.0 scoped-storage
我正在尝试创建许多文件,作为用户的一项功能。例如,我可能会编写一个应用程序,为他们过去几周听过的每首歌曲创建一个文件(例如,带有歌词的文本文件)。我不能让用户为我生成的每个文件选择目录和文件名,这需要他们几个小时。用户应该可以从其他应用程序访问这些文档。
在 Android 11 中,存储访问框架似乎没有用处。我注意到最初有两个有趣的选项:
WRITE_EXTERNAL_STORAGE. 不幸的是,此权限在 Android 11 上被拒绝。因此,我无法使用此处发布的解决方案。ACTION_OPEN_DOCUMENT_TREE)访问目录以访问目录,但我无法将文件写入此目录。(我明白了FileNotFoundException,因为这不是普通路径,而是树路径。)我想在我的情况下,我需要沿着“管理存储设备上的所有文件”的路线走下去,如此处所述,这涉及使用ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION. 我宁愿不请求读取整个驱动器的权限,也不想让用户进入设置应用程序以授予权限。写入文件不应该需要任何权限...
您将如何为用户保存许多(非媒体)文件?
Kit-Kat问题无法写入外部SD卡,
如 Goolge文档中所述 为了简化运行KITKAT或更早版本的设备上的代码,您可以使用fromFile(File)模拟DocumentsProvider的行为 下面的代码(New API)适用于Lollipop,但如何使用kitkat的新API?
public class MyActivity extends Activity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_my);
Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT_TREE);
startActivityForResult(intent, 42);
}
public void onActivityResult(int requestCode, int resultCode, Intent resultData) {
if (resultCode == RESULT_OK) {
Uri treeUri = resultData.getData();
DocumentFile pickedDir = DocumentFile.fromFile(new File("/mnt/extSdCard/Test"));
// List all existing files inside picked directory
for (DocumentFile file : pickedDir.listFiles()) {
Log.d("Tag", "Found file " + file.getName() + " with size " + file.length()); …Run Code Online (Sandbox Code Playgroud) 我正在尝试将文件从任何位置(包括内部设备存储)移动到 SD 卡,
为此我有
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
Run Code Online (Sandbox Code Playgroud)
在我的清单中,并通过检查是否使用以下方法授予权限来检查它是否有效:
Contex.checkCallingOrSelfPermission("android.permission.WRITE_EXTERNAL_STORAGE") 和 Contex.checkCallingOrSelfPermission("android.permission.READ_EXTERNAL_STORAGE")
我尝试了 3 种不同的方法来做到这一点:
这种方法:
public static void move(File src, File dst) throws IOException {
FileInputStream inStream = new FileInputStream(src);
FileOutputStream outStream = new FileOutputStream(dst);
FileChannel inChannel = inStream.getChannel();
FileChannel outChannel = outStream.getChannel();
inChannel.transferTo(0, inChannel.size(), outChannel);
inStream.close();
outStream.close();
}
Run Code Online (Sandbox Code Playgroud)original.renameTo(newPath1);
我阅读了很多关于此的 SO 帖子,我尝试过的所有解决方案都不起作用,我确保安装了 SD 卡,并且在尝试时我没有将我的设备连接到 PC。我什至尝试了 2 种不同的带有 SD 卡的设备。请注意,我可以使用 BitmapFactory.decode() 以完全相同的路径访问图像,并且可以将该图像加载到 imageview。
我总是收到 EACCES(权限被拒绝)。我不知道还能做什么来解决这个问题:(
11-13 11:11:54.358 19192-19372/xaday.ofek.ron.xaday W/System.err: java.io.FileNotFoundException: /storage/sdcard1/DCIM/thai2/IMG-20150702-WA0001.jpg: open …Run Code Online (Sandbox Code Playgroud)