Android BroadcastReceiver within Activity - android

I'm just trying this little sample project, all it does:
Activity one has a Button that sends a Broadcast. Activity two displays a toast when received.
Below is the code, the Broadcast is never received. What do I do wrong?
Sending the Broadcast
public class SendBroadcast extends Activity {
public static String BROADCAST_ACTION = "com.unitedcoders.android.broadcasttest.SHOWTOAST";
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void sendBroadcast(View v){
Intent broadcast = new Intent();
broadcast.setAction(BROADCAST_ACTION);
sendBroadcast(broadcast);
}
}
Receiving it
public class ToastDisplay extends Activity {
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
}
};
#Override
protected void onResume() {
IntentFilter filter = new IntentFilter();
filter.addAction(SendBroadcast.BROADCAST_ACTION);
registerReceiver(receiver, filter);
super.onResume();
}
#Override
protected void onPause() {
unregisterReceiver(receiver);
super.onPause();
}
}
Manifest
<application android:icon="#drawable/icon" android:label="#string/app_name">
<activity android:name=".SendBroadcast" android:label="#string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"></action>
</intent-filter>
</activity>
</application>

What do I do wrong?
The source code of ToastDisplay is OK (mine is similar and works), but it will only receive something, if it is currently in foreground (you register receiver in onResume). But it can not receive anything if a different activity (in this case SendBroadcast activity) is shown.
Instead you probably want to startActivity ToastDisplay from the first activity?
BroadcastReceiver and Activity make sense in a different use case. In my application I need to receive notifications from a background GPS tracking service and show them in the activity (if the activity is in the foreground).
There is no need to register the receiver in the manifest. It would be even harmful in my use case - my receiver manipulates the UI of the activity and the UI would not be available during onReceive if the activity is not currently shown. Instead I register and unregister the receiver for activity in onResume and onPause as described in
BroadcastReceiver documentation:
You can either dynamically register an instance of this class with Context.registerReceiver() or statically publish an implementation through the tag in your AndroidManifest.xml.

Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT);
makes the toast, but doesnt show it.
You have to do Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();

Extends the ToastDisplay class with BroadcastReceiver and register the receiver in the manifest file,and dont register your broadcast receiver in onResume() .
<application
....
<receiver android:name=".ToastDisplay">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
if you want to register in activity then register in the onCreate() method e.g:
onCreate(){
sentSmsBroadcastCome = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Toast.makeText(context, "SMS SENT!!", Toast.LENGTH_SHORT).show();
}
};
IntentFilter filterSend = new IntentFilter();
filterSend.addAction("m.sent");
registerReceiver(sentSmsBroadcastCome, filterSend);
}

You need to define the receiver as a class in the manifest and it will receive the intent:
<application
....
<receiver android:name=".ToastReceiver">
<intent-filter>
<action android:name="com.unitedcoders.android.broadcasttest.SHOWTOAST"/>
</intent-filter>
</receiver>
</application>
And you don't need to create the class manually inside ToastDisplay.
In the code you provided, you must be inside ToastDisplay activity to actually receive the Intent.

I think your problem is that you send the broadcast before the other activity start ! so the other activity will not receive anything .
The best practice to test your code is to sendbroadcast from thread or from a service so the activity is opened and its registered the receiver and the background process sends a message.
start the ToastDisplay activity from the sender activity ( I didn't test that but it may work probably )

You forget to write .show() at the end, which is used to show the toast message.
Toast.makeText(getApplicationContext(), "received", Toast.LENGTH_SHORT).show();
It is a common mistake that programmer does, but i am sure after this you won't repeat the mistake again... :D

Your also have to register the receiver in onCreate(), like this:
IntentFilter filter = new IntentFilter();
filter.addAction("csinald.meg");
registerReceiver(receiver, filter);

Related

Why does this Broadcast Receiver work in Android?

I am a Beginner in programming in Android and now I am sitting in front of this problem: I would code a Broadcast Receiver, which gets fired whenever the Phone gets charged or "discharged". So, registered the Receiver in the Manifest.xml:
<receiver
android:name=".Starter"
android:enabled="true"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.ACTION_POWER_CONNECTED" />
<action android:name="android.intent.action.ACTION_POWER_DISCONNECTED" />
</intent-filter>
</receiver>
In the Class of the Broadcast Receiver, I wrote a Toast into the onReceive()-Method, which should be performed, when the Receiver would work:
> public class Starter extends BroadcastReceiver {
>
> #Override
> public void onReceive(Context context, Intent intent) {
> Toast.makeText(context,"blablabla",Toast.LENGTH_LONG).show();
> }
> }
I am so thankful for every Help, LG
When using a BroadcastReceiver, it must be registered with the class that will listen for broadcasts.
This is done using Context.registerReceiver() (https://developer.android.com/reference/android/content/Context#registerreceiver)
or
LocalBroadcastManager.getInstance(...).registerReceiver(...) (https://developer.android.com/reference/android/support/v4/content/LocalBroadcastManager).
Create IntentFilters that will listen for the particular broadcast.
Register your receiver in onResume() in a class that extends Activity or Fragment.
class MainActivity extends Activity
{
Starter myReceiver = new Starter(); // This is your class that extends BroadcastReceiver
#Override
public void onResume()
{
super.onResume();
// Create IntentFilters that will listen for certain actions:
IntentFilter intentFilterConnected = new IntentFilter(Intent.ACTION_POWER_CONNECTED);
IntentFilter intentFilterDisconnected = new IntentFilter(Intent.ACTION_POWER_DISCONNECTED);
// Then pass these intents to registerReceiver():
registerReceiver(myReceiver, intentFilterConnected);
registerReceiver(myReceiver, intentFilterDisconnected);
}
}
Now myReceiver's onReceive() will execute when MainActivity receives the broadcasts matching the IntentFilters.
Note: If the class that instantiates myReceiver does not extend Activity or Fragment, then you will need to use LocalBroadcastManager.getInstance(...).registerReceiver(...).

Register a Local BroadcastReceiver in AndroidManifest.xml?

Is there anyway to register a BroadcastReceiver in AndroidManifest.xml and receives broadcast that is send by a LocalBroadcastManager?
Currently I must call
registerReceiver(BroadcastReceiver receiver, IntentFilter filter)
to register a Receiver, declare in AndroidManifest.xml won't work. But this means I must know exactly the receiver's package name and class name, not just the intent filter. Is it possible to declare the receiver in the manifest file?
following is my current code.
AndroidManifest.xml:
...
<receiver
android:name="com.example.test.MessageReceiver"
android:enabled="true" >
<intent-filter>
<action android:name="com.m2x.test.intent.MESSAGE_RECEIVED" />
</intent-filter>
</receiver>
...
MainActivity.java:
Intent intent = new Intent();
intent.setAction("com.m2x.test.intent.MESSAGE_RECEIVED");
LocalBroadcastManager manager = LocalBroadcastManager.getInstance(mContext.get());
manager.sendBroadcast(intent);
MessageReceiver.java
public class MessageReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("com.m2x.test.intent.MESSAGE_RECEIVED")) {
Toast.makeText(context, "user message received", Toast.LENGTH_SHORT).show();
}
}
}
No, you can't.
The local BroadcastReceiver isn't a real BroadcastReceiver, basically its a list of callbacks functions.
You can check the source code of LocalBroadcastManager.java.

I want to access and launch broadcast receiver from an activity and do somthing

I am trying to develop an android app, in which I want to sent a message from the phone while making call.
The destination number is taken from the application database.
I have completed till that part, but I cant access the broadcast receiver in my activity:
public class PARENT_CALLActivity extends Activity
{
/** Called when the activity is first created. */
String PARENT=null;
EditText edparent;
Button submit;
String parent_number;
public static final String BROADCAST = "sha.pcall.android.action.broadcast";
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
edparent=(EditText)findViewById(R.id.editText1);
submit=(Button)findViewById(R.id.btnsubmit);
submit.setOnClickListener(new OnClickListener()
{
#Override
public void onClick(View v)
{
// TODO Auto-generated method stub
PARENT=edparent.getText().toString();
MyDabasehandler db=new MyDabasehandler(getApplicationContext());
if(db.getContact().equals(null))
{
db.addContact(new Contacts(PARENT));
}
else
{
db.editContact();
}
Intent intent = new Intent(getApplicationContext(),LocationUpdateReceiver.class);
sendBroadcast(intent);
finish();
}
});
}
public class LocationUpdateReceiver extends BroadcastReceiver
{
#Override
public void onReceive(Context context, Intent intent)
{
String outgoing_number=intent.getStringExtra(Intent.EXTRA_PHONE_NUMBER);
Toast.makeText(context, outgoing_number, Toast.LENGTH_LONG).show();
}
}
}
If you are creating a separate class by extending Broadcast receiver I suggest you do it in a separate Class file. If you only want to receive broadcasts as long as the activity is open create a private Broadcast receiver variable. like in this question:
Where to register a BroadcastReceiver (Activity lifecycle fun)
In latter case you can register the broadcast receiver variable with this method called registerreceiver.
Here is the link
It all actually depends on the requirements. If you want to receive broadcasts even if your app is closed (or the activity is not in the foreground), you need to register your broadcast receiver in the manifest file like this:
<receiver
android:name="com.example.myapp.GCMBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND">
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="com.example.myapp" />
</intent-filter>
</receiver>
This is an example of google cloud message broadcast receiver. You also need to add intent filter, to specify which type of broadcast you want to receiver. In the above example the broadcast receiver can receive (see the intent-filter tag) two intents with actions:
"com.google.android.c2dm.intent.RECEIVE"
and
"com.google.android.c2dm.intent.REGISTRATION"
After you are done with this you can accomplish your tasks in the overridden onReceive() method of broadcast receiver.
Hope this helps.

In Android how do you register to receive headset plug broadcasts?

I am working in Android 2.1, and I want to detect when the headset is plugged in/taken out. I'm pretty new to android.
I think the way to do it is using a Broadcast receiver. I sublcassed this, and I also put the following in my AndroidManifest.xml. But do you have to register the receiver somehwere else, like in the activity? I'm aware there are lots of threads on this, but I don't really understand what they're talking about. Also, what's the difference between registering in AndroidManifest.xml versus registering dynamically in your activity?
<receiver android:enabled="true" android:name="AudioJackReceiver" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" >
</action>
</intent-filter>
</receiver>
And this was the implementation of the class (plus imports)
public class AudioJackReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
Log.w("DEBUG", "headset state received");
}
}
I was just trying to see if it works, but nothing shows up when I unplug/plug in the headset while running the application.
EDIT: the documentation doesn't say this, but is it possible that this one won't work if registered in the manifest? I was able to get it to respond when I registered the receiver in one of my applications (or do you have to do that anyway?)
Just complementing Greg`s answer, here is the code that you need divided in two parts
Register the Service in the first Activity (here its called MainActivity.java).
Switch over the result of the ACTION_HEADSET_PLUG action in the BroadCastReceiver.
Here it goes:
public class MainActivity extends Activity {
private static final String TAG = "MainActivity";
private MusicIntentReceiver myReceiver;
#Override protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
myReceiver = new MusicIntentReceiver();
}
#Override public void onResume() {
IntentFilter filter = new IntentFilter(Intent.ACTION_HEADSET_PLUG);
registerReceiver(myReceiver, filter);
super.onResume();
}
private class MusicIntentReceiver extends BroadcastReceiver {
#Override public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_HEADSET_PLUG)) {
int state = intent.getIntExtra("state", -1);
switch (state) {
case 0:
Log.d(TAG, "Headset is unplugged");
break;
case 1:
Log.d(TAG, "Headset is plugged");
break;
default:
Log.d(TAG, "I have no idea what the headset state is");
}
}
}
}
Here are two sites that may help explain it in more detail:
http://www.grokkingandroid.com/android-tutorial-broadcastreceiver/
http://www.vogella.com/articles/AndroidBroadcastReceiver/article.html
You have to define your intent; otherwise it won't access the system function. The broadcast receiver; will alert your application of changes that you'd like to listen for.
Every receiver needs to be subclassed; it must include a onReceive(). To implement the onReceive() you'll need to create a method that will include two items: Context & Intent.
More then likely a service would be ideal; but you'll create a service and define your context through it. In the context; you'll define your intent.
An example:
context.startService
(new Intent(context, YourService.class));
Very basic example. However; your particular goal is to utilize a system-wide broadcast. You want your application to be notified of Intent.ACTION_HEADSET_PLUG.
How to subscribe through manifest:
<receiver
android:name="AudioJackReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>
Or you can simply define through your application; but. Your particular request; will require user permissions if you intend to detect Bluetooth MODIFY_AUDIO_SETTINGS.
You need to enable the broadcast receiver and set the exported attribute to true:
<receiver
android:name="AudioJackReceiver"
android:enabled="true"
android:exported="true" >
<intent-filter>
<action android:name="android.intent.action.HEADSET_PLUG" />
</intent-filter>
</receiver>

My Broadcast receiver get execute even if my application is not working

My broadcast receiver is Still getting execute even if My application is not working.
as an example I am using android.intent.action.NEW_OUTGOING_CALL to check outgoing call and than i stop music and push notification ..
but even i close my app and kill all task and after if i call than i get notification of my app..
So how do i manage to work my broadcast when i am using my app.
I have crated Service to play music and 2 broadcast receiver file for incoming and outgoing.
Help to solve this problem.
Also How can i destroy my app with service running behind If user press exit button.
**Update I made edited it and its working now fine..thank you so much you all
here is my code
<activity
android:name=".MainActivity"
android:label="#string/title_activity_main"
android:launchMode="singleTask">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name="OutgoingCallInterceptor">
<intent-filter android:priority="1">
<action android:name="android.intent.action.NEW_OUTGOING_CALL" />
</intent-filter>
</receiver>
<receiver android:name="IncomingCallInterceptor">
<intent-filter android:priority="1">
<action android:name="android.intent.action.PHONE_STATE" />
<action android:name="android.media.AUDIO_BECOMING_NOISY" />
</intent-filter>
</receiver>
Update
as you all suggest me i have made receiver into main class file and register it from there but it wont work
public class MainActivity extends Activity {
RemoteViews layout;
int SDK_INT;
BroadcastReceiver br;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter("android.media.AUDIO_BECOMING_NOISY");
this.registerReceiver(br, filter);
setContentView(R.layout.activity_main);
SDK_INT = android.os.Build.VERSION.SDK_INT;
System.out.println(SDK_INT);
Button start = (Button)findViewById(R.id.play);
Button stop = (Button)findViewById(R.id.stop);
start.setOnClickListener(startListener);
stop.setOnClickListener(stopListener);
br = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
if (intent.getAction().equals(android.media.AudioManager.ACTION_AUDIO_BECOMING_NOISY)) {
context.stopService(new Intent(context, myPlayService.class));
Toast.makeText(context, "Headphones disconnected.", Toast.LENGTH_SHORT).show();
}
} }
};
#Override
protected void onDestroy() {
super.onDestroy();
unregisterReceiver(br);
}
an example: how a broadcast reciver can be registered and un registered change as per your need "i hope the code is self explanatory"
private final BroadcastReceiver xyz= new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
//ur reciver
}
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
IntentFilter filter = new IntentFilter(ACTION);//ur action
this.registerReceiver(xyz, filter);
}
#Override
protected void onDestroy(){
super.onDestroy();
unregisterReceiver(xyz);
}
You need to declare unregisterReceiver() in onResume() or in onpause() methods.
This will solve your problem.
First:
use unregisterReceiver() in onPause() and re-register in onStart().
It's always better to have locally registering the receiver if you want to provide the functionality only when your app is up.
Second:
Use service after binding it and don't call unBind while exiting the app will keep your service alive even after your app is down. I guess you are starting the service locally. Start service by binding it.
Hope this will solve your problem.

Categories

Resources