I have a registered BroadcastReceiver in my main activity. Activity sends a sticky in one of the tabs to trigger the broadcast receiver (TabActivity application).
Everything works fine, but when I restart the app the sticky is sent automatically (not triggered by user) and view is opened.
My question is: how is that possible? Did I misunderstand something? And how can I fix that?
MainActivity:
OnCreate:
registerReceiver(openOutgoingCall, new IntentFilter("OPENOUTGOINGCALL"));
BroadcastReceiver:
private BroadcastReceiver openOutgoingCall = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if(extras.isEmpty() == false) {
HashMap<String,String> callData = (HashMap<String, String>) extras.get("callData");
openOutgoingCall(callData);
}
}
};
Activity inside TabHost
public void openCall(View view) {
Intent i = new Intent("OPENOUTGOINGCALL");
i.putExtra("callData", detailInfo);
sendStickyBroadcast(i);
}
Sticky broadcasts are supposed to stay around (even they are received) so that they can be retrieved afterwards too. Perhaps you should try the simple way of broadcasting using:
sendBroadcast(i);
Read this.
Related
I have a registered BroadcastReceiver in my main activity. Activity sends a sticky in one of the tabs to trigger the broadcast receiver (TabActivity application).
Everything works fine, but when I restart the app the sticky is sent automatically (not triggered by user) and view is opened.
My question is: how is that possible? Did I misunderstand something? And how can I fix that?
MainActivity:
OnCreate:
registerReceiver(openOutgoingCall, new IntentFilter("OPENOUTGOINGCALL"));
BroadcastReceiver:
private BroadcastReceiver openOutgoingCall = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Bundle extras = intent.getExtras();
if(extras.isEmpty() == false) {
HashMap<String,String> callData = (HashMap<String, String>) extras.get("callData");
openOutgoingCall(callData);
}
}
};
Activity inside TabHost
public void openCall(View view) {
Intent i = new Intent("OPENOUTGOINGCALL");
i.putExtra("callData", detailInfo);
sendStickyBroadcast(i);
}
Sticky broadcasts are supposed to stay around (even they are received) so that they can be retrieved afterwards too. Perhaps you should try the simple way of broadcasting using:
sendBroadcast(i);
Read this.
I'm dealing with wearable, and my purpose is the next:
From my watch, I want to press a simple button, which send a simple message to the mobile. But I would like to handle all those behaviors :
when mobile app isn't yet launched, then launch the app and pass the message from wear, which can be handled in the launcher activity
when mobile app is launched but in the background, then just bring it to foreground and handle message from wear, which can be handled in the launcher activity
when mobile app is launched and in foreground, juste handle the message in the launcher activity
So far, I handle to launch the app when it isn't not yet launched, but I can't get the extra message in the launcher activity contained in the intent. Here the code.
the mobile service
public class MobileWearService extends WearableListenerService {
private static final String START_ACTIVITY = "/start_activity";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
String event = messageEvent.getPath();
String msg = new String(messageEvent.getData());
if (event.equals(START_ACTIVITY)) {
Intent intent = new Intent( this, MainActivity.class );
intent.putExtra("Data", msg);
intent.setFlags( Intent.FLAG_ACTIVITY_NEW_TASK
| Intent.FLAG_ACTIVITY_CLEAR_TOP
| Intent.FLAG_ACTIVITY_SINGLE_TOP);
startActivity( intent );
}
}
}
However, if I use a broadcast to send the message from service to the main activity, it works only if the app is launched and foreground
public class MobileWearService extends WearableListenerService {
private static final String START_ACTIVITY = "/start_activity";
#Override
public void onMessageReceived(MessageEvent messageEvent) {
super.onMessageReceived(messageEvent);
String event = messageEvent.getPath();
String msg = new String(messageEvent.getData());
if (event.equals(START_ACTIVITY)) {
broadcastIntent.setAction("com.me.project.wear.to.app");
broadcastIntent.putExtra("Data", msg);
broadcastIntent.putExtras(intent);
sendBroadcast(broadcastIntent);
}
}
}
launcher activity
private IntentFilter mIntentFilter = new IntentFilter("com.me.project.wear.to.app");
private BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null && intent.getAction().equals("com.me.project.wear.to.app")) {
String msg = intent.getStringExtra("Data");
}
}
};
#Override
protected void onResume() {
super.onResume();
registerReceiver(mReceiver, mIntentFilter);
}
#Override
protected void onPause() {
super.onPause();
unregisterReceiver(mReceiver);
}
So I would to combine the fact to get the message from wear (I know how to) but pass this message to get it in the launcher activity regardless of the state of the app.
Just make the static BroadcastReceiver
public class WatchMessageReceiver extends BroadcastReceiver{
#Override
public void onReceive(Context context, Intent intent) {
if (intent != null &&
intent.getAction().equals("com.me.project.wear.to.app")) {
String msg = intent.getStringExtra("Data");
Intent launcherIntent = new Intent(context, LauncherActivity.class);
launcherIntent.putExtra("Data",msg);
startActivity(launcherIntent);
}
}
}
in your manifest file
<receiver android:name ="WatchMessageReceiver"
<intent-filter>
<action android:name="com.me.project.wear.to.app"/>
</intent-filter>
</receiver>
In the Sending and Syncing Data training, there is a Handling Data Layer Events:
When you make a call to the Data Layer API, you can receive the status of the call when it completes. You also can listen for data events, resulting from data changes that your application makes anywhere on the Android Wear network.
Listen for Data Layer Events
Because the data layer synchronizes and sends data across the handheld and wearable, it is usually necessary to listen for important events. Examples of such events include creation of data items and receipt of messages.
To listen for data layer events, you have two options:
Create a service that extends WearableListenerService.
Create an activity that implements DataApi.DataListener.
With both these options, you override the data event callback methods for the events you are interested in handling.
Some of the events you can listen for using WearableListenerService are as follows:
onDataChanged(): Whenever a data item object is created, deleted, or changed, the system triggers this callback on all connected nodes.
onMessageReceived(): A message sent from a node triggers this callback on the target node.
onCapabilityChanged(): When a capability that an instance of your app advertises becomes available on the network, that event triggers this callback. If you're looking for a nearby node you can query the isNearby() method of the nodes provided in the callback.
According to the related SO post:
WearableListenerService does not run constantly - it is only started when a new message/node connection/data layer change is sent and stopped when there are no more messages.
Hope this helps.
I am using broadcast receiver in my app to detect incomming call and it works fine. But problem is I can not send action to activity. I mean.. I want do something in activity not in receiver. I read many tutorial but they all are performing action in receiver. Any idea ?
You can declare a BroadcastReceiver as inner class of the Activity. In this case you can directly call activity's methods:
public class MyActivity extends Activity {
private final BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
activityMethod();
}
};
private final IntentFilter filter = new IntentFilter("android.intent.action.PHONE_STATE");
#Override
protected void onStart() {
super.onResume();
registerReceiver(receiver, filter);
}
#Override
protected void onStop() {
super.onPause();
unregisterReceiver(receiver);
}
private void activityMethod() {
}
}
You can start the Activity using an Intent and put a command code in the Intent extra fields. In your Activity you can then decide the behaviour based on the command code or resort to a default behaviour if none is present.
You can start an activity from your receiver via the normal means:
#Override
public void onReceive(Context context, Intent intent) {
Intent i = new Intent(context, YourActivity.class);
startActivity(i);
}
Note though that the user is going to expect that the phone application starts up since they are receiving a phone call. It is very likely a bad idea to hijack the phone call by dumping your own activity on top of the stock dialer app.
I have a main activity that launches a service to do a web search in the background and I would like the main activity to get an intent when the search is done.
In my main activity , I defined a BroadcastReceiver and an Intent Filter to listen to the "end of search" intent:
public class AgeRage extends Activity {
// Listener to all results from background processes
BroadcastReceiver receiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(ImageSearchService.SEARCH_RESULT_ACTION)) {
0);
Toast.makeText(context,"Got " + i + "results", Toast.LENGTH_SHORT).show();
}
else Toast.makeText(context,"unknown intent", Toast.LENGTH_SHORT).show();
}
};
IntentFilter receiverFilter = new IntentFilter ();
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
// Register to image search service messages
receiverFilter.addAction(ImageSearchService.SEARCH_RESULT_ACTION);
registerReceiver(receiver,receiverFilter);
...
In the service , I do the search and when it is done , I send an Intent:
public class ImageSearchService extends IntentService {
...
protected void onHandleIntent (Intent intent) {
... doing search ...
Intent i = new Intent (this,AgeRage.class);
i.setAction (SEARCH_RESULT_ACTION);
i.putExtra(SEARCH_STATUS, (searchStatus ==SearchStatus.DONE) ? true:false);
i.putExtra (SEARCH_RESULT_NUM, totalResultNum);
i.putExtra (SEARCH_ID, searchID);
sendBroadcast (i,null);
}
But, the main activity doesn't get the Intent. I know that the sendBroadcast is being called and the the receiver's OnReceive is not (checked with a debugger).
I assume that since I create the filter dynamically , I do not need to define a filter in the manifest file.
Am I doing something wrong ?
Thanks
Isaac
Ok. Well I just checked mine and we are doing it the same way, however ...
ImageSearchService.SEARCH_RESULT_ACTION
Try doing com.yourpackagename.ImageSearchSrvice.SEARCH_RESULT_ACTION
where SEARCH_RESULT_ACTION is a public static string variable. See if that helps.
I think it must be the naming of the ACTION. Also note that you might want to run tru the breakpoints and just check log. do intent.getAction() and print this out rather than checking inside the if statement. Just always print it out and see. Don't need to break inside a broacast receiver it will crash after a while.
i have a android service running in the background which receives the coordinates from the server every few seconds. i am not sure how do i display the coordinates on a map every time the service receives a response from the server. kindly help or give an idea.
thanks
I don't know any tutorials on this, but here's a version of mine:
To send a broadcast, you use the 'sendBroadcast(Intent i)' method of the Context class. The Service class extends Context, so you can access it from your implementation.
So in your Service goes:
public static final String BROADCAST_ACTION="com.yourservice.update";
public void onStart( Intent intent, int startId ) {
...
Intent broadcastIntent = new Intent(BROADCAST_ACTION);
sendBroadcast(broadcastIntent);
...
}
You have to register a receiver for this broadcast in you Activity (possibly before you start boradcasting them), like this:
private BroadcastReceiver receiver=new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//Here goes handling the stuff you got from the service
Bundle extras = intent.getExtras();
if(extras != null)processUIUpdate(extras);
}
};
public void onResume() {
...
//Register for the update broadcasts from the torrent service
registerReceiver(receiver, new IntentFilter(YourService.BROADCAST_ACTION));
...
}
Don't forget to deregister when the Activity goes background:
public void onPause() {
...
//Deregister for the update broadcast from the torrent service
unregisterReceiver(receiver);
...
}
This should work.
Your service could broadcast intents whenever it wants to update the displayed location on the map. The Activity displaying the map should register a receiver for that boradcast, and the boradcast's intent can hold the values for lat. and long.