能否一次性上传多个文件到Firebase存储?

3
在我的图片上传应用中,我目前已经设置好了使用以下代码将单个文件上传到Firebase:
 private void chooseImage() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent, "Select Picture"), PICK_IMAGE_REQUEST);
    }
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK
            && data != null && data.getData() != null )
    {
        filePath = data.getData();
        try {
            Bitmap bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), filePath);
            imageView.setImageBitmap(bitmap);
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
    }
 }

private void uploadImage() {

    Date myDate = new Date();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
    final String myDateString = sdf.format(myDate);
    String Gap ="/";

    if(filePath != null)
    {
        final ProgressDialog progressDialog = new ProgressDialog(this);
        progressDialog.setTitle("Uploading...");
        progressDialog.show();

        StorageReference ref = storageReference.child(myDateString+Gap+ UUID.randomUUID().toString());
        FirebaseDatabase db = FirebaseDatabase.getInstance();
        DatabaseReference rootRef = db.getReference().child("PreviousJobs");
        String d = ref.toString();

        rootRef
                .child(myDateString)
                .setValue(myDateString);

        ref.putFile(filePath)
                .addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        progressDialog.dismiss();
                        Toast.makeText(photoUploader.this, "Uploaded", Toast.LENGTH_SHORT).show();
                    }
                })
                .addOnFailureListener(new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        progressDialog.dismiss();
                        Toast.makeText(photoUploader.this, "Failed "+e.getMessage(), Toast.LENGTH_SHORT).show();
                    }
                })
                .addOnProgressListener(new OnProgressListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onProgress(UploadTask.TaskSnapshot taskSnapshot) {
                        double progress = (100.0*taskSnapshot.getBytesTransferred()/taskSnapshot
                                .getTotalByteCount());
                        progressDialog.setMessage("Uploaded "+(int)progress+"%");
                    }
                });
    }
}

XML的样子是这样的:
 <Button
    android:id="@+id/btnChoose"
    android:layout_width="0dp"
    android:layout_height="wrap_content"
    android:layout_marginStart="50dp"
    android:layout_marginTop="40dp"
    android:layout_weight="1"
    android:text="Choose"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<Button
    android:id="@+id/btnUpload"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginTop="40dp"
    android:layout_marginEnd="50dp"
    android:layout_weight="1"
    android:text="Upload"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintTop_toTopOf="parent" />

<ImageView
    android:id="@+id/imgView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_marginStart="171dp"
    android:layout_marginTop="40dp"
    android:layout_marginEnd="168dp"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toBottomOf="@+id/btnChoose" />

什么是将多个文件一次性上传的最佳方法?我对Firebase存储方面还不熟悉,完全不知道该怎么做。我在一些帖子上看到说这是不可能的。这是真的吗,还是有什么变通方法?
编辑
使用这段代码,我成功地实现了多个文件的上传。但是奇怪的是,在应用程序中,回收站只显示一个项目。

recycle_item.xml

 android:layout_height="match_parent"
xmlns:app="http://schemas.android.com/apk/res-auto">
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:layout_alignParentTop="true"
    android:layout_centerHorizontal="true"
    android:orientation="horizontal"
    android:padding="10dp"
    android:weightSum="10">


    <ImageView
        android:id="@+id/upload_icon"
        android:layout_width="40dp"
        android:layout_height="40dp"
        android:layout_weight="2"
        android:src="@drawable/ic_attach_file_black_24dp"/>

    <TextView
        android:id="@+id/upload_filename"
        android:layout_width="wrap_content"
        android:layout_height="match_parent"
        android:layout_weight="6"

        android:gravity="center_vertical"
        android:text="Filename.type"
        android:textSize="16sp" />
</LinearLayout>

photoUploader类

     initVariables();

}
private void initVariables() {
    mStorage = FirebaseStorage.getInstance().getReference();

    mSelectBtn = findViewById(R.id.select_btn);
    mUploadList = findViewById(R.id.upload_list);

    mUploadList = (RecyclerView) findViewById(R.id.upload_list);

    fileNameList = new ArrayList<>();
    fileDoneList = new ArrayList<>();

    uploadListAdapter = new UploadListAdapter(fileNameList, fileDoneList);

    //RecyclerView

    mUploadList.setLayoutManager(new LinearLayoutManager(this));
    mUploadList.setHasFixedSize(true);
    mUploadList.setAdapter(uploadListAdapter);

    mSelectBtn.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
    chooseImage();
        }
    });
}

  private void chooseImage() {
    Intent intent = new Intent();
    intent.setType("image/*");
    intent.putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true);
    intent.setAction(Intent.ACTION_GET_CONTENT);
    startActivityForResult(Intent.createChooser(intent,"Select Picture"), 
RESULT_LOAD_IMAGE);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent 
    data) {
    super.onActivityResult(requestCode, resultCode, data);
    if(requestCode == RESULT_LOAD_IMAGE && resultCode == RESULT_OK){

        if(data.getClipData() != null){
            int totalItemsSelected = data.getClipData().getItemCount();

            for(int i = 0; i < totalItemsSelected; i++){

                Uri fileUri = data.getClipData().getItemAt(i).getUri();

                String fileName = getFileName(fileUri);

                fileNameList.add(fileName);
                fileDoneList.add("uploading");
                uploadListAdapter.notifyDataSetChanged();

                Date myDate = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
                final String myDateString = sdf.format(myDate);
                String Gap ="/";


                StorageReference fileToUpload = mStorage.child(myDateString+Gap+ UUID.randomUUID().toString());

                final int finalI = i;
                fileToUpload.putFile(fileUri).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                    @Override
                    public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                        FirebaseDatabase sb = FirebaseDatabase.getInstance();
                        DatabaseReference rootRef = sb.getReference().child("PreviousJobs");


                        rootRef
                                .child(myDateString)
                                .setValue(myDateString);
                        fileDoneList.remove(finalI);
                        fileDoneList.add(finalI, "done");

                        uploadListAdapter.notifyDataSetChanged();

                    }
                });

            }

            //Toast.makeText(MainActivity.this, "Selected Multiple Files", Toast.LENGTH_SHORT).show();

        } else if (data.getData() != null){

            Toast.makeText(photoUploader.this, "Selected Single File", Toast.LENGTH_SHORT).show();

        }

    }
}


    public String getFileName(Uri uri) {
    String result = null;
    if (uri.getScheme().equals("content")) {
        Cursor cursor = getContentResolver().query(uri, null, null, null, 
    null);
        try {
            if (cursor != null && cursor.moveToFirst()) {
                result = 
     cursor.getString(cursor.getColumnIndex(OpenableColumns.DISPLAY_NAME));
             }
        } finally {
            cursor.close();
        }
    }
    if (result == null) {
        result = uri.getPath();
        int cut = result.lastIndexOf('/');
        if (cut != -1) {
            result = result.substring(cut + 1);
        }
    }
    return result;
}

最后是适配器类:
public List<String> fileNameList;
    public List<String> fileDoneList;

public UploadListAdapter(List<String> fileNameList, List<String>fileDoneList){

        this.fileDoneList = fileDoneList;
        this.fileNameList = fileNameList;

    }

    @Override
    public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {

        View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.recycle_item, parent, false);
        return new ViewHolder(v);

    }

    @Override
    public void onBindViewHolder(ViewHolder holder, int position) {

        String fileName = fileNameList.get(position);
        holder.fileNameView.setText(fileName);

        String fileDone = fileDoneList.get(position);

        if(fileDone.equals("uploading")){

            holder.fileDoneView.setImageResource(R.drawable.progress);

        } else {

            holder.fileDoneView.setImageResource(R.drawable.checked);

        }

    }

    @Override
    public int getItemCount() {
        return fileNameList.size();
    }

    public class ViewHolder extends RecyclerView.ViewHolder {

        View mView;

        public TextView fileNameView;
        public ImageView fileDoneView;

        public ViewHolder(View itemView) {
            super(itemView);

            mView = itemView;

            fileNameView = (TextView) mView.findViewById(R.id.upload_filename);
            fileDoneView = (ImageView) mView.findViewById(R.id.upload_loading);


        }

    }

}

这个问题在第三个版本中发生了非常大的变化,以至于下面给出的答案不能适用于那个版本中的问题。我曾经考虑过是否回退到第一个或者第二个版本让给出的答案有意义——最终我选择了第二个版本,并进行了重大的案例、拼写和语法整理。 - halfer
1个回答

1

在 Firebase Android SDK 中,没有内置的功能用于发送批量请求。不过,你可以直接利用 Google Cloud Storage API 来发送批量请求,尽管这需要一些复杂操作。

如果你选择这条路线,首先要知道的是你的 Firebase 存储 "bucket" 的 id。如 此处 所述,你只需取出桶名称中的 gs:// 部分,并将其传递给 GCS 资源。

例如,如果我的 bucket 是 gs://kato-sandbox.appspot.com,那么我就使用 kato-sandbox.appspot.com

要在 Firebase 中查找你的 bucket 名称,请访问 console.firebase.google.com 上的存储页面 并查看列出的 URL。

enter image description here


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