I'm trying to use a BroadcastReceiver to detect if wifi is connected and simply display a toast when the status changes (wifi disonnect/reconnect/turn off) but it doesn't seem to be working. Any ideas?
ConnectionChangeReceiver class:
public class ConnectionChangeReceiver extends BroadcastReceiver
{
#Override
public void onReceive( Context context, Intent intent )
{
ConnectivityManager connMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connMgr.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
final boolean isWifiConn = networkInfo.isConnected();
Log.d("debug", "Wifi connected: " + isWifiConn);
Toast toast = Toast.makeText(context, "Wifi connected: " + isWifiConn, Toast.LENGTH_LONG);
toast.show();
}
}
Manifest:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<receiver android:name="ConnectionChangeReceiver" android:label="NetworkConnection">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
</receiver>
I go in the app, and disconnect wifi, reconnect, no toast. I disable wifi, no toast. re-enable it, no toast. I suspect that there's something wrong with the broadcast receiver.
Thanks in advance.
I got it working.
My problem was in the Manifest. I was putting my receiver block outside the application tag. Once I moved it inside, it worked perfectly.
Related
i wrote simple BroadcastReceiver to detect internet connection and check internet available to send data to server, only return true on first opening application, it mean, after open application this BroadcastReceiver can be detect correctly connecting to internet, after that on each turn on/turn off wifi i get only false and it doesn't correct and must be true or false
public class ConnectionListener extends BroadcastReceiver {
private boolean isNetworkAvailable(Context context) {
ConnectivityManager connectivityManager
= (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo activeNetworkInfo = connectivityManager.getActiveNetworkInfo();
return activeNetworkInfo != null && activeNetworkInfo.isConnected();
}
#Override
public void onReceive(Context mContext, Intent intent) {
Log.e("check ", isNetworkAvailable(mContext) + "");
if (isNetworkAvailable(mContext)) {
EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.connected));
} else
EventBus.getDefault().post(new EventNetworkConnectionStateEvent(EventNetworkConnectionStateEvent.ConnectionState.disconnected));
}
}
manifest:
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"/>
receiver:
<receiver android:name="..Broadcasts.ConnectionListener">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.net.wifi.STATE_CHANGE"/>
</intent-filter>
</receiver>
I'm trying to make an android application which listens to wifi change broadcast and do some action. But the problem is that it is not working when the process is killed. I found this question which says that it won't work without an activity
How to create BroadcastReceiver without Activity/Service?
So that is not an alternative. Hence I created an activity which is empty. I don't want to create a service which keeps running in the background. How can I make my application keep listening even when it is killed. I have registered the broadcast in the manifest.
<activity
android:name=".MainActivity"
android:label="#string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="com.background.service.BroadCastReceiver">
<intent-filter>
<action android:name="android.net.wifi.WIFI_STATE_CHANGED"/>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
This is my class
public class BroadCastReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
//do some action
}
}
Looks like you have it correct defining in the manifest with one exception. The broadcast receiver will trigger an ANR if it doesn't complete in 10 secs. http://developer.android.com/training/articles/perf-anr.html
in your broadcast receiver simply start a service.
public class ReceiverUpload extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
context.startService(new Intent(context, ServiceUploader.class));
}
}
Then in your service start an asynctask because you don't want to be on the UI thread for example you start the same service from an activity in your app.
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
// start asynctask to get off this thread
new MyBackGround().execute(startId);
return Service.START_REDELIVER_INTENT;
}
First thing to do in the asynctask is check for wifi
Below is excerpt from a function I call to check network if it returns false the asynctask just finishes if it's true it does network stuff which hey has to be in the background anyways so asynctask makes even more sense.
// check for network connection
ConnectivityManager connMgr = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
if (connMgr == null) {
return false;
}
// check ok to process
NetworkInfo networkInfo = connMgr.getActiveNetworkInfo();
if (networkInfo == null || !networkInfo.isConnected()) {
return false;
}
boolean isWifi = networkInfo.getType() == ConnectivityManager.TYPE_WIFI;
if (!isWifi) {
return false;
}
return true;
Note in this example the startId passed to the asynctask is used to cancel OS redelivering the intent.
#Override
public void onPostExecute(Integer startId) {
if (startId != null) {
stopSelfResult(startId);
}
}
You already doing right with the Broadcast Receiver and declaring it the Manifest. That's all you need to do. No services running in the background are needed.
Just make sure you install and run the app at least once otherwise the broadcast receives won't be registered
The best that worked for me:
AndroidManifest
<receiver android:name="com.AEDesign.communication.WifiReceiver" >
<intent-filter android:priority="100">
<action android:name="android.net.wifi.STATE_CHANGE" />
</intent-filter>
</receiver>
BroadcastReceiver class
public class WifiReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
NetworkInfo info = intent.getParcelableExtra(WifiManager.EXTRA_NETWORK_INFO);
if(info != null) {
if(info.isConnected()) {
// Do your work.
// e.g. To check the Network Name or other info:
WifiManager wifiManager=(WifiManager)context.getSystemService(Context.WIFI_SERVICE);
WifiInfo wifiInfo = wifiManager.getConnectionInfo();
String ssid = wifiInfo.getSSID();
}
}
}
}
Permissions
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
best solution is to make a broadcast receiver , it will work
public class NetworkChangeReceiver extends BroadcastReceiver {
#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()) {
// Enjoy coding here
Log.d("Netowk Available ", "Flag No 1");
}
}}
in manifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.broadcastreceiverforinternetconnection"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<receiver android:name=".NetworkChangeReceiver" >
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE" />
<action android:name="android.net.wifi.WIFI_STATE_CHANGED" />
</intent-filter>
</receiver>
</application>
Normally, if app is killed and broadcast comes your app process will be started by system for you. There is absolutely no need to keep something alive or do any additional manipulations (otherwise why would you need BroadcastReceiver if you can just use Service?)
Updated answer 05/2022
The docs on Broadcasts and Broadcast limitations inform that from Android 7 (Android 8 made it even more stringent)
you cannot use the manifest to declare a receiver for implicit broadcasts (broadcasts that do not target your app specifically), except for a few implicit broadcasts
That means, for most use cases manifest-declared Broadcast won't work anymore and must be replaced with scheduled jobs or services. Be aware, the latter suffers from being killed by the OS for battery optimization.
i am a beginner in android and i am developing an application where BrocastReceiver starts whenever the user makes a call... i am trying to monitor the network status inside the broadcast receiver... and i am trying to start the activity when the user hangs up the phone... but unfortunately it is giving me an error...please let me know how to do this...
My broadcast receiver starts properly when the user make a call... but i do not know how to monitor the network inside the BroadcastReceiver when the user is on call.. and invoke the activity from the BroadcastReceiver when the user hangs up the phone...
Please let me know how to achieve this... Thanks in advance.. :-)
my code...
BroadcastReceiver Code
public class MoniterNetworkStatus extends BroadcastReceiver{
private ConnectivityManager connectivityManager;
private NetworkInfo info;
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "Monitering Network Status !!!", Toast.LENGTH_LONG).show();
boolean networkStatus = false;
TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Intent activityIntent = new Intent(context, NetworkStatusActivity.class);
// I am monitoring the network status as long as user is on call...
while(telephonyManager.getCallState()!= TelephonyManager.CALL_STATE_IDLE){
info = connectivityManager.getActiveNetworkInfo();
if(info == null){
networkStatus = false;
}else if(info.getType() == ConnectivityManager.TYPE_MOBILE){
networkStatus = info.isConnected();
}else{
networkStatus = false;
}
}
//Putting the network details in to the activity.
activityIntent.putExtra("operatorName", telephonyManager.getNetworkOperatorName());
activityIntent.putExtra("networkStatus", networkStatus);
// starting the activity
context.startActivity(activityIntent);
abortBroadcast();
}
}
My Manifest File
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="8" />
<uses-permission android:name="android.permission.PROCESS_OUTGOING_CALLS" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<!-- <uses-permission android:name="android.permission.INTERNET"/> -->
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme" >
<activity android:name="com.abc.activity.NetworkStatusActivity"></activity>
<receiver android:name="com.abc.broadcastreceiver.MoniterNetworkStatus"
android:enabled="true" >
<intent-filter>
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
<action android:name="android.intent.action.ANSWER" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</receiver>
</application>
My broadcast receiver starts properly when the user make a call... but i do not know how to monitor the network when the user is on call.. and invoke the activity when the user hangs up the phone...
Please let me know how to achieve this... Thanks in advance.. :-)
You need to register another receiver to accept ACTION_PHONE_STATE_CHANGED. This may be a duplicate of Detecting outgoing call and call hangup event in android
i want to check if we are connected to the Internet in my application. I am using a broadcastReceiver. If the connection is lost i want to change an entry in my DB SQLite and stop a service which does htpp requests in another thread every minute.
Log.i doesn't display anything, when i try to update my DB or stop the service , my application crashes and i have no error message in logcat and no exception.
public class InternetConnection extends BroadcastReceiver {
private AccountBDD accountBdd;
#Override
public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) context
.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null) {
State networkState = networkInfo.getState();
if (networkState.compareTo(State.CONNECTED) == 0)
Log.i("INTERNET CONNEC", "connection retrieved");
Toast.makeText(context, "RETRIEVED CONNECTION ", Toast.LENGTH_LONG)
.show();
}
Toast.makeText(context, "CONNECTION LOST", Toast.LENGTH_LONG).show();
Log.i("INTERNET CONNEC", "loss of connection");
// context.stopService(new Intent(context, PeriodicSync.class));
// accountBdd.updateSyncUtility(syncUtility);
// Log.i(" Value ", " offlineWork = "
// + accountBdd.getSyncUtility().getOfflineWork());
}
}
the manifest :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.android"
android:versionCode="1"
android:versionName="1.0">
<uses-sdk android:minSdkVersion="13" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<application
android:label="#string/app_banner"
android:name="SQLiteApplication">
<service android:name="PeriodicSync" />
<receiver android:enabled="true" android:name="com.android.InternetConnection">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
</application>
has anybody an idea ? Thx
I want to receive notification when Mobile network connection is lost or received. Through following code, I can receive notification for Wi-Fi (Data) connection but not for Mobile (Voice) connection.
Manifest :
<uses-permission android:name="android.permission.ACCESS_NETWORK_ST ATE"/>
<application android:icon="#drawable/icon" android:label="#string/app_name">
<receiver android:name=".notifier">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE " />
</intent-filter>
</receiver>
</application>
Java :
public class notifier extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Toast toast = Toast.makeText(context, "Network Changed !!", Toast.LENGTH_LONG);
toast.show();
}
}
Please tell me, how can I receive notification for Mobile Network (Voice).
Pseudocode!!
PhoneStateListener myListener = new PhoneStateListener() {
#Override
public void onServiceStateChanged (ServiceState serviceState) {
// Handle different service states here.
}
};
((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE))
.listen(myListener, PhoneStateListener.LISTEN_SERVICE_STATE);
http://developer.android.com/reference/android/telephony/TelephonyManager.html#listen(android.telephony.PhoneStateListener, int)
Check the permission in the AndroidManifest.xml, first.
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_NETWORK_STATE"></uses-permission>
And try this code below.
ConnectivityManager manager = (ConnectivityManager)appContext.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo mobile = manager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
if(mobile.isConnected()) {
//Do Sth.
}
If this is not work, check your phone's brand. If the phone's developer blocked some codes or not implement some code, it doesn't work. What is your phone?