0

In the model object there is a list of objects that each one can contain internal and external images. I read that I can not process a url request in the main thread, so I thought of using AsyncTask. But, I also need to know when one image was processed... so I thought of using the execute().get(), but I also think that this is not working. I also thought that I would be able to download and storing all the images sequential with the source code that is bellow... But somehow, I the main activity receives the answer before all the downloads are completed. And to make things stranger, yes, I am able to download/save the images, but somehow, they all have the same size 48bits and when I try to open the image everything is "black".... I think that somehow, there are shared variables with this threading....

I am sure that my code is full of flaws and some part of the code is repeated ( I could do some code refactoring)... but... for now I am only looking to make it work.

public void ProcessImages(MyModel model) {
    if (model == null || model.History == null || model.History .size() == 0) {
        return;
    }
    model.History .forEach((h) -> {
        if (h.InternalImages != null && h.InternalImages.size() > 0) {
            h.InternalImages.forEach((i) -> {
                ExecuteSaveToInternalStorage(i);
                return;
            });
        }
        if (h.ExternalImages != null && h.ExternalImages.size() > 0) {
            h.ExternalImages.forEach((i) -> {
                ExecuteSaveToInternalStorage(i);
                return;
            });
        }
    });
}

.

public void ExecuteSaveToInternalStorage(LKImage lkImage){
    try {
        (new AsyncTask<Void,Void,Void>() {

            @Override
            protected Void doInBackground(Void... voids) {
                SaveToInternalStorage(lkImage);
                return null;
            }

            @Override
            protected void onPostExecute(Void aVoid) {
                //multiTaskHandler.taskComplete();
            }
        }).execute().get();
    } catch (ExecutionException e) {
        e.printStackTrace();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

.

public boolean SaveToInternalStorage(LKImage lkImage) {
    String path = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).toString() + File.separator + ImageDirectory;
    File outputDir = new File(path);
    if (!outputDir.exists()) {
        outputDir.mkdir();
    }
    boolean res = true;
    File imageThumb = new File(path + File.separator + "thumb" + "_" + lkImage.Id + "_" + lkImage.Name);
    if (!imageThumb.exists()) {
        try {
            InputStream inputStream = new java.net.URL(GetAPIServerUrl() + "/Images/GetImage/" + lkImage.Id + "?s=" + lkImage.ImageSource + "&t=True&type=.jpg&tId=" + lkImage.TenantId).openStream();
            Bitmap bitmapImage = BitmapFactory.decodeStream(inputStream);
            FileOutputStream out = new FileOutputStream(imageThumb);
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, out);
        } catch (Exception e) {
            e.printStackTrace();
            res = false;
        }
    }
    File imageBig = new File(path + File.separator + lkImage.Id + "_" + lkImage.Name);
    if (!imageBig.exists()) {
        try {
            InputStream inputStream = new java.net.URL(GetAPIServerUrl() + "/Images/GetImage/" + lkImage.Id + "?s=" + lkImage.ImageSource + "&t=False&type=.jpg&tId=" + lkImage.TenantId).openStream();
            Bitmap bitmapImage = BitmapFactory.decodeStream(inputStream);
            FileOutputStream out = new FileOutputStream(imageBig);
            bitmapImage.compress(Bitmap.CompressFormat.PNG, 100, out);
        } catch (Exception e) {
            e.printStackTrace();
            res = false;
        }
    }
    return res;
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Dryadwoods
  • 2,875
  • 5
  • 42
  • 72
  • `AsyncTask` is not recommended for downloading multiple files (Also its getting [depricated](https://stackoverflow.com/questions/58767733/android-asynctask-api-deprecating-in-android-11-what-are-the-alternatives) i guess) . It has some down side when its comes to lifecycle . I think you should be using a `DownloadManager` or Foreground Service to download images .. – ADM Mar 23 '20 at 15:03
  • can you provide image URL or response of the download service api for our reference – Poovarasan Selvaraj Mar 23 '20 at 16:56

2 Answers2

0

Image url is a string and you can easily create a list of string data type and store Image urls in it and to show it in your app.

Glide.with(getContext()).load(imageurl[0]).into(ImageView);
Nimantha
  • 6,405
  • 6
  • 28
  • 69
Shimaa Yasser
  • 587
  • 4
  • 12
0

First, You should that AsyncTask become deprecated, according to the official documentation.

Second, I suggest using DownloadManager of the android. It's a very simple and handy API, you will be able to download your images.

    internal var dowloadId: Long = 0

    private fun prepareDownloadRequest() {
    
    val file = File(this@MainActivity.getExternalFilesDir(null), "your path")
    val request =
        DownloadManager.Request(Uri.parse("Your Url"))
            .setTitle("This title would be shown in the notification center")
            .setDescription("This title would be shown in the notification center")
            .setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE)
            .setDestinationUri(Uri.fromFile(file))
            .setAllowedOverMetered(true)

    val downloadManager = getSystemService(Context.DOWNLOAD_SERVICE) as DownloadManager
    dowloadId = downloadManager.enqueue(request)
}

To make an ultimate solution for that, I suggest creating a Broadcast receiver which notifies the user that download has been completed as the following:

    private val onDownloadComplete = object : BroadcastReceiver() {
    override fun onReceive(context: Context, intent: Intent) {
        //Fetching the download id received with the broadcast
        val id = intent.getLongExtra(DownloadManager.EXTRA_DOWNLOAD_ID, -1)
        //Checking if the received broadcast is for our enqueued download by matching download id
        if (dowloadId == id) {
            Toast.makeText(this@MainActivity, "Download Completed", Toast.LENGTH_SHORT).show()
          
        }
    }
}
Nimantha
  • 6,405
  • 6
  • 28
  • 69
MustafaKhaled
  • 1,343
  • 9
  • 25