Android DownloadManager 'Download Requires Network' error - android

I'm using the DownloadManager to queue up some downloads I'm making but running into this issue when I specifically try to use the Mobile/4G connection. I'm using an Android 2.3.4 phone. My code is using the 2.3.3 API.
I'm doing the following command (I want to force the connection to use 4G/3G)
request.setAllowedNetworkTypes(Request.NETWORK_MOBILE);
Whenever it attempts to download however, it places the download in the DownloadManager listing but it forever remains in the status "In progress" and an error at the top lists the file name and the error "Download requires network."
When I investigate further and connected my device to see the logs in logcat, I see the following error when it attempts to download:
Aborting request for download 92: download was requested to not use the current network type
I have the following permissions:
android.permission.WRITE_OWNER_DATA
android.permission.READ_OWNER_DATA
android.permission.WRITE_EXTERNAL_STORAGE
android.permission.INTERNET
android.permission.ACCESS_NETWORK_STATE
android.permission.ACCESS_WIFI_STATE
android.permission.CHANGE_WIFI_MULTICAST_STATE
android.permission.CHANGE_NETWORK_STATE
android.permission.CHANGE_WIFI_STATE
Any ideas of what it could be? Am I still missing a permission? Is there another setting that I need to control to specify the use of the Network connection only?
EDIT:
I have tried this on a brand new Galaxy tablet and this is the behavior I notice using this device: When the wifi is on and connected, it fails to download when specifying to use the NETWORK_MOBILE. If the wifi is turned off or not connected, it has no problem using the 4G connection. I'm thinking this is a security feature being done by the device, can this be overidden?

I dont know how you are setting up your download manager but this is how ive used it in the pass.
private long enqueue;
private DownloadManager dm;
public void onClick(View view) {
dm = (DownloadManager) getSystemService(DOWNLOAD_SERVICE);
Request request = new Request(
Uri.parse("File URL"));
enqueue = dm.enqueue(request);
}
public void showDownload(View view) {
Intent i = new Intent();
i.setAction(DownloadManager.ACTION_VIEW_DOWNLOADS);
startActivity(i);
}

This error occurs when you have no data connection (doesn't matter whether or not you are connected to wifi). You are allowed to specify NETWORK_MOBILE by itself, but it will throw you an error saying "Download Requires Network" if it tries to do the download when your data connection isn't currently working.
My advice to get a data connection again is to walk around until you get a connection again. I can tell when I have a data connection on my Droid Bionic phone because the top bar icons that say 4G LTE and the 4 bars turn blue instead of white.

Related

HttpURLConnection.connect() fails after network reconnection on Android 10

My app connects to an external device using it's WiFi (the device works as a server). With introduction of Android 10 I needed to implement separate WiFi connectivity flow for different plaftorms (WifiNetworkSpecifier for Android 10+ and wifiManager.enableNetwork for < Android 10). The connectivity flow itself works fine, but I have some problems with stream communication.
In the app I have the ability to upload files to that external device. To do that I need to use HttpURLConnection. So I run:
val url = URL(UPDATE_FIRMWARE_URL)
val connection = (url.openConnection() as HttpURLConnection)
with(connection) {
doInput = true
doOutput = true
useCaches = false
requestMethod = METHOD_POST
//setRequestProperty(HEADER_CONNECTION, "Keep-Alive")
setRequestProperty("Connection", "close")
connectTimeout = 6000
setRequestProperty(HEADER_USER_AGENT, "Android Multipart HTTP Client 1.0")
setRequestProperty(HEADER_CONTENT_TYPE, "multipart/form-data; boundary=$boundary")
}
connection.connect()
val outputStream = connection.outputStream
DataOutputStream(outputStream).use { outputStream ->
// actual file upload
}
Now, the actual update consists of two files, and after first upload the device restarts, and I need to reconnect to it's wifi and upload the second file.
On Android < 9 the entire upload flow (with two files) works fine but on Android 10, after I send the first file and reconnect to the device's WiFi, when I call connection.connect() I get ConnectExcpetion with internal cause connect failed: ENETUNREACH (Network is unreachable) (which really makes no sense, cause I'm connected to that network...)
java.net.ConnectException: Failed to connect to (...)
at com.android.okhttp.internal.io.RealConnection.connectSocket(RealConnection.java:1409)
at com.android.okhttp.internal.io.RealConnection.connect(RealConnection.java:1359)
at com.android.okhttp.internal.http.StreamAllocation.findConnection(StreamAllocation.java:221)
at com.android.okhttp.internal.http.StreamAllocation.findHealthyConnection(StreamAllocation.java:144)
at com.android.okhttp.internal.http.StreamAllocation.newStream(StreamAllocation.java:106)
at com.android.okhttp.internal.http.HttpEngine.connect(HttpEngine.java:400)
at com.android.okhttp.internal.http.HttpEngine.sendRequest(HttpEngine.java:333)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.execute(HttpURLConnectionImpl.java:483)
at com.android.okhttp.internal.huc.HttpURLConnectionImpl.connect(HttpURLConnectionImpl.java:135)
Initially I had a problem also with connecting for the first time on Android 10, but I found this article, and adding the connectTimeout helped, but now the connection still fails when I try to connect for the second (and every next) time. The only thing that helps is restaring the entire app (which is no real solution).
What may be the problem, that the next connections fail despite I always execute the same code?
After a few days I finally found an answer to my question. It turns out that on Android 10 when you connect to the Access Point that does not offer the internet (eg. my external device) the standard API calls (using Retrofit) works fine, but when trying to use HttpURLConnection the system tries to use some network with internet connection, and as there is none, the connection fails.
The only way for the connection to work is to force the system to use our network by using ConnectivityManager.bindProcessToNetwork(network). This solution was proposed here and I've got no idea why someone downvoted that answer. It's correct.
What's interesting is that if we connect to the no-internet network via device settings, the connection works just fine even without binding.

How to save EAP wifi network in Android 10 after Android Enterprise provisioning

Up to API lvl 29 we have been using WifiConfiguration to set up wifi connections with our DPC (both device and Profile Owner modes). Since API lvl 29 we can still save Open, WEP, WPA networks, but any attempt of saving EAP network is completely ignored. We tried to use WifiSuggestions method and the suggestion is properly displayed in the notification bar, but when the user taps on "allow" - nothing happens. There are no errors in the log, addNetworkSuggestions() method returns STATUS_NETWORK_SUGGESTIONS_SUCCESS.
This problem exists only when our DPC is provided Device/Profile Owner permissions with full provisioning process (work profile creation or fully managed during the first start). Getting Device Owner status using ADB lets us save the network by allowing the network suggestion.
This is how we set up the network suggestion:
#RequiresApi(api = Build.VERSION_CODES.Q)
public static WifiNetworkSuggestion setupWifiNetworkSuggestion (WifiConfiguration wifiConfiguration){
return new WifiNetworkSuggestion.Builder()
.setSsid(wifiConfiguration.SSID)
.setIsHiddenSsid(wifiConfiguration.hiddenSSID)
.setWpa2EnterpriseConfig(wifiConfiguration.enterpriseConfig)
.build();
}
after that we call:
List<WifiNetworkSuggestion> networkSuggestionList = new ArrayList<>();
networkSuggestionList.add(setupWifiNetworkSuggestion(wifiConfiguration));
int status = mWifiManager.addNetworkSuggestions(networkSuggestionList);
if (status != WifiManager.STATUS_NETWORK_SUGGESTIONS_SUCCESS) {
_logger.error("Problem adding network suggestion, status code: " + status);
}
Are we missing something? The same code works in our other app where we do not use EMM provisioning to get Device Owner. All the requested permissions are the same in both apps. We tried to get some error info or set up some logs but we only get success statuses all the way.
We finally made it work! The problem was caused by three separate issues:
We were lacking allowed key management setting WifiConfiguration.KeyMgmt.WPA_EAP
Our test RADIUS server rejects connection attempts when any domain is provided in the enterprise config. It was giving us unnecessary disconnections even at the point when we resolved Android-side issues
MOST IMPORTANT: For some reason our password policy was not enforced and on test environment we use self-signed certificates. Without at least PIN-lock set up on the device, the certificates cannot be attached to the network profile, therefore it cannot be added/connected to. Even if the network is saved, it lacks the certificate which has to be selected manually (it is deployed properly to the certificate store, though)
WiFi networks added through addNetworkSuggestions do not appear on the system-provided list of saved WiFi networks. But if the device sees the WiFi, it will add a note that this network was suggested by this and that app. Then the user can connect with the WPA Enterprise credentials configured in the code.
From my understanding, it is expected behavior that nothing happens that the user could see.
Also, if you uninstall the app, the suggested networks disappear again.
As a Device Owner, you should be able to use the otherwise deprecated WifiManager.AddNetwork() method to add the network to the system list. I haven't tested that myself.
On Android 12 (but not with 10 and 11), you can ask the user to add a network to the system list using this code:
var suggestionsList = new WifiNetworkSuggestion[]
{
networkSuggestion
};
Bundle bundle = new Bundle();
bundle.PutParcelableArrayList(
Android.Provider.Settings.ExtraWifiNetworkList,
suggestionsList
);
Intent intent = new Intent(Android.Provider.Settings.ActionWifiAddNetworks);
intent.PutExtras(bundle);
intent.AddFlags(ActivityFlags.NewTask);
Android.App.Application.Context.StartActivity(intent);

Android Download Manager "Download Unsuccessful"

This is my first time trying to implement DownloadManager and no matter what I try, I always get a notification saying "Download unsuccessful." I've looked at many other SO forums, a few tutorials, and what I have should work. Yes, I've set internet and external storage permissions in the manifest file. And yes, I've given storage permission in the app settings on the phone. I've tried this on both an Android emulator running API 28 and a real phone running the same. Here is the code I have:
String url = "http://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4";
DownloadManager downloadManager = (DownloadManager)getSystemService(DOWNLOAD_SERVICE);
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setTitle("title");
request.setDescription("Your file is downloading");
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED);
request.setDestinationInExternalPublicDir(Environment.DIRECTORY_MUSIC, "" + System.currentTimeMillis());
request.allowScanningByMediaScanner();
request.setAllowedOverMetered(true);
request.setAllowedOverRoaming(true);
//Enqueue download and save the referenceId
long downloadReference = downloadManager.enqueue(request);
if (downloadReference != 0) {
Toast.makeText(getApplicationContext(), "download started", Toast.LENGTH_SHORT).show();
}else {
Toast.makeText(getApplicationContext(), "no download started", Toast.LENGTH_SHORT).show();
}
Any help or suggestions are appreciated. Thanks.
This issue occur due to network security. If You are using un-secure url in above pie API, then it can't execute your url. Check Official Documentation.
Reason for avoiding cleartext traffic is the lack of confidentiality,
authenticity, and protections against tampering; a network attacker
can eavesdrop on transmitted data and also modify it without being
detected.
Add following in manifest to bypass all security.
<application
android:name=".ApplicationClass"
....
android:usesCleartextTraffic="true">
My Experience on 1/11/2021, min SDK 19, Target SDK 30
I spent a day on using Download Service and finally it worked.
To sum it up for anyone who wants to try for the first time:
Dont't forget to add WRITE_EXTERNAL_STORAGE and INTERNET permissions in Manifest.
use requestPermissions() to grant permission from user.
use getExternalFilesDir() instead of getExternalStorageDirectory().
If you're downloading from http:// so add usesCleartextTraffic="true" to manifest.

How to use Android's DownloadManager over P2P connection

From an Android application, I would like to use DownloadManager to download files from a peer which is connected using P2P (Wi-Fi Direct).
However, I found that unless the tablet/phone is connected to a WiFi network, DownloadManager will refuse to download over the P2P connection. It will output an error claiming "NO CONNECTION". If both Wi-Fi and P2P are connected, I can successfully download over the P2P connection.
Here's a sample code:
String url = "http://ipv4.download.thinkbroadband.com/5MB.zip";
String localFile = "5MB.zip";
DownloadManager.Request request = new DownloadManager.Request(Uri.parse(url));
request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);
request.setTitle("test.txt");
request.setDescription("Testing DownloadManager -- 5MB.zip");
request.setVisibleInDownloadsUi(true);
request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE);
request.setDestinationInExternalFilesDir(context, null, localFile);
DownloadManager downloadManager = (DownloadManager)context.getSystemService(context.DOWNLOAD_SERVICE);
long downloadId = downloadManager.enqueue(request);
Now, I'm not sure if I'm just not using it correctly, or whether it's an unsupported feature. I'm willing to change Android's codebase if needed in order to get it to work (but I can't choose an alternative to DownloadManager).
Inspecting Android's code, it seems that the method checkCanUseNetwork() will return "NO_CONNECTION" because it gets a null NetworkInfo from mSystemFacade. See:
/packages/providers/DownloadProvider/src/com/android/providers/downloads/DownloadInfo.java
Further investigation hints to a "problem" in ConnectivityService. While it sets its mActiveDefaultNetwork to the correct type when Wi-Fi network is connected, it won't do anything when P2P is connected.
/frameworks/base/services/core/java/com/android/server/ConnectivityService.java
I'm using Nexus 4 with Android 5.0.1, but I've seen the same issue with KitKat 4.4.
If you remove following line of code, it will work.
"request.setAllowedNetworkTypes(DownloadManager.Request.NETWORK_WIFI | DownloadManager.Request.NETWORK_MOBILE);"

AIR for Android checking internet connection issue ( actionscript 3 )

I'm developing a simple app for my school which will show you the newest updates from the website, but checking the internet connection seems a little problem in AIR.
I'll be more specific:
I'm using Adobe Flash CS6 to develop the app (Using AIR for android)
The app contains a menu, and the "internet frame", of which the code doesn't really work.
I've tried a couple of things already: URLMonitor(like is available = true), URLLoader(and cathing the IOError if it occurs when there's no internet connection) and something like HTMLLoader (long time ago :P, no success)
The URLLoader works "fine", but I also need to know if the webpage just isn't available (404) when there IS an active internet connection, but in either those cases it will just throw the same "stream error" , so I can distinguish them. That's why it doesn't suit my needs.
The URLMonitor also works "fine", but here comes to problem:
When testing the app on the emulator, it can without a problem detect that there is no internet connection. BUT, when exporting to .apk and running on my android device, it won't succeed in detecting the internet connectivity.
Here's my code:
var monitor:URLMonitor = new URLMonitor(new URLRequest("http://www.google.nl"));
monitor.addEventListener(StatusEvent.STATUS, netConnectivity);
monitor.start();
function netConnectivity(e:StatusEvent):void
{
if(e.target.available)
{
//checking the content
output_txt.text += "\ninternet available";
loader = new URLLoader(new URLRequest(webURL));
loader.addEventListener(IOErrorEvent.IO_ERROR, onIOErrorLoader);
loader.addEventListener(Event.COMPLETE, onCompleteLoader);
}
else
{
//
//
// NO INTERNET CONNECTION AVAILABLE!
//
//
output_txt.text += "\nno internet available";
popupnoconnection_mc.alpha = 100;
popupnoconnection_mc.play();
popupnoconnection_mc.addEventListener(MouseEvent.MOUSE_DOWN, BackToMenu);
}
monitor.stop();
}
As you can see, it adds an EventListener to the URLMonitor, starts the checking, and the function checks the availability of the internet connection. WORKS ON THE EMULATOR, NOT PROPERLY ON MY DEVICE.
What's even more interesting:
What DOES work on my device, is when the internet IS connected. It will just show the text in my output field, but it won't when there is no internet connection!
Also, when lauching the app with an internet connection set up, then entering this frame, then going back to the main menu, then turning the internet off, and then entering this frame again, this code suddently works great!
So it has got to do something with the creation of the URLMonitor, and checking the connection at the same frame I guess, but I need a little hand here!
I think this can't be too difficult!
Thank you so much in advance! (sorry for typos)
You can use NetworkInfo to detect whether there is an internet connection - it works on Android.

Categories

Resources