Behaviour of sendBroadcast - android

I need to send some data to my service on app startup. I put data to Intent, cast sendBroadcast(intent) in onCreate method of my activity. So my service doesn't receive any intents.
But if i use Handler.post with custom Runnable in onCreate everything works fine.
Can someone explain me such a strange behavior?
Doesn't work at all:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
broadcastIntent = new Intent(BROADCAST);
broadcastIntent.putStringArrayListExtra("URLs", alURLS);
sendBroadcast(broadcastIntent);
}
Works perfectly:
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
broadcastIntent = new Intent(BROADCAST);
broadcastIntent.putStringArrayListExtra("URLs", alURLS);
hDelayedPost = new Handler();
hDelayedPost.post(rHandleDelayedSendBroadcast);
}
private Runnable rHandleDelayedSendBroadcast = new Runnable() {
#Override
public void run() {
sendBroadcast(broadcastIntent);
}
};

So my service doesn't receive any intents
Services do not receive broadcasts. BroadcastReceivers receive broadcasts.
UPDATE: Presumably, your Service is not yet running in onCreate() of your activity, and you are calling startService() sometime between onCreate() and when your delayed sendBroadcast() is called.

Related

service does not listen to certain broadcasts

My service:
#Override
public void onCreate() {
if (debug_mode) {Log.i(TAG,"onCreate");}
super.onCreate();
// set receivers
m_filter.addAction("PREPARE_AUDIO");
m_receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (debug_mode) {Log.i(TAG,"broadcast received: " + intent.getAction());}
if (intent.getAction().equals("PREPARE_AUDIO")) {
set_up_audio();
}
}
};
registerReceiver(m_receiver, m_filter);
}
and my activity:
#Override
protected void onStart() {
super.onCreate(savedInstanceState);
if (debug_mode) Log.i(TAG, "onCreate");
setContentView(R.layout.activity_guide);
// start service
startService(new Intent(this, PlayerService.class));
}
#Override
protected void onStart() {
if (debug_mode) {Log.i(TAG,"onStart");}
super.onStart();
// prepare audio
Intent intent = new Intent();
intent.setAction("PREPARE_AUDIO");
sendBroadcast(intent);
}
This won't trigger the BroadcastReceiver in my service. It won't trigger it either if I put the code on onCreate or onResume. It will trigger it, however, if put e.g. on some Listener associated with a Button, or in the activity's onStop callback. Why is that?
Rather than try to send a broadcast right away, just have the service do its setup work in its onCreate() or onStartCommand() method.
Note that using system broadcasts for this is a fairly bad idea, unless your service is in a separate process from your UI. Even then, you need to think through the security, as any app can tell your service what to do, by sending it broadcasts.
If your service and UI will be in the same process, use an in-process event bus (e.g., LocalBroadcastManager, greenrobot's EventBus), not only for improved security, but for better performance.

LocalBroadcastManager.sendBroadcast not triggering BroadcastReceiver onReceive

I am working on using the LocalBroadcastReceiver to send messages from an IntentService to an activity. I have a basic activity all the activities in my project inherit from that contains the activity code below. And a basic IntentService that is initialized by a WakefulBroadcastReceiver that contains the service code below.
In my activity I have:
#Override
protected void onCreate(Bundle savedInstanceState) {
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("push-message"));
super.onCreate(savedInstanceState);
}
#Override
protected void onPause(){
LocalBroadcastManager.getInstance(this).unregisterReceiver(
mMessageReceiver);
super.onPause();
}
#Override
protected void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(
mMessageReceiver, new IntentFilter("push-message"));
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
String message = intent.getStringExtra("message");
Log.d("receiver", "Got message: " + message);
}
};
And in my service I have:
public class SimpleMessagerService extends IntentService {
public SimpleMessagerService() {
super("SimpleMessagerService");
}
#Override
protected void onHandleIntent(Intent intent) {
Intent newintent = new Intent("push-message");
// You can also include some extra data.
String message = intent.getExtras().getString("message");
newintent.putExtra("message", message);
LocalBroadcastManager.getInstance(this).sendBroadcast(intent);
}
}
The service onHandleIntent is being triggered, and when I put a break point in it and evaluate the expression: LocalBroadcastManager.getInstance(this); I can see the mMessageReceiver in the mReceivers list; however when I put a breakpoint in mMessageReceiver's onReceive, I find that it is never being triggered.
More info:
It seems my service cannot actively do anything when it is called, but does not throw an exception. I tried saving my current context in the application file and throwing up a toast message from the service. The process seems to succeed, but the toast message never appears. This is what I have in the manifest for the service:
<service
android:name="packagename.services.SimpleMessagerService"
android:exported="false">
</service>
turns out a couple things where wrong. First exported needed to be true in the manifest. Second, because the service is an Intent service it operates in a different thread than the main activities, so in order to send a broadcast to them I have to make it look something like:
Handler mHandler = new Handler(getMainLooper());
mHandler.post(new Runnable() {
#Override
public void run() {
Intent newintent = new Intent("push-message");
newintent.putExtra("message", message);
LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(newintent);
}
});
So the main thread is hit. I hope this helps someone else with the same problem.
I'd like to credit rubenlop88 in the for posting this solution for a similar problem in the thread,
java.lang.RuntimeException: Handler (android.os.Handler) sending message to a Handler on a dead thread

broadcast message keeps coming into service after quit and re-start the activity which starts the service

I'm working on a Android APP. There's a main activity and a service. The service is started by calling startService(intent) in main activity. and it would be running in background no matter the activity is running or not. After the activity is created, it will send broadcast message to service to query some status. The first time of the running is okay, both activity and service initiated correctly. But I get an issue that when I quit the activity and restart it, the service will keep receiving the query message like the activity is sending it repeatedly. But I confirmed the sending code in activity was only executed once. Anyone have idea where the messages comes from?
the codes in main activity onCreate method
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Log.v("debug", "Main.onCreate");
Intent intent=new Intent(MainActivity.this, PingService.class);
startService(intent);
Intent intent = new Intent(PingService.ACTION_QUERY);
sendBroadcast(intent);
}
And below are codes in service
private BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(PingService.ACTION_QUERY)) {
Log.v("debug", "PingService.receiver.onReceive: ACTION_QUERY");
//the program keeps coming here
}
}
};
#Override
public void onCreate() {
Log.v("debug", "PingService.onCreate");
HandlerThread thread = new HandlerThread("pingd",
android.os.Process.THREAD_PRIORITY_BACKGROUND);
thread.start();
//handlers
serviceHandler = new ServiceHandler();
daemonHandler = new DaemonHandler(thread.getLooper());
//register broadcast receiver
IntentFilter filter = new IntentFilter();
filter.addAction(PingService.ACTION_ADD);
filter.addAction(PingService.ACTION_QUERY);
filter.setPriority(999);
registerReceiver(receiver, filter);
instance = this;
}

Handler will not be called in my activity

I created a Handler in my activity. The handler will be stored in the application object.
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.action_activity);
appData = (AttachApplication) getApplication();
Handler updateHandler = new Handler() {
public void handlerMessage(Message msg) {
Log.d( TAG, "handle message " );
}
};
appData.setUpdateHandler( updateHandler );
}
My plan is that this handleMessage will be called when i setEmtpyMessage in my service. The service retrieves the handler from the application object.
public int onStartCommand(Intent intent, int flags, int startId) {
Log.d(TAG, "onStartCommand of attachService");
List<Job> jobList = DBManager.getInstance().getAllOpenJobs();
appData = (AttachApplication) getApplication();
updateHandler = appData.getUpdateHandler();
updateHandler.sendEmptyMessage( 101 );
I checked the logs, but there is no handle message so that it seems that my plan does not work. I want to update a textfield each time my service did its job.
In Your case You shoild use BroadcastReceiver like this:
define receiver in your Activity class:
public class DataUpdateReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MainService.REFRESH_DATA_INTENT)) {
//do something
}
}
}
on your onCreate or onStart method you must register receiver:
DataUpdateReceiver dataUpdateReceiver = new DataUpdateReceiver();
IntentFilter intentFilter = new IntentFilter(MainService.REFRESH_DATA_INTENT);
registerReceiver(dataUpdateReceiver, intentFilter);
on your service add this:
public static final String REFRESH_DATA_INTENT = "done";
and when you done all staff you must send brocast like this:
sendBroadcast(new Intent(MainService.REFRESH_DATA_INTENT));
Your code snippet says public void handlerMessage(Message msg), but I think you mean public void handleMessage(Message msg), without the r. You can avoid these problems by using the #Override tag when you intent to override methods from a superclass; so your snippet would be rendered #Override public void handleMessage(Message msg), whereas #Override public void handlerMessage(Message msg) would be an error.
What are you trying to do? I really don't see the point of instantiating a Handler in an Activity, since all you're doing is getting Messages from the MessageQueue. You certainly don't want to fool around with any of the Messages that Android posts, and there are much better ways of sending messages to the Activity.
Of course, you don't include the code for AttachApplication, so I can only speculate.
You're also trying to access this Handler from a Service. Something is going on, but I'm not sure what.
If you want to update a TextView every time your Service does its job, send a broadcast Intent from the Service to the Activity, and use a broadcast receiver in the Activity. You should also consider using an IntentService instead of a Service.

Android: Broadcast Receiver and Service issues

I have written a simple activity to test out services and broacast receivers and a service to go along with it. In order to know whether or not it's working I've set up a Toast within the main activity to be showed once the OnReceive() method is called. But for the life of me I can't get this to work.
These are the codes:
public class ServicesAndBroadcastIntentActivity extends Activity {
private Toast test;
private Intent intent;
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
intent = new Intent(this,serviceD.class);
test = Toast.makeText(this,"Test",Toast.LENGTH_LONG);
test.setGravity(Gravity.CENTER,0,0);
}
private BroadcastReceiver broadcastReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
test.setText((intent.getStringExtra("EXTRA_MSG")));
test.show();
}
};
#Override
public void onResume(){
super.onResume();
startService(intent);
registerReceiver(broadcastReceiver, new IntentFilter(serviceD.BROADCAST_ACTION));
}
#Override
public void onPause() {
super.onPause();
unregisterReceiver(broadcastReceiver);
stopService(intent);
}
}
public class serviceD extends Service{
private Intent intent;
static final String BROADCAST_ACTION = "com.mejg.ServicesAndBroadcastIntent";
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
public void onStart(){
intent.putExtra("EXTRA_MSG","hola");
sendBroadcast(intent);
stopSelf();
}
#Override
public IBinder onBind(Intent arg0) {
// TODO Auto-generated method stub
return null;
}
}
You are calling startService() before registerReceiver(). Both are asynchronous operations, but they will still likely occur in sequence. Hence, onStart() of your service will be called before registerReceiver() does its work, which means your broadcast goes out before your receiver is set up.
For this sort of experimentation, I recommend setting up a basic UI (e.g., one really big button) and doing the startService() call when the button is pressed.
Also, since the service calls stopSelf(), you do not need to call stopService() from the activity.
Also also, you might consider using LocalBroadcastManager for this -- same basic syntax with better performance and security, since it all stays within your process.
UPDATE
Also also also, onStart() has been deprecated for two-plus years, and your method signature for it is wrong, anyway. Please use onStartCommand(), with the right parameters.
Also also also also, use #Override when overriding methods, to help you catch these sorts of problems.

Categories

Resources