Access the results of a started service from two different activities in Android

心已入冬 提交于 2019-12-02 07:49:21

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!