通过Android中的两个不同活动访问启动服务的结果 [英] Access the results of a started service from two different activities in Android

查看:81
本文介绍了通过Android中的两个不同活动访问启动服务的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一项服务,它可以获取用户的位置并按意图广播纬度和经度.

I have a service that gets the user's location and broadcasts the latitude and longitude in an intent.

我认为我需要将该服务作为启动服务(而不是绑定服务),因为我希望它能够在来自Firebase的新geoFire条目进入其半径时向用户发送推送通知即使该应用已关闭.

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.

这是一个展示我问题的最小示例.

具体来说,我可以通过注册一个广播接收器来获得在第一个活动上显示的纬度和经度,但是我不能通过注册一个单独的广播接收器来获得在第二个活动上显示的纬度和经度.

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.

我已阅读有关服务的Android文档,但实际上并没有知道我应该怎么做才能解决这个问题.

I have read Android's documentation on Services but still don't really know what I'm supposed to do to resolve this problem.

我一直在Android Studio的仿真器上测试这一切:Nexus 5X API 25 x86.

I've been testing this all on an emulator from Android Studio: Nexus 5X API 25 x86.

更新2017年11月8日:我已经更新了github项目,以包含下面提供的EventBus解决方案.它在eventBus分支中. master分支仍然包含与该问题有关的,有问题的代码.

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.

要查看:

git clone https://github.com/Atticus29/locationServiceMCV.git
git checkout eventBus

然后,打开选择的AndroidStudio或IDE并按照通常的方式查看/运行.

Then, open AndroidStudio or IDE of choice and view/run as you normally would.

推荐答案

广播结果是解决此问题的一种方法.但是,如果您愿意在项目中添加一个库,我强烈建议绿色机器人的EventBus .这是一个非常轻量级的库,因为它很快.另外,通过它发布复杂的对象也很简单,而无需实现 Parcelable 界面.

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.

首先,必须在build.gradle文件上添加依赖项,如下所示.

First of all, you have to add the dependency on your build.gradle file as below.

implementation 'org.greenrobot:eventbus:3.0.0'

如果您在Kotlin项目中,还请添加此依赖项:

If you're on a Kotlin project, also add this dependency:

kapt 'org.greenrobot:eventbus-annotation-processor:3.0.1'

然后,定义一个Event类,该类将负责通过应用程序携带您的数据.请注意,这可以从ServiceActivity完成.从Fragment到另一个.在活动之间,等等.

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;
    }
}

之后,您必须在Activity上订阅这些事件.

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.
    };
}

实施该功能后,您就可以发布事件了.现在,在Service内部,当您获得新的纬度/经度信息时,调用以下代码.

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));

您可以阅读有关如何在文档上或在文档上 设置和自定义EventBus的更多信息. 本教程.

You can read more on how to setup and customize the EventBus on the docs, or on this tutorial.

这篇关于通过Android中的两个不同活动访问启动服务的结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆