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

112

我想启动一个可返回任何类型文件的应用选择器

目前我使用的是(我从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
1
@dtech:我不需要文件浏览器返回文件,只需要它的路径。 - ErGo_404
@subrussn90:我需要让用户选择任何类型的文件。可以是pdf,.doc,.zip,任何类型的文件。 - ErGo_404
获取SD卡上指定文件的Uri是否足够? - subrussn90
https://github.com/criss721/Android-FileSelector - Criss
8个回答

96

不是针对相机,而是针对其他文件。

在我的设备上,我安装了ES文件浏览器,这个简单的方法在我的情况下有效。

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

7
它可以与外部文件管理器(例如ES文件浏览器或Astro文件管理器)一起使用,但无法与三星文件管理器一起使用。他们没有实现正确的意图过滤器来响应该操作,这似乎很奇怪。 - ErGo_404
3
我该如何获取所选文件?我猜是路径,但怎么做呢? - Francisco Corrales Morales
1
@FranciscoCorralesMorales - 在 onActivityResult() 方法中,你可以获取文件的 Uri - user370305
1
PICKFILE_RESULT_CODE 应该改为 PICKFILE_REQUEST_CODE - Aron Lorincz
在三星S4上,使用Android 5.0.1无法显示任何内容。请使用@alireza的答案,该答案甚至适用于三星设备。 - vovahost
显示剩余4条评论

56

三星文件浏览器需要传递不仅是自定义操作 (com.sec.android.app.myfiles.PICK_DATA), 还需要包括类别部分 (Intent.CATEGORY_DEFAULT) 和 MIME 类型作为额外参数。

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
无论如何,以下是我的解决方案,在三星和其他设备上都适用:

您还可以使用此操作来打开多个文件: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启动时不接受任何类型的文件之外,这对我几乎有效。我可以浏览文件夹,但仅限于此。 - Radu
问题在于intent需要具有mimeType:"file / *",而Samsung sIntent需要" * / "( / *之间不要有空格)。 - Radu
1
其他的11k个安卓设备怎么办? - Oliver Dixon
1
请问您能帮我设置此意图的URI吗? - PriyankaChauhan
1
在Samsung Intent(“com.sec.android.app.myfiles.PICK_DATA”)的情况下,您可以尝试放置字符串额外的“FOLDERPATH”或“START_FOLDER”。 - Chupik
显示剩余6条评论

45

这对我的Galaxy Note有效,它显示了设备上安装的联系人、文件管理器、图库和音乐播放器。

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

在 activity 的 onActivityResult 中获取路径。

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

}

6
如何将获取的 URI 转换成 util.File? - Anand Savjani
不确定如何获取java.io.File,但可以使用以下方式打开: http://developer.android.com/reference/android/content/ContentResolver.html#openInputStream(android.net.Uri) 获取简单名称的方法在这里: https://dev59.com/FWYr5IYBdhLWcg3w7uhx#23270545 - demaksee
3
如何选择文件夹? - hornet2319
我喜欢这个答案,因为排版允许您选择图片。 - Hashim Akhtar
在 Kotlin 中使用 File(data.dataString)。 - Talha Akbar

15

这给了我最好的结果:

    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? - Kishan Donga
1
另请参阅org.openintents.action.PICK_FILE以获取第三个选项。 http://www.openintents.org/action/org-openintents-action-pick-file/您的代码还假定每个使用三星手机的人都使用并(仍然)拥有三星文件管理器。使用带有三星回退的intent.resolveActivity将更加健壮。 - Marcus Wolschon
谢谢。这是我唯一成功让用户从多种类型中选择文件的方法(在我的情况下,我只需要pdf和txt格式的文件)。 - ice_chrysler

1
原来三星文件浏览器使用了自定义操作。这就是为什么我可以在三星应用程序中查找文件时看到三星文件浏览器,但在我的应用程序中却看不到的原因。
操作是“com.sec.android.app.myfiles.PICK_DATA”。
我创建了一个自定义活动选择器,它显示过滤两个意图的活动。

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

0
如果您想了解这个,存在一个名为 aFileDialog 的开源库,它是一个小巧且易于使用的文件选择器。
与其他 Android 文件选择器库不同的是,aFileDialog 可以让您选择将文件选择器作为对话框或活动打开。
它还允许您选择文件夹、创建文件、使用正则表达式过滤文件并显示确认对话框。

0
其他答案并不是错误的。然而,现在有更多打开文件的选项。例如,如果您希望应用程序长期、永久地访问文件,可以使用 ACTION_OPEN_DOCUMENT。请参阅官方文档:使用存储访问框架打开文件。另外请参考此答案

0
ES File Explorer在Google Play上已经不存在了,作为替代方案,您可以使用FS文件管理器,该应用程序允许选择任何类型的文件。 我之前制作了一个库,以便更好地与FS文件管理器进行通信: https://github.com/YounesHass/fs-selection

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接