40

这是我的代码,但这是针对单个文件解决方案的。

我可以像下面的单个文件一样共享多个文件和上传吗?

Button btn = (Button)findViewById(R.id.hello);

    btn.setOnClickListener(new OnClickListener() {

            @Override
            public void onClick(View v) {
                Intent intent = new Intent(Intent.ACTION_SEND);

                String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/pic.png";
                File file = new File(path);

                MimeTypeMap type = MimeTypeMap.getSingleton();
                intent.setType(type.getMimeTypeFromExtension(MimeTypeMap.getFileExtensionFromUrl(path)));

                intent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
                intent.putExtra(Intent.EXTRA_TEXT, "1111"); 
                startActivity(intent);
            }
        }); 
4

4 回答 4

117

是的,但您需要使用Intent.ACTION_SEND_MULTIPLE而不是Intent.ACTION_SEND.

Intent intent = new Intent();
intent.setAction(Intent.ACTION_SEND_MULTIPLE);
intent.putExtra(Intent.EXTRA_SUBJECT, "Here are some files.");
intent.setType("image/jpeg"); /* This example is sharing jpeg images. */

ArrayList<Uri> files = new ArrayList<Uri>();

for(String path : filesToSend /* List of the files you want to send */) {
    File file = new File(path);
    Uri uri = Uri.fromFile(file);
    files.add(uri);
}

intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, files);
startActivity(intent);

这绝对可以简化,但我留下了一些行,以便您可以分解所需的每个步骤。

更新:从 API 24 开始,共享文件 URI 将导致 FileUriExposedException。要解决这个问题,您可以将 compileSdkVersion 切换为 23 或更低,或者您可以使用带有 FileProvider 的内容 URI

更新(更新)谷歌最近宣布,新的应用程序和应用程序更新将需要针对最新版本的 Android 之一发布到 Play 商店。也就是说,如果您计划将应用程序发布到商店,则以 API 23 或更低版本为目标不再是一个有效的选择。您必须走 FileProvider 路线。

于 2013-03-22T18:38:39.687 回答
15

这是 Mceley 的解决方案即兴创作的小改进版本。这可以用于同时发送异构文件列表(如图像、文档和视频),例如同时上传下载的文档、图像。

public static void shareMultiple(List<File> files, Context context){

    ArrayList<Uri> uris = new ArrayList<>();
    for(File file: files){
        uris.add(Uri.fromFile(file));
    }
    final Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
    intent.setType("*/*");
    intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uris);
    context.startActivity(Intent.createChooser(intent, context.getString(R.string.ids_msg_share)));
}
于 2016-12-06T10:15:42.007 回答
4

如果您在运行 KitKat 及更高版本的设备上与其他应用程序共享文件,则需要提供 Uri 权限。


这就是我在 KitKat 前后处理多个文件共享的方式:

//All my paths will temporarily be retrieve into this ArrayList
//PathModel is a simple getter/setter
ArrayList<PathModel> pathList;
//All Uri's are retrieved into this ArrayList
ArrayList<Uri> uriArrayList = null;
//This is important since we are sending multiple files
Intent sharingIntent = new Intent(Intent.ACTION_SEND_MULTIPLE);
//Used temporarily to get Uri references
Uri shareFileUri;

if (android.os.Build.VERSION.SDK_INT < Build.VERSION_CODES.KITKAT) {

    //My paths are stored in SQLite, I retrieve them first
    SQLiteHelper helper = new SQLiteHelper(this);
    pathList = helper.getAllAttachments(viewholderID);
    helper.close();

    //Create new instance of the ArrayList where the Uri will be stored
    uriArrayList = new ArrayList<>();

    //Get all paths from my PathModel
    for (PathModel data : pathList) {
        //Create a new file for each path
        File mFile = new File(data.getPath());
        //No need to add Uri permissions for pre-KitKat
        shareFileUri = Uri.fromFile(mFile);
        //Add Uri's to the Array that holds the Uri's
        uriArrayList.add(shareFileUri);
    }


} else {

    //My paths are stored in SQLite, I retrieve them first
    SQLiteHelper helper = new SQLiteHelper(this);
    pathList = helper.getAllAttachments(viewholderID);
    helper.close();

    //Create new instance of the ArrayList where the Uri will be stored
    uriArrayList = new ArrayList<>();

    //Get all paths from my PathModel
    for (PathModel data : pathList) {
        //Create a new file for each path
        File mFile = new File(data.getPath());
        //Now we need to grant Uri permissions (kitKat>)
        shareFileUri = FileProvider.getUriForFile(getApplication(), getApplication().getPackageName() + ".provider", mFile);
        //Add Uri's to the Array that holds the Uri's
        uriArrayList.add(shareFileUri);
    }

    //Grant read Uri permissions to the intent
    sharingIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);

}

//I know that the files which will be sent will be one of the following
sharingIntent.setType("application/pdf/*|image|video/*");
//pass the Array that holds the paths to the files
sharingIntent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, uriArrayList);
//Start intent by creating a chooser
startActivity(Intent.createChooser(sharingIntent, "Share using"));

在我的情况下,路径存储在 中SQLite,但路径可以来自任何地方。

于 2019-07-23T07:31:08.423 回答
3
/* 
 manifest file outside the applicationTag write these permissions
     <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
     <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> */

    File pictures = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
                            //Get a top-level public external storage directory for placing files of a particular type. 
                            // This is where the user will typically place and manage their own files, 
                            // so you should be careful about what you put here to ensure you don't 
                            // erase their files or get in the way of their own organization...
                            // pulled from Standard directory in which to place pictures that are available to the user to the File object

                            String[] listOfPictures = pictures.list();
                            //Returns an array of strings with the file names in the directory represented by this file. The result is null if this file is not a directory.

                            Uri uri=null; 
                            ArrayList<Uri> arrayList = new ArrayList<>();
                            if (listOfPictures!=null) {
                                for (String name : listOfPictures) {
                                    uri = Uri.parse("file://" + pictures.toString() + "/" + name );
                                    arrayList.add(uri);
                                }
                                Intent intent = new Intent();
                                intent.setAction(Intent.ACTION_SEND_MULTIPLE);
                                intent.putExtra(Intent.EXTRA_STREAM, arrayList);
                                //A content: URI holding a stream of data associated with the Intent, used with ACTION_SEND to supply the data being sent.
                                intent.setType("image/*"); //any kind of images can support.
                                chooser = Intent.createChooser(intent, "Send Multiple Images");//choosers title
                                 startActivity(chooser);
                            }
于 2017-04-11T23:10:48.637 回答