I have a question regarding on how mobile OSs such as iOS and Android work regarding a cancelled download. I was wondering if there is any guaranteed way to restore a download from the point where it was cancelled.
I do understand that for instance iOS does not provide access to its temporary downloaded files, but you could continue a download as long as you were using
cancel(byProducingResumeData ..)
However, there is no guarantee that the resumed data will still be available at the moment you start the download again. Furthermore, there is an overload in storing this checkpoint in case the app is terminated meanwhile.
I was wondering if there is a way to provide some sort of custom URLCache to the URLSessionConfiguration so that the temporary files of a download are stored at a location (on disk maybe) where it is certain to have access if you try to start the download again.
Same question for Android: is the data flushed on cancel or there is a nice controlled way to go back to it?
Related
As far as I know, once you click "add to homescreen" on a PWA's website, the browser generates an .apk using the provided manifest file and sources and installs it like a normal app.
I noticed that when I update the website, the app also displays the updated content which suggests that the app is just a wrapper for accessing the website. I also noticed that the update to a website is not displayed instantly, I assume this is due to internal caching.
My question is, are my assumptions correct? Or more generally, when and how are PWAs updated and is there a way to force an update on a client machine?
No cache scenario (No Service worker): Your PWA app will be cached only when you use Service worker. Manifest.json will help adding your web app to home screen with a icon and open without address bar. If you don't have a service worker or if your browser don't support it, web page will be loaded fresh every single time. No Cache.
Cache-On Scenario (With Service worker): Assuming you have service workers configured, service workers can cache by lazy loading or prefetching the files that are configured for caching (You can include or exclude caching anything from html, CSS, images to JSON/XML API responses).
After the initial cache, service worker will use the cache to serve your apps network request based on cache approach you have implemented from below ones.
cache falling back to network
Network falling back to cache
Cache then network
Most apps choose to precache due to performance benefits and look for new files on loading, if any changes found will be loaded on next session or prompt user to refresh. With this solution, each file will have a long Hash string for each file cached by service worker. On load of each application, hash code from server will be fetched to match and find what file needs to be updated and the same will be updated in a separate service worker thread. You can notice this in network tab -> service worker response in chrome developer tools.
If you choose network-first approach, you can avoid showing old content on initial load, but loose significant performance benefits that comes with caching.
Only two events…
In essence, there are only two events that will automatically trigger a PWA update:
A change in the linked manifest.json; e.g. a changed icon file or a changed scope or start_url.
A one-character change in the controlling service-worker.js. Hence, if you store the version number in a const in this file and change it, an update of the PWA will be triggered.
When a change is detected, the new version will normally be activated only with the next PWA load. So, in all, two reloads are necessary to see a change.
How the update eventually is handled, is ultimately determined by the service-worker.js. Different update strategies may be defined in terms of the size and volatility of the PWA assets. It is also possible to activate a new service immediately.
However, there is one important caveat. Make sure that the browser cache expiry directive set by the .htaccess file of your asset server is set to a really short duration (e.g. hours) or even to none.
Failing to do so, will result in the browser not seeing any change for days to come in the manifest.json nor the service-worker.js.
More details about service worker behaviour are available from Google Web Fundamentals.
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.
We are developing an Android application, where there is a need to upload several photos to our server in an asynchronous way. Consider that as soon as a picture is taken, it will start being uploaded. As soon as it has finished being uploaded, the next one (all of them will be placed in a queue) will start being uploaded.
However, it is also important to support cancellation functionality, meaning that the user can interact with the app in a way that will remove an image from the queue or even cancel a running upload.
After searching for possible solutions, we have come to the following possible scenarios:
1) Use an IntentService for the queue mechanism and implement our own logic inside it. However, there are some worries as to how easy it is going to be to support cancellation.
2) Use the SD card and a local database to store the files and a Service to check for new files. This has been described here:
Android (or iOS) - Image Upload Queue
3) Find a way to use the built-in Android DownloadManager for uploads (can it really be done?)
4) Use AsyncTask and isCancelled() function.
5) Or ideally find another built-in Android/Java mechanism to do all of the above in a seamless way.
Any ideas?
The Scenario: My App has many activities. At the end the user uploads his all data in just one click.
The Problem: A problem might arise if the user is on the move and goes out of service(internet service / poor connectivity), then he/she couldn't upload the data.
In this context I want to know what might be a best efficient approach.
I have thought of one approach. If due to poor connectivity / no service I will save the data locally in SQLite. Keep a thread alive when user opens the App next time to check if service/connectivity available. If yes, it will be uploaded instantly.
I will be eagerly waiting for your comments.
Save all your data to SQLite with a sync flag. Use a service to constantly check for unsynced flags, and try to send to server in the background, update the flag when sync is completed.
Another approach if you are syncing to a direct SQL Server from SQLite, you can set transactions or batch updates, so if connectivity fails, it will revert back the transaction.
For learning how to upload data I recommend watching Google I/O 2012 - Making Good Apps Great: More Advanced Topics for Expert Android Developers : http://www.youtube.com/watch?v=PwC1OlJo5VM# from 16:43. It deals with efficiency and impact on battery life.
To summarize the video:
Do one large upload instead of several small uploads due to how the phone radio works, and try to minimize touching the network.
On a lower level do as user370305 said, try to upload the data, if there is no connectivity delay the upload for the next time the user opens the app or clicks the upload button.
Currently i have an application where an activity calls a service which sends a file to a server. This is working fine..However, i was wondering does anybody know what happens if the internet connection is interrupted. Will the service run again when the connection comes back...Or is there something i need to implement to do this? If so how and what etc? thanks
The service will not run again when the connection comes back unless you add logic to do so. I'd recommend using a success flag to determine if a file was uploaded correctly, and if it wasn't due to an error (such as an interrupt), then you start the upload over again.
Perhaps alerting the user that a file upload has failed would be the best route to take, that way he/she can decide if its worth another try. This would also help keep your app from spiraling out of control while endlessly uploading a file to a server (although you could add a variable like maxNumberOfTries to avoid this).