I have a BroadCastRecevier that works in an asnyc task and it works when server sent a message then broadcast sends this server messages to activities. When activity get the message I am doing some process using a Handler However sometimes handler is not triggered. I mean broadcast sends three messages but handler works two times.
g.broadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
srvrMessage = intent.getStringExtra("message");
try {
Thread.sleep(50);
} catch (InterruptedException e) {
e.printStackTrace();
}
myHandler.sendEmptyMessage(1);
}
};
To avoid this issue I decide to use a Service. I have created a service class and want that handler work inside of it but I could not send myHandler as a parameter while starting the service. How can I make this handler works in the service?
I think these links will help you:-
http://techblogon.com/android-service-example-code-description-complete-tutorial/
http://blog.denevell.org/android-service-handler-tutorial.html
Related
I have an android activity that has BroadcastReceiver as below.
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, intentFilter);
}
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.i("TAG", intent.getAction());
}
};
The problem is I am receiving message from network and depending on message type I create the activity or send Broadcast message to activity, since I receive message very fast the message type to create activity arrives right before(in few milliseconds) the message type to send Broadcast message to the same activity and I get an error handleWindowVisibility: no activity for token android.os.BinderProxy researching a bit I found that the activity might not be created correctly before I send the broadcast intent.
So I made the thread sleep for 3 seconds.
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrace();
}
Now everything works as expected but the above looks ugly and a bit hackish, is there a better way to send broadcast intent right before the activity creation?
Instead of creating the Activity and sending a broadcast Intent to it, just put the contents of the broadcast Intent in the Intent you use to start the Activity (as an "extra"). Then you don't need the 3 second delay, you just only send the broadcast Intent if the Activity is already running.
In my app there are 2 buttons. With one button; output is "A", with both buttons the output is "B".
I use broadcast receiver to get appropriate data. But there is a problem with pressing 2 buttons. Because i sometimes don't press each buttons at the same time. So receiver gets "A" firstly then "B". I think i can solve this problem with delaying receiver for a while. But how?
My broadcast code is below. I have tried Thread.sleep(100); but it doesn't work.
String word="";
IntentFilter intentFilter = new IntentFilter("android.intent.action.MAIN");
broadcastReceiver = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
try {
Thread.sleep(100);
}catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
word=intent.getExtras().getString("keyboard");
}
};
registerReceiver(broadcastReceiver, intentFilter);
Instead of adding a delay in the Broadcast receiver, create a delay before sending the broadcast.
In the button handlers, use some boolean variables to check button clicks, and use handler.postDelayed
to call sendBroadcast. You can also add some checks to make sure that only one broadcast is sent during subsequent clicks
You can not operate on two intents inside a BroadcastReceiver. The way it works is that you receive one intent, you perform your operation on it (serially) and then finish it until you receive next intent. Your solution does not work because you put the thread in sleep, and in this duration of course you can't get the next bcasted intent either, until the sleep period is over, which then you finish processing the current intent, and then you receive the next one.
I am not sure what is your scenario, but you need to somehow keep the state in your code, so your code knows you already have received the first intent. For example you can define a variable outside of broadcastReceiver, which keeps track of the intents received so far, and then inside the receiver, you can check the state, and based on whether input A already is received or not you can operate.
You can send broadcast delayed, like use this wrap function.
public static void sendBroadcastDelayed(Context context, Intent intent, long delay) {
Handle handler = new Handle();
handler.postDelayed(new Runnable() {
#override
public void run() {
context.sendBroadcast(intent);
}
}, delay);
}
I have a service which is running in the background and an Activity that opens up every couple of minutes. When the activity opens the user pushes a button which needs to send a message to the service. The problems is that after the user pushes the button the activity closes. It appears that the activity is closing before the Activity can bind to the service so I am not able to send a message using my Messenger.
Is the best way to handle this to have the service listen to a broadcast receiver and then trigger that broadcast from my activity?
Thanks for any help you can offer!
-Nathan
#Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.end_activity_button:
endActivity();
break;
}
}
private void endActivity() {
sendMessageToService(ActivityService.MSG_CANCEL_ACTIVITY);
getActivity().finish();
}
/**
* Send data to the service
*
* #param intvaluetosend The data to send
*/
private void sendMessageToService(int intvaluetosend) {
if (mIsBound) {
if (mServiceMessenger != null) {
try {
Message msg = Message.obtain(null, intvaluetosend, 0, 0);
msg.replyTo = mMessenger;
mServiceMessenger.send(msg);
} catch (RemoteException e) {
}
}
}
}
Edit I have implemented Ricardo's solution but I am using localbroadcasts. Everything is now working properly. Thanks for the help!
Is this mServiceMessenger a service of yours to send a message? I have exactly the same scenario as you but I do it differently.
On my Service, I register a BroadcastReceiver like in this post: https://stackoverflow.com/a/4805733/362298
Then, in my activity, whenever I need to send a message, I simply call:
Intent myIntent = new Intent("MY_ACTION_FOR_THE_SERVICE_TO_HANDLE");
//Put some extra here
sendBroadcast(myIntent);
I actually do this right before calling finish() on my activity as well. Is there any reason why you are not using sendBroadcast?
I have a dynamic broadcast receiver registered in a service and my service is doing some heavy sdcard read/write operation in a while(somecondition) loop.
When a broadcast is sent from my another Application (which is in other process) is not received by my broadcast receiver.
This same broadcast is received when it is not executing while loop.
I also tried to put end of loop with Thread.Sleep(100) just to give some time for broadcast receiver to get executed but it is not working.
Any help regarding this will help me a lot.
-Thanks & regards,
Manju
Code below for registering BxRx:
this.registerReceiver(myReceiver, new IntentFilter(ACTIVITY_NAME));
code below for sending broadcast:
Intent intnt = new Intent(ACTIVITY_NAME);
intnt.putExtra("STOP_ALL_TESTING", true);
Log.d(TAG,"Sending BX STOP_ALL_TESTING");
myActivity.this.sendBroadcast(intnt);
code below for while loop:
while(somecondition){
:
:
:
Thred.sleep(100);
}
public void onReceive(Context context, Intent intent) {
Log.d(TAG,"Received intent: "+intent.getAction());
boolean flag = intent.getBooleanExtra("STOP_ALL_TESTING", false);
Log.d(TAG,"Flag set to: "+flag);
if((boolean)intent.getBooleanExtra("STOP_ALL_TESTING",false)){
Log.d(TAG,"Broadcast received to STOP_ALL_TESTING");
Log.d(TAG,"Bx Rx, setting flag to stop testing as requested by user");
synchronized(this){
bStopTesting=true;
}
}
}
Please paste your complete code.
It looks like your problem is that you have an endless loop in service's onStartCommand method. Both onStartCommand and onReceive are executed on the same thread and only one after another. Applications main thread is a Looper thread, which handles events in a sequential manner. Basically, if you have an endless operation in the service, you will block the whole main thread, which includes all the GUI, services and Broadcast receivers. Calling Thread.sleep() won't help, because the method does not return. To avoid this, you can use IntentService http://developer.android.com/reference/android/app/IntentService.htmlclass, which will handle intents on another thread.
public class HeavyService extends IntentService {
public HeavyService() {
super("HeavyService");
}
#Override
public void onCreate() {
super.onCreate();
//do your initialization
}
#Override
protected void onHandleIntent(Intent intent) {
//this will be executed on a separate thread. Put your heavy load here. This is
//similar to onStartCommand of a normal service
}
}
I build an AsyncTask that create a service and now I want to sent from service to AsyncTask message.
my code on the AsyncTask is:
class ResponseHandler extends Handler {
public void handleMessage(Message message) {
// Toast.makeText(this, "message from service",Toast.LENGTH_SHORT).show();
}
hope that it will handle the message from service correct my if I wrong.
and from service tried to do this
Message message = Message.obtain(null, MyService.ADD_RESPONSE_HANDLER);
message.replyTo = messenger;
try {
myService.send(message);
catch (RemoteException e) {
e.printStackTrace();
}
but my errors are cannot find symbol in lines:
MyService.ADD_RESPONSE_HANDLER
message.replyTo = messenger;
try {
myService.send(message);
What do I need to add? Please give me a code that will do the work. thanks a lot.
One way is using ResultReceiver. Here is my complete blog post which I had recently posted with an Example.
How to update Activity from Service using ResultReceiver
For sending a message or any data from service to Activity you will need to Register an Custom Broadcast receiver.see these tutorials for sending data from service to Activity:
Communication between service and activity – Part 1
Custom Intents and Broadcasting with Receivers