Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ConnectivityManager.requestNetwork in Android 6.0

I'm trying to get the new ConnectivityManager.bindProcessToNetwork(Network) using ConnectivityManager.requestNetwork(NetworkRequest, ConnectivityManager.NetworkCallback)

The reason is to force the app to call the future request in some specific network, which doesn't have a internet connectivity (it's a local hardware communication network). At this point, the system is sending the requests over 3G/4G network and never reach the desired Wifi network, because this network doesn't respond the connectivity check that android call.

When I call the requestNetwork method, I receive the following error:

java.lang.SecurityException: com.xyz.app was not granted  either of these permissions: android.permission.CHANGE_NETWORK_STATE, android.permission.WRITE_SETTINGS.

I try to call the new method to request permission available in Android 6.0:

 requestPermissions(new String[]{Manifest.permission.CHANGE_NETWORK_STATE, Manifest.permission.WRITE_SETTINGS}, PERMISSIONS_REQUEST_WIFI);

But the callback is always PackageManager.PERMISSION_DENIED.

I put both of these permissions in the AndroidManifest.xml, without success.

Notice: The Manifest.permission.WRITE_SETTINGS is not in the Permissions Groups.

like image 789
Deividi Cavarzan Avatar asked Aug 24 '15 15:08

Deividi Cavarzan


People also ask

What is ConnectivityManager in Android?

android.net.ConnectivityManager. Class that answers queries about the state of network connectivity. It also notifies applications when network connectivity changes. The primary responsibilities of this class are to: Monitor network connections (Wi-Fi, GPRS, UMTS, etc.)

How can you instantiate the object of ConnectivityManager?

Checking Network Connection getSystemService(Context. CONNECTIVITY_SERVICE); Once you instantiate the object of ConnectivityManager class, you can use getAllNetworkInfo method to get the information of all the networks. This method returns an array of NetworkInfo.

What is network watchlist?

The watchlist is a collection of endpoint pairs. Each endpoint pair has a vantage point at one end and a market city and provider at the other end. The watchlist updates latency measurements for each endpoint pair daily. Use the watchlist to identify performance trends for your locations and providers of interest.


2 Answers

I'm not sure if this was intended by Google, but the following is the behavior I'm seeing:

CHANGE_NETWORK_STATE seems to always be denied (as noted in the comments, its a signature permission) but it also doesn't seem to matter. My ConnectivityManager network requests all seem to be gated by WRITE_SETTINGS only - so if you have WRITE_SETTINGS you don't need CHANGE_NETWORK_STATE.

As noted in comments, you do this differently than other permissions, using:

 Intent goToSettings = new Intent(Settings.ACTION_MANAGE_WRITE_SETTINGS);  goToSettings.setData(Uri.parse("package:" + Context.getPackageName()));  startActivity(goToSettings); 

And after that, my ConnectivityManager network requests were peachy.


To check if the permission is already granted before calling the ACTION_MANAGE_WRITE_SETTINGS activity, this answer has the solution using Settings.System.canWrite(Context)

Can't get WRITE_SETTINGS permission


UPDATE: as of Android 6.0.1, CHANGE_NETWORK_STATE is auto granted when requested in your manifest file. The above WRITE_SETTINGS checks are only required for 6.0

like image 164
Splash Avatar answered Sep 21 '22 12:09

Splash


This was an Android 6.0 bug. It's fixed in Android 6.0.1, requestNetwork() can be called if you request CHANGE_NETWORK_STATE in the manifest. No need to call requestPermissions(), it's a normal permission.

like image 23
cuihtlauac Avatar answered Sep 20 '22 12:09

cuihtlauac