Firebase存储 - 防止覆盖文件

时间:2016-12-24 00:32:34

标签: java android firebase android-camera firebase-storage

我允许用户拍照并将其存储到Firebase。下面是我的代码,其中包含加载相机应用程序,保存图像,然后上传到Firebase存储的意图。我遇到的问题是每次后续上传到Firebase存储都会覆盖以前的上传,这意味着我在存储中有1个文件不断被覆盖。我想继续添加多个文件:

private void createAlertDialog() {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle(R.string.add_image_dialog_title);
    builder.setItems(new CharSequence[]
                    {getResources().getString(R.string.add_image_web), getResources().getString(R.string.add_image_camera), getResources().getString(R.string.add_image_gallery)},
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    // The 'which' argument contains the index position
                    // of the selected item
                    switch (which) {
                        case 0:
                            Intent toImageSearch = new Intent(CreateActivity.this, NewImageActivity.class);
                            startActivityForResult(toImageSearch, USE_WEB);
                            break;
                        case 1:
                            Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                            if (takePictureIntent.resolveActivity(getApplication().getPackageManager()) != null) {
                                startActivityForResult(takePictureIntent, TAKE_PICTURE);
                            } else {
                                Toast.makeText(getApplicationContext(), getResources().getString(R.string.camera_error), Toast.LENGTH_LONG).show();
                            }
                            break;
                        case 2:
                            Toast.makeText(getApplicationContext(), "clicked 2", Toast.LENGTH_LONG).show();
                            break;
                        case 3:
                            Toast.makeText(getApplicationContext(), "clicked 3", Toast.LENGTH_LONG).show();
                            break;
                    }
                }
            }

    );
    builder.create().

            show();
}

OnActivityResult()

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    switch (requestCode) {
        case USE_WEB:
            if (resultCode == CreateActivity.RESULT_OK) {
                resultImageURL = data.getStringExtra("result");
                mAddImageButton.setVisibility(View.INVISIBLE);
                Picasso.with(getApplicationContext())
                        .load(resultImageURL)
                        .into(mImagePreview);
            }
            if (resultCode == CreateActivity.RESULT_CANCELED) {
                //Write your code if there's no result
            }

        case TAKE_PICTURE:
            if (resultCode == CreateActivity.RESULT_OK) {
                Bundle extras = data.getExtras();
                Bitmap imageBitmap = (Bitmap) extras.get("data");
                mImagePreview.setImageBitmap(imageBitmap);
                encodeBitmapAndSaveToFirebase(imageBitmap);
            }
    }
}

保存到Firebase:

 private void encodeBitmapAndSaveToFirebase(Bitmap bitmap) {
    ByteArrayOutputStream baos = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, baos);
    byte[] data = baos.toByteArray();

    UploadTask uploadTask = mPollImageStorage.putBytes(data);
    uploadTask.addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            Toast.makeText(getApplicationContext(), "Error Loading Photo", Toast.LENGTH_LONG).show();
        }
    }).addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
            // taskSnapshot.getMetadata() contains file metadata such as size, content-type, and download URL.
            Uri downloadUrl = taskSnapshot.getDownloadUrl();
            mAddImageButton.setVisibility(View.INVISIBLE);
            resultImageURL = downloadUrl.toString();
            Picasso.with(getApplicationContext())
                    .load(resultImageURL)
                    .into(mImagePreview);
        }
    });

}

2 个答案:

答案 0 :(得分:2)

每次上传都需要使用单独的位置或单独的文件名。

您可以创建如下自定义位置:

 FirebaseStorage storage = FirebaseStorage.getInstance();
            StorageReference storageRef = storage.getReferenceFromUrl("gs://myfirebaseproject.appspot.com");
            StorageReference fileRef =
                    storageRef.child(channelId)
                    .child(String.valueOf(message.getSender()))
                    .child(String.valueOf(message.getTimestamp()));

            UploadTask uploadTask = fileRef.putFile(message.getAttachmentUri());
            uploadTask.addOnSuccessListener(new OnSuccessListener<UploadTask.TaskSnapshot>() {
                @Override
                public void onSuccess(UploadTask.TaskSnapshot taskSnapshot) {
                    sendMessage(channelId, message.getMessageText(), taskSnapshot.getStorage().toString(), message.getAttachmentType(), callback);
                }
            });
            uploadTask.addOnFailureListener(new OnFailureListener() {
                @Override
                public void onFailure(@NonNull Exception e) {
                    callback.onError(e.toString());
                }
            }); 

您可以看到我们正在向我们的基本存储参考添加自定义位置,以便我们不会覆盖现有项目。

答案 1 :(得分:1)

存储图像的位置取决于onCreate引用的内容。如果 StorageReference mPollingStorage = storageRef.child("polling.jpg"); 始终引用相同的位置,即在您的camerapic.jpg中执行以下操作:

import Data.Char (chr) data Tree a = Leaf a | Node (Tree a) (Tree a) deriving Show build :: [Int] -> [Tree Char] build xs = foldr go (\_ _ -> []) xs 0 0 where nil = Leaf '?' go 0 run 0 0 = case run 0 0 of [] -> Node nil nil:[] x:[] -> Node x nil:[] x:y:zs -> Node x y :zs go 1 run 0 0 = run 0 1 go _ _ _ 0 = error "this should not happen!" go x run v 7 = (Leaf $ chr (v * 2 + x)): run 0 0 go x run v k = run (v * 2 + x) (k + 1)

然后它将继续覆盖\> head $ build [0,0,0,1,1,1,0, ...] -- the list of 01s as in the question Node (Node (Node (Leaf 'k') (Leaf 't')) (Node (Node (Leaf 'q') (Leaf 'g')) (Leaf 'r'))) (Node (Leaf 'w') (Leaf 'a')) 。如果您不想覆盖它,可以将图像名称设置为类似于拍摄图像的时间,或者根据此stackoverflow帖子生成UUID:Store files with unique/random names