通过 Android 中的 Intent 选择任何类型的文件

Posted

技术标签:

【中文标题】通过 Android 中的 Intent 选择任何类型的文件【英文标题】:Pick any kind of file via an Intent in Android 【发布时间】:2012-02-15 06:16:56 【问题描述】:

我想为可以返回任何类型文件的应用程序启动一个意图选择器

目前我使用的是(我从 android 电子邮件源代码中复制的文件附件)

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.setType("*/*");
Intent i = Intent.createChooser(intent, "File");
startActivityForResult(i, CHOOSE_FILE_REQUESTCODE);

但它只在我的 Galaxy S2 上显示“图库”和“音乐播放器”。此设备上有一个文件资源管理器,我希望它出现在列表中。我还希望相机应用程序显示在列表中,以便用户可以拍摄照片并通过我的应用程序发送。 如果我安装 Astro 文件管理器,它也会响应该意图。我的客户只是 Galaxy SII 的所有者,我不想强​​迫他们安装 Astro 文件管理器,因为他们已经有一个基本但足够的文件管理器。

知道如何实现这一目标吗?我很确定我已经看到默认文件管理器出现在这样的菜单中以选择文件,但我不记得在哪个应用程序中。

【问题讨论】:

您需要非常不同的代码来拍摄照片然后选择文件。我实际上并不认为大多数文件浏览器都可以返回文件,但我可能错了。 你能指定你主要需要访问什么样的文件吗? @dtech : 我不希望文件资源管理器返回文件,我只需要它的路径。 @subrussn90 :我需要让用户选择任何类型的文件。它可以是 pdf、.doc、.zip、任何类型的文件。 拿到sd卡上指定文件的Uri就够了吗??? 【参考方案1】:

其他答案没有错。但是,现在有更多用于打开文件的选项。例如,如果您希望应用程序对文件具有长期、永久的访问权限,则可以改用ACTION_OPEN_DOCUMENT。参考官方文档:Open files using storage access framework。还有refer to this answer。

【讨论】:

【参考方案2】:

这给了我最好的结果:

    Intent intent;
    if (android.os.Build.MANUFACTURER.equalsIgnoreCase("samsung")) 
        intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
        intent.putExtra("CONTENT_TYPE", "*/*");
        intent.addCategory(Intent.CATEGORY_DEFAULT);
     else 

        String[] mimeTypes =
                "application/msword", "application/vnd.openxmlformats-officedocument.wordprocessingml.document", // .doc & .docx
                        "application/vnd.ms-powerpoint", "application/vnd.openxmlformats-officedocument.presentationml.presentation", // .ppt & .pptx
                        "application/vnd.ms-excel", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", // .xls & .xlsx
                        "text/plain",
                        "application/pdf",
                        "application/zip", "application/vnd.android.package-archive";

        intent = new Intent(Intent.ACTION_GET_CONTENT); // or ACTION_OPEN_DOCUMENT
        intent.setType("*/*");
        intent.putExtra(Intent.EXTRA_MIME_TYPES, mimeTypes);
        intent.addCategory(Intent.CATEGORY_OPENABLE);
        intent.putExtra(Intent.EXTRA_LOCAL_ONLY, true);
    

【讨论】:

你能分享你的 onActivityResultCode @Islam Khaled 第三个选项参见 org.openintents.action.PICK_FILE。 openintents.org/action/org-openintents-action-pick-file 您的代码还假设三星手机上的每个人都使用并且(仍然)拥有三星文件管理器。使用三星的 intent.resolveActivity 作为后备会更加稳健。【参考方案3】:

三星文件浏览器不仅需要自定义操作(com.sec.android.app.myfiles.PICK_DATA), 而且类别部分(Intent.CATEGORY_DEFAULT)和 mime-type 也应该作为额外的传递。

Intent intent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
intent.putExtra("CONTENT_TYPE", "*/*");
intent.addCategory(Intent.CATEGORY_DEFAULT);

您还可以使用此操作打开多个文件:com.sec.android.app.myfiles.PICK_DATA_MULTIPLE 无论如何,这是我适用于三星和其他设备的解决方案:

public void openFile(String mimeType) 

        Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
        intent.setType(mimeType);
        intent.addCategory(Intent.CATEGORY_OPENABLE);

        // special intent for Samsung file manager
        Intent sIntent = new Intent("com.sec.android.app.myfiles.PICK_DATA");
         // if you want any file type, you can skip next line 
        sIntent.putExtra("CONTENT_TYPE", mimeType); 
        sIntent.addCategory(Intent.CATEGORY_DEFAULT);

        Intent chooserIntent;
        if (getPackageManager().resolveActivity(sIntent, 0) != null)
            // it is device with Samsung file manager
            chooserIntent = Intent.createChooser(sIntent, "Open file");
            chooserIntent.putExtra(Intent.EXTRA_INITIAL_INTENTS, new Intent[]  intent);
         else 
            chooserIntent = Intent.createChooser(intent, "Open file");
        

        try 
            startActivityForResult(chooserIntent, CHOOSE_FILE_REQUESTCODE);
         catch (android.content.ActivityNotFoundException ex) 
            Toast.makeText(getApplicationContext(), "No suitable File Manager was found.", Toast.LENGTH_SHORT).show();
        
    

这个解决方案对我很有效,也许对其他人有用。

【讨论】:

它几乎对我有用,除了 sIntent 在启动时不接受任何类型的文件。我可以浏览文件夹,仅此而已。 问题是intent需要mimeType: "file/*",而三星sIntent需要" * / *" - * / *之间没有空格 其他 11k 的 Android 设备呢。 如何为这个意图设置 URI,你能帮我吗? 在三星 Intent ("com.sec.android.app.myfiles.PICK_DATA") 的情况下,您可以尝试添加额外的字符串“FOLDERPATH”或“START_FOLDER”【参考方案4】:

不是用于相机,而是用于其他文件..

在我的设备中,我安装了ES File Explorer,这对我来说很简单..

Intent intent = new Intent(Intent.ACTION_GET_CONTENT);
intent.setType("file/*");
startActivityForResult(intent, PICKFILE_REQUEST_CODE);

【讨论】:

它确实适用于外部文件资源管理器(例如 ES 文件资源管理器或 Astro 文件管理器,但不适用于三星文件资源管理器。奇怪的是他们没有实现正确的意图过滤器来响应那个动作。 @Lukap - 使用开源 android 文件管理器并将其与您的应用程序集成,然后您不需要任何第三方应用程序。 如何获取选中的文件?我想这是路径,但如何? @FranciscoCorralesMorales - 在onActivityResult()- 你可以获得文件的Uri PICKFILE_RESULT_CODE 应该是PICKFILE_REQUEST_CODE【参考方案5】:

如果你想知道这一点,它存在一个名为aFileDialog 的开源库,它是一个小且易于使用的提供文件选择器的库。

与其他 Android 文件选择器库的不同之处在于,aFileDialog 提供了将文件选择器作为 Dialog 和 Activity 打开的选项。

它还允许您选择文件夹、创建文件、使用正则表达式过滤文件并显示确认对话框。

【讨论】:

【参考方案6】:

我在 Galaxy Note 上为我工作 它的表演 联系方式, 安装在设备上的文件管理器, 画廊, 音乐播放器

private void openFile(Int  CODE) 
    Intent i = new Intent(Intent.ACTION_GET_CONTENT);
    i.setType("*/*");
    startActivityForResult(intent, CODE);

在这里获取活动的onActivityResult 中的路径。

protected void onActivityResult(int requestCode, int resultCode, Intent data) 
     String Fpath = data.getDataString();
    // do somthing...
    super.onActivityResult(requestCode, resultCode, data);


【讨论】:

如何将获取 uri 转换为 util.File ? 不确定是否获取 java.io.File,但可以通过以下方式打开:developer.android.com/reference/android/content/… 如何获取简单名称在这里:***.com/a/23270545/755313 如何选择文件夹? 我喜欢这个答案,因为类型设置也允许您选择图像。 在 Kotlin 中使用 File(data.dataString)【参考方案7】:

原来三星文件资源管理器使用自定义操作。这就是为什么我在从三星应用程序中查找文件时可以看到三星文件资源管理器,而不是我的文件。

动作是“com.sec.android.app.myfiles.PICK_DATA”

我创建了一个自定义的活动选择器,它显示过滤两个意图的活动。

【讨论】:

嗨,你能解释一下吗?对于三星 Galaxy 手机,我使用 Intent selectFile = new Intent("com.sec.android.app.myfiles.PICK_DATA");但它会导致错误 我现在不确定,但我可以稍后检查。我认为这是 Activity Not Found 异常。你有任何可行的解决方案吗?我几乎尝试了所有方法,但无法修复它 这个意图在 Galaxy SII 上对我有用。在 GT-B5510 (Galaxy Y Pro) 上尝试过,但没有成功。如果您想针对所有三星设备,我认为这是不可靠的。我最终将一个开源文件管理器集成到我的应用程序中,但对于这种基本需求来说,它是一个繁重的解决方案。 如何为这个意图设置 URI,你能帮我吗?

以上是关于通过 Android 中的 Intent 选择任何类型的文件的主要内容,如果未能解决你的问题,请参考以下文章

Android(Intent 学习)

android 文件选择

在没有安装任何文件管理器的 Android 中选择一个文件

为 Android 中的通用文件选择哪种 mimeType?

如何指定Android中的浏览器跳转界面?

通过 Android 中的 Intent 反序列化 Serializable 对象时出现 ClassNotFoundException