Broadcast receiver for checking internet connection in android app
Answer to your first question: Your broadcast receiver is being called two times because
You have added two <intent-filter>
Change in network connection :
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
Change in WiFi state:
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
Just use one:
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
.
It will respond to only one action instead of two. See here for more information.
Answer to your second question (you want receiver to call only one time if internet connection available):
Your code is perfect; you notify only when internet is available.
UPDATE
You can use this method to check your connectivity if you want just to check whether mobile is connected with the internet or not.
public boolean isOnline(Context context) {
ConnectivityManager cm = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo netInfo = cm.getActiveNetworkInfo();
//should check null because in airplane mode it will be null
return (netInfo != null && netInfo.isConnected());
}
Broadcast receiver to check the Internet Connection
Okay so i'm not the best programmer but this should work.
this is for a fragment but you should easily be able to change it for an
activity.
first make 3 variables:
Context _mContext;
BroadcastReceiver br = null;
IntentFilter filter;
in your onCreate() paste this:
BroadcastReceiver br = new MyBroadCastReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
_mContext = getActivity().getApplicationContext()
_mContext.registerReceiver(br, filter);
with this you register your fragment to the broadcastreceiver class MyBroadCastReceiver.
Now make a MyBroadCastReceiver class and paste this:
public class MyBroadCastReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
int extraWifiState = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
WifiManager.WIFI_STATE_UNKNOWN);
switch(extraWifiState) {
case: WifiManager.WIFI_STATE_DISABLED:
//do something
break;
case WifiManager.WIFI_STATE_ENABLED:
//do something
break;
case: WifiManager.WIFI_STATE_ENABLING:
//do something
break;
case: WifiManager.WIFI_STATE_DISABLING:
//do something
break;
case: WifiManager.WIFI_STATE_UNKNOWN:
//do something with data if you desire so, I found it unreliable until now so i've done nothing with it
}
}
}`
Go back to your fragment and paste this somewhere at the bottom:
@Override
public void onPause() {
try {
if (br == null) {
Log.d("Receiver", "Can't unregister a receiver which was never registered");
} else {
getActivity().getApplicationContext().unregisterReceiver(br);
br = null;
}
} catch(Exception err) {
Log.e(err.getClass().getName(), err.getMessage(), err);
Log.e("Receiver not registered", "Couldn't get context");
}
super.onPause();
}
@Override
public void onResume() {
if(br != null) {
Log.d("Receiver", "Can't register receiver which already has been registered");
} else {
try {
br = new MyBroadCastReceiver();
filter = new IntentFilter();
filter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
filter.addAction(CONNECTIVITY_SERVICE);
_mContext = getActivity().getApplicationContext();
_mContext.registerReceiver(br, filter);
} catch(Exception err) {
Log.e(err.getClass().getName(), err.getMessage(), err);
}
}
super.onResume();
}
You should be able to call register/unregister the broadcast like this anywhere.
I hope this is enough
Broadcast receiver is not calling on internet connectivity check
Apps targeting Android 7.0 (API level 24) and higher must register the
following broadcasts with
registerReceiver(BroadcastReceiver,IntentFilter)
Declaring a receiver in the manifest does not work.
CONNECTIVITY_ACTION
Beginning with Android 8.0 (API level 26), the
system imposes additional restrictions on manifest-declared receivers.
If your app targets API level 26 or higher, you cannot use the
manifest to declare a receiver for most implicit broadcasts
(broadcasts that do not target your app specifically). You can still
use a context-registered reciever when the user is actively using your
app.
directly from official doc.
you need to register for CONNECTIVITY_CHANGE action at runtime from activity.
using registerReceiver.
IntentFilter filter = new IntentFilter();
filter.addAction("android.net.conn.CONNECTIVITY_CHANGE");
registerReceiver(new NetworkStateChangeReceiver(), filter);
And don't forget to unregister.
Check internet connectivity on android nougat in background thread
I got an answer to my question.
Broadcast receiver with action <action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
, which is registered in manifest will not fire in android N. But one can register a broadcast programatically and make it work. But it will not work when the app is killed.
Then in my case, I had two options (thats what I thought), Schedule the sync operation with
GCM Network manager
OR
Job scheduler
The problem with job scheduler is that it works only above API level 21, but it doesn't need Google play service to work. On the other hand GCM Network manager had backwards compatibility, but needs google play service to run.
Then I visited Intelligent Job Scheduling, and they said, go with Firebase Job dispatcher,
Firebase JobDispatcher supports the use of Google Play services as an
implementation for dispatching (running) jobs, but the library also
allows you to define and use other implementations: For example, you
might decide to use JobScheduler or write your own, custom code.
Because of this versatility, we recommend that you use this Firebase
JobDispatcher if your app targets a version of Android lower than 5.0
(API level 21).
And I took that advice,
and this is what I did,
Created a service (SyncService.java) which does the sync job,
added that service to manifest
<service
android:exported="false"
android:name=".SyncService">
<intent-filter>
<action android:name="com.firebase.jobdispatcher.ACTION_EXECUTE"/>
</intent-filter>
</service>
And in my activity, created and executed a Job to sync
Job syncJob=jobDispatcher.newJobBuilder()
.setService(SyncService.class)
.setRecurring(true)
.setLifetime(Lifetime.FOREVER)
.setRecurring(true)
.setLifetime(Lifetime.FOREVER)
.setTrigger(Trigger.executionWindow(3,600))
.setConstraints(Constraint.ON_ANY_NETWORK) //does job when network is available
.setReplaceCurrent(true)
.setTag("syncService")
.build();
jobDispatcher.mustSchedule(syncJob);
And this works in background.
Android BroadcastReceiver for internet connection called twice
Check this link
For Android 7 and above you need to register your receiver in your activity file not in the manifest file.
So in your activity's onCreate() add the following lines:
myConnectivityReceiver = new ConnectivityReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction(getResources().getString(R.string.action_connectivity_change));
registerReceiver(myConnectivityReceiver,filter);
and in onDestroy()
@Override
protected void onDestroy() {
unregisterReceiver(myConnectivityReceiver);
super.onDestroy();
}
define the intent action in strings.xml
<string name="action_connectivity_change">android.net.conn.CONNECTIVITY_CHANGE</string>
Internet connectivity and Broadcast Receiver
The reason that your BroadcastReceiver
is immediately triggered is because the broadcast Intent
ConnectivityManager.CONNECTIVITY_ACTION
is a "sticky" broadcast. This allows apps to register for and receive immediately the last broadcast event of this type (so that they can determine the current connectivity situation). If this "sticky" broadcast is causing you problems, just check for that in onReceive()
and ignore it:
// Ignore the sticky broadcast of the initial state
if (isInitialStickyBroadcast()) {
return;
}
There is a lot of data passed as "extras" in the Intent
that your BroadcastReceiver
gets. You can tell, for example, if the event is a CONNECT or a DISCONNECT event, etc. Check the documenttion on ConnectivityManager
to determine what "extras" are sent and how to use them.
Related Topics
Java.Lang.Classnotfoundexception: Didn't Find Class on Path: Dexpathlist
Com.Android.Build.Transform.API.Transformexception
Android: Internet Connectivity Change Listener
Java Refuses to Start - Could Not Reserve Enough Space For Object Heap
Difference Between Public, Protected, Package-Private and Private in Java
How to Create a Java String from the Contents of a File
Element Myelement Is Not Clickable At Point (X, Y)... Other Element Would Receive the Click
Create Instance of Generic Type in Java
Error - Trustanchors Parameter Must Be Non-Empty
How to Simulate the C++ 'Friend' Concept in Java
What Is a Stringindexoutofboundsexception - How to Fix It
How to Display Data from Firestore in a Recyclerview With Android
Parsing Query Strings on Android
Java Command Not Found on Linux
Non-Static Variable Cannot Be Referenced from a Static Context