Shared string between Service and MainActivity in Android - android

I have a service and the main activity. Is there any way I can share a String in particular between these two. I have a method in the MainActivity that has to be executed only after the String from the service arrives. Is there any way of doing the same.
Thanks.

The following code will allow your Service to publish a String to your Activity. If you need to send data in the other direction use a more casual approach such as startService(Intent).
Setup a local BroadcastReceiver in your Activity:
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (!MyService.ACTION_NEW_STRING.equals(intent.getAction()) return;
String myString = intent.getStringExtra(MyService.EXTRA_STRING);
// do whatever you need to do here
}
}
#Override
public void onStart() {
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(mReceiver, new IntentFilter(MyService.ACTION_NEW_STRING));
}
#Override
public void onStop() {
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(mReceiver);
}
In your Service declare needed constants:
public static final String ACTION_NEW_STRING = "your_application_id.ACTION_NEW_STRING";
// or BuildConfig.APPLICATION_ID + ".ACTION_NEW_STRING" in Android Studio
public static final String EXTRA_STRING = "EXTRA_STRING";
private LocalBroadcastManager mManager;
#Override
public void onCreate() {
mManager = LocalBroadcastManager.getInstance(getApplicationContext());
}
In your service once you have your new String:
Intent i = new Intent(ACTION_NEW_STRING);
i.putExtra(EXTRA_STRING, myString);
mManager.sendBroadcast(i);
More reading on this topic: http://developer.android.com/reference/android/content/BroadcastReceiver.html

Related

How to receive values from an IntentService in another IntentService?

I have this IntentService (HttpService) which fetches raw json data from a webservice:
public class HttpService extends IntentService {
public static final String BROADCAST_ACTION = "com.example.HttpService";
public HttpService() {
super("HttpService");
}
#Override
protected void onHandleIntent(Intent intent) {
//code to get a String with jsonData
//Then I send a broadcast
Intent broadcastHttpResponseIntent = new Intent();
broadcastHttpResponseIntent.setAction(BROADCAST_ACTION);
broadcastHttpResponseIntent.putExtra("jsonData", jsonData);
sendBroadcast(broadcastHttpResponseIntent);
}
}
Now from the IntentService that uses HttpService I'm trying to get the broadcast:
public class RestaurantModel extends IntentService {
public static final String BROADCAST_ACTION = "com.example.RestaurantModel";
public RestaurantModel() {
super("RestaurantModel");
}
#Override
protected void onHandleIntent(Intent intent) {
Log.v("RestaurantModel", "onHandleIntent");
BroadcastReceiver httpBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("RestaurantModel", "onReceive");
String jsonResponse = intent.getStringExtra("jsonData");
}
};
Intent getRestaurantsJsonIntent = new Intent(RestaurantModel.this, HttpService.class);
getRestaurantsJsonIntent.putExtra("urlRestaurants", intent.getStringExtra("urlRestaurants"));
startService(getRestaurantsJsonIntent);
registerReceiver(httpBroadcastReceiver, new IntentFilter(HttpService.BROADCAST_ACTION));
}
}
SO I'm getting this error:
RestaurantModel has leaked IntentReceiver com.example.RestaurantModel$1#42374590 that was originally registered here. Are you missing a call to unregisterReceiver()?
So I tried unregistering the Receiver but it seems to need a Context to unregister the receiver.
How to receive values from an IntentService into another IntentService?
The best answer is: have only one IntentService.
The next-best answer is: get rid of the broadcast stuff entirely, and have the first IntentService call startService() to kick off the second IntentService.
Agree with #CommonsWare, in case you want to use BroadcaseReceiver inside of an IntentService, register it in the onCreate method and unregister it in the onDestroy method.
public class RestaurantModel extends IntentService {
public static final String BROADCAST_ACTION = "com.example.RestaurantModel";
private BroadcastReceiver httpBroadcastReceiver;
public RestaurantModel() {
super("RestaurantModel");
}
#Override
public void onCreate() {
super.onCreate();
httpBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
Log.v("RestaurantModel", "onReceive");
String jsonResponse = intent.getStringExtra("jsonData");
}
};
LocalBroadcastManager.getInstance(getApplicationContext()).registerReceiver(httpBroadcastReceiver);
}
#Override
public void onDestroy() {
super.onDestroy();
LocalBroadcastManager.getInstance(getApplicationContext()).unregisterReceiver(httpBroadcastReceiver);
}
#Override
protected void onHandleIntent(Intent intent) {
Log.v("RestaurantModel", "onHandleIntent");
Intent getRestaurantsJsonIntent = new Intent(RestaurantModel.this, HttpService.class);
getRestaurantsJsonIntent.putExtra("urlRestaurants", intent.getStringExtra("urlRestaurants"));
startService(getRestaurantsJsonIntent);
}
}

Android pass message from IntentService to Activity

I IntentService that I would like to send message to the main Activity it is nested in. I am using a broadcast receiver to broadcast the message I got from the IntentService as such:
public static class ResponseReceiver extends BroadcastReceiver {
public static final String ACTION_RESP = "com.mypackage.intent.action.MESSAGE_PROCESSED";
#Override
public void onReceive(Context context, Intent intent) {
String text;
text = intent.getStringExtra(RegistrationIntentService.PARAM_OUT);
regid = text;
}
}
I have registered the receiver in the Oncreate method of the main Activity. How can I send the "text" in this case? It is weird that regid in this case is null while "text" has the string data I wanted.
you can user result receiver with intent service to get the result into activity or fragment, follow the following links,
http://sohailaziz05.blogspot.in/2012/05/intentservice-providing-data-back-to.html
In your service you do
Intent intent = new Intent();
intent.setAction(yourActionToMatchBroadcastReceiverIntentFilter);
intent.putExtra(RegistrationIntentService.PARAM_OUT, yourText);
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
In activity register your BroadcastReceiver in onResume() and unregister it in onPause(). Whenever your activity is active the receiver will receive intents from your IntentService.
EDIT
public static class ResponseReceiver extends BroadcastReceiver {
MapActivity activity;
public ResponseReceiver(MapActivity activity) {
this.activity = activity;
}
#Override
public void onReceive(Context context, Intent intent) {
activity.regid = intent.getStringExtra(RegistrationIntentService.PARAM_OUT);
// do whatever you need here
}
}
When registering, this was what worked for me
IntentFilter filter = new IntentFilter(ResponseReceiver.ACTION_RESP);
filter.addCategory(Intent.CATEGORY_DEFAULT);
receiver = new ResponseReceiver();
LocalBroadcastManager.getInstance(this).registerReceiver(receiver, filter);
as opposed to
registerReceiver(receiver, filter);
#Override
public void onReceive(Context context, Intent intent) {
final String text = intent.getStringExtra(RegistrationIntentService.PARAM_OUT);
button.setOnClickListener(new OnClickListener() {
#Override
public void onClick(View view) {
//access the string text and send it to backend
}
});
}
I hope this will help someone. Sending the string like suggested in the comments didn't work for me. I was getting nullpointerexception at that specific line where I assigned ma.regid = text;

How to refresh a ListView from a BroadcastReceiver?

If I call notifyDataSetChanged() on the custom adapter associated to my ListView, all the views should refresh themself (getView() will be called).
Now I have a BroadcastReceiver that is listening to an event. When the event fires, the ListView must be refreshed. How can I achieve this?
Thanks!
If you refresh listview from receiver you'll have code like this:
BroadcastReceiver br;
public final static String BROADCAST_ACTION = "BROADCAST_ACTION";
br = new BroadcastReceiver() {
public void onReceive(Context context, Intent intent) {
//code refreshing...
}
};
IntentFilter intFilt = new IntentFilter(BROADCAST_ACTION);
registerReceiver(br, intFilt);
And you call it with code:
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
If you need the refresh to be another action you just need to add (after action):
Intent intent = new Intent(BROADCAST_ACTION);
sendBroadcast(intent);
As requested, please see the sample code below:
public interface OnDataUpdateListener {
void onDataAvailable(ArrayList<String> newDataList);
}
public class MyTestReceiver extends BroadcastReceiver {
public static final String DATA_LIST = "DATA_LIST";
private OnDataUpdateListener mDataUpdateListener = null;
public MyTestReceiver(OnDataUpdateListener dataUpdateListener) {
mDataUpdateListener = dataUpdateListener;
}
#Override
public void onReceive(Context ctx, Intent intent) {
// assuming data is available in the delivered intent
ArrayList<String> dataList = intent.getSerializableExtra(DATA_LIST);
if (null != mDataUpdateListener) {
mDataUpdateListener.onDataAvailable(dataList);
}
}
}
public class MyActivity extends FragmentActivity implements OnDataUpdateListener {
public static final String ACTION_DATA_UPDATE_READY = "ACTION_DATA_UPDATE_READY";
private MyTestReceiver mTestReceiver = null;
private <SomeAdapterClass> mAdapter = null;
#Override
protected void onCreate(Bundle savedInstanceState) {
// other required initialization
mTestReceiver = new MyTestReceiver(this);
}
#Override
public void onResume() {
super.onResume();
if (null != mTestReceiver) {
registerReceiver(mTestReceiver, new IntentFilter(ACTION_DATA_UPDATE_READY));
}
}
void onDataAvailable(ArrayList<String> newDataList) {
// assuming you want to replace existing data and not willing to append to existing dataset
mAdapter.clear();
mAdapter.addAll(newDataList);
mAdapter.notifyDataSetChanged();
}
}
In the code where your data is updated, fire off a message signalling that data has been changed...
(You will need access to either the Activity or the Application context to do this)
Intent intent = new Intent("ListViewDataUpdated");
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
Then just catch the catch the message using the following code in your activity, and tell your ListAdapter to update...
private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
myListAdapter.notifyDataSetChanged();
}
};
#Override
public void onResume(){
super.onResume();
LocalBroadcastManager.getInstance(this).registerReceiver(mMessageReceiver, new IntentFilter("ListViewDataUpdated"));
myListAdapter.notifyDataSetChanged();//in case our data was updated while this activity was paused
}
#Override
protected void onPause() {
LocalBroadcastManager.getInstance(this).unregisterReceiver(mMessageReceiver);
super.onPause();
}
Credit: adapted from Vogella
LocalBroadcastManager.getInstance(context.sendBroadcast(intent));
change to
LocalBroadcastManager.getInstance(context).sendBroadcast(intent);
I might be wrong but it works for me...

Communication between Activity and Service

I am trying to make my own MusicPlayer for android. Where i came to a problem is running some things in background. Main activity manages GUI and up to now all the songs are playing. I wanted to separate GUI and music playing classes. I want to put music managing part in Service and leave other things as they are now.
My problem is that i can't organize communication between Activity and Service as lot of communication is happening between them including moving objects in both directions. I tried many techniques that I searched here on Stack Overflow but every time I had problems. I need Service to be able to send objects to Activity and vice versa. When I add widget i also want it to be able to communicate with Service.
Any tips are appreciated, if you need source code place comment bellow but now in this transition it became chaotic.
Is there any more advanced tutorial on this than calling one method that returns random number from service? :P
EDIT: Possible solution is to use RoboGuice library and move objects with injection
I have implemented communication between Activity and Service using Bind and Callbacks interface.
For sending data to the service I used Binder which retruns the Service instace to the Activity, and then the Activity can access public methods in the Service.
To send data back to the Activity from the Service, I used Callbacks interface like you are using when you want to communicate between Fragment and Activity.
Here is some code samples for each:
The following example shows Activity and Service bidirectional relationship:
The Activity has 2 buttons:
The first button will start and stop the service.
The second button will start a timer which runs in the service.
The service will update the Activity through callback with the timer progress.
My Activity:
//Activity implements the Callbacks interface which defined in the Service
public class MainActivity extends ActionBarActivity implements MyService.Callbacks{
ToggleButton toggleButton;
ToggleButton tbStartTask;
TextView tvServiceState;
TextView tvServiceOutput;
Intent serviceIntent;
MyService myService;
int seconds;
int minutes;
int hours;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
serviceIntent = new Intent(MainActivity.this, MyService.class);
setViewsWidgets();
}
private void setViewsWidgets() {
toggleButton = (ToggleButton)findViewById(R.id.toggleButton);
toggleButton.setOnClickListener(btListener);
tbStartTask = (ToggleButton)findViewById(R.id.tbStartServiceTask);
tbStartTask.setOnClickListener(btListener);
tvServiceState = (TextView)findViewById(R.id.tvServiceState);
tvServiceOutput = (TextView)findViewById(R.id.tvServiceOutput);
}
private ServiceConnection mConnection = new ServiceConnection() {
#Override
public void onServiceConnected(ComponentName className,
IBinder service) {
Toast.makeText(MainActivity.this, "onServiceConnected called", Toast.LENGTH_SHORT).show();
// We've binded to LocalService, cast the IBinder and get LocalService instance
MyService.LocalBinder binder = (MyService.LocalBinder) service;
myService = binder.getServiceInstance(); //Get instance of your service!
myService.registerClient(MainActivity.this); //Activity register in the service as client for callabcks!
tvServiceState.setText("Connected to service...");
tbStartTask.setEnabled(true);
}
#Override
public void onServiceDisconnected(ComponentName arg0) {
Toast.makeText(MainActivity.this, "onServiceDisconnected called", Toast.LENGTH_SHORT).show();
tvServiceState.setText("Service disconnected");
tbStartTask.setEnabled(false);
}
};
View.OnClickListener btListener = new View.OnClickListener() {
#Override
public void onClick(View v) {
if(v == toggleButton){
if(toggleButton.isChecked()){
startService(serviceIntent); //Starting the service
bindService(serviceIntent, mConnection, Context.BIND_AUTO_CREATE); //Binding to the service!
Toast.makeText(MainActivity.this, "Button checked", Toast.LENGTH_SHORT).show();
}else{
unbindService(mConnection);
stopService(serviceIntent);
Toast.makeText(MainActivity.this, "Button unchecked", Toast.LENGTH_SHORT).show();
tvServiceState.setText("Service disconnected");
tbStartTask.setEnabled(false);
}
}
if(v == tbStartTask){
if(tbStartTask.isChecked()){
myService.startCounter();
}else{
myService.stopCounter();
}
}
}
};
#Override
public void updateClient(long millis) {
seconds = (int) (millis / 1000) % 60 ;
minutes = (int) ((millis / (1000*60)) % 60);
hours = (int) ((millis / (1000*60*60)) % 24);
tvServiceOutput.setText((hours>0 ? String.format("%d:", hours) : "") + ((this.minutes<10 && this.hours > 0)? "0" + String.format("%d:", minutes) : String.format("%d:", minutes)) + (this.seconds<10 ? "0" + this.seconds: this.seconds));
}
}
And here is the service:
public class MyService extends Service {
NotificationManager notificationManager;
NotificationCompat.Builder mBuilder;
Callbacks activity;
private long startTime = 0;
private long millis = 0;
private final IBinder mBinder = new LocalBinder();
Handler handler = new Handler();
Runnable serviceRunnable = new Runnable() {
#Override
public void run() {
millis = System.currentTimeMillis() - startTime;
activity.updateClient(millis); //Update Activity (client) by the implementd callback
handler.postDelayed(this, 1000);
}
};
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//Do what you need in onStartCommand when service has been started
return START_NOT_STICKY;
}
#Override
public IBinder onBind(Intent intent) {
return mBinder;
}
//returns the instance of the service
public class LocalBinder extends Binder{
public MyService getServiceInstance(){
return MyService.this;
}
}
//Here Activity register to the service as Callbacks client
public void registerClient(Activity activity){
this.activity = (Callbacks)activity;
}
public void startCounter(){
startTime = System.currentTimeMillis();
handler.postDelayed(serviceRunnable, 0);
Toast.makeText(getApplicationContext(), "Counter started", Toast.LENGTH_SHORT).show();
}
public void stopCounter(){
handler.removeCallbacks(serviceRunnable);
}
//callbacks interface for communication with service clients!
public interface Callbacks{
public void updateClient(long data);
}
}
Update: July 10 2016
IMO I think using BroadcastReceiver for custom events is better way
as the Messengers mentioned don't handle activity recreation on device
rotation as well as possible memory leaks.
You may create custom BroadCast Receiver for events in the activity, Then you may also use Messengers.
In your Activity
create a MessageHandler class as
public static class MessageHandler extends Handler {
#Override
public void handleMessage(Message message) {
int state = message.arg1;
switch (state) {
case HIDE:
progressBar.setVisibility(View.GONE);
break;
case SHOW:
progressBar.setVisibility(View.VISIBLE);
break;
}
}
}
Now you can have it's instance as
public static Handler messageHandler = new MessageHandler();
Start your Service with this Handler object as an extra data as
Intent startService = new Intent(context, SERVICE.class)
startService.putExtra("MESSENGER", new Messenger(messageHandler));
context.startService(startService);
In your Service you receive this object from the intent and initialize the Messenger variable in Service as
private Messenger messageHandler;
Bundle extras = intent.getExtras();
messageHandler = (Messenger) extras.get("MESSENGER");
sendMessage(ProgressBarState.SHOW);
And then write a method sendMessage to send messages to activity.
public void sendMessage(ProgressBarState state) {
Message message = Message.obtain();
switch (state) {
case SHOW :
message.arg1 = Home.SHOW;
break;
case HIDE :
message.arg1 = Home.HIDE;
break;
}
try {
messageHandler.send(message);
} catch (RemoteException e) {
e.printStackTrace();
}
}
The sample code above shows and hides a ProgressBar in Activity as messages are received from Service.
Intents are good solution for communication between Activitiy and Service.
A fast solution for receive intents in your service is subclassing IntentService class. It handles asynchronous requests expressed as Intents using a queue and worker thread.
For communication from service to Activity you can broadcast the intent but instead of using normal sendBroadcast() from Context, a more efficent way is to use LocalBroadcastManager from support library.
Example service.
public class MyIntentService extends IntentService {
private static final String ACTION_FOO = "com.myapp.action.FOO";
private static final String EXTRA_PARAM_A = "com.myapp.extra.PARAM_A";
public static final String BROADCAST_ACTION_BAZ = "com.myapp.broadcast_action.FOO";
public static final String EXTRA_PARAM_B = "com.myapp.extra.PARAM_B";
// called by activity to communicate to service
public static void startActionFoo(Context context, String param1) {
Intent intent = new Intent(context, MyIntentService.class);
intent.setAction(ACTION_FOO);
intent.putExtra(EXTRA_PARAM1, param1);
context.startService(intent);
}
public MyIntentService() {
super("MyIntentService");
}
#Override
protected void onHandleIntent(Intent intent) {
if (intent != null) {
final String action = intent.getAction();
if (ACTION_FOO.equals(action)) {
final String param1 = intent.getStringExtra(EXTRA_PARAM_A);
// do something
}
}
}
// called to send data to Activity
public static void broadcastActionBaz(String param) {
Intent intent = new Intent(BROADCAST_ACTION_BAZ);
intent.putExtra(EXTRA_PARAM_B, param);
LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
bm.sendBroadcast(intent);
}
}
Example Activity
public class MainActivity extends ActionBarActivity {
// handler for received data from service
private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
#Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(MyIntentService.BROADCAST_ACTION_BAZ)) {
final String param = intent.getStringExtra(EXTRA_PARAM_B);
// do something
}
}
};
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
IntentFilter filter = new IntentFilter();
filter.addAction(MyIntentService.BROADCAST_ACTION_BAZ);
LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
bm.registerReceiver(mBroadcastReceiver, filter);
}
#Override
protected void onDestroy() {
LocalBroadcastManager bm = LocalBroadcastManager.getInstance(this);
bm.unregisterReceiver(mBroadcastReceiver);
super.onDestroy();
}
// send data to MyService
protected void communicateToService(String parameter) {
MyIntentService.startActionFoo(this, parameter);
}
}
I think there is a problem with the correct answer. I have not enough reputation to comment on it.
Right in the answer:
Activity call bindService() to get pointer to Service is ok. Because service context is maintained when connection is maintained.
wrong in the answer:
service pointer to Activity class to call back is bad way. Activity instance maybe not null during Activity context is being Release => exception here.
solution for the wrong in the answer:
service send intent to Activity. and Activity receiver intent via BroadcastReceiver.
Note:
in this case, Service and Activity in the same Process, you should use LocalBroadcastManager to send intent. It make performance and security better
This is a simple example of communication between activity and service
Activity
MyReceiver myReceiver; //my global var receiver
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.layourAwesomexD);
registerReceiver();
}
//When the activity resume, the receiver is going to register...
#Override
protected void onResume() {
super.onResume();
checkStatusService(); // verficarStatusServicio(); <- name change
registerReceiver();
}
//when the activity stop, the receiver is going to unregister...
#Override
protected void onStop() {
unregisterReceiver(myReceiver); //unregister my receiver...
super.onStop();
}
//function to register receiver :3
private void registerReceiver(){
//Register BroadcastReceiver
//to receive event from our service
myReceiver = new MyReceiver();
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(MyService.SENDMESAGGE);
registerReceiver(myReceiver, intentFilter);
}
// class of receiver, the magic is here...
private class MyReceiver extends BroadcastReceiver {
#Override
public void onReceive(Context arg0, Intent arg1) {
//verify if the extra var exist
System.out.println(arg1.hasExtra("message")); // true or false
//another example...
System.out.println(arg1.getExtras().containsKey("message")); // true or false
//if var exist only print or do some stuff
if (arg1.hasExtra("message")) {
//do what you want to
System.out.println(arg1.getStringExtra("message"));
}
}
}
public void checkStatusService(){
if(MyService.serviceStatus!=null){
if(MyService.serviceStatus == true){
//do something
//textview.text("Service is running");
}else{
//do something
//textview.text("Service is not running");
}
}
}
Service
public class MyService extends Service {
final static String SENDMESAGGE = "passMessage";
public static Boolean serviceStatus = false;
#Override
public void onCreate() {
super.onCreate();
serviceStatus=true;
}
#Nullable
#Override
public IBinder onBind(Intent intent) {return null;}
#Override
public int onStartCommand(Intent intent, int flags, int startId) {
//you service etc...
passMessageToActivity("hello my friend this an example of send a string...");
return START_STICKY;
}
#Override
public void onDestroy() {
super.onDestroy();
passMessageToActivity("The service is finished, This is going to be more cooler than the heart of your ex...");
System.out.println("onDestroy");
serviceStatus=false;
}
private void passMessageToActivity(String message){
Intent intent = new Intent();
intent.setAction(SENDMESAGGE);
intent.putExtra("message",message);
sendBroadcast(intent);
}
}
if we don't unregister BroadcastReceiver we will have an error, you need to unregister when the activity go onPause, onStop, onDestroy...
if you don't register BroadcastReceiver when you back to activity, it will not listen anything from the service... the service will send information to BroadcastReceiver but it will not receive anything because it isn't registered.
When you create more than one service, the following services are going to begin in onStartCommand.
You can pass information to service with intent and you get it in onStartCommand
Difference about return in onStartCommand: Difference between START_STICKY and START_REDELIVER_INTENT? and check the official website of google: Services
The best way in this case is to communicate by doing broadcasting from your service for different actions and receiving it in your activity. You can create a custom broadcast and send some codes defining specific events like complete, change, prepare etc...
Most easy and efficient way will be using EventBus from GreenRobot.
Use simple 3 steps:
1 Define events
public static class MessageEvent { /* Additional fields if needed */ }
2 Prepare subscribers: Declare and annotate your subscribing method, optionally specify a thread mode:
#Subscribe(threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {/* Do something */};
Register and unregister your subscriber. For example on Android, activities and fragments should usually register according to their life cycle:
#Override
public void onStart() {
super.onStart();
EventBus.getDefault().register(this);
}
#Override
public void onStop() {
super.onStop();
EventBus.getDefault().unregister(this);
}
3 Post events:
EventBus.getDefault().post(new MessageEvent());
Very easy yet powerful way is to use EventBus you can add it to your gradle build and enjoy the easy publisher/subscriber pattern .

sending intent extras from service to activity

I have a service that listens for (ON_BATTERY_CHANGE), then onReceive service sends a Broadcast to My MainActivity. The problem is that I somehow can't get them from service to my main activity. Code: Main Activity:
public class MainActivity extends Activity
private BroadcastReceiver batteryReceiverService;
private TextView text2;
....
protected void onCreate(Bundle savedInstanceState) {
text2=(TextView)findViewById(R.id.TV_text2);
batteryReceiverService = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent) {
text2.setText("left: "+intent.getStringExtra("H")+" hours "+intent.getStringExtra("M")+" minute(s)");
Log.e("text2","text2 HHH " +intent.getStringExtra("H")); //log shows 0
Log.e("text2","text2 MMM " +intent.getStringExtra("H")); // log shows 0
}
};
registerReceiver(batteryReceiverService, new IntentFilter(UltimateBatterySaverService.BROADCAST_ACTION));
....
#Override
protected void onDestroy() {
unregisterReceiver(batteryReceiverService);
super.onDestroy();
}
Service:
public class UltimateBatterySaverService extends Service {
private Intent intent;
static final String BROADCAST_ACTION = "lt.whitegroup.ultimatebatterysaver";
private BroadcastReceiver batteryLevelReceiver;
....
public void onCreate() {
super.onCreate();
intent = new Intent(BROADCAST_ACTION);
}
#Override
public void onDestroy() {
unregisterReceiver(batteryLevelReceiver);
super.onDestroy();
}
IntentFilter batteryLevelFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
batteryLevelReceiver = new BroadcastReceiver(){
#Override
public void onReceive(Context context, Intent intent){
// Receiving data, calculating and etc
averageChargingH=timeAllInHours;
averageChargingM=timeAllInMinutes;
// to put extras and send broadcast
does();
......
public void does(){
String strLong = Long.toString(averageChargingH);
String strLong2 = Long.toString(averageChargingM);
Log.e("cccccc","strLong h "+strLong); // getting good value not 0(everything ok)
Log.e("cccccc","strLong2 m"+strLong2); // getting good value not 0(everything ok)
intent.putExtra("H", strLong);
intent.putExtra("M", strLong2);
sendBroadcast(intent);
}
Any ideas why my information is not transfered correctly?
The does() method seems to be using variables in the same scope as onReceive so I'm guessing that the intent variable in does() is actually the Intent passed in from onReceive.
Try adding some logging before sending the broadcast to check if the action of the intent is correct, or simply create the broadcast intent in the onReceive method and name it intent2.

Categories

Resources