I have been working on an android application.For one of the feature, I need the active network information(i.e. whether it's connected with Wi-Fi or mobile data). I got this piece of code from the internet.
NetworkInfo activeNetworkInfo = context.getSystemService(ConnectivityManager.class).getActiveNetworkInfo();
But this API is deprecated and I don't want to use any deprecated API.
After some more googling, I found that we should use ConnectivityManager.NetworkCallback instead. But I am not able to get an example of it. How can I use this?. Please help me if anyone having an idea about using ConnectivityManager.NetworkCallback
Check out this function in Kotlin
fun networkConnection(): Boolean {
var networkAvailable = false
val connectivityManager: ConnectivityManager = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
val network: Network = connectivityManager.activeNetwork!!
val networkCapabilities: NetworkCapabilities = connectivityManager.getNetworkCapabilities(network)!!
if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR)) {
networkAvailable = true
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
networkAvailable = true
} else if (networkCapabilities.hasTransport(NetworkCapabilities.TRANSPORT_VPN)) {
networkAvailable = true
}
return networkAvailable
}
try the following code:
private void registerNetworkCallback(Context context) {
final ConnectivityManager manager =
(ConnectivityManager) context.getSystemService(CONNECTIVITY_SERVICE);
manager.registerNetworkCallback(
new NetworkRequest.Builder()
.addTransportType(NetworkCapabilities.TRANSPORT_WIFI)
.addTransportType(NetworkCapabilities.TRANSPORT_ETHERNET)
.build(),
new NetworkCallback() {
#Override
public void onAvailable(Network network) {
/** here to get the available info
this ternary operation is not quite true, because non-metered
doesn't yet mean, that it's wifi
nevertheless, for simplicity let's assume that's true
*/
Log.i("vvv", "connected to " + (manager.isActiveNetworkMetered() ? "LTE" : "WIFI"));
}
#Override
public void onCapabilitiesChanged(Network network,
NetworkCapabilities networkCapabilities){
/**here to get the change network info
Value is TRANSPORT_CELLULAR, TRANSPORT_WIFI,
TRANSPORT_BLUETOOTH, TRANSPORT_ETHERNET, TRANSPORT_VPN
*/
if(networkCapabilities.hasTransport("type")){
}
}
});
}
connectivityManager = (ConnectivityManager)
context.getSystemService(ConnectivityManager.class);
#RequiresApi(api = Build.VERSION_CODES.M)
private void getActiveNet() {
Network currentNetwork = connectivityManager.getActiveNetwork();
}
Note that "active network" is synonymous in android with "default network".
ConnectivityManager#getActiveNetworkInfo()
Returns details about the currently active default data network...
ConnectivityManager#registerDefaultNetworkCallback(NetworkCallback)
Registers to receive notifications about changes in the application's
default network...
Therefore using ConnectivityManager#registerDefaultNetworkCallback(NetworkCallback) you can listen for default (aka "active") network changes. Unfortunately, this only returns the Network object which does not have information regarding transport (Wi-Fi vs Cellular) in which case you'll need to make an additional call to ConnectivityManager#getNetworkCapabilities(Network) to get that info.
Here is an example:
final ConnectivityManager connectivityManager = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkCallback networkCallback = new NetworkCallback() {
#Override
void onAvailable(Network network) {
// Triggers when a default network is available.
NetworkCapabilities nc = connectivityManager.getNetworkCapabilities(network);
boolean isWifi = nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
boolean isCellular = nc.hasTransport(NetworkCapabilities. TRANSPORT_CELLULAR);
}
};
connectivityManager.registerDefaultNetworkCallback(networkCallback);
Related
One of the things android 10 is changing is that we cannot get READ_PHONE_STATE automatically,
And have to direct the user to manually give the permission by going to app info > permissions > phone > turn on.
is there any way to get network state (if the phone is on wifi / 3g, etc) on android 10 and above
Without directing the user to go to the application settings by himself and change the permission manually?
I was thinking to bypass the permission asking with
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkCapabilities caps = cm.getNetworkCapabilities(cm.getActivityNetwork());
boolean isMobile = caps.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR);
boolean isWifi = caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI);
would that be ok and then not needed to use the READ_PHONE_STATE permission ?
There is a class NetworkInfo it have a function
getTypeName() that return string value contain MOBILE or WIFI
I try to write function I hope it will be helpful for you :
/**
* #param mType : type of network connection "MOBILE" or "WIFI"
* #return : true of false
*/
public boolean isMyType(String mType) {
ConnectivityManager connectivityManager = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
//
if (activeNetworkInfo != null && activeNetworkInfo.isConnected()) {
return activeNetworkInfo.getTypeName().equals(mType);
} else {
// no internet connection
return false;
}
}
than you can call it :
boolean isMobile = isMyType("MOBILE");
boolean isWifi = isMyType("WIFI");
// for logcat debug
Log.i("typeNetwork", "is mobile :" + isMobile);
Log.i("typeNetwork", "is wifi :" + isWifi);
let me know if this works for you..
I am trying to detect if there are any active internet connections (WIFI or MOBILE INTERNET). The code is as follows:
private boolean haveNetwork() {
ConnectivityManager connMgr =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
boolean flag=false;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
for (Network network : connMgr.getAllNetworks()) {
NetworkInfo networkInfo = connMgr.getNetworkInfo(network);
if (networkInfo.getType() == ConnectivityManager.TYPE_WIFI) {
flag=true;
break;
} else if (networkInfo.getType() == ConnectivityManager.TYPE_MOBILE) {
flag=true;
break;
}
}
}
Log.d("flag", String.valueOf(flag)); //returns true even if there's no internet connection
return flag;
}
As the title says, my connection status always remains to be true, even if there is no internet connection
What you have currently will only tell you if there is either a mobile or Wi-Fi network tracked by ConnectivityManager, not whether you are connected to it or not.
Since you appear to be doing this synchronously, you want to use these two methods:
ConnectivityManager.getActiveNetwork()
ConnectivityManager.getNetworkCapabilities(Network network)
You can use this if you want to call ConnectivityManager synchronously by replacing your for loop.
Network activeNetwork = connMgr.getActiveNetwork();
if (null == activeNetwork) {
return false;
}
NetworkCapabilities nc = connMgr.getNetworkCapabilities(activeNetwork);
return nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET)
&& nc.hasCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
Use NetworkCapabilities as NetworkInfo is deprecated and check the getLinkDownstreamBandwidthKbps() is greater then 1kbps for 1g 32 kbps for at least 2g speed
This question might be a duplicate question, but i cant find proper solution.
I have chat app in which i set function for when remote android device on background mode it will get notification by FCM when new message will come(new node added in chatroom).
So
if remote device is in the foreground mode than it will get notification by app and its has definitely internet connectivity for this i can set message delivery successfully.
if remote device is in the background mode than it will get notification by FCM and its has definitely internet connectivity. for this i can also set message delivery successfully.
So how do i check that remote device is totally offline(no internet connection) or how to check FCM is not success to send notification ?
for example:
if(messegeReceiver(remote device) has no internet connectivity )
{
//here i want to change data in firebase//
}
else
{
//here i want to change data in firebase//
}
I have "Users" node in which every users set device_token while login the app.
You can device checking offline/online mode via set one param in your chat table. When user exit or minimize application then set states to 0 and maximum set to 1.Best way if possible you use firebase real-time database for online offline.
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
NetworkChangeReceiver receiver = new NetworkChangeReceiver();
regisenter code hereterReceiver(receiver, filter);
public static class NetworkChangeReceiver extends BroadcastReceiver {
public static boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in air plan mode it will be null
return (netInfo != null && netInfo.isConnected());
}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivity = (ConnectivityManager)
context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivity != null) {
NetworkInfo[] info = connectivity.getAllNetworkInfo();
if (info != null) {
for (int i = 0; i < info.length; i++) {
if (info[i].getState() == NetworkInfo.State.CONNECTED) {
if (!isConnected) {
relativelayout_connection.setVisibility(View.GONE);
isConnected = true;
return true;
}
} else {
relativelayout_connection.setVisibility(View.VISIBLE);
}
}
}
} else {
relativelayout_connection.setVisibility(View.GONE);
isConnected = false;
return false;
}
return isConnected;
}
#Override
public void onReceive(final Context context, final Intent intent) {
// isNetworkAvailable(context);
if (isOnline(context)) {
} else {
relativelayout_connection.setVisibility(View.VISIBLE);
}
}
}
FCM does not guarantee that the push notification gets delivered. It completely depends upon various factors like internet connection (as you mentioned), OEM behavior, Doze mode etc.
In your case, you are trying to send messages via FCM from one device to another and shown messages in the form notifications just like any other chat application.
The only problem here is that the FCM does not provide you with delivery parameters in response (image attached) that you are looking for. It only gives count for number of notifications that has been accepted by the gateway i.e. FCM (success) and the count for number of notifications that has been rejected by the gateway (failure). It also gives the reason for rejection (error) message like NotRegistered, MissingRegistrationToken, etc and you can refer this for the same.
My suggestion here would be to have a handshake message in place that acknowledges the delivery of the push notification from the other device. As soon as you receive the push notification send a handshake message via FCM and that gets received by the first device which understands that the push notification has been delivered. In case if the device does not receive the handshake you assume that the message is yet to be delivered.
I hope this really helps you and please up vote the answer or accept the answer if you feel like doing so.
I would like to know if on android it is possible to get a broadcast once the user clicks the wifi disconnect button to run a method BEFORE the device disconnects from the internet , I am already using a broadcast receiver to catch network change but it is executed after internet is disconnected I am using the code below :
public class InternetReceiver extends BroadcastReceiver {
#Override
public void onReceive(final Context context, final Intent intent) {
if (isNetworkAvailable(context) && !isMyServiceRunning(MessagingService.class,context)){
Intent i = new Intent(context,MessagingService.class);
context.startService(i);
Log.e("service started ","true");
}
}
private boolean isMyServiceRunning(Class<?> serviceClass, Context c) {
ActivityManager manager = (ActivityManager) c.getSystemService(Context.ACTIVITY_SERVICE);
for (ActivityManager.RunningServiceInfo service : manager.getRunningServices(Integer.MAX_VALUE)) {
if (serviceClass.getName().equals(service.service.getClassName())) {
return true;
}
}
return false;
}
public boolean isNetworkAvailable(Context c) {
ConnectivityManager connectivityManager
= (ConnectivityManager) c.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
}
I am using the code above to run the service once internet is connected but it is just an example
Edit: I assume that you want to react to the user's click on the wifi disconnect button
You could check the state of the wifi connection by using Android's WifiManager which offers some possibilities to get information about your wifi environment and connection.
Connectivity can be established or torn down, and dynamic information about the state of the network can be queried.
Source: http://developer.android.com/reference/android/net/wifi/WifiManager.html
Have a look at the following. I guess it'll be helpful to you.
WIFI_STATE_CHANGED_ACTION Broadcast intent action indicating that Wi-Fi has been enabled, disabled, enabling, disabling, or unknown.
int WIFI_STATE_DISABLED Wi-Fi is disabled.
int WIFI_STATE_DISABLING Wi-Fi is currently being disabled.
is there a possiblity to explicitely use the wifi connection for doing Http Url requests?
In fact i just need to know if an internet connection (access to google.com for example) is possible via wifi.
(not via 2g / 3g / ..)
As far as I know, no. This is all abstracted from us by the platform.
But you can check to see if WIFI is available:
ConnectivityManager conMan = (ConnectivityManager)
getSystemService(Context.CONNECTIVITY_SERVICE);
if(conMan!=null){
try {
NetworkInfo[] networkInfos = conMan.getAllNetworkInfo();
for(NetworkInfo ni : networkInfos){
if(ni.isAvailable() && ni.isConnected() && ni.getTypeName().equals("WIFI")){
result = true;
break;
}
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
You may find this useful:
public class ConnectivityHelper {
public static boolean isWiFiNetworkConnected(Context context) {
return getWiFiNetworkInfo(context).isConnected();
}
private static NetworkInfo getWiFiNetworkInfo(Context context) {
return getConnectivityManager(context).getNetworkInfo(ConnectivityManager.TYPE_WIFI);
}
private static ConnectivityManager getConnectivityManager(Context context) {
return (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
}
}
I havent done this, so i'm not sure, but I found this looking through the documentation.
public boolean wifiAvailable() {
ConnectivityManager connMgr = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo info = connMgr.getActiveNetworkInfo();
if((info.isAvailable() && info.isConnected() && (info.getType()==ConnectivityManager.TYPE_WIFI))) return true;
return false;
}
Where you are going to fire a request, evaluate this method, if it returns true the system will automatically use WiFi, android will always use wifi over 3G/2G when available AFAIK.