You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android Kotlin中指定目录打开文件管理器并过滤无关应用

解决方案

问题原因分析

  1. 无关应用弹出:原代码使用ACTION_VIEW + type="*/*",这个组合会匹配所有能处理任意类型数据的应用(包括邮件、社交类APP),而非仅文件管理器。
  2. 打开错误目录:Uri.fromFile()生成的file:// Uri在Android 10+的Scoped Storage机制下存在权限限制,且多数文件管理器对这类Uri的处理逻辑不一致,导致默认跳转到Downloads目录。

修正后的代码实现

以下是适配Android 10+的正确代码,既能精准定位到Documents目录,又能仅显示文件管理器类应用:

import android.content.Intent
import android.content.pm.PackageManager
import android.net.Uri
import android.os.Build
import android.os.Environment
import android.provider.DocumentsContract
import android.provider.MediaStore
import androidx.appcompat.app.AppCompatActivity

fun AppCompatActivity.openDocumentsDirectory() {
    // 构建打开目录的Intent,使用SAF(Storage Access Framework)
    val intent = Intent(Intent.ACTION_OPEN_DOCUMENT_TREE).apply {
        // 指定初始跳转目录为Documents
        val documentsUri = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
            // Android 10+ 用SAF的方式获取Documents目录Uri
            MediaStore.Files.getContentUri("external").buildUpon()
                .appendPath(Environment.DIRECTORY_DOCUMENTS)
                .build()
        } else {
            // 兼容Android 9及以下,使用旧方式(注意:Android 10+已废弃)
            Uri.fromFile(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOCUMENTS))
        }
        putExtra(DocumentsContract.EXTRA_INITIAL_URI, documentsUri)
        
        // 添加持久化权限,后续可直接访问该目录
        flags = Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
    }

    // 过滤仅保留文件管理器类应用
    val packageManager = packageManager
    val resolveInfos = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY)
    val filteredIntents = mutableListOf<Intent>()

    resolveInfos.forEach { resolveInfo ->
        val componentName = resolveInfo.activityInfo.componentName
        val targetIntent = Intent(intent).apply {
            setComponent(componentName)
        }
        filteredIntents.add(targetIntent)
    }

    // 创建选择器,只显示过滤后的应用
    if (filteredIntents.isNotEmpty()) {
        val chooser = Intent.createChooser(filteredIntents.removeAt(0), "选择文件管理器")
        chooser.putExtra(Intent.EXTRA_INITIAL_INTENTS, filteredIntents.toTypedArray())
        startActivity(chooser)
    }
}

关键说明

  • 使用SAF机制:ACTION_OPEN_DOCUMENT_TREE是Android官方推荐的目录访问方式,仅文件管理器类应用会注册该Intent的处理逻辑,从根源避免无关应用出现。
  • 指定初始目录:通过DocumentsContract.EXTRA_INITIAL_URI传递Documents目录的SAF Uri,确保文件管理器直接跳转到目标目录。
  • 应用过滤:通过queryIntentActivities获取所有能处理该Intent的应用,再构建仅包含这些应用的选择器,进一步确保只显示文件管理器。

内容的提问来源于stack exchange,提问作者Androidew1267

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.20 09:11:15