Android 29 has dropped the ability to programatically enable/disable the phone's Wi-Fi interface. An application I work on connects to an external wi-fi device (p2p, no outbound internet) programatically. If wi-fi is not enabled, we ask the user to enable it.
There is a new system UI Panel API documented here. We can show a basic toggle switch to the user to enable wi-fi via this:
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
Once Wi-Fi is enabled we connect via the process described below:
Eg:
val ssid = ssidObtainedExternally()
val psk = pskObtainedExternally()
val specifier = WifiNetworkSpecifier.Builder()
.setSsid(ssid)
.setWpa2Passphrase(psk)
.build()
val request = NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.removeCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
.setNetworkSpecifier(specifier)
.build()
connectivityManager.requestNetwork(request, networkCallback)
However, one issue with this is that after the user switches the toggle to enabled, the same dialog will then start showing a list of available Wi-Fi networks which may entice the customer to choose the wi-fi device (since the SSID is just the name of the device, which they know). Since we will programmatically connect, we don't want the user to try and manually select the wi-fi network since they won't know the PSK. It would be ideal to dismiss the dialog as soon as they toggle the switch to enable.
I tested this with the GoPro 8 and that app seems to have a mechanism to dismiss the dialog once the user toggles the switch.
I've tried a few things so far with no luck. I tried using Application.registerActivityLifecycleCallbacks but it doesn't pick up the settings panel being created, started, or resumed.
I also tried the tip here: https://stackoverflow.com/a/32929066/94557
With no luck (the only visible activities were ones declared in my app that were in the stack)
Any ideas?
It looks like I've found a hack that seems to work and is probably what the gopro app does. The idea is to keep a reference to your current activity after you launch the Wifi settings panel. Once you detect that Wifi is enabled, call
yourPreviousActivity.startActivity(yourPreviousActivityIntent)
with an intent that represents the screen you were on previously. You will want to add the following flag to the intent:
FLAG_ACTIVITY_CLEAR_TOP
The end result is your activity is re-launched and the settings panel is hidden.
If you have any animation runs on open you will want to disable it.
Related
Can I from my application force android to reconnect to cellular network immediately?
If yes how to do this?
Apparently the functionality as of Android 5 has been moved to system apps only. How to enable mobile data on/off programmatically
But you can still register a listener for network changes.
https://developer.android.com/training/basics/network-ops/reading-network-state
When you get the onLost() event you can start a Wireless Setting Activity so the user can do it manually.
//As seen in the link above.
Intent intent = new Intent(Settings.ACTION_WIRELESS_SETTINGS);
startActivity(intent);
This will be a common occurrence so get use to it. For example you can createBond() for a Bluetooth device, but you can't removeBond() anymore. Thus you have to send the user to the Bluetooth setting activity for the user to
"forget" about the device.
I want to programmatically switch on/off Connect to open networks and Open network notification from the android settings:
https://source.android.com/devices/tech/connect/wifi-infrastructure
How can I do this? Do I have to use ConnectivityManager / WifiManager?
The reason for this is that I am annoyed by my phone telling me about "open" telekom wifi/hotspot when I am outside. Also I cannot find the settings page to turn these settings off on my Samsung Galaxy S7.
Update
As I have not found a viable solution programatically I have solved the problem the following way:
Remove public hotpots that I do not want to connect to from my "Saved WiFi Network" list. Use MacroDroid/Tasker to disable WiFi when I am leaving my home.
It seems you can disable Open network notification:
Settings.Secure.putInt(cr, Settings.Secure.WIFI_NETWORKS_AVAILABLE_NOTIFICATION_ON, 0);
But therefore you need the permission android.permission.WRITE_SECURE_SETTINGS which is only available to system apps.
We are developing a locked down "kiosk-style" Android app on a stock Samsung tablet, which is mounted in customer vehicles. We would like to be able to allow customers to edit their wifi settings, without giving them access to the rest of the Settings app (e.g. Launcher, accounts, etc)
We have been able to launch the Wifi Settings activity, but it allows the user to go into other areas.
I'm not sure whether it's possible to create a custom interface for connecting to wifi, but even if it were possible, this seems fragile and a lot of work for something quite simple.
Is there any way to solve this well?
I would create a device policy controller app that is provisioned on the device as a device owner using Android Enterprise (Android for Work) APIs.
https://developers.google.com/android/work/dpc/build-dpc
As a device owner, you can set your app in lock task mode which is generally used for kiosks.
https://developer.android.com/work/cosu.html
Then, you can set user restrictions:
addUserRestriction api
user restrictions list
The user restrictions don't cover everything in the settings app, but the coverage is pretty good.
Then I would provision it using NFC or QR code reader from the Google Setup Wizard welcome screen.
https://github.com/googlesamples/android-NfcProvisioning
You might want to also look at existing open source EMM/MDM implementations that already exist such as WSO2.
Other references:
How to enable task locking in Android 5.0 production devices
How to make sure there is only one app
I was also working on Kiosk Type applications and we have to give options for Change wifi and Display Settings So we have used these commands on Button click for Wifi And Display
Settings
btnWifiSetting.setOnClickListener {
startActivityForResult( Intent(android.provider.Settings.ACTION_WIFI_SETTINGS), 0);
}
And For Display Setting
btnDisplay.setOnClickListener {
startActivityForResult(Intent(android.provider.Settings.ACTION_DISPLAY_SETTINGS),0)
}
And you can also check the full list of Available Commands here
https://ourcodeworld.com/articles/read/318/how-to-open-android-settings-programmatically-with-java
try LineAgeOS
https://lineageos.org/
Your requirement needs to access OS System level, this way you have access and customize the WIFI settings before releasing the phone itself
can you try this way.
WifiManager wifiManager = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
wifiManager.setWifiEnabled(false);
Tools_WiFi.setImageResource(R.drawable.tool_wifi_off);
} else {
wifiManager.setWifiEnabled(true);
Tools_WiFi.setImageResource(R.drawable.tool_wifi_on);
}
You can try this:
startActivityForResult(new Intent(Settings.ACTION_WIFI_SETTINGS), 0);
Hope it helps you.
I'm encountering this issue on my Samsung devices running KitKat. It doesn't seem to affect my Nexus devices running Lollipop.
I use this code to switch between Wi-Fi networks:
private void switchToNetwork(String ssid) {
WifiConfiguration configuration = new WifiConfiguration();
configuration.SSID = String.format(Locale.US, "\"%s\"", ssid);
// ... other configuration changes such as password and cipher
manager.disconnect();
manager.enableNetwork(params[0].configuration.networkId, true);
manager.reconnect();
}
However, I'm noticing that if I was previously connected to a Wi-Fi network before running this code, these Samsung devices change the state of that previous network to "Turned off." This happens because the second parameter in my call to enableNetwork, disableOthers, was set to true.
The "turned off" state means that the network will not automatically be switched-to if the other network turns off. For my purposes, I'm manually switching back to the network, but there are certain cases (e.g. an app crash) where it might be desirable for the network to be switched automatically.
When I change disableOthers to false, however, it doesn't always change me to the SSID I asked for in switchToNetwork(). It'll often stay on the previous SSID.
So: How do I guarantee that I'm switching to a new network without disabling the previous network?
One way of doing it is by caching the current Network ID.
You can store the currently connected network ID using getConnectionInfo.getNetworkId API and store it temporarily.
Now connect to your desired network and when you are done connect back to previous network using ID you stored before.
Is it considered best practice or more acceptable or, for any other reason, preferable, to initialise WiFI on an Android device via a programmatic approach:
WifiManager oWiFIMgr = (WifiManager) getApplicationContext().getSystemService(Context.WIFI_SERVICE);
oWiFIMgr .setWifiEnabled(true);
vs. launching the WiFI settings activity?
startActivity(new Intent(Settings.ACTION_WIFI_SETTINGS));
I guess it depends on the purpose of your app.
If you are going to create a home screen widget like wifi toggle or something similar, the user would be pleased if just touching the widget turns On the wifi, but if its some app that just require the wifi access to do certain task, it would be better to open the wifi page allowing the user to take his own choice.
What really matters is you should design your app in such a way that once the purpose of wifi is done, it should be turned off again.
PS: No matter which choice you make in your app design the permissions of that app is going to be displayed during the installation.
So just keep in mind for the user friendliness of your app and its performance.
In Android Q (Android 10) you can't enable/disable wifi programmatically anymore. So you don't have a choice, you need to use Settings Panel to toggle wifi connectivity:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
val panelIntent = Intent(Settings.Panel.ACTION_INTERNET_CONNECTIVITY)
startActivityForResult(panelIntent, 0)
}
Always let user take those kind of decisions, enable WiFi, GPS .. stuff like that .. new Google maps app does that .. i think it's best ..