I am checking Internet connectivity in my app using BroadcastReceiver and I show an alert dialog if the connection is lost. It works fine. But my problem is that BroadcastReceiver works even if my app is in backgroung. So dialog pops up when internet connection is lost even if user is in some other app. This is totally ruining my app.
Has anyone got any idea how to restrict Broadcast receiver in the app only?
Here is my BroadcastReceiver :
public class ConnectivityChangedReceiver extends BroadcastReceiver{
#Override
public void onReceive( Context context, Intent intent )
{
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo != null && networkInfo.isConnected()) {
} else {
try{
Intent i=new Intent(context, InternetDialogActivity.class);
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(i);
} catch(Exception e){
e.printStackTrace();
}
}
}
}
And the activity is:
public class InternetDialogActivity extends Activity implements OnClickListener{
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.internet_dialog_box);
getWindow().setLayout(LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT);
Button retryButton = (Button) findViewById(R.id.retryInternetButton);
retryButton.setOnClickListener(this);
}
public boolean checkConnectivity(){
ConnectivityManager connectivityManager = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo networkInfo = connectivityManager.getActiveNetworkInfo();
if (networkInfo!=null && networkInfo.isConnected()) {
finish();
return true;
} else {
Intent intent = getIntent();
finish();
startActivity(intent);
return false;
}
}
#Override
public void onClick(View view) {
switch(view.getId()){
case R.id.retryInternetButton:
try{
checkConnectivity();
} catch(Exception e){
e.printStackTrace();
}
break;
}
}
}
Here is how I declared receiver and activity in manifest:
<receiver android:name="com.lisnx.service.ConnectivityChangedReceiver"
android:label="NetworkConnection">
<intent-filter>
<action android:name="android.net.conn.CONNECTIVITY_CHANGE"/>
</intent-filter>
</receiver>
<activity android:name="com.lisnx.activity.InternetDialogActivity"
android:configChanges="orientation|keyboardHidden"
android:theme="#android:style/Theme.Dialog" />
I have read that we can restrict BroadcastReceiver to work within the app by not declaring it in the manifest. But I don't know how will receiver work then? Please help me. I am stuck on it badly. Thanx in advance.
A BroadcastReceiver works when the app is in the background because the event that the receiver picks up are sent globally, and each app is registered to listen in on these, regardless of whether or not it is running.
To deal with this, in your BroadcastReceiver's onReceive code, check if your app is in the foreground.
There is one--and only one that I know of--consistently effective method to do this. You need to keep track of your pause/resume actions for your application. Ensure that you check this in every activity.
There is some sample code in this answer (solution #1). In your case, you would want to check MyApplication.isActivityVisible() == true as a validation before doing anything from your BroadcastReceiver.
Have you tried to remove the Intent filter from the manifest and register/unregister it in activity? So you can try to register Intent filter in onStart() and unregister it on onStop() methods. The code goes somethink like this:
static final String ACTION = "android.net.conn.CONNECTIVITY_CHANGE";
IntentFilter filter = new IntentFilter(ACTION);
this.registerReceiver(ConnectivityChangedReceiver, filter);
unregisterReceiver(ConnectivityChangedReceiver);
You should also learn about Activity Lifecycle, if it's not familiar yet.
You should register/unregister your BroadcastReceiver in onPause() and onResume() of each activity. Then you know that the receiver is only "listening" when your app is in the foreground. You can easily do that by creating your own BaseActivity that extends Activity and overrides onPause() and onResume() and registers/unregisters your receiver. Just have all your activities extend BaseActivity and have them call through to super.onResume() and super.onPause() as usual. Here's example code:
public class BaseActivity extends Activity {
// Create an IntentFilter to listen for connectivity change events
static IntentFilter filter = new IntentFilter("android.net.conn.CONNECTIVITY_CHANGE");
// Create an instance of our BroadcastReceiver
static ConnectivityChangedReceiver receiver = new ConnectivityChangedReceiver();
#Override
protected void onPause() {
super.onPause();
// Stop listening for connectivity change events
unregisterReceiver(receiver);
}
#Override
protected void onResume() {
super.onResume();
// Listen for connectivity change events
registerReceiver(receiver, filter);
}
}
All your activities should extend BaseActivity and if they need to do anything special in onResume() or onPause() just make sure to call through to super.onXXXXX() like this:
public MyActivity extends BaseActivity {
#Override
protected void onResume() {
super.onResume();
// Here you do whatever you need to do in onResume() of your activity
...
}
#Override
protected void onPause() {
super.onPause();
// Here you do whatever you need to do in onPause() of your activity
...
}
}
I didn't run the code through a compiler so I apologize if there's a typo or I missed something.
I think you will have to make sure that you are not using the receiver when app is in background. For that you will have to use every activities onPause() and onResume() methods.
As far as I know, if Broadcast receiver is registered inside manifest.xml then broadcast receiver exists as long as application exists. Also, Dynamically registered receivers (that means, Register your BroadcastReceiver programmatically) are called on the UI thread. This means that your receivers blocks any UI handling and thus the onReceive() method should be as fast as possible.
However, I will try to discuss information about Broadcast Receiver. But, first should know some information. Firstly, Broadcast receiver is a standalone application component which means it will continue running even when other application component are not running. That's why we unregister broadcast receiver in onPause on the activity. Also, Developer should register this in Activity.onResume() implementation.
Secondly, Developer should not unregister in Activity.onSaveInstanceState(), because this won't be called if the user moves back in the history stack. I have put that information from BroadcastReceiver documentation.
Another point is that a BroadcastReceiver object is only valid for the duration of the call to onReceive(). As soon as the onReceive() method is finished, your BroadcastReceiver terminates.
Now, how to register your receiver programmatically:
public abstract Intent registerReceiver (BroadcastReceiver receiver, IntentFilter filter)
Here, BroadcastReceiver- receiver will be call when any broadcast intent match with filter.
And IntentFilter- Intent specifies which event your receiver should listen to.
Register:
YourConnectionListener receiver;
this.reciever = new YourConnectionListener();
IntentFilter filter = new IntentFilter();
filter.addAction(WifiManager.NETWORK_STATE_CHANGED_ACTION);
filter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
registerReceiver(this.reciever, filter);
Sent your Broadcast Info:
Intent intent = new Intent();
intent.putExtra("Message", "Your connectivity info has Changed!!");
this.sendBroadcast(intent);
Receiver:
Now, need to receive the Broadcast. Android calls the onReceive() method on all registered broadcast receivers whenever the event occurs. Say you want to be notified whenever the connection is changed.
public class YourConnectionListener extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent){
// your Code
}
}
onReceive() has two arguments:
context: The Context object you can use to access additional information or to start services or activities.
intent: Intent used to register your receiver. This object contains additional information that you can use in your implementation.
Additionally, Developer should avoid any long-lasting tasks in your BroadcastReceiver. So, In statically and dynamically registered receivers, Developer should do minor tasks in the receiver itself.For any longer tasks you should start a service from within your receiver.
To make a Broadcast Receiver that fires only when you app is running follow the below code.
1. Create your Broadcast Receiver like this:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
public class InternetStatusNotifier extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
//Recieve notification here
}
}
2. Make an activity or fragment where you want the Broadcast Receiver to work like this:
import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
public class MainActivity extends Activity {
private InternetStatusNotifier mInternetStatusNotifier;
#Override
protected void onCreate(Bundle savedInstanceState) {
mInternetStatusNotifier = new InternetStatusNotifier();
super.onCreate(savedInstanceState);
}
#Override
protected void onResume() {
registerReceiver(mInternetStatusNotifier, new IntentFilter(
"android.net.conn.CONNECTIVITY_CHANGE"));
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(mInternetStatusNotifier);
super.onPause();
}
Note: That is how you use broadcasts receiver in a screen specific manner. Only the screen displaying will receive broadcasts in this way. When you register broadcast using manifest file then they are even received when app is closed
That is the way broadcast receivers work in Android. If you register for a broadcast in the manifest and your app is not running, Android will start a new process to handle the broadcast. It is generally a bad idea to directly show a UI from a broadcast receiver, because this may interrupt other apps. I'm also not convinced that a universal 'connection lost' dialog is a good idea either. This should probably be handled by each activity that uses network access.
As for the original question, you need to disable your receiver when your activity goes in the background (onPause(), etc.) and enable it when you come to the foreground (onResume(), etc). Put enabled=false in your manifest and then use something like this in your code to toggle it as necessary:
public static void toggle(Context context, boolean enable) {
int flag = enable ? PackageManager.COMPONENT_ENABLED_STATE_ENABLED
: PackageManager.COMPONENT_ENABLED_STATE_DISABLED;
ComponentName receiver = new ComponentName(context,
ConnectivityMonitor.class);
context.getPackageManager().setComponentEnabledSetting(receiver, flag,
PackageManager.DONT_KILL_APP);
}
A simple way of finding whether the app is in foreground or not
if((mContext.getPackageName().equalsIgnoreCase(
((ActivityManager) mContext.getSystemService(Context.ACTIVITY_SERVICE))
.getRunningTasks(1).get(0).topActivity.getPackageName())))
{
//app is in foreground;
}
I better suggest you to check the internet setting from the application when someone opens it, here is the piece of code how i do it.
public static boolean isNetworkConnected(Context ctx) {
ConnectivityManager cm = (ConnectivityManager) ctx.getSystemService(Context.CONNECTIVITY_SERVICE);
NetworkInfo ni = cm.getActiveNetworkInfo();
if (ni == null) {
return false; // There are no active networks.
} else
return true;
}
Related
How can I get current/running Activity from Android Service? I am working on Screen Locker and I need to getActivity() and getWindow() in order to getDecorView() to make navigation bar hidden. If anyone knows better solution, please comment. Thanks!
There is no way to get a reference to the Activity as far as I know.
A classic aproach to communicate between a Service and an Activity is by using a BroadcastReceiver.
Here is an Example:
on your Activity you can create a Inner class that extends BroadcastReceiver:
private class ServiceReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
if (arg1.hasExtra(Constants.SOME_ACTION)) {
//DO YOUR THING
}
}
}
Don't forget to register it on onCreate:
serviceReceiver = new ServiceReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(Constants.SERVICE_RECEIVER);
registerReceiver(serviceReceiver, intentFilter);
and to unRegister it on onPause()
if (serviceReceiver != null)
unregisterReceiver(serviceReceiver);
Then from your Service you can send a Broadcast on an Event, something like this:
Intent intent = new Intent();
intent.setAction(Constants.SERVICE_RECEIVER);
intent.putExtra(Constants.SOME_ACTION, true);
sendBroadcast(intent);
This way your Activity can react to Events on your Service.
Can anybody tell me a way to create an in-application BroadcastReceiver? I have created BroadcastReceiver which Toasts a message. It works even when the application is in background state, I want it to work only when application is in foreground.
public class MainActivity extends Activity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
this.registerReceiver(this.mConnReceiver, new IntentFilter(
ConnectivityManager.CONNECTIVITY_ACTION));
}
private BroadcastReceiver mConnReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
boolean noConnectivity = intent.getBooleanExtra(
ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
String reason = intent
.getStringExtra(ConnectivityManager.EXTRA_REASON);
boolean isFailover = intent.getBooleanExtra(
ConnectivityManager.EXTRA_IS_FAILOVER, false);
NetworkInfo currentNetworkInfo = (NetworkInfo) intent
.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO);
NetworkInfo otherNetworkInfo = (NetworkInfo) intent
.getParcelableExtra(ConnectivityManager.EXTRA_OTHER_NETWORK_INFO);
if (currentNetworkInfo.isConnected()) {
System.out.println("Connected");
Toast.makeText(getApplicationContext(), "Connected",
Toast.LENGTH_LONG).show();
} else {
System.out.println("Not Connected");
Toast.makeText(getApplicationContext(), "Not Connected",
Toast.LENGTH_LONG).show();
}
}
};
}
So here is my code which is checking network state and generating a BroadcastReceiver. I haven't added anything in manifest.
There are a number of ways to do this. The first 2 I can think of are like this:
If your <receiver> is declared in the manifest with an <intent-filter>, you can enable it and disable it from your application so that it is only enabled when the app is in the foreground. To do this, initially set the receiver disabled by adding android:enabled="false" to the manifest entry for <receiver>.
Now, when your app is running, in onResume() you want to enable the receiver. Use PackageManager.setComponentEnabledSetting() to do this. When your activity goes to the background, in onPause() you can disable the receiver again.
Dynamically register and unregister the receiver. For this you don't need to declare the receiver in the manifest. In your application, create an instance of your BroadcastReceiver and in onResume() call registerReceiver() with the appropriate intent filter. When the app goes to the background, in onPause() call unregisterReceiver() to remove it. The receiver will only receive calls to onReceive() while the app is in the foreground.
see Context.registerReceiver() and Context.unregisterReceiver()
I'm using C2DM, my BroadcastReceivers propagate the C2DM events to a local service. the service complete the registration by sending the id to my webserver pus it's responsible for letting the device know about new messages, however if the application (one of the activities) is up we want to send an intent to that activity with the new data so it can be updated, if not than the NotificationManager is used to notify the user.
The issue is, how to know the activity is running ? the Application object is not an option since the Service is part of the application it's obviously going to be present. unregister in the onDesroy of each application is also not an option since it may occur in orientation change...
Any standard way to get it done ?
Solution 1:
You can use ActivityManager for Checking if Activity is Running or not:
public boolean isActivityRunning() {
ActivityManager activityManager = (ActivityManager)Monitor.this.getSystemService (Context.ACTIVITY_SERVICE);
List<RunningTaskInfo> activitys = activityManager.getRunningTasks(Integer.MAX_VALUE);
isActivityFound = false;
for (int i = 0; i < activitys.size(); i++) {
if (activitys.get(i).topActivity.toString().equalsIgnoreCase("ComponentInfo{com.example.testapp/com.example.testapp.Your_Activity_Name}")) {
isActivityFound = true;
}
}
return isActivityFound;
}
need to add the permission to your manifest..
<uses-permission android:name="android.permission.GET_TASKS"/>
Solution 2:
Your can use an static variable in your activity for which you want to check it's running or not and store it some where for access from your service or broadcast receiver as:
static boolean CurrentlyRunning= false;
public void onStart() {
CurrentlyRunning= true; //Store status of Activity somewhere like in shared //preference
}
public void onStop() {
CurrentlyRunning= false;//Store status of Activity somewhere like in shared //preference
}
I hope this was helpful!
The next approach would work well if you want to handle incoming Google Cloud message (C2DM) by your activity (if any is running) or issue a notification if no activities are running.
Register one BroadcastReceiver in the manifest file. This receiver will handle C2D messages whenever application not running. Register another BroadcastReceiver programmatically in your activity. This receiver will handle C2D messages whenever activity is running.
AndoroidManifest.xml
<receiver
android:name=".StaticReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="com.mypackage" />
</intent-filter>
</receiver>
MyReceiver.java
public class StaticReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Trigger a Notification
}
}
MyActivity.java
public class MyActivity extends ActionBarActivity {
#Override
protected void onResume() {
super.onResume();
final IntentFilter filter = new
IntentFilter("com.google.android.c2dm.intent.RECEIVE");
filter.addCategory("com.mypackage");
filter.setPriority(1);
registerReceiver(dynamicReceiver, filter,
"com.google.android.c2dm.permission.SEND", null);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(dynamicReceiver);
}
private final BroadcastReceiver dynamicReceiver
= new BroadcastReceiver()
{
#Override
public void onReceive(Context context, Intent intent) {
// TODO Handle C2DM
// blocks passing broadcast to StaticReceiver instance
abortBroadcast();
}
};
}
Note! To catch broadcasts first, the priority of dynamicReceiver IntentFilter must be higher than priority of StaticReceiver instance IntentFilter (default priority is '0').
PS. It looks like broadcasts issued by Google Cloud Messaging Service are ordered broadcasts. Original idea author: CommonsWare
Copied from here.
you can use a static variable within the activity.
class MyActivity extends Activity {
static boolean active = false;
public void onStart() {
active = true;
}
public void onStop() {
active = false;
}
}
Easiest way to check that whether an Activity is running or not is:
Context context = MyActivity.this;
if (! ((Activity) context).isFinishing()) {
// Activity is running
} else {
// Activity has been finished
}
Note: If activity is not running you should not perform any UI related operation.
I am writing an alarm code and using a broadcast receiver. I am able to receive the broadcast receiver. but now I want to come back to the calling activity and update the UI of my activity. I am not able to this.
I used the following code in my activity but it is never executing that code.
private BroadcastReceiver myBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "I am back!!", Toast.LENGTH_LONG).show();
}
};
#Override
protected void onPause()
{
super.onPause();
unregisterReceiver(myBroadcastReceiver);
}
#Override
protected void onResume()
{
super.onResume();
IntentFilter intentFilter = new IntentFilter("com.test.Main");
registerReceiver(myBroadcastReceiver, intentFilter);
}
in the manifest file I have included the following, here gotAlarm is the broadcast receiver file
<receiver android:name=".gotAlarm"
android:enabled="true">
</receiver>
gotAlarm file is one which gets called from the pending intent of the alarm set
public class gotAlarm extends BroadcastReceiver {
public void onReceive(Context context, Intent intent){
Toast.makeText(context, "Wake Up!!", Toast.LENGTH_LONG).show();
}
}
May be I am missing something very basic.
please help.
Two things:
If you dynamically register the receiver via Context.registerReceiver() then you won't receive broadcasts when Activity is paused (or stopped or not-running). If you need to receive broadcasts even when Activity is paused then create a top-level BroadcastReceiver class (as opposed to your inner class) and use <receiver> to register it.
BroadcastReceiver lifecycle docs state that BroadcastReceiver object is alive only during processing of onReceive(). You can not do any async tasks like showing dialogs, etc.. In your case (Activities might not be running and you receive a broadcast) you should use NotificationManager to notify user something happened.
I have dropped this way and I am starting a new activity on receiving broadcast. And I am sending information data from calling activity to broadcast and from broadcast to next activity. This has served the purpose.
Did you register your BroadcastReceiver (you can do this in the 'onResume'-method of your Activity)? Also, you should unregister your BroadcastReceiver in the 'onPause'-method.
I'd like to know what is the best practice/way of programmatically register a broadcast receiver. I want to register specific receivers according to user choice.
As the registration is done through the manifest file, I'm wondering if there's a proper way to achieve this in code.
In your onCreate method you can register a receiver like this:
private BroadcastReceiver receiver;
#Override
public void onCreate(Bundle savedInstanceState){
// your oncreate code should be
IntentFilter filter = new IntentFilter();
filter.addAction("SOME_ACTION");
filter.addAction("SOME_OTHER_ACTION");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//do something based on the intent's action
}
};
registerReceiver(receiver, filter);
}
Remember to run this in the onDestroy method:
#Override
protected void onDestroy() {
if (receiver != null) {
unregisterReceiver(receiver);
receiver = null;
}
super.onDestroy();
}
One important point that people forget to mention is the life time of the Broadcast Receiver. The difference of programmatically registering it from registering in AndroidManifest.xml is that. In the manifest file, it doesn't depend on application life time. While when programmatically registering it it does depend on the application life time. This means that if you register in AndroidManifest.xml, you can catch the broadcasted intents even when your application is not running.
Edit: The mentioned note is no longer true as of Android 3.1, the Android system excludes all receiver from receiving intents by default if the corresponding application has never been started by the user or if the user explicitly stopped the application via the Android menu (in Manage → Application). https://developer.android.com/about/versions/android-3.1.html
This is an additional security feature as the user can be sure that only the applications he started will receive broadcast intents.
So it can be understood as receivers programmatically registered in Application's onCreate() would have same effect with ones declared in AndroidManifest.xml from Android 3.1 above.
It sounds like you want to control whether components published in your manifest are active, not dynamically register a receiver (via Context.registerReceiver()) while running.
If so, you can use PackageManager.setComponentEnabledSetting() to control whether these components are active:
http://developer.android.com/reference/android/content/pm/PackageManager.html#setComponentEnabledSetting(android.content.ComponentName, int, int)
Note if you are only interested in receiving a broadcast while you are running, it is better to use registerReceiver(). A receiver component is primarily useful for when you need to make sure your app is launched every time the broadcast is sent.
Define a broadcast receiver anywhere in Activity/Fragment like this:
mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(TAG," onRecieve"); //do something with intent
}
};
Define IntentFilter in onCreate()
mIntentFilter=new IntentFilter("action_name");
Now register the BroadcastReciever in onResume() and Unregister it in onPause() [because there is no use of broadcast if the activity is paused].
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
if(mReceiver != null) {
unregisterReceiver(mReceiver);
mReceiver = null;
}
super.onPause();
}
For detail tutorial, have a look at broadcast receiver-two ways to implement.
package com.example.broadcastreceiver;
import android.app.Activity;
import android.content.IntentFilter;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity {
UserDefinedBroadcastReceiver broadCastReceiver = new UserDefinedBroadcastReceiver();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
#Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
/**
* This method enables the Broadcast receiver for
* "android.intent.action.TIME_TICK" intent. This intent get
* broadcasted every minute.
*
* #param view
*/
public void registerBroadcastReceiver(View view) {
this.registerReceiver(broadCastReceiver, new IntentFilter(
"android.intent.action.TIME_TICK"));
Toast.makeText(this, "Registered broadcast receiver", Toast.LENGTH_SHORT)
.show();
}
/**
* This method disables the Broadcast receiver
*
* #param view
*/
public void unregisterBroadcastReceiver(View view) {
this.unregisterReceiver(broadCastReceiver);
Toast.makeText(this, "unregistered broadcst receiver", Toast.LENGTH_SHORT)
.show();
}
}
Two choices
1) If you want to read Broadcast only when the Activity is visible
then,
registerReceiver(...) in onStart() and unregisterReceiver(...) in onStop()
2) If you want to read Broadcast even if Activity is in Background
then,
registerReceiver(...) in onCreate(...) and unregisterReceiver(...) in onDestroy()
Bonus:
If you are lazy
If you don't want to write boilerplate code for registering and unregistering a BroadcastReceiver again and again in each Activity then,
Create an abstract Activity
Write boilerplate code in Activity
Leave the implementation as abstract methods
Here is the code snippet:
Abstract Activity
public abstract class BasicActivity extends AppCompatActivity {
private BroadcastReceiver broadcastReceiver;
private IntentFilter filter;
private static final String TAG = "BasicActivity";
/**********************************************************************
* Boilerplate code
**********************************************************************/
#Override
public void onCreate(Bundle sis){
super.onCreate(sis);
broadcastReceiver = getBroadcastReceiver();
filter = getFilter();
}
#Override
public void onStart(){
super.onStart();
register();
}
#Override
public void onStop(){
super.onStop();
unregister();
}
private void register(){
registerReceiver(broadcastReceiver,filter);
}
private void unregister(){
unregisterReceiver(broadcastReceiver);
}
/**********************************************************************
* Abstract methods
**********************************************************************/
public abstract BroadcastReceiver getBroadcastReceiver();
public abstract IntentFilter getFilter();
}
Using this approach you can write more boilerplate code such as
writing common animations, binding to a service, etc.
See full code:
HERE
According to Listening For and Broadcasting Global Messages, and Setting Alarms in Common Tasks and How to Do Them in Android:
If the receiving class is not
registered using in its
manifest, you can dynamically
instantiate and register a receiver by
calling Context.registerReceiver().
Take a look at registerReceiver (BroadcastReceiver receiver, IntentFilter filter) for more info.
It is best practice to always supply the permission when registering the receiver, otherwise you will receive for any application that sends a matching intent. This can allow malicious apps to broadcast to your receiver.
for LocalBroadcastManager
Intent intent = new Intent("any.action.string");
LocalBroadcastManager.getInstance(context).
sendBroadcast(intent);
and register in onResume
LocalBroadcastManager.getInstance(
ActivityName.this).registerReceiver(chatCountBroadcastReceiver, filter);
and Unregister it onStop
LocalBroadcastManager.getInstance(
ActivityName.this).unregisterReceiver(chatCountBroadcastReceiver);
and recieve it ..
mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.e("mBroadcastReceiver", "onReceive");
}
};
where IntentFilter is
new IntentFilter("any.action.string")
Create a broadcast receiver
[BroadcastReceiver(Enabled = true, Exported = false)]
public class BCReceiver : BroadcastReceiver
{
BCReceiver receiver;
public override void OnReceive(Context context, Intent intent)
{
//Do something here
}
}
From your activity add this code:
LocalBroadcastManager.getInstance(ApplicationContext)
.registerReceiver(receiver, filter);