Notify network status in same activity using Receivers - android

I am working with google chat application
When chatting if network fails, I have to notify user that network disconnected and if network connected again i have to notify network connected in the same activity.But not worked out
Following is the code which I written:
public class GTChat extends ListActivity
{
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
}
private BroadcastReceiver mConnReceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent)
{
boolean noConnectivity = intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
NetworkInfo info = (NetworkInfo)intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
if (info.getState().equals(NetworkInfo.State.CONNECTED))
{
Toast.makeText(getApplicationContext(), "Network connected",Toast.LENGTH_LONG).show();
}
else
{
Toast.makeText(getApplicationContext(), "Network not connected",Toast.LENGTH_LONG).show();
}
}
};
protected void onPause()
{
unregisterReceiver(mConnReceiver);
super.onPause();
}
protected void onResume()
{
registerReceiver(mConnReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
super.onResume();
}

call the super.onResume()/super.onPause() before to register/unregistering receiver.
protected void onPause()
{
super.onPause();
unregisterReceiver(mConnReceiver);
}
protected void onResume()
{
super.onResume();
registerReceiver(mConnReceiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION));
}

Related

I can't stop receiving broadcasts

I can't stop receiving broadcasts. Why?
This is the code I have:
public class MainActivity extends AppCompatActivity {
BroadcastReceiver br = new CustomReceiver();
IntentFilter filter = new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION);
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
BroadcastReceiver br = new CustomReceiver();
filter.addAction(Intent.ACTION_POWER_CONNECTED);
filter.addAction(Intent.ACTION_POWER_DISCONNECTED);
this.registerReceiver(br, filter);
}
#Override
protected void onStart() {
super.onStart();
if(!br.isOrderedBroadcast())
this.registerReceiver(br, filter);
}
#Override
protected void onStop() {
super.onStop();
if(br.isOrderedBroadcast())
this.unregisterReceiver(br);
}
#Override
protected void onPause() {
super.onPause();
if(br.isOrderedBroadcast())
this.unregisterReceiver(br);
}
#Override
protected void onResume() {
super.onResume();
if(!br.isOrderedBroadcast())
this.registerReceiver(br, filter);
}
#Override
protected void onDestroy() {
super.onDestroy();
if(br.isOrderedBroadcast())
this.unregisterReceiver(br);
}
}
public class CustomReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
String toastMessage = "TOAST";
switch (intentAction){
case Intent.ACTION_POWER_CONNECTED:
toastMessage="Power Connected!";
break;
case Intent.ACTION_POWER_DISCONNECTED:
toastMessage="Power Disconnected!";
break;
}
Toast.makeText(context, toastMessage, Toast.LENGTH_SHORT).show();
}
}
When I go to onPause() and onStop() the app continues to show toast message of connect and disconnect charge. I don't know why.
My guess is that condition (which you're using in onPause() and onStop()) br.isOrderedBroadcast() is false so CustomReceiver won't get unregistered.
Also, according to the documentation, you should register/unregister CustomReceiver either in onCreate()/onDestroy() or in onResume()/onPause().

Activity has leaked IntentReceiver Error

before marking this post as closed or duplicate i want to say that i have done all the things that are mentioned on similar posts but none of them worked.
I have 2 receivers which i get data from. So i want to register the receivers when the activity starts and unregister them when the activity is not visible.
My Code:
public class MainActivity extends AppCompatActivity {
private CheckNetworkStatusReceiver checkNetworkStatusReceiver;
private CheckBatteryStatusReceiver checkBatteryStatusReceiver;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkConnection();
}
public void checkConnection() {
if(!ConnectionManager.isNetworkAvailable(MainActivity.this)){
ConnectionManager.wifiSettingsDialog(MainActivity.this).show();
}else{
registerReceivers();
}
}
public void registerReceivers() {
checkNetworkStatusReceiver = new CheckNetworkStatusReceiver();
checkBatteryStatusReceiver = new CheckBatteryStatusReceiver();
registerReceiver(checkNetworkStatusReceiver, new IntentFilter(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE));
registerReceiver(checkBatteryStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
#Override
protected void onDestroy() {
super.onDestroy();
try{
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}catch (Exception e){
e.printStackTrace();
}
}
#Override
protected void onResume() {
registerReceivers();
super.onResume();
}
#Override
protected void onRestart() {
registerReceivers();
super.onRestart();
}
#Override
protected void onStop() {
super.onStop();
try{
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}catch (Exception e){
e.printStackTrace();
}
}
}
The receiver code:
public class CheckNetworkStatusReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
Log.e("Action ",intent.getAction());
if(intent.getAction().equalsIgnoreCase(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE)) {
if (!ConnectionManager.isNetworkAvailable(context)){
Toast.makeText(context, R.string.no_internet, Toast.LENGTH_SHORT).show();
}
if (MobileDataManager.slowInternetConnection(context)){
Toast.makeText(context, R.string.slow_internet_delay, Toast.LENGTH_SHORT).show();
}
}
}
}
}
and the battery receiver:
public class CheckBatteryStatusReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null){
int level = intent.getIntExtra(BatteryManager.EXTRA_LEVEL, 0);
if (level <= 15){
Toast.makeText(context, "Batter level " + level + "% is very low. Please connect to a charger.", Toast.LENGTH_SHORT).show();
}
}
}
}
i get the error on the registerReceivers() method. Any ideas?
You register the receivers in onCreate() and then again in onResume(). This will leak the receivers that you registered in onCreate(), because you overwrite the variables you are using to hold references to them every time registerReceivers() is called.
This is not very robust code. You don't need to create new instances of the BroadcastReceiver every time. What you should do is to create one instance of each BroadcastReceiver in onCreate(). Then declare a boolean member variable in your class called receiversRegistered. In registerReceivers() you should check this boolean. If it is true, the receivers are already registered and you should do nothing. If not, register the receivers and then set the boolean to true. When you unregister the receivers, set the boolean to false.
EDIT: Here it is all done for you:
public class MainActivity extends AppCompatActivity {
private CheckNetworkStatusReceiver checkNetworkStatusReceiver;
private CheckBatteryStatusReceiver checkBatteryStatusReceiver;
private boolean receiversRegistered;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
checkNetworkStatusReceiver = new CheckNetworkStatusReceiver();
checkBatteryStatusReceiver = new CheckBatteryStatusReceiver();
checkConnection();
}
public void checkConnection() {
if(!ConnectionManager.isNetworkAvailable(MainActivity.this)){
ConnectionManager.wifiSettingsDialog(MainActivity.this).show();
}else{
registerReceivers();
}
}
public void registerReceivers() {
// Only register if not already registered
if (!receiversRegistered) {
registerReceiver(checkNetworkStatusReceiver, new IntentFilter(Constants.INTENT_FILTER_CONNECTIVITY_CHANGE));
registerReceiver(checkBatteryStatusReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
receiversRegistered = true;
}
}
#Override
protected void onDestroy() {
super.onDestroy();
if (receiversRegistered) {
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
}
}
#Override
protected void onResume() {
registerReceivers();
super.onResume();
}
#Override
protected void onRestart() {
registerReceivers();
super.onRestart();
}
#Override
protected void onStop() {
super.onStop();
if (receiversRegistered) {
unregisterReceiver(checkNetworkStatusReceiver);
unregisterReceiver(checkBatteryStatusReceiver);
receiversRegistered = false;
}
}
}
Move the unregisterReceiver inside onPause not in onDestroy.
When your activity is moved in background onDestroy is not called. The activity is only paused. onDestroy is called when the app is closed manually or by the system.
(onPause is called before onDestroy in above situation)

Android Wifi Direct onPeersAvailable doesn't shows anything

I'm trying to develop a simple app using Wifi Direct. The problem is I can't get a list of available peers using onPeersAvailable method. I tried the solutions mentioned here and here but no luck.There is nothing at logs, tried using Toast instead of log but nothing showed up on the screen either. Here is my Main and BroadCastReceiver classes.
Main Class:
public class MainActivity extends AppCompatActivity {
private final String TAG = this.getClass().toString();
WifiP2pManager mManager;
WifiP2pManager.Channel mChannel;
BroadcastReceiver mReceiver;
IntentFilter mIntentFilter;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
mChannel = mManager.initialize(this, getMainLooper(), null);
mReceiver = new WiFiDirectBroadcastReceiver(mManager, mChannel, this);
mIntentFilter = new IntentFilter();
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION);
mIntentFilter.addAction(WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION);
Button btn_discover = (Button) findViewById(R.id.btn_discover);
btn_discover.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
mManager.discoverPeers(mChannel, new WifiP2pManager.ActionListener() {
#Override
public void onSuccess() {
/*Toast.makeText(getApplicationContext(), "Discovery is a success.",
Toast.LENGTH_SHORT).show();*/
//startActivity(new Intent(Settings.ACTION_WIRELESS_SETTINGS));
}
#Override
public void onFailure(int reasonCode) {
Toast.makeText(getApplicationContext(), "Discovery is a failure "+reasonCode,
Toast.LENGTH_SHORT).show();
}
});
}
});
}
/* register the broadcast receiver with the intent values to be matched */
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
/* unregister the broadcast receiver */
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}}
BroadCastReceiver class:
public class WiFiDirectBroadcastReceiver extends BroadcastReceiver {
private final String LOG_TAG = this.toString();
private WifiP2pManager mManager;
private WifiP2pManager.Channel mChannel;
private MainActivity mActivity;
public WiFiDirectBroadcastReceiver(WifiP2pManager manager, WifiP2pManager.Channel channel,
MainActivity activity) {
super();
this.mManager = manager;
this.mChannel = channel;
this.mActivity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
if (WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION.equals(action)) {
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) {
Log.i(LOG_TAG, "Wifi Direct is enabled");
} else {
Log.i(LOG_TAG, "Wifi Direct is not enabled");
}
} else if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {
// request available peers from the wifi p2p manager. This is an
// asynchronous call and the calling activity is notified with a
// callback on PeerListListener.onPeersAvailable()
if (mManager != null) {
mManager.requestPeers(mChannel, new WifiP2pManager.PeerListListener() {
#Override
public void onPeersAvailable(WifiP2pDeviceList wifiP2pDeviceList) {
Log.i(LOG_TAG, "Found some peers!!! "+wifiP2pDeviceList.getDeviceList().size());
}
});
}
} else if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {
// Respond to new connection or disconnections
} else if (WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION.equals(action)) {
// Respond to this device's wifi state changing
}
}}
I am sure my device (2012 Nexus 7 running Android 4.4.4) supports Wifi Direct.
I think the issue is because you are creating new "PeerListListener" inside the "WiFiDirectBroadcastReceiver".
Try to add it to your main activity instead:
public class MainActivity extends AppCompatActivity implements WifiP2pManager.PeerListListener
And then add new method to you main activity to listen to available peers:
#Override
public void onPeersAvailable(WifiP2pDeviceList peerList) {
Log.i(LOG_TAG, "Found some peers!!! " + peerList.getDeviceList().size());
}
Note: Don't forget to create new listener variable instead "WiFiDirectBroadcastReceiver" and pass the main activity as a reference to it.
Hope this helps.

Creating my own action for BroadcastReceiver

I have an method like this:
public static boolean checkConnection(){
if(getConnection()!=null){
return true;
}else
return false;
}
I trying to listen to the result of this method throughout my application. Till my application is alive. Only inside my application
How should I create my own action so that in BroadcastReceiver I can listen to this method and show an dialog when it returns false and hide the dialog automatically when it start returning true?
How and what will be the best approach to do this?
public class BroadCastActivity extends Activity implements OnClickListener{
ConnectionReceverLocal mReceverLocal;
Button mSwithcOn,mSwitchOff;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_broad_cast);
/*Intent intent = new Intent();
intent.setAction("com.broadcast.myconnectionbroadcast");
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);*/
mReceverLocal = new ConnectionReceverLocal();
mSwitchOff = (Button)findViewById(R.id.switchoff);
mSwithcOn = (Button)findViewById(R.id.switchon);
mSwitchOff.setOnClickListener(this);
mSwithcOn.setOnClickListener(this);
}
private void sendMessage() {
new AsyncTask<Void, Void, Boolean>() {
#Override
protected Boolean doInBackground(Void... params) {
// TODO Auto-generated method stub
Log.d("Connection result Checking Asynctasks", ""+ConnectionProvider.checkConnection());
return ConnectionProvider.checkConnection();
}
#Override
protected void onPostExecute(Boolean result) {
super.onPostExecute(result);
Intent intent = new Intent("com.broadcast.myconnectionbroadcast");
// Add data
intent.putExtra("message", result);
LocalBroadcastManager.getInstance(BroadCastActivity.this).sendBroadcast(intent);
}
}.execute();
}
#Override
protected void onPause() {
super.onPause();
LocalBroadcastManager.getInstance(this).unregisterReceiver(mReceverLocal);
}
#Override
protected void onResume() {
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mReceverLocal,
new IntentFilter("com.alignminds.broadcast.myconnectionbroadcast"));
sendMessage();
}
public class ConnectionReceverLocal extends BroadcastReceiver {
public ConnectionReceverLocal() {
}
#Override
public void onReceive(Context context, Intent intent) {
AlertDialog.Builder mDBuilder = new AlertDialog.Builder(BroadCastActivity.this);
Boolean intentAction = intent.getBooleanExtra("message", false);
if(intentAction==false)
{
Log.d("Connection is false in broadcast recever", "Connection is false");
if(mDBuilder!=null)
{
mDBuilder.setMessage("No Network");
mDBuilder.create().show();
}
}else {
Log.d("Connection is true in broadcast recever", "Connection is true");
if(mDBuilder!=null)
{
mDBuilder.setMessage("Network Ok");
mDBuilder.create().show();
}
}
}
}
#Override
public void onClick(View v) {
if(v==mSwithcOn)
{
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(true);
}
if(v==mSwitchOff)
{
WifiManager wifiManager = (WifiManager)this.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(false);
}
}
}
Send a broadcast with whatever action you want like this
Intent intent = new Intent();
intent.setAction("my_fancy_action");
intent.putExtra(EVENT_MESSAGE, message);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
Subclass BroadcastReceiver class to listen for broadcasts
#Override
public void onReceive(Context context, Intent intent) {
String intentAction = intent.getAction();
// Do something
}
Register your receiver to listen to the broadcast
IntentFilter filter = new IntentFilter();
filter.addAction("my_fancy_action");
LocalBroadcastManager.getInstance(context).registerReceiver(myReceiver, filter);

BroadcastReceiver with multiple filters or multiple BroadcastReceivers?

I have an Android Activity that needs to catch two different broadcasts. My current approach is to have a single BroadcastReceiver within the Activity and catch both the broadcasts with it:
public class MyActivity extends Activity {
private MyActivity.BroadcastListener mBroadcastListener;
private boolean mIsActivityPaused = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mylayout);
// Create the broadcast listener and register the filters
mIsActivityPaused = false;
mBroadcastListener = new BroadcastListener();
IntentFilter filter = new IntentFilter();
filter.addAction(Params.INTENT_REFRESH);
filter.addAction(Params.INTENT_UPDATE);
registerReceiver(mBroadcastListener, filter);
}
#Override
protected void onResume() {
super.onResume();
mIsActivityPaused = false;
}
#Override
protected void onPause() {
super.onPause();
mIsActivityPaused = true;
}
#Override
protected void onDestroy() {
unregisterReceiver(mBroadcastListener);
super.onDestroy();
}
private void refresh() {
// refresh
}
private void update() {
// update
}
private class BroadcastListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_REFRESH && !mIsActivityPaused)) {
refresh();
} else if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
}
}
}
}
I want to execute refresh() only if my Activity is visible on the screen, but I want to catch INTENT_UPDATE and execute update() during the entire lifetime of the Activity, regardless of whether the Activity is visible or not.
I didn't find any way to unregister only one of the two filters that I register in onCreate, so I use a flag to enable or disable the action to be executed when the INTENT_REFRESH broadcast is caught, depending on the state of the Activity.
The question is: is this the correct approach?
Or, would it be better to have two separate BroadcastReceivers as follows:
public class MyActivity extends Activity {
private MyActivity.BroadcastListenerRefresh mBroadcastListenerRefresh;
private MyActivity.BroadcastListenerUpdate mBroadcastListenerUpdate;
private boolean mIsBroadcastListenerRefreshRegistered = false;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Create the broadcast listeners
mBroadcastListenerRefresh = new BroadcastListenerRefresh();
mBroadcastListenerUpdate = new BroadcastListenerUpdate();
registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
registerReceiver(mBroadcastListenerUpdate, new IntentFilter(Params.INTENT_UPDATE));
}
#Override
protected void onResume() {
super.onResume();
if (mBroadcastListenerRefresh != null && !mIsBroadcastListenerRefreshRegistered) {
registerReceiver(mBroadcastListenerRefresh, new IntentFilter(Params.INTENT_REFRESH));
mIsBroadcastListenerRefreshRegistered = true;
}
}
#Override
protected void onPause() {
super.onPause();
if (mBroadcastListenerRefresh != null && mIsBroadcastListenerRefreshRegistered) {
unregisterReceiver(mBroadcastListenerRefresh);
mIsBroadcastListenerRefreshRegistered = false;
}
}
#Override
protected void onDestroy() {
unregisterReceiver(mBroadcastListenerRefresh);
unregisterReceiver(mBroadcastListenerUpdate);
super.onDestroy();
}
private void refresh() {
// refresh
}
private void update() {
// update
}
private class BroadcastListenerRefresh extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_REFRESH)) {
refresh();
}
}
}
private class BroadcastListenerUpdate extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
}
}
}
}
And which one has better performance?
instead, you may provide two different intent filters:
filter for refresh only
IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
filter for refresh and update
IntentFilter filterRefreshUpdate = new IntentFilter();
filterRefreshUpdate.addAction(Params.INTENT_REFRESH);
filterRefreshUpdate.addAction(Params.INTENT_UPDATE);
now you may switch between intent filters by registering and un-registering the desired one but your receiver's implementation would be same
For every action , create IntentFilter and register it.
#Override
protected void onResume() {
super.onResume();
BroadcastListener receiver = new BroadcastListener();
// Register the filter for listening broadcast.
IntentFilter filterRefresh = new IntentFilter(Params.INTENT_REFRESH);
IntentFilter filterUpdate = new IntentFilter(Params.INTENT_UPDATE);
registerReceiver(receiver, filterRefresh);
registerReceiver(receiver, filterUpdate);
}
private class BroadcastListener extends BroadcastReceiver {
public void onReceive(Context ctx, Intent intent) {
if (intent.getAction().equals(Params.INTENT_UPDATE)) {
update();
} else if(intent.getAction().equals(Params.INTENT_REFRESH)) {
refresh();
}
}
}
Using KOTLIN you can do it inline:
broadcastReceiver = NukeBroadcastReceiver()
registerReceiver(broadcastReceiver, IntentFilter().apply {
addAction(ACTION_DESTROY_EVERYTHING)
addAction(ACTION_RESTART_WORLD)
})

Categories

Resources