Check internet connection at runtime - android

Good Day, I have an app with 2 activities: main and details page.
When there is internet connection user can navigate from main to details page. When no internet connection he can`t do that.
The problem is: When I`m in details page and switch off wifi I would like to finish this activity, how can I implement this functionality?
I have check in main activity class something like that:
private boolean isNetworkAvailable() {
ConnectivityManager connectivityManager
= (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
It`s works fine when I start the app with internet or without that, but when I switch off the wifi at runtime it doesn`t works.
Anyway, thank you!

You have to Monitor for Changes in Connectivity
The ConnectivityManager broadcasts the CONNECTIVITY_ACTION ("android.net.conn.CONNECTIVITY_CHANGE") action whenever the connectivity details have changed. You can register a broadcast receiver in your manifest to listen for these changes and resume (or suspend) your background updates accordingly.
Whenever internet state changes, your broadcast receiver will be called, and if the internet disconnects then you can handle it accordingly.
public class InternetReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (isConnected())
Log.d("NetReceiver", "Internet is connected");
else
Log.d("NetReceiver", "Internet is not connected");
}
};
This method checks for connections from all internet sources, including 3g
public boolean isConnected() {
Runtime runtime = Runtime.getRuntime();
try {
Process ipProcess = runtime.exec("/system/bin/ping -c 1 8.8.8.8");
int exitValue = ipProcess.waitFor();
return (exitValue == 0);
} catch (IOException e) { Log.e("ERROR", "IOException",e); }
catch (InterruptedException e) { Log.e("ERROR", "InterruptedException",e); }
return false;
}
In your manifest file add this:
<receiver android:name=".InternetReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
Here is the Source

You may want to implement a broadcast receiver listening to the Event of connection termination, so that you can immediately take action and finish the detail activity.
this link may help.

Try this:
Create a helper method that checks internet state or connection
Create a Thread or Runnable
Inside the run() of the Thread or Runnable, call the helper method
In onCreate() of your MainActivity, start the Thread or Runnable to run every n sec/min

Related

Need to create a background service that uploads data when internet is available

I have a personalized feed, with an option for liking comments. When a user hits like button, the app check internet connection, if internet is available api hits gets successful, if internet is down the comment_id is stored in db. I want that when internet resumes, api call should be made with these comment_id.
I Tried broadcast receiver but on changing internet connection broadcast receiver doesn't initialize or wake up.
This is connectivityReceiver code.
public class ConnectivityReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent arg1) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork != null
&& activeNetwork.isConnectedOrConnecting();
Log.d("LLLL",""+isConnected);
}
}
This is my manifest file.
<receiver
android:name=".backgroundServices.ConnectivityReceiver"
android:enabled="true">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
To check the internet you can use this function.
public boolean hasInternet() {
ConnectivityManager connectivity = (ConnectivityManager) 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) {
return true;
}
}
return false;}
This function will return true if internet is working.
Make a timer to check internet again and again once you get the true from the function perform your connection.
You can use WorkManager !
The WorkManager API makes it easy to specify deferrable, asynchronous tasks and when they should run. These APIs let you create a task and hand it off to WorkManager to run immediately or at an appropriate time. For example, an app might need to download new resources from the network from time to time. Using these classes, you can set up a task, choose appropriate circumstances for it to run (like "only while device is charging and online"), and hand it off to WorkManager to run when the conditions are met. The task is still guaranteed to run, even if your app is force-quit or the device is rebooted.
WorkManager is intended for tasks that require a guarantee that the
system will run them even if the app exits, like uploading app data to
a server. It is not intended for in-process background work that can
safely be terminated if the app process goes away; for situations like
that, we recommend using
you even can set condition's like if there was networkConnection to work Manager and your task will be executed under that condition
here is the document :
https://developer.android.com/topic/libraries/architecture/workmanager#java
You need to use the JobScheduler for this purpose. Whenever you have pending things to do set the JobScheduler and then it will execute when specified conditions are met. Conditions like
val jobScheduler = getSystemService(Context.JOB_SCHEDULER_SERVICE) as JobScheduler
jobScheduler.schedule(JobInfo.Builder(111,
ComponentName(this, UploadLikesJobService::class.java))
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
.setBackoffCriteria(JobInfo.DEFAULT_INITIAL_BACKOFF_MILLIS, JobInfo.BACKOFF_POLICY_LINEAR)
.setPersisted(true)
.build())
This is the UploadLikesJobService class :
/**
* Created by nileshdeokar on 09/02/2018.
*/
class UploadLikesJobService : JobService() {
override fun onStartJob(jobParameters: JobParameters?): Boolean {
// Call webservice here and pass the result true or false to jobFinished
// OS will do the reschedule for you if you pass second parameter true in jobFinished()
jobFinished(jobParameters, false)
return true
}
override fun onStopJob(jobParameters: JobParameters?): Boolean {
return true
}
}

Race condition when detecting connectivity status change in Android

I need to monitor and determine connectivity status changes in my Android app. For that, I have registered my class as a broadcast receiver:
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
context.registerReceiver(this, filter);
Now, for determining the connectivity status, you can do the following:
#Override
public void onReceive(Context context, Intent intent) {
if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
return;
}
NetworkInfo aNetworkInfo =
intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (aNetworkInfo == null) {
return;
}
boolean isConnected = aNetworkInfo.isConnected();
int networkType = aNetworkInfo.getType();
// by using isConnected & networkType, get the new connectivity status..
}
The issue is that ConnectivityManager.EXTRA_NETWORK_INFO is deprecated. Now, you are suggested to use the CONNECTIVITY_SERVICE with getActiveNetworkInfo(), something like that:
#Override
public void onReceive(Context context, Intent intent) {
if (!ConnectivityManager.CONNECTIVITY_ACTION.equals(intent.getAction())) {
return;
}
ConnectivityManager connManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connManager == null) {
return;
}
NetworkInfo activeNetworkInfo = connManager.getActiveNetworkInfo();
boolean isConnected =
(activeNetworkInfo != null) && activeNetworkInfo.isConnected();
int networkType =
(activeNetworkInfo != null) ? activeNetworkInfo.getType() : -1;
// by using isConnected & networkType, get the new connectivity status..
}
This raises the following question:
In the 2nd implementation, when using the CONNECTIVITY_SERVICE and not the EXTRA_NETWORK_INFO:
Is there a chance for a race condition? As the onReceive is called asynchronously, when getting the network info from the connectivity service, may the connectivity state be different from the network info in the intent (as the connectivity might change in the meanwhile)?
Meaning, when using the intent, I am sure that the network info includes the data that triggered the onReceive, but when using the service - the network info might be different...?
If so, what's the best way to get the info that triggered the onReceive?
Also, if the only way to do so is to keep using the intent - doesn't that make 2 sources of truth? (one from the Connectivity Service, and one from the sent intent...)
UPDATE:
An example of the possible race condition:
Someone connected to WiFi and immediately disconnected from WiFi. This will result in 2 intents to be sent (one for connected to WiFi, and one for disconnecting from WiFi. More intents are actually sent, but I will focus on these 2). The possible race condition I am asking about is that: when we get the first intent (WiFi connected), the intent extra EXTRA_NETWORK_INFO will result in isConnected = true and networkType = TYPE_WIFI. But, is it possible that when I get the data from the Connectivity Service, as the onReceive is called asynchronously, the WiFi has already disconnected, resulting in isConnected = false and networkType = TYPE_WIFI while the intent still holds the right values for this call of onReceive? Or this will always happen fast enough so you get the right values from the Connectivity Service in the onReceive.. ?
My solution was sending a broadcast everytime connection changes adding an extra if the status of connection is up or down, hope it helps:
public class ConnectivityChangeReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.i(context.getClass().getName(), " Changed connection ");
context.sendBroadcast(new Intent(MyApplication.ACTION_CONNECTION_CHANGED)
.putExtra(MyApplication.INTENT_EXTRA_CONNECTION_STATUS,NetWorkUtils.isNetworkAvailable(context)));
}}
public static boolean isNetworkAvailable(Context context) {
ConnectivityManager cm =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
return activeNetwork != null &&
activeNetwork.isConnectedOrConnecting();
}
Android manifest:
<receiver android:name=".ConnectivityChangeReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>

How To Connect my android Application To Internet Automatically whenever network found

My android application is based on network connection i.e WIFI/Mobile Network. It works fine when my mobile is connected to internet but when internet connection disconnected it stops working (obesely) and it still stop working after my mobile again connected to internet.
I wish to (re)start my application automatically whenever internet connection is (re)established.
You can check the network state using broadcast receiver. Whenever the network is available, you can start your application.
First, create a background service and start your service when the device boots up. Now, in this service, register a broadcast receiver and monitor the network state. If the network is available, you can start your application; and if unavailable, you can close it.
Please refer to the code below for broadcast receiver.
public class BroadCastSampleActivity extends Activity
{
/** Called when the activity is first created. */
#Override
protected void onCreate(Bundle savedInstanceState)
{
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
this.registerReceiver(this.mConnReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}
private BroadcastReceiver mConnReceiver = new BroadcastReceiver()
{
public void onReceive(Context context, Intent intent)
{
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
String reason = intent.getStringExtra(ConnectivityManager.EXTRA_REASON);
boolean isFailover = intent.getBooleanExtra(ConnectivityManager.EXTRA_IS_FAILOVER, false);
NetworkInfo currentNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
NetworkInfo otherNetworkInfo = (NetworkInfo) intent.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
if(currentNetworkInfo.isConnected())
{
Toast.makeText(getApplicationContext(), "Connected", Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Not Connected", Toast.LENGTH_LONG).show();
}
}
};
}
I think you must need to checking continue for network connections, that means you need to check for internet connection in background tasks. Android Services is better option for that, create one Service and start it when your app starts, inside that just do one code and that is for checking Internet Connectivity, when it lost, do some task and when it found you can do whatever you want. So I suggest you to use services and get your task done.
Here are some links to refer.
http://www.tutorialspoint.com/android/android_services.htm
http://www.vogella.com/tutorials/AndroidServices/article.html
I think you should create a spread thread or service in background for checking network connection after some interval . use following code in thread or service whatever you want to create .
NetworkInfo i = conMgr.getActiveNetworkInfo();
if (i == null)
return false;
if (!i.isConnected())
return false;
if (!i.isAvailable())
return false;
return true;

Android network state change detection takes time

I am trying to detect network state change in my android app. I followed the answer in that question : Check INTENT internet connection
This works, but it takes time for broadcastreceiver to detect changes. When i turn wifi on or off, about 10 seconds later the onReceive() method is called. Why is that taking so much time? Can anyone help?
Thanks
Here is my code:
public class NetworkStateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.d("app", "Network connectivity change");
if (intent.getExtras() != null) {
NetworkInfo ni = (NetworkInfo) intent.getExtras().get(
ConnectivityManager.EXTRA_NETWORK_INFO);
if (ni != null && ni.getState() == NetworkInfo.State.CONNECTED) {
Log.i("app", "Network " + ni.getTypeName() + " connected");
Toast.makeText(context, "CONNECTED", Toast.LENGTH_LONG).show();
} else if (intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, Boolean.FALSE)) {
Toast.makeText(context, "DISCONNECTED", Toast.LENGTH_LONG).show();
Log.d("app", "There's no network connectivity");
}
}
}
}
and in my Manifest's application tag:
<receiver android:name="com.mypackage.NetworkStateReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
I found the solution.
Instead of extending BroadcastReceiver class and creating NetworkStateChangeReceiver, i created a broadcastreceiver on my activity and registered it there. Now it works and onReceive() method is triggered immediately.
public static boolean isInternetAvailable(Context context) {
boolean isConnection = false;
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connectivityManager != null) {
NetworkInfo[] info = connectivityManager.getAllNetworkInfo();
if (info != null) {
for (int index = 0; index < info.length; index++) {
if (info[index].getState() == NetworkInfo.State.CONNECTED) {
isConnection = true;
break;
}
}
}
}
return isConnection;
}
I have similar code within my app to detect if there's a connection present, and prompt the user of connection state changes.
Within my application, it receives the connection change for disconnect within a second, however when you go to turn the WiFi on it takes around ~7 seconds before my app receives the change in connection state.
However I receive the state change exactly the same time Android makes the toast saying "Connected to Wi-Fi network [your network name]".
Chances are you'd be receiving the change simultaneously from when it connects to a network, and not from when you pushed the Wi-Fi toggle to turn it on.
Is there a particular reason you need that instant feedback from when the toggle is pressed?

Can android differentiate between a lost internet connection and no internet connect?

When I press a button on my app to open an image it shows a progress bar of the image being downloaded and then it opens. If there is no wifi connection it displays an error message saying "No wifi". I have used the code below to check for a wifi connection:
ConnectivityManager cm =
(ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetwork = cm.getActiveNetworkInfo();
boolean isConnected = activeNetwork.isConnectedOrConnecting();
boolean isWiFi = activeNetwork.getType() == ConnectivityManager.TYPE_WIFI;
I want to implement an error message that is displayed when the connection is lost. So if you click on the image and while its downloading you turn off the wifi then it displays a message saying "wifi disconnected".
Is this possible? Whether a connection is lost or there is no wifi all you are doing is checking if there is a connection available which is the same thing
You need to use a BroadcastReceiver that will be triggered when the connectivity status for Wi-Fi has changed.
Set following things before registering BroadcastReceiver:
private class ConnectionChangeReceiver extends BroadcastReceiver {
public void onReceive( Context context, Intent intent ) {
Log.d(tag, "Inside Broadcast Reciever");
CheckWifiStatus();
}
}
private void RegisterWifiWatcher()
{
if(wifiWatcher == null)
wifiWatcher = new ConnectionChangeReceiver();
final IntentFilter intentFilter= new IntentFilter();
intentFilter.addAction("android.net.wifi.WIFI_STATE_CHANGED");
intentFilter.addAction("android.net.wifi.STATE_CHANGE");
registerReceiver(wifiWatcher, intentFilter);
}
WIFI_STATE_CHANGED :
Broadcast intent action indicating that Wi-Fi has been enabled, disabled, enabling, disabling, or unknown.
Permissions in Manifest :
<user-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<user-permission android:name="android.permission.ACCESS_WIFI_STATE" />
NOTE:
The broadcast intents that we receive for the different WiFi states have extras along with them that you can access to determine the different states of the WiFi connection.
Sure its possible. Adding to the above answer another option:
You can check with your code if wifi is available first.
Then start downloading the image and if you catch an exception during that time, toast the message wi-fi disconnected.

Categories

Resources