Android Internet Connection checker OUTSIDE the app - java

My app needs to do something whenever the internet is connected and vice-versa. However, I need to do this OUTSIDE my application. There are a lot of ideas and help here on stackoverflow but it is always WITHIN the application. I know that the AlarmManager works outside the application but it would just be draining the battery if I try to check if there's internet connection every 5 minutes. What I wanted is to check the connection outside the app to download something.
I also found out that Intent Service can work outside the application as well. I have tried to put this inside the Wakeful Broadcast Receiver. However, it is still not being called.
Can someone out there help me? Thanks!
Here's my Wakeful Broadcast Receiver
public class ConnectivityOutsideAppReceiver extends WakefulBroadcastReceiver {
private static final String LOG_TAG = ConnectivityOutsideAppReceiver.class.getSimpleName();
private ConnectivityManager connectivityManager;
private static boolean connection = false;
#Override
public void onReceive(Context context, Intent intent){
ComponentName comp = new ComponentName(context.getPackageName(),
ConnectivityOutsideAppService.class.getName());
// Start the service, keeping the device awake while it is
// launching.
startWakefulService(context, (intent.setComponent(comp)
));
}
}
This is the Intent Service
public class ConnectivityOutsideAppService extends IntentService {
private static final String LOG_TAG = ConnectivityOutsideAppService.class.getSimpleName();
private ConnectivityManager connectivityManager;
private static boolean connection = false;
private Context context;
public ConnectivityOutsideAppService() {
super(ConnectivityOutsideAppService.class.getSimpleName());
this.context = context;
}
#Override
protected void onHandleIntent(Intent intent) {
connectivityManager =
(ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
checkConnectionOnDemand();
Log.e(LOG_TAG, " ## onHandleIntent##");
if (connection == true
&& intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
false)) {
Log.e(LOG_TAG, " ## connection == true ##");
connection = false;
} else if (connection == false
&& !intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY,
false)) {
Log.e(LOG_TAG, " ## connection == false ##");
connection = true;
}
ConnectivityOutsideAppReceiver.completeWakefulIntent(intent);
}
public static boolean hasConnection() {
return connection;
}
private void checkConnectionOnDemand() {
Log.e(LOG_TAG, " ## checkConnectionOnDemand ##");
final NetworkInfo info = connectivityManager.getActiveNetworkInfo();
if (info == null || info.getState() != NetworkInfo.State.CONNECTED) {
if (connection == true) {
Log.e(LOG_TAG, " ## connection == true ##");
connection = false;
}
} else {
if (connection == false) {
Log.e(LOG_TAG, " ## connection == false ##");
connection = true;
}
}
}
}
This is my Android Manifest
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<service
android:name="com.timetrackermobilelog.BusinessServices.ConnectivityOutsideAppService"
android:exported="false"/>
<receiver android:name="com.timetrackermobilelog.Utilities.ConnectivityOutsideAppService"
android:enabled="true"
android:process=":remote">
<intent-filter android:priority="1000" >
<action android:name="com.timetrackermobilelog.Utilities.ConnectivityOutsideAppService" />
<category android:name="com.Utilities" />
</intent-filter>
</receiver>
I have tried registering the receiver inside the Activity but it doesn't work as well.
IntentFilter intentFilter = new IntentFilter("com.pointwest.timetrackermobilelog.Utilities.ConnectivityOutsideAppReceiver");
ConnectivityOutsideAppReceiver connectivityOutsideAppReceiver = new ConnectivityOutsideAppReceiver();
registerReceiver(connectivityOutsideAppReceiver, intentFilter);
Is there anything that I missed?

Thanks to #Mike M. in giving the answer with just a few lines of changes.
In Android Manifest, change it to :
<intent-filter android:priority="1000" >
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
And onHandleIntent of the Service, change it to :
connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);

Related

what is the best way to check Internet connection continuously in android

I am developing an application. In that one screen check Internet connection, immediately after onCreate() method. If network connection is good i am calling one AsyncTask class for load countries list and show it on screen in spinnerView. If there is no network connection i am showing Toast Message to User and call check_Network(AsyncTask). In this class protected Long doInBackground(URL... params) method i'm checking Network connected or not if connected call countries AsyncTask otherwise again i am calling check_Network(AsyncTask). this process repeat until network is connected. my problem is It is correct way for Check Network Repeatedly. please suggested me. sorry i am poor in english please understand.blow i am showing my code
if (CheckNetwork.isOnline(this)) {
try {
new CountryProcess().execute();
} catch (Exception e) {
e.printStackTrace();
}
} else {
Toast.makeText(
getApplicationContext(),
getString(R.string.network_connection_fail)
+ "!", Toast.LENGTH_LONG).show();
new NetWork_connectivity().execute();
}
//.......................//
class NetWork_connectivity extends AsyncTask<URL, Integer,Long>
{
#Override
protected Long doInBackground(URL... params)
{
if (CheckNetwork.isOnline(MainActivity.this)) {
new CountryProcess().execute();
}else
{
new NetWork_connectivity().execute();
}
return null;
}
}
Add below code in manifest, for adding receiver with connectivity change intent
<receiver android:name=".NetworkStateReceiver">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
And at receiver side, get extras associated with intent and check for status. So whenever there is change in network status, you will be notified then perform your task accordingly.
public class NetworkStateReceiver extends BroadcastReceiver {
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent.getExtras()!=null) {
NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
//connected
}
}
if(intent.getExtras().getBoolean(ConnectivityManager.EXTRA_NO_CONNECTIVITY,Boolean.FALSE)) {
//not connected
}
}
}
For your case, you would like to add permission in manifest and register receiver in your activity.
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(networkReceiver, filter);
Make sure to unregister it as well before leaving activity with
unregisterReceiver(networkReceiver);
private BroadcastReceiver networkReceiver = new BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
super.onReceive(context, intent);
if(intent.getExtras()!=null) {
NetworkInfo ni=(NetworkInfo) intent.getExtras().get(ConnectivityManager.EXTRA_NETWORK_INFO);
if(ni!=null && ni.getState()==NetworkInfo.State.CONNECTED) {
//connected
}
}
//not connected
}
}
And based upon your requirement that you requires connected status only one time. First check for connectivity and if not connected then only register receiver.
public boolean isNetworkConnected() {
ConnectivityManager cm =
(ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnectedOrConnecting()) {
return true;
}
return false;
}
To access internet we need INTERNET Permission
To detect network status we need ACCESS_NETWORK_STATE Permission
Add these lines in your AndroidManifest.xml:
<!-- Internet Permissions -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Network State Permissions -->
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
Create this method in your java class:
public boolean isConnectingToInternet(){
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)
{
return true;
}
}
return false;
}
When ever you want to check Internet Status in your application call isConnectingToInternet() function and it will return true or false
ConnectionDetector cd = new ConnectionDetector(getApplicationContext());
Boolean isInternetPresent = cd.isConnectingToInternet(); // true or false

Android check WIFI status (disconnected or user changed WIFI) How to FLAG it?

I is there a way to Flag if a WIFI connection got disconnected/ dropped off OR if the user actually changed the WIFI network ?
I need my app to do :
Connect to a WIFI XYZ, if XYZ get disconnect (FLAG 1) or dropped off Then reconnect to XYZ.
But is the user change to another wifi BTOpen (FLAG 2) then allow the connect and Stop my service.
If user connect to XYZ again then start the loop again.
What I got so far is :
<!-- WIFI Receiver -->
<receiver android:name=".ReceiverWifi" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<service android:name=".ServiceWifiMonitor" />
<receiver android:name=".ServiceController" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
BroadcastReceiver:
myApplication = (MyApplication) context.getApplicationContext();
conManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
networkInfo = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isConnected = networkInfo != null && networkInfo.isConnected();
int reconnectedCount = myApplication.getReconnectedCount();
if (wifiManager.isWifiEnabled()) {
if("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
//Start and Stop Service
if(myApplication.isReconnect()) startServiceWifiMonitor(); else stopServiceWifiMonitor();
if (isConnected) {
//There is a WIFI Connection
myApplication.setConnectedWifi(NetworkUtil.getCurrentSSID(context));
myApplication.setWifiStatus("connected");
if (NetworkUtil.isConnectedToXYZ(context)) {
startServiceWifiMonitor();
if(pref.getisFirstTime())
{
myApplication.setWifiByChoise("XYZ");
pref.setisFirstTime(false);
}
else { myApplication.setisReconnect(true); }
}
else {
//Connected to different NetWork
if(myApplication.isReconnect() && NetworkUtil.isXYZAvailable(context))
{
//ReConnect to XYZ
NetworkUtil.connectToXYZ(context);
myApplication.setReconnectedCount(reconnectedCount++);
}
else { resetValues("AAAA"); }
}
}//end if
else
{
if(NetworkUtil.isXYZAvailable(context) && myApplication.getWifiByChoise().equals("XYZ"))
{
NetworkUtil.connectToXYZ(context);
myApplication.setReconnectedCount(reconnectedCount++);
}
else { resetValues(""); }
}
}//end CONNECTIVITY_CHANGE
Service Monitor:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand > Received start id " + startId + ": " + intent);
objHandler.postDelayed(mTasks, 1000);
return START_STICKY;
}//end onStartCommand
private Runnable mTasks = new Runnable() {
public void run() {
if(myApplication.getWifiByChoise().equals("XYZ") && NetworkUtil.isXYZAvailable(context)) {
try
{
//Get the numbers of Reconnection
int count = myApplication.getReconnectedCount();
if(!NetworkUtil.isWifiConnected(context))
{
NetworkUtil.connectToXYZ(context);
myApplication.setisReconnect(true);
myApplication.setReconnectedCount(count++);
}
if(!NetworkUtil.isConnectedToXYZ(context))
{
NetworkUtil.connectToXYZ(context);
myApplication.setisReconnect(true);
myApplication.setReconnectedCount(count++);
}
} catch (Exception e) {e.printStackTrace();}
}
else { stopSelf(); }
int ms_interval = 3000;
objHandler.postDelayed(mTasks, ms_interval);
}
};//end Runnable mTasks
The problem with my app is that :
It crashed the device, Seems like its eating up all the memory ram.
sometimes with the wifi XYZ get disconnect it wont connect again and if user change to another wifi, it won't allow the connection.
I really appreciate your help. Thank you.
Check the network connected Name by using:
public String getWifiName(Context context) {
WifiManager manager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (manager.isWifiEnabled()) {
WifiInfo wifiInfo = manager.getConnectionInfo();
if (wifiInfo != null) {
DetailedState state = WifiInfo.getDetailedStateOf(wifiInfo.getSupplicantState());
if (state == DetailedState.CONNECTED || state == DetailedState.OBTAINING_IPADDR) {
return wifiInfo.getSSID();
}
}
}
return null;
}
if this name matches your networkSSID, i.e. XYZ, then resume the service, else if it doesn't match, then stop the service:
if getWifiName(this).compareTo("XYZ") == 0 { //XYZ is your network name on which you want to resume the service
//code to resume
} else {
//code to stop the service
}
This is how I handle it in my app:
public class WifiStateWatcher extends BroadcastReceiver {
private MainActivity activity;
public WifiStateWatcher(MainActivity activity) {
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(WifiManager.SUPPLICANT_STATE_CHANGED_ACTION);
}
#Override
public void onReceive(Context context, Intent intent) {
SupplicantState supState;
WifiManager wifiManager = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
supState = wifiInfo.getSupplicantState();
if (supState.equals(SupplicantState.COMPLETED)) {
//we are connected to Wi-Fi network
} else {
//we lost Wi-Fi connectivity
}
}
}
You will need android.permission.ACCESS_WIFI_STATE permission
What you have done is almost correct. you need to check the network ssd name with the user connected wifi name.If it matched then do your part.
WifiManager wifiManager= (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
if (wifiManager.isWifiEnabled()) {
WifiInfo networkInfo = wifiManager.getConnectionInfo();
if (networkInfo != null) {
DetailedState state = WifiInfo.getDetailedStateOf(networkInfo .getSupplicantState());
if (state == DetailedState.CONNECTED ) {
return networkInfo.getSSID();
}
}
}
return null;
Now you have the network SSID so try to check with the your wifi name and SSID then you will get to know the connection status.....
Happy Programming
Also just checked this and found out that the main difference is:
/** IP traffic should be available. */
DetailedState.CONNECTED
and:
/**
* …
* This state indicates that the supplicant has completed its
* processing for the association phase and that data connection is
* fully configured. Note, however, that there may not be any IP
* address associated with the connection yet. Typically, a DHCP
* request needs to be sent at this point to obtain an address.
*/
SupplicantState.COMPLETED
So to trust that wifi is completely up, i now added the checks that:
boolean isConnected = activeNetworkInfo.isConnected();
and DetailedState.CONNECTED :)
happy coding

Android check WIFI status (disconnected or user changed WIFI)

I is there a way to Flag if a WIFI connection got disconnected/ dropped off OR if the user actually changed the WIFI network ?
I need my app to do :
Connect to a WIFI XYZ, if XYZ get disconnect (FLAG 1) or dropped off Then reconnect to XYZ.
But is the user change to another wifi BTOpen (FLAG 2) then allow the connect and Stop my service.
If user connect to XYZ again then start the loop again.
What I got so far is :
<!-- WIFI Receiver -->
<receiver android:name=".ReceiverWifi" >
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
<service android:name=".ServiceWifiMonitor" />
<receiver android:name=".ServiceController" >
<intent-filter >
<action android:name="android.intent.action.BOOT_COMPLETED" />
<category android:name="android.intent.action.QUICKBOOT_POWERON" />
</intent-filter>
</receiver>
BroadcastReceiver:
myApplication = (MyApplication) context.getApplicationContext();
conManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
wifiManager = (WifiManager) context.getSystemService(Context.WIFI_SERVICE);
networkInfo = conManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
boolean isConnected = networkInfo != null && networkInfo.isConnected();
int reconnectedCount = myApplication.getReconnectedCount();
if (wifiManager.isWifiEnabled()) {
if("android.net.conn.CONNECTIVITY_CHANGE".equals(intent.getAction())) {
//Start and Stop Service
if(myApplication.isReconnect()) startServiceWifiMonitor(); else stopServiceWifiMonitor();
if (isConnected) {
//There is a WIFI Connection
myApplication.setConnectedWifi(NetworkUtil.getCurrentSSID(context));
myApplication.setWifiStatus("connected");
if (NetworkUtil.isConnectedToXYZ(context)) {
startServiceWifiMonitor();
if(pref.getisFirstTime())
{
myApplication.setWifiByChoise("XYZ");
pref.setisFirstTime(false);
}
else { myApplication.setisReconnect(true); }
}
else {
//Connected to different NetWork
if(myApplication.isReconnect() && NetworkUtil.isXYZAvailable(context))
{
//ReConnect to XYZ
NetworkUtil.connectToXYZ(context);
myApplication.setReconnectedCount(reconnectedCount++);
}
else { resetValues("AAAA"); }
}
}//end if
else
{
if(NetworkUtil.isXYZAvailable(context) && myApplication.getWifiByChoise().equals("XYZ"))
{
NetworkUtil.connectToXYZ(context);
myApplication.setReconnectedCount(reconnectedCount++);
}
else { resetValues(""); }
}
}//end CONNECTIVITY_CHANGE
Service Monitor:
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
Log.i(TAG, "onStartCommand > Received start id " + startId + ": " + intent);
objHandler.postDelayed(mTasks, 1000);
return START_STICKY;
}//end onStartCommand
private Runnable mTasks = new Runnable() {
public void run() {
if(myApplication.getWifiByChoise().equals("XYZ") && NetworkUtil.isXYZAvailable(context)) {
try
{
//Get the numbers of Reconnection
int count = myApplication.getReconnectedCount();
if(!NetworkUtil.isWifiConnected(context))
{
NetworkUtil.connectToXYZ(context);
myApplication.setisReconnect(true);
myApplication.setReconnectedCount(count++);
}
if(!NetworkUtil.isConnectedToXYZ(context))
{
NetworkUtil.connectToXYZ(context);
myApplication.setisReconnect(true);
myApplication.setReconnectedCount(count++);
}
} catch (Exception e) {e.printStackTrace();}
}
else { stopSelf(); }
int ms_interval = 3000;
objHandler.postDelayed(mTasks, ms_interval);
}
};//end Runnable mTasks
The problem with my app is that :
It crashed the device, Seems like its eating up all the memory ram.
sometimes with the wifi XYZ get disconnect it wont connect again and if user change to another wifi, it won't allow the connection.
I really appreciate your help. Thank you.

NetworkChangeReceiver's onReceive method is called multiple times when 3G and WIFI are enable at same time

I'm developing an android application and I have the next problem:
I implemented Broadcast receiver for connectivity change and the method onReceive seems to be called 4 times in a row when 3G and Wifi are enabled at the same time.
So my question is:
Is there a way listen only for internet connection, not for network change?
Or is there any way for the method onReceive to be called only once when 3G and Wifi are enable at the same time?
Here is my code:
public class NetworkChangeReceiver extends BroadcastReceiver {
public static final String TAG = "NetworkMonitoring";
#Override
public void onReceive(Context context, Intent intent) {
if (isOnline(context)) {
Log.v(TAG, "Connected!");
// update(context);
} else {
Log.v(TAG, "Not connected!");
// stopUpdate(context);
}
}
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
if (netInfo != null && netInfo.isConnected())
return true;
return false;
}
}
In the Android Manifest:
<receiver android:name="xxxxx.xxxxx.xxxxx.NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
Here is the log:
05-06 16:24:05.985: V/NetworkMonitoring(569): Connected!
05-06 16:24:10.250: V/NetworkMonitoring(569): Connected!
05-06 16:24:10.720: V/NetworkMonitoring(569): Connected!
05-06 16:24:11.031: V/NetworkMonitoring(569): Connected!
(Notice the time!)
I had the same problem with the same type of broadcast receiver.
Searched a little and found a workaround.
BroadcastReceiver receives multiple identical messages for one event
Edit:
The workaround is to use a flag that tells you when is the first time onReceive is being invoked.
public class ConnectionChangeReceiver extends BroadcastReceiver {
private static boolean firstConnect = true;
#Override
public void onReceive(Context context, Intent intent) {
final ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
final NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
if (activeNetInfo != null) {
if(firstConnect) {
// do subroutines here
firstConnect = false;
}
}
else {
firstConnect= true;
}
}
}
Hope it helps.

Query a web page

How must I go about coding to get an app to query the state of a device, through internet protocol to see if its on or off.
public void port0156 (View view) {
webView = (WebView) findViewById(R.id.webView);
webView.getSettings().setJavaScriptEnabled(true);
webView.loadUrl("http://192.168.2.66/index.html?o0=1");
}
You can register a broadcastreceiver to monitor connectivity changes.
In manifest :
<receiver android:name="com.yourpackage.NetworkChangeReciever" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
</intent-filter>
</receiver>
the class in com.yourpackage :
public class NetworkChangeReciever extends BroadcastReceiver {
private final static String TAG = "NetworkChangeReciever";
public interface NetworkChangeRecieverListener {
public void OnNetworkChangeReciever(boolean wifiConnected);
}
#Override
public void onReceive(final Context context, final Intent intent) {
final ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
final android.net.NetworkInfo wifi = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final android.net.NetworkInfo mobile = connMgr.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if (wifi.isAvailable()) || mobile.isAvailable()) {
Log.d(TAG, "Network Available.");
}
else {
Log.d(TAG, "Network Unavailable");
}
}
}
You can see if the app is online (or reachable) by seeing if it returns a ping you can easily do this by using OS and parsing the output.

Categories

Resources