Download multiple files in parallel like whats app in Android - android

I already know that using Services/Intent services we download multiple files in background. But this problem have one more complexity to solve.
I have to download multiple videos/images in different activities in parallel like whats app. I have seen in whats app that we can start download and then we can moves on different screens or press home button etc. But when we move back on that screen again the downloading is still continue with and showing the updated progress.
Like above there is 4 activities and user started downloading of ABC.mp4 on activity and A and then moves on to Activity B. Then moves on to C and started downloading of video/image. If user moves back on to the A and I want to show the progress of that ABC.mp4 file that how much downloaded and same case for the other activities.
Please let me know to you Services or any other way to do, so I can update the UI as well with the updated value of the downloading file. Any help is appreciated.

Well here's my piece of advice:
I did the same thing but with Pdf files a while a ago. First you need to choose a good Http client library to perform the downloads and forget about all the issues related to the downloads that you'll have if you perform this operations by yourself. I recommend you use the Ion librabry has a lot of useful features like cancel the downloads, attach callbacks to have an eye in the download progress, known if the download succeded, failed, etc.
Second, you obviously need a Service running in background, always, you can do this by making your own service, and It's very important that the Service process name in the android manifest is like android:name="com.company.app.services.MyService" and not like android:name=":MyRemoteService" doing so you'll make sure that the service will be running in background all the time (keep in mind that the OS can and will kill the service if It's neccesary, but the service will be restarted when the resources will made available again).
Third, to keep all the views, custom views, activities, fragments, etc. that display those files updated, you need trigger BroadcastReceivers from your Service. Keep in mind that doing so you can't use the LocalBroadcastReceiver, because your Service has its own process indipendent from your application.
Keep in mind that:
1) Theres no need to explicitly use an Activity, you can register your broadcasts anywhere where you see It fit. A RecyclerAdapter (most likely), a Fragment, or an Activity.
2) The communication App/Service is done through Intents so all data that you send to and from the Service must be Serializable.
3) You can use several different types of broadcast each one for differents situations (error, fail, success, progress, etc.) or you can use only one an send a enum that describe this kind of status through the Bundle of the Intent when you fire the broadcasts from your service
Hope this helps you, If you have any doubt, let me know.

Related

Downloading multiple files using WorkManager

Our app needs to download files with the following requirements:
User can dynamically add or cancel downloads
Files are downloaded one at a time
Sometimes in background we need to schedule several file downloads
It would be nice to display a notification displaying download progress and a cancel button
We had all this implented in a foreground service that would maintain a queue of tasks and having an aidl interface with methods that allowed to enqueue new downloads or cancel active/enqueued.
Since Android 12 we can no longer start foreground service when the app is in background, so we can't reliably download files anymore in this situation (requirement #3)
As far as I can understand, the recommended way of implementing such task is using WorkManager, but I can't find a good way of doing it.
I consider two approaches, but both are far from perfect:
Every downloaded file is a separate Work. It's easy to cancel when needed and we only need to suply a file URL and that's it.
But the downsides are: there's no way to enqueue several downloads at once (requirement #3), we need to wait for previous work to finish and then enqueue the next one.
Using ExistingWorkPolicy.APPEND doesn't help here - our downloads are independent and if one is cancelled or fails, others should stay in the queue.
Another annoying issue with this approach is that if we display a notification from our ListenableWorker via startForeground(), then for each file download it will be shown and hidded instead of just updating its contents for every new downloaded file.
Use a long running ListenableWorker that would download many files. But this requires somehow delivering enqueue and cancel(fileUrl) messages to the running worker instance (what we did previously using our service with the aidl/binder stuff). As far as I can see, the WorkManager API doesn't support anything like that. So the only thing we can do is to use some static vars to deliver those messages, which would work (if our worker works in the same process as the main app - hopefully, I can rely on that). But using statics in such a way is always kind of a code smell, I would avoid it if possible.
Are there any other possibilities to do this using WorkManager? Maybe I'm missing some part of the API?

Design for downloading files before starting of an Activity

I have a use case where I want to download some files from the server and store them locally before starting another activity that is dependent on this file. This kind of design can be found on karaoke kind of applications where clicking on one song would
Load the required files from the server
Once the download is finished, open the required activity.
Let us assume that my app is a karaoke app. My question is how to design this flow. Basically, on clicking on one song, I want to show progress on the screen and when the download is finished, I want to move to the activity. Another requirement is that once I am inside the karaoke activity screen and playing a song, I have an option which leads to loading of another lesson. If a user uses that option, I want to again download the required files. Based on this requirement, should I:
Have the file loading thing as a separate activity?
OR
It can be used as Fragmentinside the activity where I choose a particular song. In this case, once entering the karaoke screen, if I choose an option which leads to downloading some files and reloading of this activity, is this the best design?
I would recommend two different approaches depending on how long you plan on keeping the data that you've downloaded. If it is single use than a bound service would be ideal. However, if you are planning on keeping the downloaded content for more than a single use, I would recommend you use a content provider and possibly a sync adapter(Depending on how frequent/predictable content downloading is). This combo would help guide you into not having to think about the 'design' as much(Since it is pretty standard at this point), plus it would provide a lot of features that you may/may not find useful: you can make your internal data 'public' via the content provider/authority(s), you can make an 'account' on the phone associated with your app so that the user can manage its syncing via the sync manager(actually via widgets/apps using the sync manager, but still), and most importantly a set of clean(ish)/standard means to interact with it/propagate UI, etc.
My simple version would be an Activity that spawns either a async-AIDL service with callback (which is in my opinion the only way to use a bound service) that would allow you to asynchronously design your 'starter' activity, its "currently downloading" spinner (which can get progress updates via the callback if you design it that way). Then once the download is complete then send the results (via a parcel file descriptor in the Intent's bundle) to the new activity that makes use of it.
However, if you are planning on using the data more than once, I'd recommend downloading the content like you did above, but then also store it in a content provider for easy access later. Providers also have a lot of nice associated functionality related to cursor loaders, etc. that will help keep a list of the content currently being stored nice and clean/up-to-date/dynamic/etc. However, this is a lot more work to setup once, then later it would save you time in reduced.
A sync adapter is best when the data to be downloaded is predictable, either based on user's account or temporally (such as someone having an account to download data from (email account, etc.) or when the target is fairly constant, but the data should be updated every hour or so(such as the current weather)). So this will depend a lot on your application's exact specifics.
Here is an assignment for an Android App Development course I wrote that is an even more simplified version of the first option (it has intent service + broadcast receiver for returning download results back to the Activity). Obviously since this is an assignment it has sections cut out to make skeleton code, but the documentation is ABSURDLY detailed and should be fairly easily implemented.
https://gitlab.com/vandy-aad-3/aad-3-assg-2/tree/master
Here is the extension of that assignment for that same course that focuses on implementing a simple content provider's 4 main methods (Create, Read, Update, & Delete). Everything else about the provider is given to you.
https://gitlab.com/vandy-aad-3/aad-3-assg-3/tree/master
Obviously the content being downloaded in both applications is probably not what you intended, but that is a simple swap to replace in what you do want.
Not to shill to hard, but here is the (free) Specialization that this course is a part of: https://www.coursera.org/learn/androidapps
Point one : Don't download video file within the Activity level. You can start a Service to handle it. Once the download function is finished you can start the second Activity. While download function is in progress you can show a ProgressBar
Point Two : Best Design is show a ProgressBar with percentage to user. Or disable the function. After download complete enable or start the second activity.

Download file on AsyncTask or Service?

What would be the best approach for download on Android. You would be using AsyncTask or Service. I see several example being made of two ways, but what would be the best approach?
That's not the right question to ask, and the answer may be both. An AsyncTask is a separate thread of execution. A Service is just a piece of your app that runs in the background and can live past the end of an Activity.
You need to download any files on a non-UI thread, so either a Thread or AsyncTask is necessary whether you use a Service or not. So you'll always use one of those two. The question of whether or not to also use a service is a question of whether you need the file downloaded even if the user goes to another Activity (there's a few other reasons why you may want to use a Service, but this is the main one).
i suggest ,it depends upon the size of file.for small content file ,asynch is great but if is gonna be a longer task then you can go for service because service also comes with restart feature (start_sticky) in case user kill your app or your app got killed by the android os(LMK : low memory killer) in case of memory crises

Need two-way communication with a background process and Activity in Android - Suggestions?

Problem
Throughout my app I need to download files. In some cases I only need one-way communication, basically communicating with the Activity that a download has finished. In other cases, I need to be able to communicate to the background process to cancel the download, then relay back to the Activity once that task has been complete (two-way communication).
Stipulations
In all cases, a download is only associated with one Activity, so a Service seems unnecessary since I don't need to keep a download running in the background while the user does other things. The user is always blocked while the download is occurring. The download process should be Activity-independent (not specialized for one Activity...reuseable). It would be ideal to have one solution that meets all requirements.
Use cases
The two cases I have right now are as follows:
A user is shown a ProgressDialog while a file is being downloaded. Once the file completes downloading, the user proceeds to the next Activity. Progress does not need to be shown.
A user is shown a ProgressBar while a large file is being downloaded. There is a Cancel button to abort downloading the file. Pressing the Cancel button should signal to the background process to abort downloading the file, then inform the Activity once that action has been performed. Progress needs to be shown while downloading the file.
What I've tried
My original implementation was a separate class, ran in a thread, that passed in a Context that would broadcast progress. This allowed communication from the background process to the Activity, but not vise-versa.
I attempted a Service, but from various articles I read, determined my needs did not justify a Service, as the user needed to be blocked while the download was occurring. I had never implemented a Service before, so I also ran into communication problems (probably poor implementation).
What would be ideal
A two-way BroadcastReceiver. Is that possible? I like being able to register for a BroadcastReceiver if I want to get feedback from the background process, or not if I don't care. I already have a method in a class that takes in an InputStream and a File and makes the transfer, so that method is being reused everywhere that needs to download a file right now.
What you want to do is use an AsyncTask. Read these here on Stackoverflow:
Download a file with Android, and showing the progress in a ProgressDialog
and
Cancelling file download with httpclient and asynctask
Besides AsyncTask, you can also use Loaders.
They do pretty much what you need to do and I think they are available since android 1.6 with android compatibility package [related post]. I think this is your best option :)

Which Android service path to choose for implementing a large upload?

I am trying to implement a RESTful API in which I have to upload files that are relatively large for a mobile platform. The upload could take anywhere from 30 seconds to 5 minutes.
I would like my application to be completely usable while the upload takes place. I've been doing some research and I've come across a few methods from which I can't decide which is the correct solution to my problem.
These are the two things I have come across.
Using an IntentService -- handles the worker thread so I don't have to.
Using my own type of Service-- still need to implement an AsyncTask to handle the large process.
Implement an AsyncTask in a singleton file that would allow me to do all the work there but without using the service class.
My question is which method is the best -- if one isn't listed but is a more apt solution to my problem then I would appreciate suggestions.
After researching all these methods I am still also confused on one thing. Lets say I upload a 2MB files, but I want to know when it is done. For example, lets say I have a service that uploads an image and returns and imageID -- I need to be able to know when that service returns an imageID -- process that and then move on to the next upload until the rest are finished.
As always, thanks in advance.
EDIT: I forgot to specify that while uploading I want the app to be usable-- that means that I can switch activities and still have the same service run.
I used IntentService. It extends service so it basically has all the functions of the normal service, expect that it handles the threading for me so I don't have to worry about that. Its working very well at the moment.

Categories

Resources