简体   繁体   中英

How properly download multiple files from Firebase Storage on Android?

I have a problem with file download from Firebase Storage on Android application. I know the method how to download one image and display it on ImageView . But I have a problem when I need to download more than one image in single activity.
I have the names of the files in the List<String> and they are for example: [ img1, img2 ] .

For files download I have written a method:

private void downloadImg(String name) {
    String path = "images/"+name+".png";
    StorageReference ref = storage.getReference().child(path);
    try {
        final File localFile = File.createTempFile("Images", "png");
        ref.getFile(localFile).addOnSuccessListener(new OnSuccessListener< FileDownloadTask.TaskSnapshot >() {
            @Override
            public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
                Bitmap bitmap = BitmapFactory.decodeFile(localFile.getAbsolutePath());
                if (bitmap != null) {
                    initImages(bitmap);
                }
            }
        }).addOnFailureListener(new OnFailureListener() {
            @Override
            public void onFailure(@NonNull Exception e) {
                Log.e(Tags.IMAGES, e.getMessage());
            }
        });
    } catch(IOException e) {
        Log.e(Tags.IMAGES, e.getMessage());
    }
}  

This method downloads a .png file with given name as a parameter and sets it to new ImageView .

The method to set the image on the ImageView:

( Problem shouldn't be there )

 private void initImages(Bitmap bitmap) { int total = imageNames.size(); int column = 4; ImageView image; for (int i = 0, c = 0, r = 0; i < total; i++, c++) { if (c == column) { c = 0; r++; } image = new ImageView(this); image.setScaleType(ImageView.ScaleType.CENTER_CROP); image.setContentDescription(getString(R.string.addImageDescription)); image.setBackgroundColor(getResources().getColor(R.color.bHint)); image.setImageBitmap(bitmap); image.setOnClickListener(imageClickListener(bitmap)); imagesGrid.addView(image, i); GridLayout.LayoutParams params = new GridLayout.LayoutParams(); params.setGravity(Gravity.CENTER); params.height = hw_60; params.width = hw_60; params.setMargins(padding_5, padding_5, padding_5, padding_5); params.columnSpec = GridLayout.spec(c); params.rowSpec = GridLayout.spec(r); image.setLayoutParams(params); } } 

This method creates new ImageView and sets downloaded Bitmap to it.
I am using downloadImg(name); method on activity onCreate() method like this:

 for(String name : imageNames) { downloadImg(name); } 

Summary and main question:

I have two objects in my Firebase Storage with given names [ img1, img2 ] . Same file names are stored to List<String> for getting files by name. In activity onCreate() method calls downloadImg(name) method for each name. The method downloads the image and sets it to new ImageView .
My problem is that only one of the images will be downloaded and displayed twice. I have tried some other methods to get the names from list and download the file. So sometimes img1 appears on both ImageView s and sometimes - img2 . For this method appears only img1 twice.

ps: I have searched for the answers for this type of problem. There is no possible duplicates.

I had similar probs, the localFile var was overwritten by the time the download completes and onSuccess wants to use that. I ended up doing something like this

ArrayMap<String, File> localTmpFileArray = new ArrayMap<String, File>();
...
private void populateAvailableImages() {

    populateImageView("firstImpression.jpg", R.id.image_edit_profile_first_impression);
    populateImageView("profileImage1.jpg", R.id.image_profile_1);
    populateImageView("profileImage2.jpg", R.id.image_profile_2);
}
private void populateImageView(final String serverSideImageName, final int
        imageViewResourceId) {

    File imageLocalTmpFile = null;

    try {
        imageLocalTmpFile = File.createTempFile(serverSideImageName, "jpg");
    } catch (IOException e) {
        Log.w("ops", e);
        Toast.makeText(getApplicationContext(), "Could not create local file. Storage " +
                "full??", Toast.LENGTH_LONG).show();
    }

    localTmpFileArray.put(serverSideImageName, imageLocalTmpFile);

    StorageReference storageRef;
    storageRef = FirebaseStorage.getInstance().getReference();
    StorageReference imageRef = storageRef.child("users/" + FauthUtils.getUserId() + "/" +
            serverSideImageName);
    imageRef.getFile(localTmpFileArray.get(serverSideImageName)).addOnSuccessListener(new OnSuccessListener<FileDownloadTask.TaskSnapshot>() {
        @Override
        public void onSuccess(FileDownloadTask.TaskSnapshot taskSnapshot) {
            ImageView imageView = (ImageView) findViewById(imageViewResourceId);
            imageView.setImageURI(Uri.fromFile(localTmpFileArray.get(serverSideImageName)));
        }
    }).addOnFailureListener(new OnFailureListener() {
        @Override
        public void onFailure(@NonNull Exception exception) {
            // Handle failed download
            // ...
        }
    });
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM