如何在 Android 10 使用 Android Studio 列出目录中的所有文件?

huangapple go评论86阅读模式
英文:

How do I list all file in a directory in android 10 using Android Studio?

问题

我的当前代码使用:

String DirectoryPath = "/storage/emulated/0";
File f = new File(DirectoryPath);
File[] file = f.listFiles();

问题是,对于位于以下路径之外的任何文件:

/storage/emulated/0/Android/data/com.example.myProgram

数组为空。根据我在网上的阅读,这在Android 10+上不再起作用。那么我该如何列出特定目录中的所有文件?(作为应用程序的一部分创建文件资源管理器)

英文:

My current code uses:

String DirectoryPath = "/storage/emulated/0";
File f = new File(DirectoryPath);
File[] file = f.listFiles();

The problem is that the array comes up as blank for anything outside:

/storage/emulated/0/Android/data/com.example.myProgram

From what I read online this no longer works with android 10+. So how would I list all files in a certain directory? (Making a file explorer as part of an App)

答案1

得分: 2

只需将以下代码行添加到应用程序标签中的清单中。

android: requestLegacyExternalStorage= "true"

英文:

Just add this line of code to your manifest in the application tag.

android: requestLegacyExternalStorage= "true"

答案2

得分: 2

是的,使用旧代码是行不通的。在这里,我找到了解决方案:

List<Uri> filesList = new ArrayList<>();

Uri collection;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
    collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
    collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}

String[] projection = new String[]{
        MediaStore.Images.Media._ID,
        MediaStore.Images.Media.DISPLAY_NAME,
        MediaStore.Images.Media.SIZE
};
String selection = null;
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
    selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
            " =? ";
}
String[] selectionArgs = new String[]{
        "Your folder name"
};
String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + " ASC";
Cursor cursor = getApplicationContext().getContentResolver().query(
        collection,
        projection,
        selection,
        selectionArgs,
        sortOrder
);
if (cursor != null && cursor.moveToFirst()) {
    Log.d("continue", "not null");
} else {
    Log.d("continue", "null return");
    return;
}
// Cache column indices.
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int nameColumn =
        cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);

do {
    // Get values of columns for a given Images.
    long id = cursor.getLong(idColumn);
    String name = cursor.getString(nameColumn);
    int size = cursor.getInt(sizeColumn);

    Uri contentUri = ContentUris.withAppendedId(
            MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
    Log.d("continue", "path-->" + contentUri);
    filesList.add(contentUri);

    // Stores column values and the contentUri in a local object
    // that represents the media file.
} while (cursor.moveToNext());

在上面的代码中,我只针对图像编写了代码,如果您想要其他文件,比如音频、视频,您需要将"Images"替换为"Audio"、"Video"等等。

注意:如果将Uri转换为文件或字符串,那么在Android 10中将无法使用这些文件。您将会收到错误。

英文:

Yes, With old code it won't work. Here i found the solution

    List&lt;Uri&gt; filesList = new ArrayList&lt;&gt;();
Uri collection;
if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.Q) {
collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
} else {
collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
}
String[] projection = new String[]{
MediaStore.Images.Media._ID,
MediaStore.Images.Media.DISPLAY_NAME,
MediaStore.Images.Media.SIZE
};
String selection = null;
if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.Q) {
selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
&quot; =? &quot;;
}
String[] selectionArgs = new String[]{
&quot;Your folder name&quot;
};
String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + &quot; ASC&quot;;
Cursor cursor = getApplicationContext().getContentResolver().query(
collection,
projection,
selection,
selectionArgs,
sortOrder
);
if (cursor != null &amp;&amp; cursor.moveToFirst()) {
Log.d(&quot;continue&quot;, &quot;not null&quot;);
} else {
Log.d(&quot;continue&quot;, &quot;null return&quot;);
return;
}
// Cache column indices.
int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
int nameColumn =
cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
do {
// Get values of columns for a given Images.
long id = cursor.getLong(idColumn);
String name = cursor.getString(nameColumn);
int size = cursor.getInt(sizeColumn);
Uri contentUri = ContentUris.withAppendedId(
MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
Log.d(&quot;continue&quot;, &quot;path--&gt;&quot; + contentUri);
filesList.add(contentUri);
// Stores column values and the contentUri in a local object
// that represents the media file.
} while (cursor.moveToNext());

In the above code, I written for images only if you want any other files audio video you need to replace Images with Audio and Video ...etc

Note: if you convert Uri to file or string, then you can't use those files. You will get an error in android 10

答案3

得分: 1

获取文件名,请尝试以下代码:

File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, "path");
for (File f : yourDir.listFiles()) {
    if (f.isFile()) {
        String name = f.getName();
        // 执行你的操作
    }
}
英文:

for get fileNames,try this.

File sdCardRoot = Environment.getExternalStorageDirectory();
File yourDir = new File(sdCardRoot, &quot;path&quot;);
for (File f : yourDir.listFiles()) {
if (f.isFile())
String name = f.getName();
// Do your stuff
}

答案4

得分: 1

你所描述的是有效的。

使用存储访问框架,可以列出所有目录。

英文:

What you described is valid.

Use Storage Access Framework to be able to list all directories.

答案5

得分: 1

基于 https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory/ 的内容,为了提升用户隐私,直接访问共享/外部存储设备的方式已被弃用。应用可以通过迁移到其他替代方案,如 Context#getExternalFilesDir(String)、MediaStore 或 Intent#ACTION_OPEN_DOCUMENT,继续访问存储在共享/外部存储上的内容。

在我的情况下,我需要在用户设备上查找图片或任何类型的文档,如 .docx、.xls 文件,因此我正在使用以下方式的 ACTION_OPEN_DOCUMENT:

Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setType("*/*");
startActivityForResult(intent, REQUEST_CODE_INTENT_GET_CV);
英文:

Base on https://developer.android.com/reference/android/os/Environment#getExternalStorageDirectory(), To improve user privacy, direct access to shared/external storage devices is deprecated Apps can continue to access content stored on shared/external storage by migrating to alternatives such as Context#getExternalFilesDir(String), MediaStore, or Intent#ACTION_OPEN_DOCUMENT.

In my case,I need to find images or any kind of documents like .docx,.xls file on user's device so I'm using ACTION_OPEN_DOCUMENT like bellow:

     Intent intent = new Intent();
intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
intent.setType(&quot;*/*&quot;);
startActivityForResult(intent, REQUEST_CODE_INTENT_GET_CV);

huangapple
  • 本文由 发表于 2020年6月29日 12:13:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/62631105.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定