问题
I have a service that gets the user's location and broadcasts the latitude and longitude in an intent.
I believe that I need the service to be a started service (as opposed to bound service), because I would like for it to be able to send a push notification to the user when a new geoFire entry from firebase enters their radius even when the app is closed.
Currently, the service is set up to broadcast the location.
Given that the location service will be a started service, I don't know how to access the broadcast from two separate activities.
I believe that I could achieve this if it were a bound service, but since I want it to stay alive indefinitely, I'm not sure what to do.
Here is a minimal example that demonstrates my issue.
Specifically, I can get the latitude and longitude to display on the first activity by registering a broadcast receiver, but I can't get the latitude and longitude to display on the second activity by registering a separate broadcast receiver.
I have read Android's documentation on Services but still don't really know what I'm supposed to do to resolve this problem.
I've been testing this all on an emulator from Android Studio: Nexus 5X API 25 x86.
UPDATE Nov. 8, 2017: I've updated the github project to contain the EventBus solution provided below. It is in the eventBus branch. The master branch still contains the ualtered, problematic code pertaining to the question.
To view:
git clone https://github.com/Atticus29/locationServiceMCV.git
git checkout eventBus
Then, open AndroidStudio or IDE of choice and view/run as you normally would.
回答1:
Broadcasting the results is one way to solve this issue. But if you're willing to add a lib on your project I would strongly recommend Green Robot's EventBus. It's a very lightweight lib, as it's fast. Also, it's simple to post complex objects through it without having to implement the Parcelable interface.
This lib works on a publisher/subscriber fashion, where in your case, both Activities would be the subscribers, and the Service would be the publisher.
First of all, you have to add the dependency on your build.gradle
file as below.
implementation 'org.greenrobot:eventbus:3.0.0'
If you're on a Kotlin project, also add this dependency:
kapt 'org.greenrobot:eventbus-annotation-processor:3.0.1'
Then, define an Event class that will be responsible to carry your data through the app. Note that this could be done from a Service
to an Activity
. From a Fragment
to another. Between Activities, and so on.
public class MessageEvent {
public double lat;
public double lng;
// Add additional fields here if needed
public MessageEvent(double lat, double lng) {
this.lat= lat;
this.lng = lng;
}
}
After that, you have to subscribe to those events on your Activity
.
public class MyActivity extends AppCompatActivity {
// ...
@Override
public void onResume() {
super.onResume();
// This line will register your Activity to the EventBus
// making sure that all the methods annotated with @Subscribe
// will be called if their specific Events are posted.
EventBus.getDefault().register(this);
}
@Override
public void onPause() {
super.onPause();
// This line will unregister your Activity.
// It's a good practice to put this on the onPause() method
// to make your event handling system tied to the Activity lifecycle.
EventBus.getDefault().unregister(this);
}
// The threadMode MAIN makes sure this method is called on the main Thread.
// But you could also set it up to be called on other threads if needed. Check the docs for more info.
@Subscribe(sticky = true, threadMode = ThreadMode.MAIN)
public void onMessageEvent(MessageEvent event) {
/* Call this line below if you want to remove the sticky event.
* That will prevent that this event will be seen by other subscribers once they subscribe.
* In your specific use case, you don't have to remove the sticky event here.
*/
// EventBus.getDefault().removeStickyEvent(event);
double lat = event.lat;
double lng = event.lng;
// Do whatever you want with the data.
};
}
With that implemented, you're ready to post your events. Now, inside your Service
, call the following code when you get the new Lat/Lng information.
EventBus.getDefault().postSticky(new MessageEvent(lat,lng));
You can read more on how to setup and customize the EventBus on the docs, or on this tutorial.
来源:https://stackoverflow.com/questions/47147833/access-the-results-of-a-started-service-from-two-different-activities-in-android