Using the Connectivity Manager Class we can get access to either wifi or Internet Network:
ConnectivityManager connec = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
// ARE WE CONNECTED TO THE NET
if ( connec.getNetworkInfo(0).getState() == NetworkInfo.State.CONNECTED ||
connec.getNetworkInfo(1).getState() == NetworkInfo.State.CONNECTED ) {
// ...
}
where 0 and 1 respectively refers to mobile and wifi connection
If my Android device is connected to both, can we switch between any of the networks or can we disable any of the networks? Like using a function:
connec.getNetworkInfo(0).setState(NetworkInfo.State.DISCONNECTED);
I know of enabling or disabling wifi:
WifiManager wifiManager = (WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(status);
where status may be true or false as per requirement.
Edit:
You also need the following permissions in your manifest file:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
To Enable WiFi:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(true);
To Disable WiFi:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false);
Note:
To access with WiFi state, we have to add following permissions inside the AndroidManifest.xml file:
android.permission.ACCESS_WIFI_STATE
android.permission.UPDATE_DEVICE_STATS
android.permission.CHANGE_WIFI_STATE
A complete solution:
try {
WifiManager wifi = (WifiManager)
context.getSystemService(Context.WIFI_SERVICE);
WifiConfiguration wc = new WifiConfiguration();
wc.SSID = "\"SSIDName\"";
wc.preSharedKey = "\"password\"";
wc.hiddenSSID = true;
wc.status = WifiConfiguration.Status.ENABLED;
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
wc.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
wc.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
wc.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.TKIP);
wc.allowedPairwiseCiphers
.set(WifiConfiguration.PairwiseCipher.CCMP);
wc.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
boolean b=wifi.isWifiEnabled();
if (b) {
wifi.setWifiEnabled(false);
Toast.makeText(context, "yes", Toast.LENGTH_SHORT).show();
} else {
wifi.setWifiEnabled(true);
Toast.makeText(context, "no", Toast.LENGTH_SHORT).show();
}
//Log.d("WifiPreference", "enableNetwork returned " + b );
} catch (Exception e) {
e.printStackTrace();
}
Reference: http://amitkumar-android.blogspot.com/p/installation-steps.html
In Android Q (Android 10) you can't enable/disable wifi programmatically anymore. Use Settings Panel to toggle wifi connectivity:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
// can also use `Settings.Panel.ACTION_WIFI` to enable/disable only WiFi
val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
startActivityForResult(panelIntent, 0)
} else {
// use previous solution, add appropriate permissions to AndroidManifest file (see answers above)
(this.context?.getSystemService(Context.WIFI_SERVICE) as? WifiManager)?.apply { isWifiEnabled = true /*or false*/ }
}
To enable disable Wifi use the WifiManager class to get system(android device) services for Wifi :
WifiManager wifi =(WifiManager)getSystemService(Context.WIFI_SERVICE);
Now the object wifi of the WifiManager class is used to get the wifi status:
if(wifi.isWifiEnabled())
//Perform Operation
else
//Other Operation
And most importantly do not forget to give the following permission in your Android Manifest File:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.UPDATE_DEVICE_STATS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
To get detailed info and full sample code of the project for enable/disable Wifi on android visit my website link.
This method is deprecated now from now starting with Android Q.
Try This will really help.
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {// if build version is less than Q try the old traditional method
if (!wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(true);
btnOnOff.setText("Wifi ONN");
} else {
wifiManager.setWifiEnabled(false);
btnOnOff.setText("Wifi OFF");
}
} else {// if it is Android Q and above go for the newer way NOTE: You can also use this code for less than android Q also
Intent panelIntent = new Intent(Settings.Panel.ACTION_WIFI);
startActivityForResult(panelIntent, 1);
}
add this permission in your manifest and than use the above code to change WiFi state:
<!--permission ge enable and disable WIFI in android-->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
I could not access the context object directly.
My solution is as following:
Context appContext = Android.App.Application.Context;
var wifiManager = (WifiManager)appContext.GetSystemService(WifiService);
wifiManager.SetWifiEnabled(state);
Also I had to change some writings eg. WIFI_SERVICE vs. WifiService.
It is possible to enable/disable wifi on pre Android 10 devices using the following code:
WifiManager wifiManager =
(WifiManager)this.context.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(status);
But note that it is not possible to do this anymore on Android 10 and probably going ahead as well.
https://issuetracker.google.com/issues/141011684
Android 10 (Q) onwards wifi can not be enabled/disabled you need to open the setting intent,
// for android Q and above
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
Intent panelIntent = new
Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY);
startActivityForResult(panelIntent, 0);
} else {
// for previous android version
WifiManager wifiManager = (WifiManager)
this.getApplicationContext().getSystemService(WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
}
In manifest,
<uses-permission
android:name="android.permission.CHANGE_WIFI_STATE"
android:required="true" />
Related
My app is communicating with another device by wifi.
I tried to ask all permissions at app's start, but is never asked about wifi.
By the way, every time I need to change wifi, user must give permission.
How can I ask for change wifi state permission once and never bother user again?
Sample of code that I used to change wifi is below
WifiConfiguration wifiConfig = new WifiConfiguration();
wifiConfig.SSID = String.format("\"%s\"", ssid);
if (!key.equals(""))
wifiConfig.preSharedKey = String.format("\"%s\"", key);
final int netId = wifiManager.addNetwork(wifiConfig);
Log.d("Network ID", Integer.toString(netId));
wifiManager.disconnect();
wifiManager.enableNetwork(netId, true);
wifiManager.reconnect();
The permission my phone is asked about below
It is Russian. Translation is "Would you give this app a permission to turn on/turn off WIFI?".
I tested it on another phone, and it keeps happening. Both phones is xiaomi and have their own android version MIUI.
Add this code snippet in AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
And use this code:
WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE);
wifi.setWifiEnabled(false); // activate/deactivate wifi
You only need to declare it in AndroidManifest.xml:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
Android > 6.0 user prompted runtime permission is NOT required for CHANGE_WIFI_STATE, because it is one of the safe ones.
If something is still goes wrong, please provide code sample which you are using.
UPD:
Tested your code on Samsung J5 with Android 6.0 and everithing works fine.
Also you are using deprecated methods. You need to use something like this for >= Android.O
In manifest:
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"
tools:ignore="ProtectedPermissions" />
And code:
WifiNetworkSpecifier.Builder builder = new WifiNetworkSpecifier.Builder();
builder.setSsid("SSID");
builder.setWpa2Passphrase("PASSWORD");
WifiNetworkSpecifier wifiNetworkSpecifier = builder.build();
NetworkRequest.Builder networkRequestBuilder1 = new NetworkRequest.Builder();
networkRequestBuilder1.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
networkRequestBuilder1.setNetworkSpecifier(wifiNetworkSpecifier);
NetworkRequest nr = networkRequestBuilder1.build();
final ConnectivityManager cm = (ConnectivityManager)
getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
ConnectivityManager.NetworkCallback networkCallback = new
ConnectivityManager.NetworkCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onAvailable(Network network) {
super.onAvailable(network);
Log.d("TEST", "onAvailable:" + network);
cm.bindProcessToNetwork(network);
}
};
cm.requestNetwork(nr, networkCallback);
I have connected my android phone with LAN connection. I would like to display a toast or an alert when I disable LAN connection. I am trying the following code but its of no use. What am I missing ?
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
isNetworkAvailable(MainActivity.this);
}
// to check connection state
public static boolean isNetworkAvailable(Context context){
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities networkCapabilities = connectivityManager.getNetworkCapabilities(network);
if(networkCapabilities == null){
Toast.makeText(context, "No Internet connection!", Toast.LENGTH_LONG).show();
}
return true;
}
}
I couldn't Use NetworkInfo since its been deprecated. Thanks in advance
UPDATE:
I solved my problem using the example from the link below.
Very well explained. Have a look :)
Detect internet Connection
First of all the code you showed will be triggered only when activity is created and only once. What you need is Monitor for changes in connectivity
As mentioned:
Apps targeting Android 7.0 (API level 24) and higher do not receive CONNECTIVITY_ACTION broadcasts if they declare the broadcast receiver in their manifest
Meaning that you will have to create a custom broadcast receiver (I use kotlin for android development, you should be able to translate that to java):
class NetworkStatusReceiver : BroadcastReceiver() {
override fun onReceive(context: Context?, intent: Intent?) {
// check intent action for the connection status
}
}
To use the receiver, you need to register it in your activity (a better choice would be to use a service if you need it across multiple activities):
val filter = IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)
filter.addAction("mypackage.CONNECTIVITY_CHANGE")
val permissionReceiver = NetworkStatusReceiver()
registerReceiver(permissionReceiver, filter)
To avoid memory leaks or multiple bindings it is recommended to unbind the receiver once the lifecycle of you component ends, you can do that by:
unregisterReceiver(permissionReceiver)
Also don't forget to add to your manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Try this
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(isNetworkConnected){
}else{
Toast.makeText(context, "No Internet
connection!",Toast.LENGTH_LONG).show();
}
}
public boolean isNetworkConnected(Context context) {
ConnectivityManager cm = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
return netInfo != null && netInfo.isConnected();
}
}
First added network permissions in you manifest.xml file:
ex:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Then create and register a broadcast receiver class which will be notified whenever there is a change in network/internet connection.
Here is a good example
link: https://www.androidhive.info/2012/07/android-detect-internet-connection-status/
This question already has answers here:
How do I see if Wi-Fi is connected on Android?
(24 answers)
Closed 3 years ago.
I have a Button that downoad a File, and works fine. If I dont have Internet conection, the file doesnt download (obviously). The problem is that the app continues trying to download, instead of stop it.
I want to show a Toast saying "The device its not connected" or some stuff like that and NOT begin the download process then. I want a function that returns true or false if I have WIFI connection avaiable AT THE MOMENT or not
I try with the answers of these post: How to check currently internet connection is available or not in android , but the function retuns always true, even with Airplane mode.
I download the File with a DownloadManager and continues after download with a BroadcastReceiver.
Add this permission in Manifest file
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Following condition will help you
ConnectivityManager connManager = (ConnectivityManager)getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo wifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (wifi.isConnected()){
// If Wi-Fi connected
}else{
Toast.makeText(getApplicationContext() /*Context field*/,"Please Connect to Wifi",Toast.LENGTH_SHORT).show();
}
Add this permission in Manifest file
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
Use this condition to check if Wifi Connected or not
ConnectivityManager connManager = (ConnectivityManager);getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mWifi = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
if (mWifi.isConnected()) {
// Do whatever
}
Here's Network connectivity checking code
public class NetworUtil {
private static NetworkInfo activeNetwork;
public static boolean isInternetConnected(Context context) {
if (context == null)
return false;
else {
ConnectivityManager cm =(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null && activeNetwork.isConnectedOrConnecting();
}
}
}
Below permission must be required in the AndroidManifest file.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
I'm working on a simple system app in Oreo AOSP to turn ON wifi Hotspot with predefined SSID and preshared key.
As my APP is built as a system app so i don't need reflection.
MainActivity.java
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
boolean result = false;
WifiManager mwifiManager;
mwifiManager = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
try {
Method method = mwifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration netconfig = (WifiConfiguration) method.invoke(mwifiManager);
netconfig.SSID = "DummyApp";
netconfig.preSharedKey = "1234567890";
netconfig.allowedKeyManagement.set(4);
mwifiManager.setWifiEnabled(false);
method = mwifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
result = (boolean) method.invoke(mwifiManager, netconfig, true);
if (!result) {
Toast.makeText(this, "Hotspot creation failed", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Wifi Enabled", Toast.LENGTH_SHORT).show();
}
} catch (Exception e) {
e.printStackTrace();
}
finish();
}
#Override
protected void onResume() {
super.onResume();
}
}
AndroidManifest.xml
android:protectionLevel="signature|privileged"
android:sharedUserId="android.uid.system">
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<!-- for wifi -->
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WRITE_SETTINGS" />
<uses-permission android:name="android.permission.WRITE_SECURE_SETTINGS" />
<uses-permission android:name="android.permission.OVERRIDE_WIFI_CONFIG" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_LOCATION_EXTRA_COMMANDS" />
<uses-permission android:name="android.permission.TETHER_PRIVILEGED" />
Wifi Should turn ON but getting following result:
Toast Message: Hotspot creation failed
Logcat: WifiManager: PACKAGE_NAME attempted call to setWifiApEnabled: enabled = true
update1: How to turn on/off wifi hotspot programmatically in Android 8.0 (Oreo)
I have tried above changes. It will turn on Hotspot locally but no custom SSID and password.
update2: After getting input from #Mr.AF.
Method setConfigMethod = mWifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
......code snip.........
netconfig.allowedKeyManagement.set(4);
Method Method = mWifiManager.getClass().getMethod("setWifiApConfiguration", WifiConfiguration.class);
HOTSPOT Creation FAiled
To turn ON Portable HotSpot in Android Nougat and below following code works.
Method method = mwifiManager.getClass().getMethod("getWifiApConfiguration");
WifiConfiguration netconfig = (WifiConfiguration) method.invoke(mwifiManager);
method = mwifiManager.getClass().getMethod("setWifiApEnabled", WifiConfiguration.class, boolean.class);
result = (boolean) method.invoke(mwifiManager, netconfig, true);
Above API is deprecated in Oreo.
Following is a #system hidden API in oreo, If the android application is built as a system app then only below API code can be accessed. In my case, I can use the below API.
ConnectivityManager oncm = (ConnectivityManager)ontext.getSystemService(Context.CONNECTIVITY_SERVICE);
oncm.startTethering(ConnectivityManager.TETHERING_WIFI, true, new ConnectivityManager.OnStartTetheringCallback() {
#Override
public void onTetheringStarted() {
super.onTetheringStarted();
Log.i(TAG, "Hotspot is successfully opened");
}
#Override
public void onTetheringFailed() {
super.onTetheringFailed();
Log.e(TAG, "Hotspot failed to open");
}
});
You don't need to use reflection for versions>=Oreo. After android's public exposed API startLocalOnlyHotspot. I've explained this answer in detail on this question on Stackoveflow.
After developing a working system in 6.0 (S6) I'm testing the same code in 8.0 (S9) and I've noticed that ConnectivityManager.requestNetwork() is no longer doing anything.
Here is the function I'm using:
public static void enableWifi() {
ConnectivityManager connectivityManager = (ConnectivityManager)
mContext.getApplicationContext().getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkRequest.Builder request = new NetworkRequest.Builder();
request.addTransportType(NetworkCapabilities.TRANSPORT_WIFI);
request.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
connectivityManager.requestNetwork(
request.build(),
new ConnectivityManager.NetworkCallback() {
#RequiresApi(api = Build.VERSION_CODES.M)
#Override
public void onAvailable(Network network) {
connectivityManager.bindProcessToNetwork(network);
Log.i(TAG, "bindProcessToNetwork called");
}
},
30000
);
}
after calling this function, I check to see whether the connection has been switched to Wifi for 20 seconds:
wifiManager.setWifiEnabled(true);
enableWifi();
long start_time = System.currentTimeMillis();
while (!MainActivity.getNetworkClass(mContext).contains("WIFI")) {
if (System.currentTimeMillis() - start_time > 20000) {
Log.i(TAG, "connection timed out");
}
}
After the timeout I'm still on the 4G network, wifi is never truly enabled. All logs shown above are called, yet the network state never changes to Wifi.
The manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.WAKE_LOCK"/>
Edit:
After much frustration I was able to establish a connection once using this setup, but not again since. I am not sure where to even begin troubleshooting this and assume it's a bug in 8.0 until I find otherwise.