I have one Activity which creates a BroadcastReceiver with an IntentFilter in the method onCreate(...):
IntentFilter iFilter = new IntentFilter("action");
receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
}
};
registerReceiver(receiver, iFilter);
On the other side is an IntentService, which shall send some data:
Intent intent = new Intent(getApplicationContext(), receiver.class);
intent.setAction("action");
[...]
sendBroadcast(intent);
But it seems not to work. No Broadcast ist received.
My service class is in an android lib, perhaps this makes trouble.
Thanks for any advices.
Just create the intent with your action.
Intent intent = new Intent("action");
[...]
sendBroadcast(intent);
And consider renaming "action" to something more meaningful, like "com.my.package.actions.SOME_ACTION".
If you only want that your application components receive the broadcast then use:
Register a permission in your Manifest with a signature protection level (and define a use-permission for that permission). More here.
Use sendBroadcast(intent, permission), and specify the permission in 1.
if the intent is inside your app only, consider using LocalBroadcastManager
Related
I am trying to build a notification while a music playback service is running and use the notification to interact with the service (play, pause, stop) using the Broadcast mechanism.
(I know there is also the possibility to use PendingIntent.getService() as an action button in the notification, but I don't like this idea, because this would trigger the onStartCommand() of the service and I need to parse and analyze the Intent object to take action, which seems not as clean as the BroadcastReceiver approach, described below).
Let's illustrate what we have so far with some (truncated) code.
We are creating a Notification object inside the service lifecycle, add an action button, and showing the notification using startForeground().
...
Intent i = new Intent(getBaseContext(), PlayerService.class);
PendingIntent piStop = PendingIntent.getBroadcast(getBaseContext(), 1, i, PendingIntent.FLAG_ONE_SHOT);
NotificationCompat.Action actionStopPlayback = new NotificationCompat.Action(R.drawable.ic_stop_white_36dp, "Stop playback", piStop);
notification.addAction(actionStopPlayback);
...
Then we are registering a BroadcastReceiver inside the onCreate() of the service (and unregistering it in onDestroy of course; this is a more simplified example).
IntentFilter intentFilter = new IntentFilter();
registerReceiver(new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.d(getClass().toString(), "Broadcast received");
}
}, intentFilter);
And the final result is that the onReceive() of the receiver is never called. The service is a continuous one and is active when the Notification action sends the broadcast. Since I have no way of debugging broadcasts due to their nature, I'm kind of blocked here.
You're creating this explicit Intent for the PendingIntent:
Intent i = new Intent(getBaseContext(), PlayerService.class);
This won't work for a couple of reasons. Explicit Intents - those created for a specific target class - do not work with dynamically registered Receiver instances. Also, this is targeting the wrong class. A broadcast Intent with a Service class target will just fail outright. A getBroadcast() PendingIntent would need a BroadcastReceiver class as the target.
With your current setup - the dynamically registered Receiver instance - you'll need to use an implicit Intent; i.e., an Intent with an action String, rather than a target class. For example:
Intent i = new Intent("com.hasmobi.action.STOP_PLAYBACK");
You would then use that action String for the IntentFilter you're using to register the Receiver.
IntentFilter intentFilter = new IntentFilter("com.hasmobi.action.STOP_PLAYBACK");
Do note that an IntentFilter can have multiple actions, so you can register a single Receiver to handle several different actions.
Alternatively, you could stick with using an explicit Intent, and statically register a BroadcastReceiver class in the manifest. For example:
public class NotificationReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
...
}
}
In the manifest:
<receiver android:name=".NotificationReceiver" />
Then your Intent would be similar to:
Intent i = new Intent(PlayerService.this, NotificationReceiver.class);
However, this would require an additional step, as you would then need to somehow pass the broadcast info from NotificationReceiver to the Service; e.g., with an event bus, LocalBroadcastManager, etc.
Normally for a single IntentService you can define the broadcast receiver listener like this in an Activity's onCreate() method (for example)
broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//get stuff from the intent and do whatever you want
}
};
And you register the receiver like this (also in onCreate()):
LocalBroadcastManager.getInstance(this)
.registerReceiver(broadcastReceiver, new IntentFilter("my_intent_service"));
And then you start the IntentService with:
Intent intent = new Intent(this, MyIntentService.class);
startService(intent);
And in the IntentService you send messages back to the receiver with:
Intent broadcastIntent = new Intent("my_intent_service");
broadcastIntent.putExtra("whateverData", whateverData);
LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);
which triggers the onReceive method described earlier.
And then to unregister the receivers, in onDestroy method you can do:
LocalBroadcastManager.getInstance(this).unregisterReceiver(broadcastReceiver);
In the Manifest file, you add for your service:
<service
android:name=".MyIntentService"
android:exported="false" />
I want to receive broadcasts from multiple IntentServices in the same Activity.
Do you need one receiver per IntentService? As in, if I make n IntentServices do I need to register n receivers, make n listener, and unregister n receivers in onDestroy?
The way to filter multiple actions with one BroadcastReceiver is to add them to the IntentFilter:
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("my_intent_service1"); // Action1 to filter
intentFilter.addAction("my_intent_service2"); // Action2 to filter
LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, intentFilter);
And in your BroadcastReceiver:
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals("my_intent_service1")) {
// Action 1
} else if (intent.getAction().equals("my_intent_service2")) {
// Action 2
}
}
};
yes you can use one broadcast receiver in one activity, that would handle multiple intents from different services.
I’d recommend to add multiple intent-filter to your broadcast receiver to make distinction from which Service you are getting a broadcast.
I have an application that using "AlarmService". For handling alarms i have a Broadcast receiver. That receiver has to start certain activity. Code i'm using for achieving that is following:
#Override
public void onReceive(Context context, Intent intent) {
...other code....
Intent intIntent = new Intent(context, MainActivity.class);
intIntent .putExtra("IsAlarm", true);
Intent alarmChooser = Intent.createChooser(intIntent , "Alarm");
alarmChooser.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
context.startActivity(alarmChooser);
}
That works but only if activity isn't shown already (if it's not in the foreground). If called activity is already opened nothing happens. How can i overcome that?
Is there a flag that will start the activity if it's not started OR send intent to it even if it's in the foreground?
P.S. i tried using dedicated "broadcast" above the provided code. Reciever for that broadcast is registered programmatically in the MainActivity: "onResume" would register dedicated receiver, "onPause" would unregister it. That way in case MainActivity is already on it will receive a broadcast but then i have a problem when phone goes to "stand by" - "dedicated" receiver is unregistered.
Check in the activity onNewIntent callback
there should be the new intent from the receiver
I think you don't need the chooser:
#Override
public void onReceive(Context context, Intent intent) {
Intent intIntent = new Intent(context, MainActivity.class);
intIntent.putExtra("IsAlarm", true);
context.startActivity(intIntent);
}
There are some question about Android4.2 Broadcast,
android.intent.action.TIME_TICK
android.intent.action.PACKAGE_INSTALL
This two protected broadcast are define in /frameworks/base/core/res/AndroidManifest.xml
Only find where register Receiver use Context.registerRecriver(),
Question:Where to send this Broadcast attached android.intent.action.TIME_TICK
Thanks
If you declare in manifest file it wont be enough.Manifest file is like a blue print.You need to declare the broadcast receiver there and after that u need to register the broadcast receiver in your code here i am attaching sample broadcast receiver code.
batteryLevelFilter= new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
this.registerReceiver(batteryLevelReceiver, batteryLevelFilter);
BroadcastReceiver batteryLevelReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
//yourcode
}
};
You cannot receive this through components declared in manifests, only by explicitly registering for it with Context.registerReceiver().
And it only be sent by the system.
You have to register this intent programmatically : Sent every minute.
like this
IntentFilter if = new IntentFilter(Intent.ACTION_TIME_TICK);
registerReceiver(YourReceiver, if);
I've got this app, in which users update certain variables in an Activity, and this Activity passes the new variables to a IntentService using a BroadcastReceiver. However, the BroadcastReceiver in the IntentService doesn't seem to be receiving the broadcasts. This is the code within the service to create the broadcast receiver
protected class UpdateReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent){
Log.d("receiver", "Got message: ");
//state=3;
//Toast.makeText(context, "got it", Toast.LENGTH_SHORT).show();
}
};
And here's the code to register the receiver, in the onHandle() function
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction("updates");
UpdateReceiver lol = new UpdateReceiver();
DetectService.this.registerReceiver(lol, intentFilter);
Finally here's the code to send the broadcast, from the activity
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("updates");
HomePageActivity.this.sendBroadcast(broadcastIntent);
Log.d("sender", "send msg");
When I put the receiver in the same activity as the broadcasting part, it works, but not when I put it into the IntentService. Help please!
On another related note, I've tried using LocalBroadcastManager in this project since the broadcasts are all local but eclipse doesn't seem to be able to import the compatibility class. I've installed it using Android SDK manager already. Is there any thing I'm doing wrong here?
this Activity passes the new variables to a IntentService using a BroadcastReceiver.
That makes no sense. Use startService() to send a command to an IntentService. And an IntentService should not have a BroadcastReceiver, because the IntentService will be destroyed as soon as onHandleIntent() completes and therefore will never receive the broadcast.
I've tried using LocalBroadcastManager in this project since the broadcasts are all local but eclipse doesn't seem to be able to import the compatibility class.
:: shrug ::
Here is a sample project with Eclipse project files that uses LocalBroadcastManager. I encountered no particular Eclipse issues when creating the project.
protected class UpdateReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent){
Log.d("receiver", "Got message: ");
//state=3;
//Toast.makeText(context, "got it", Toast.LENGTH_SHORT).show();
}
};
In the onCreate() method or where relevant.
mReceiver = new UpdateReceiver();
IntentFilter filter = new IntentFilter();
filter.addAction("<your receivers intent goes here>");
this.registerReceiver(mReceiver, filter);
Now you should be able to send a broadcast and it be picked up.
Intent intent = new Intent("<your receivers intent goes here>");
// Add what you want to add to the intent right here.
<context-handle>.sendBroadcast(intent);