I'm making a app that is displaying the available wireless networks and a user can choose one network and connect to it.
I have a broadcast receiver and I receive the status of the connection :connected , when the connection is done , but I would like also to display more info to the user like , Authenticating, Obtaining IP address , cause now I only know when network is connected but noting till then.
Any idea how to do this?
Thanks you very much
Fine-grained connection state is available from the NetworkInfo object - getDetailedState
NetworkInfo ni = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
DetailedState state = ni.getDetailedState();
You also need to register your broadcast receiver to receive state change events from WifiManager
IntentFilter filter =
new IntentFilter(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.SUPPLICANT_CONNECTION_CHANGE_ACTION);
filter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
Related
is there a way to get details about disconnected network using android broadcast receiver or networkcallback ?
EXTRA_NETWORK_INFO, getNetworkInfo(NetworkType) are deprecated.
getAllNetworks() Returns an array of all Network currently tracked by the framework but not the disconnected network.
yes, first register Broadcast receiver like this:
final IntentFilter intentFilter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(receiver, intentFilter);
when receiver is:
new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// this part is trigered when there is some network changes, do checks here
}
};
also don't forget to unregister it.
Yes. NetworkInfo class is deprecated from API Level 29 . Instead, the ConnectivityManager class can be helpful here. It helps in monitoring the network connections, and notify the application when network connectivity changes or when connectivity to a network is lost. It also facilitates by allowing applications to know the state of the available networks and allows applications to request and select networks for their data traffic.
However, the below list of methods are deprecated in ConnectvityManager class:
getNetworkInfo returns connection status about a particular
network type.
getAllNetworkInfo returns connection status information of all network types supported by device.
getActiveNetworkInfo returns currently active default data network
network.
The ConnectivityManager.NetworkCallback is currently actively available to determine the network change status. This base class for NetworkRequest callbacks is used for notifications about network changes which can be extended by applications that are in need of network change notifications.
The below list of methods are supported :
getAllNetworks returns an array of all networks currently
tracked.
getActiveNetwork returns a network object
of currently active default data network.
The NetworkCapabilities class shall help in representation of the capabilities of an active network.
In general, whenever the system invokes onAvailable(Network), it shall pass the network that is available and whenever the system invokes onLost(Network), it shall pass the network that was lost which refers to the particular network that was lost (disconnected) and the argument tells you which network got lost (disconnected).
The onCapabilitiesChanged gets invoked immediately after onAvailable and this can help in determining capabilities of the available network like whether it is cellular network or a WiFi network by querying the NetworkCapabilities with hasTransport() and the appropriate transport constant like TRANSPORT_CELLULAR or TRANSPORT_WIFI (network of interest).
The below snippet takes into consideration the above information and helps in determining whether you have cellular or wifi network connectivity which in turn enables one to confirm whether the disconnected network(lost) is indeed not in use.
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.M) {
Network network = connectivityManager.getActiveNetwork();
NetworkCapabilities capabilities = connectivityManager.getNetworkCapabilities(network);
return capabilities != null && (capabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR) || capabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI));
}
I am trying to connect to a WiFi network using WiFiManager. Here is the code I use to do so :
WifiManager manager = [...];
WifiConfiguration config = new WifiConfiguration();
manager.setWifiEnabled(true);
//Set SSID, PSK, etc...
[...]
//Connect to the network
int netId = manager.addNetwork(config);
if (netId == -1)
{
Toast.makeText(this, "Invalid PSK", Toast.LENGTH_LONG).show();
return;
}
manager.enableNetwork(netId, true);
manager.saveConfiguration();
Beforehand, I registered a BroadcastReceiver for the WifiManager.NETWORK_STATE_CHANGED_ACTION action. I'm trying to detect when the connection succeeds or fails (for various reasons including authentication) by checking the DetailedState of the given NetworkInfo.
Everything works when the connection succeeds, but for some reason my receiver isn't "executed" when the connection fails. The network is added to the device's list, I can see it by going into WiFi Settings, but it does not try to connect (or it does try to connect but doesn't notify my receiver).
Any clue ? Thanks !
I finally managed to achieve what I wanted.
To detect that the connection succeeded, register the WifiManager.NETWORK_STATE_CHANGED_ACTION broadcast intent and check for the NetworkInfo.DetailedState.OBTAINING_IPADDR detailed state (for WiFi obviously).
To detect that the connection failed, register the WifiManager.SUPPLICANT_STATE_CHANGED_ACTION broadcast intent and check for any WifiManager.EXTRA_SUPPLICANT_ERROR integer extra (typically WifiManager.ERROR_AUTHENTICATING). You may need to gain access for Android hidden API to achieve that.
The enableNetwork method return true if the connection status is success.
This works fine on success but is not the best method to check the failed status (return true if the connection failed after the first step authentication).
I think that you can check in the networkInfo object the actual connected network to see if the request is ok:
ConnectivityManager connectivityManager = (ConnectivityManager) getApplicationContext().getSystemService(CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
I want my app to "do something" when a wifi is nearby. But the phone doesn't connect to it. I don't have the password. For example, if the wifi University0001 is reachable I would like to silent my phone but I don't have the password to University0001.
Is there a way to have a broadcast receiver that triggers when new (not connected) ssid are around?
I would not like to have a "timer" to periodically check new SSIDs. I am asking for a receiver to trigger when new networks are around and maybe then check for the one I want.
I hope to be clear.
Thanks
Is there a way to have a broadcast receiver that triggers when new (not connected) ssid are around?
yes there is.
if your WIFI is on, and you are not currently connected to a WIFI network - the system periodically scan for available access points. when it will detect new visible access point it will send the SCAN_RESULTS_AVAILABLE_ACTION broadcast.
you can register to that broadcast, and when it receives - get from WifiManager the scan results:
#Override
public void onReceive(Context context, Intent intent) {
WifiManager wifiManager (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
List<ScanResult> scanResults = wifiManager.getScanResults();
}
if you are already connected to a WIFI network - then you won't have any choice but to trigger the scan yourself periodically...
be careful:
performing from this receiver long operations (such network requests..) any time it receives is a bad approach - you'll drain the users battery very fast.
Actually In my app I have to show the toggle button on/off if mobile data packect on/off.
But there is a problem my local boradcast can't listen mobile data packet on/off event if my WiFi is already on. Actually as I understand If my WiFi on then mobile data packet enable and disable event never affect connectivity status. Thats why my some intent filter never works.
android.net.conn.CONNECTIVITY_CHANGE
I need a intent filter which is similer to android.net.wifi.WIFI_STATE_CHANGED so that whenever mobile data packet on or off event fire my broadcast can listen it easily. And I can change my widget.
I dont know of any intent-filter that we could receive when the mobile data is turned on or off but the following code is to determine whether mobile data is turn on or off.
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(CONNECTIVITY_SERVICE);
if(connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE).isConnected())
//mobile data is on
else
//mobile data is off
What you can do is write a service of your own that will constantly run the above code. When the mobile data is on, you can send a broadcast to your activity telling the same. Same goes when the mobile data is off.
Edit1:-
This works even if wi-fi is connected.
Edit2:- Don't forget to add ACCESS_NETWORK_STATE permission while using this
I think in your app,you need to import WifiManager Class.
WifiManagerclass provides the primary API for managing all aspects of Wi-Fi connectivity. Get an instance of this class by calling
Context.getSystemService(Context.WIFI_SERVICE)
I'm working on an app that logins on a public wifi network. I've got the login working by doing a http post to the authentication server.
My next step is making the app do the http post automatically when there's a new wifi connection, checking that we are connected to the correct ssid.
My question is, which is the best way of doing this? Is the best way to create a service and registering to a broadcastreceiver?
Thanks for your help
The way I do it is that i have a broadcastreceiver that listens to android.net.conn.CONNECTIVITY_CHANGE intents. In that broadcast receiver you can check what kind of connection is made by polling the ConnectivityManager:
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
boolean hasWifi = cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI) != null && cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isAvailable() && cm.getNetworkInfo(ConnectivityManager.TYPE_WIFI).isConnected();
And then start the service doing the post to the auth server.
Alternatively you could indeed let the service listen to android.net.conn.CONNECTIVITY_CHANGE intents and do the wifi check there.