Android 12中获取WhatsApp Documents文件夹PDF/CSV文件问题求助
问题解决步骤
1. 修正文件名过滤逻辑
你的FilenameFilter里误用了&&逻辑——一个文件不可能同时以.pdf和.csv结尾,必须改成||才能匹配两种格式:
return filename.toLowerCase().endsWith(".pdf") || filename.toLowerCase().endsWith(".csv");
2. 递归遍历子文件夹
listFiles()只会返回当前目录下的文件和子文件夹,不会自动遍历Sent、Private这类子目录里的内容。需要编写递归方法来遍历所有层级:
private void collectFiles(File dir, List<File> resultList) { File[] files = dir.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String filename) { File file = new File(dir, filename); // 保留子文件夹以便后续递归处理 if (file.isDirectory()) { return true; } // 匹配PDF或CSV文件 String lowerName = filename.toLowerCase(); return lowerName.endsWith(".pdf") || lowerName.endsWith(".csv"); } }); if (files == null) return; for (File file : files) { if (file.isDirectory()) { // 递归遍历子文件夹 collectFiles(file, resultList); } else { // 将符合条件的文件加入结果列表 resultList.add(file); } } }
调用示例:
File srcDir = new File(Environment.getExternalStorageDirectory().getAbsolutePath() + "/Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Documents/"); List<File> allTargetFiles = new ArrayList<>(); collectFiles(srcDir, allTargetFiles); // 遍历打印所有找到的文件 for (File file : allTargetFiles) { System.out.println("找到文件:" + file.getAbsolutePath()); }
3. 适配Android 12的存储权限
Android 10及以上启用了分区存储,直接访问Android/media下其他应用的目录需要适配权限:
方案一:使用MANAGE_EXTERNAL_STORAGE权限
在AndroidManifest.xml中添加权限声明:<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" android:minSdkVersion="30" />然后在代码中动态引导用户授权:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) { if (!Environment.isExternalStorageManager()) { Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION); Uri uri = Uri.fromParts("package", getPackageName(), null); intent.setData(uri); startActivity(intent); } }注意:该权限属于敏感权限,Google Play对使用该权限的应用有严格审核要求,仅当应用确实需要全文件访问时才建议使用。
方案二:使用MediaStore查询(推荐)
更符合分区存储规范的方式是通过MediaStore查询文件,仅需READ_EXTERNAL_STORAGE权限:private List<Uri> getWhatsAppDocuments(Context context) { List<Uri> fileUris = new ArrayList<>(); String[] projection = {MediaStore.Files.FileColumns._ID, MediaStore.Files.FileColumns.DISPLAY_NAME}; // 筛选WhatsApp Documents目录下的PDF和CSV文件 String selection = MediaStore.Files.FileColumns.RELATIVE_PATH + " LIKE ? AND (" + MediaStore.Files.FileColumns.MIME_TYPE + " = ? OR " + MediaStore.Files.FileColumns.MIME_TYPE + " = ?)"; String[] selectionArgs = { "%Android/media/com.whatsapp/WhatsApp/Media/WhatsApp Documents/%", "application/pdf", "text/csv" }; Cursor cursor = context.getContentResolver().query( MediaStore.Files.getContentUri("external"), projection, selection, selectionArgs, null ); if (cursor != null) { while (cursor.moveToNext()) { long id = cursor.getLong(cursor.getColumnIndexOrThrow(MediaStore.Files.FileColumns._ID)); Uri uri = ContentUris.withAppendedId(MediaStore.Files.getContentUri("external"), id); fileUris.add(uri); } cursor.close(); } return fileUris; }这种方式通过Content Uri操作文件,无需直接访问路径,更适配Android 10+的存储规则。
内容的提问来源于stack exchange,提问作者Bhagyashri
相关产品推荐
相关产品推荐

