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

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

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

问题

我的当前代码使用:

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

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

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

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

英文:

My current code uses:

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

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

  1. /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

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

  1. List<Uri> filesList = new ArrayList<>();
  2. Uri collection;
  3. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
  4. collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
  5. } else {
  6. collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  7. }
  8. String[] projection = new String[]{
  9. MediaStore.Images.Media._ID,
  10. MediaStore.Images.Media.DISPLAY_NAME,
  11. MediaStore.Images.Media.SIZE
  12. };
  13. String selection = null;
  14. if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.Q) {
  15. selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
  16. " =? ";
  17. }
  18. String[] selectionArgs = new String[]{
  19. "Your folder name"
  20. };
  21. String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + " ASC";
  22. Cursor cursor = getApplicationContext().getContentResolver().query(
  23. collection,
  24. projection,
  25. selection,
  26. selectionArgs,
  27. sortOrder
  28. );
  29. if (cursor != null && cursor.moveToFirst()) {
  30. Log.d("continue", "not null");
  31. } else {
  32. Log.d("continue", "null return");
  33. return;
  34. }
  35. // Cache column indices.
  36. int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
  37. int nameColumn =
  38. cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
  39. int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
  40. do {
  41. // Get values of columns for a given Images.
  42. long id = cursor.getLong(idColumn);
  43. String name = cursor.getString(nameColumn);
  44. int size = cursor.getInt(sizeColumn);
  45. Uri contentUri = ContentUris.withAppendedId(
  46. MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
  47. Log.d("continue", "path-->" + contentUri);
  48. filesList.add(contentUri);
  49. // Stores column values and the contentUri in a local object
  50. // that represents the media file.
  51. } while (cursor.moveToNext());

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

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

英文:

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

  1. List&lt;Uri&gt; filesList = new ArrayList&lt;&gt;();
  2. Uri collection;
  3. if (Build.VERSION.SDK_INT &gt;= Build.VERSION_CODES.Q) {
  4. collection = MediaStore.Images.Media.getContentUri(MediaStore.VOLUME_EXTERNAL);
  5. } else {
  6. collection = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
  7. }
  8. String[] projection = new String[]{
  9. MediaStore.Images.Media._ID,
  10. MediaStore.Images.Media.DISPLAY_NAME,
  11. MediaStore.Images.Media.SIZE
  12. };
  13. String selection = null;
  14. if (android.os.Build.VERSION.SDK_INT &gt;= android.os.Build.VERSION_CODES.Q) {
  15. selection = MediaStore.Images.Media.BUCKET_DISPLAY_NAME +
  16. &quot; =? &quot;;
  17. }
  18. String[] selectionArgs = new String[]{
  19. &quot;Your folder name&quot;
  20. };
  21. String sortOrder = MediaStore.Images.Media.DISPLAY_NAME + &quot; ASC&quot;;
  22. Cursor cursor = getApplicationContext().getContentResolver().query(
  23. collection,
  24. projection,
  25. selection,
  26. selectionArgs,
  27. sortOrder
  28. );
  29. if (cursor != null &amp;&amp; cursor.moveToFirst()) {
  30. Log.d(&quot;continue&quot;, &quot;not null&quot;);
  31. } else {
  32. Log.d(&quot;continue&quot;, &quot;null return&quot;);
  33. return;
  34. }
  35. // Cache column indices.
  36. int idColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media._ID);
  37. int nameColumn =
  38. cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DISPLAY_NAME);
  39. int sizeColumn = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.SIZE);
  40. do {
  41. // Get values of columns for a given Images.
  42. long id = cursor.getLong(idColumn);
  43. String name = cursor.getString(nameColumn);
  44. int size = cursor.getInt(sizeColumn);
  45. Uri contentUri = ContentUris.withAppendedId(
  46. MediaStore.Images.Media.EXTERNAL_CONTENT_URI, id);
  47. Log.d(&quot;continue&quot;, &quot;path--&gt;&quot; + contentUri);
  48. filesList.add(contentUri);
  49. // Stores column values and the contentUri in a local object
  50. // that represents the media file.
  51. } 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

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

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

for get fileNames,try this.

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

答案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:

  1. Intent intent = new Intent();
  2. intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
  3. intent.setType("*/*");
  4. 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:

  1. Intent intent = new Intent();
  2. intent.setAction(Intent.ACTION_OPEN_DOCUMENT);
  3. intent.setType(&quot;*/*&quot;);
  4. 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:

确定