What is the best way to upload large files in the background of an Android/Glass application? I'm currently triggering an asynch task for each file (photos / videos) I want to upload, but if the asynch task crashes or the activity that launched it hits an exception the file upload fails.
Is there an android or Glass design pattern to store files in an application-specific directory and have a task that constantly works to make sure those files are uploaded then removed from that folder?
Depending on your requirements you should either use a background service (as #straya mentioned)
https://developer.android.com/training/run-background-service/create-service.html
Or you can use a SyncAdapter:
http://developer.android.com/training/sync-adapters/creating-sync-adapter.html
The first approach you would use if you need to upload those files as soon as possible, the second approach you would use if you want to bundle up several files together and let the operating system decide when to sync them with the server (you can specify how often you'd like your app to synchronize).
I don't know the requirements of you application but sounds like the second approach is what you need. That is what google is using for many applications like gmail, etc. It is way harder to implement then the background service, but it's worth it. Android is smart about the Sync Adapters, it bundles up several adapters together when possible to preserve the battery consumption.
use a background Service to manage long-running tasks that may occur whether an Activity is created or not.
As for crashes, avoid them by programming defensively and handling possible exceptions.
Related
I'm creating an Android app that needs to download a set of images and audio files in order to work properly. Those files will be updated on the server from time to time. On startup, the app will check for updated files and download them.
My concern: The updates/downloads of those files must be completed in an atomic fashion, meaning that the update is successful only if all files have been downloaded. If one file failed to download (reason being poor internet connection, insufficient storage space on the phone, etc), the update should be rolled back.
I feel that implementing something like that from scratch could be a pretty big task, so I first wanted to ask if there's already a library/module, or at least a best practice for implementing something like this.
I feel that implementing something like that from scratch could be a pretty big task.
I disagree:
Your app can creat a temporary private folder (i.e. -tmp-update-20190321_122800) and download all files into this folder.
After all downlads finished without error the app can replace the original files.
So instead of searching for a transaction-multi-filie-download-lib you can use any android-download-lib and you must know how to copy/move/delete files.
i am developing an android app, and i want user to download the file(images) after installation and the store them on sd card ,then aply them in my app ,there will be a default app before user download the images and the these images will be applied. I know little bit about DownloadManager class but don't know how to store them and retrieving them on run time.
any tutorial or any sample source code.. ??
I personally have never used the download manager, so I cannot say anything on that. Your best bet would probably be to check for the files' existances using File.exists() and downloading / applying these images in an AsyncTask<Param, Progress, Result> or thread. AsyncTask is typically the way people go.
Whichever route you take, be wary of what is happening in the background and what is happening on the main thread. UI updates must happen on the main thread. All network code must happen in the background. Any deviation from that will crash.
I would like to know if its possible to save an object at the moment the user is installing the app on mobile.
Why I want this?
My app uses some default objects to his normal behaviour, whenever the user starts the App I want that the objests are there to be used. I could certainly just create them each time the user opens the app..
But that might consume a bit of unnecessary time and performance and battery.. If its default, I want to create only once, and then its always there.
I will also use Internal Storage to create new objects of this type, there will be the default ones, that I described above, and there will be also the option to create new ones and save them to use later, on another time that app is launched, but that its fine, I already read something about how to serialize the object and use internal storage to keep them :)
I am just here asking about the first question, create the item only once at the beginning, maybe on the install moment of the app? I was assuming.. but dont know if its possible.
It has been very helpful to have this space for over an year, I have already learned a lot here from you thank you ;)
Android provides following intent to detect app installation
<action android:name="android.intent.action.PACKAGE_ADDED"/>
<action android:name="android.intent.action.PACKAGE_REMOVED"/>
If you use these with conjunction with broadcast receiver you will be notified when user install a new app. Problem with this solution is, it will not help you as you are trying to detect your own app installation.
What you could do is every time user launch your app
check if object exist
if not create one and write it to internal storage.
in this way it will created once. Depend on type of object you are trying to save you might consider using SharedPreferences or SqlLite or simply a file IO. If you are writing Java Object yes serialization is the way to go.
Update
If you are planning to get data from network for the first time, depend on the size you can decide,
Small File: Put it inside Asset folder and ship it with apk.
large file: if the file size is huge you might consider to ship portion with apk and sync and update rest on a background process or download everything from network
I'm not sure what you mean. A Java object exists in memory, so "saving" it when the user installs the app makes little sense. It can't remain in memory unless some process is holding onto it.
If you mean something like a JPEG photo or other data, you can put the data in the directories of your project and then access it as a resource once your app is installed. See the
Providing Resources API guide.
I need to download a big file on my app (almost 2gb) and i was wondering what is the best way to do that and some libs to help me.
First I looked the Android Asynchronous Http Library but I didn't find examples showing how to publish the progress or start, pause download. Then I don't know if should I use this lib or just use a standart http commons.
Other problem is, should I use a service to download my file??
Could you guys give a hint, how to do that?
I've see you got a bunch of answer and none of them really answers it from a holistic point of view.
To download a 2k or 2gb file the actual code is the same using some type of connection handler and some type of input stream and output stream and usually wrapping the input stream with a buffered input stream. For that you can find infinite amount of java examples all around the web.
The trick here considering the Android platform is that because it's a lengthy operation, you shouldn't be doing it inside the activity life cycle at all.
Said that you have two options:
as you suggested you can create a Service, I would suggest you to use the IntentService
as it seems to be a perfect fit for this case. The IntentService automatically spans a new thread, through the intent you pass the URL as a String and let the service download using the streams, etc.
another method that probably work well, but I've never personally used, is to use the DownloadManager that is available since Gingerbread. It shouldn't be difficult to call getSystemService(Context.DOWNLOAD_SERVICE) and call dwManag.enqueue(dwRequest);
hope it helps.
If you're not targeting pre-Gingerbread devices, I would use DownloadManager as suggested as the third option in the answer you linked to. It takes care of downloading the file, displays the progress in the notification bar so that the user can see what's going on even after your app has gone into the background and you don't have to worry so much about what happens when the user goes into another app and android decides to kill your app to free memory. Also, it works with features like "only download files over wifi" that at least some android builds have.
I suggest you to use adm download manager. Downloads never fail even if there is no network and the speed is also best.
I've been looking at this guide:
http://developer.android.com/training/basics/network-ops/connecting.html
And was wondering what would be the best way to download multiple files. First I need to download a text file from a url to determine which files to download.
Should I have 2 separate ASyncTasks, one to download the file and then the other to download the remaining files? Otherwise my code which depends on the first file crashes since the Async task does not complete in time.
Also for the progress dialogue should I make a new one for each file or try to update the previous one?
Thanks
Orginally I was creating a new AsyncTask for each file to download.
In general, if you want the files to remain on the devices, and you're downloading multiple files based on the results of downloading one file, then you should
Use an IntentService to download and store/parse the first file.
Use an IntentService to read the results of the first download and then download the remaining files. If you need to, you can use a progress bar notification in the notification area. Meanwhile, the user can continue working in the app or even switch to another app and the download will continue.
An IntentService is immune to Activity lifecycle changes that might kill an AsyncTask.
Any time you download data, persist it somewhere. You can always check to see if the data is outdated. On the other hand, if there's no connectivity, users have the last "good" data.
To learn more about IntentService, see Running in a Background Service. The content provider in the sample app illustrates downloading "metadata" for other files. The sample also demonstrates how to check for connectivity before downloading.
There is no perfect answer to cover every situation possible.
If you are happy with one quick running AsyncTask, don't change anything.
If you are using API 9+, you could switch to the DownloadManager class and let it workout the particulars.
If you need references, Download a file with Android, and showing the progress in a ProgressDialog, provides examples for multiple ways to download a file with an active ProgressBar.