DownloadManager: understand retry policy and error codes - android

According to the documentation, if download is failed due to http error - the COLUMN_REASON should hold the specific http error code.
the problem I'm having is that in practice, the only reason value I see when download fail is ERROR_HTTP_DATA_ERROR
also, I see in logcat the actual failure http code in runtime, when the download is being stopped and re-try, but I don't see any way to get it from the download manager.
is it possible to get somehow this http code?
I'm using broadcast receiver to handle ACTION_DOWNLOAD_COMPLETE , but I don't see any way to listen to download paused, and I'm getting a feeling that if I'll query download manager failure reason between the retry attempts it does - then I'll get the actual status code.
is it possible to listen to "download pause" event without querying constantly the download manager?
I would expect that will be such broadcast.
the questions that I'd love to finally get answers to are:
is it possible to listen to "download pause" event without querying constantly the download manager, and without active listener to the content resolver?
is download manager (on API level 16+) supports https (ssl) ?
what exactly is download manager retry policy? can I change it default retry policy?

is it possible to get somehow this http code?
Currently, no. The DownloadManager reports a STATUS_SUCCESSFUL even when a download failed, for example because the url/file was not found (HTTP 404) (this is a bug).
Also see DownloadManager sends STATUS_SUCCESSFUL for failed download
I know it's a relatively old thread but that issue still remains. I tested it 5 minutes ago and it still doesn't work properly.
is it possible to listen to "download pause" event without querying constantly the download manager?
Weirdly, no. The only available "events" to listen for are:
To get around this, you have to query the status yourself every X time by checking
if (cursor.getInt(cursor.getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_PAUSED) {
// Do stuff
}
is download manager (on API level 16+) supports https (ssl) ?
It used to not support https (read more in Android DownloadManager and SSL (https)), however it does now. You can simply verify by trying to retrieve a file from a https origin, for example https://mdn.mozillademos.org/files/3794/mixed_content_webconsole.jpg. You will see that it retrieves the file fine.
what exactly is download manager retry policy? can I change it default retry policy?
It is currently not possible to change the retry 'policy'. See the docs and you will find there are no methods or properties regarding this functionality.
Regarding the default retry policy, useful information can be found in the following package: com.android.providers.downloads.Constants. This links to the 5.1.1 version, if you need the information for another version you can manually navigate to that. For example here is the information for android 4.0.1 (the retry policy values are the same as in 5.1.1).
It states:
The number of times that the download manager will retry its network operations when no progress is happening before it gives up.
public static final int MAX_RETRIES = 5;
The minimum amount of time that the download manager accepts for a Retry-After response header with a parameter in delta-seconds.
public static final int MIN_RETRY_AFTER = 30; // 30s
The maximum amount of time that the download manager accepts for a Retry-After response header with a parameter in delta-seconds.
public static final int MAX_RETRY_AFTER = 24 * 60 * 60; // 24h
As you might have guessed, these are final (constant) and thus cannot be changed.
Conclusion: DownloadManager is pretty useful to do some basic downloading, but it's functionality is pretty limited.
I can suggest an alternative: there's a downloadmanager in the android-common libary over at https://github.com/Trinea/android-common
I have not used it myself, but 2k+ stars on github usually means it's worth checking out.

Related

Remote Config throttling : The counter is per device or sum all calls?

The documentation says:
If an app fetches too many times in a short time period, fetch calls
are throttled and the SDK returns
FirebaseRemoteConfigFetchThrottledException. Before SDK version
17.0.0, the limit was 5 fetch requests in a 60 minute window (newer versions have more permissive limits).
This policy consider the fetch from all devices and running Apps on my project or the counter is by device?
For example, 5 different devices call fetch using my App. If a sixth device call again, in less than 1 hour, will be throttled ? Or each device can fetch 5 times before be throttled ?
Background:
I have implemented the "real time propagation" for remote config, as described on the documentation here and here
Is working correctly.
When i publish a new configuration, my app receive a silent notification. I set one flag to indicate that a new update is available and then. When user opens the App again, i verify the flag, set the fetchInterval to 0 and force fetch configuration from the firebase server. But im worried that this strategy might be throttled
Maybe this answer comes a bit late but in case someone else is useful the throttled state is by device, I was able to check this for myself, debugging with other devices at the same time that one of my devices was in the throttled state. You can also check for yourself by removing the application and installing it again. Firebase will take your device as a new one and it will no longer be in a throttled state.

Coldfusion server stops rendering pages when accessed over Chrome for Android

We have apache 2.4 running on a Windows Server 2012, everything works fine except one strange bug:
The server stops serving any pages to users after someone visits any page via Chrome for Android. The visitor on the Android device (only when using Chrome) gets an "connection reset" error, but all users after that are getting blank loading pages until Apache gets restarted. If an user is loading a page on any other device during a restart, the page finishes loading immediately.
It seems that i can't find anything specific in the Apache or CF errorlogs. The only error i'm able to find is in the coldfusion-out.log:
Apr 15, 2016 13:34:43 PM Error [ajp-nio-8016-exec-15] - The request has exceeded the allowable time limit Tag: cfhttp The specific sequence of files included or processed is: C:\projekte\removed\So-funktioniert-es-6.html, line: 98
It does mention a specific file here, but it happens no matter what file or page you try to open. It's a really strange bug and we can't find any solution to it, nor anyone else with the same problem. The server isn't overloaded at all.
Hopefully i was specific enough for someone to point us in the right direction.
The error The request has exceeded the allowable time limit Tag itself says what's wrong.
The above error means your page has taken too long to finish
processing, so ColdFusion has ended the process in order to free up the server.
If you have access to the administrator, you can increase the timeout period
server-wide in the Settings page (Timeout requests after n seconds) - if you
just want to increase the timeout period for that particular page, you can tack
on requestTimeout=x (where x is the number of seconds before the page times
out) to the url as below:
http://your_url?requestTimeout=desired_time_in_seconds
Alternatively you can use the tag <cfsetting requestTimeOut = "desired_time_in_seconds"> within your
code to overide the default setting.
Edit: If it is occuring only on Chrome then there must be something that's breaking your request. Most probably Javascript, Ajax, Jquery. But try the above method first.

android notify User on when his data changes in the server

We are working on app which is for fixing their appointment with a doctor. We will have to notify the user on that date by saying if the doctor is available or not.
How can we notify the user when the data changes in the server?
The usual workflow for sending push messages from your server to the application, is the Google Cloud Messaging, or the so-called Push Notification in Android.
Simply put, you send your message to the Google and the Google will notify your application. The actual heavily lifting is done by the Google Play Services Library and its corresponding application, which is installed on every android device. For more information on how to implement it, you may refer to the following links.
Official Documentation on Cloud Messaging
Android Push Notification Tutorial
I used http://pusher.com/ "Pusher" for a doc app a couple years ago. It was easy to do and light weight.
Simplest way I would believe is through a polling technique. However, it would not work for real time updates as there is an update interval. Depending on your application's requirements, this might work!
In order to do that.
You would have to publish a web service which would provide a Unix
timestamp. e.g. https://Your-base-url/status.aspx
Each time there is any change on the server, you change the value to a new one on the server.
Your Android device will poll that web service(status) each say 60 seconds
to see if there is an update.
The device would save the timestamp in his device and would check
whether the two timestamps match.
If not, then he will call the relevant web services to get updated
data.
However, you should note that the Android device will only get to know whenever it polls. So, the device might not know the update until his next polling cycle.
The most accurate way is to maintain a persistent Socket connection with your server at all times. Whenever an update occurs, you can immediately send the updates to the device via the open socket. However, this is more complicated as you will have to deal with the socket connections.
GCM uses socket connections internally. Therefore, a solution including GCM is an easier approach.

Android DownloadManager retry interval

I would like to know the retry interval for DownloadManager.
My downloads get stuck at STATUS_PAUSED status, with the reason PAUSED_WAITING_TO_RETRY. (This is strange because I have no connection problem and it only happens on Android 6 - please see this separate question for further info).
The app eventually retries to commence the download but the delay is way too long, and the interval seems irregular. When does DownloadManager attempt to retry the download? Is there a way to manually trigger the retry?
One way I can think of going about this is:
Keep track of the id returned on DownloadManager.enqueue
Check for status at intervals you desire and DownloadManager.remove if needed
Unfortunately, as far as I can recollect, the automatic retry cannot be triggered manually.
Hope this helps!

DNS resolution warm up in android

I have a broadcast receiver watching the wifi state and sending an http request to me server when it becomes enabled. The problem that I have is that when I run the code under debugger it works just fine, but when I run the same code without a debugger, it throws an exception.
The exception indicates that the failure is actually the DNS resolution failure - it fails to resolve the DNS name.
I decided that even though the system fired the 'enabled' event, the DNS resolver is not fully initialized yet and added a 10sec delay before the attempt to send my request and this resolved the issue, but I am really uncomfortable with this solution. Even though in my case it does not really matter, 10 sec seems too long. A bigger question will 10 sec be enough on all platforms?
Another solution would be to intercept this particular exception and try again. The question is - how many retries?
My question is - what's the best way to wait until the DNS resolver is fully initialized? Is there an event or a notification I can subscribe to?

Categories

Resources