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().
Related
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)
I've tried the examples from many different answers to similar questions, but nothing works. When I press the back button, I get "Broadcasting message" in the log but not "Broadcast received". Why?
public class MainActivity extends ActionBarActivity
implements ContactsFragment.ContactListener {
private IntentFilter filter;
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG, "Broadcast received");
}
};
#SuppressLint("NewApi")
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
...
filter = new IntentFilter(Constants.BROADCAST_ACTION);
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
}
#Override
public void onBackPressed() {
Log.d("sender", "Broadcasting message");
Intent intent = new Intent(Constants.BROADCAST_ACTION);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
if (!pane.isOpen()) {
pane.openPane();
} else {
finish();
}
}
#Override
public void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(receiver);
super.onPause();
}
}
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));
}
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)
})
I am trying to register a broadcastreceiver in a small Android app that I am playing around with. I think I am doing what I am supposed to do, but still the receiver doesn't register. It must be something small that I am missing and it is driving me crazy.
public class CreateReceiver extends Activity
{
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}//end of onCreate
BroadcastReceiver myreceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context recvc, Intent recvi)
{
}
};
#Override
public void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CAMERA_BUTTON);
if (this.registerReceiver(myreceiver, intentFilter) == null)
{
Toast.makeText(this, "Could not register receiver", Toast.LENGTH_LONG).show();
}//end of if
}//end of onResume
#Override
public void onPause()
{
this.unregisterReceiver(myreceiver);
super.onPause();
}//end of onPause
}//end of CreateReceiver
Can anyone tell me what I am doing wrong? Thanks.
You have to register your BroadcastReceiver from within onCreate
public class CreateReceiver extends Activity
{
private IntentFilter intentFilter = new IntentFilter(Intent.ACTION_CAMERA_BUTTON);
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
registerReceiver(myreceiver , intentFilter);
}//end of onCreate
BroadcastReceiver myreceiver = new BroadcastReceiver()
{
#Override
public void onReceive(Context recvc, Intent recvi)
{
}
};
...