在Android Studio

时间:2016-06-21 21:23:16

标签: android location

我不是程序员,但即便如此,我只是努力将“混合”(来自他人的样本和说明)用于艺术装置的小型android项目,该项目将在当地大学校园的户外展示。这个应用程序将显示弹出窗口,其中包含在该区域内穿过其相应的径向围栏时发生在该点上的事件的轶事叙述,需要不依赖于数据载体或Wi-Fi提供者的位置获取,因为没有该地区的覆盖范围以及那些看起来相当不稳定,即使在具有网络和Wi-Fi信号的城市环境中进行测试也是如此。

我正在使用android开发人员文档附带的官方示例,但是我已经读过,由于过度有效的练习,开发人员将API偏向于仅使用蜂窝数据和Wi-Fi,除非调用GPS_PROVIDER通过locationManager轮询它的输出,以便一旦应用程序请求,地理围栏实例可以主要从那里检索更精确的位置。但我仍然坚持在代码的哪一部分添加这个相关的行,无论它是java文件夹中的单独类,还是Mainactivity本身内部以及结构中的其他位置(除了权限形式的清单)我是否必须引用它们的存在才能使它连贯一致。

欢迎任何帮助。

1 个答案:

答案 0 :(得分:3)

根据您的描述我收集到您有几个限制。让我解释一下我的理解:

  • 您希望在多个设备上部署位置感知应用以进行展览/艺术装置。
  • 设备没有连接(没有WiFi,没有蜂窝网络),因此只需要使用GPS。
  • 您想要检测每个设备何时进入预定义区域,即感兴趣点周围的固定半径。

您的问题是:最好的方法是什么?

LocationManager与Google(Play服务)位置API

首先,了解通常建议的获取位置更新的方式在过去几年中发生了变化,这远非通过Android' {{{{{{{{{{{{{{{{ 3}}(+ DIY融合逻辑)朝着更强大和方便的LocationManager

我认为你知道两者(以及属于Location API的Google Location APIs)并且由于连接问题而排除了后者。因此,让我们看看如何使用 LocationManager 进行操作。

使用LocationManager

获取更新
  

但我仍然坚持在代码的哪一部分添加这个相关的行,无论它是java文件夹中的单独类还是Mainactivity本身内部以及结构中的其他位置(除了清单中的权限形式)我必须引用它们的存在才能使它连贯一致地工作。

您是否使用活动或其他地方的 LocationManager 主要取决于您是仅需要在一个活动中还是在多个活动中进行位置更新。

案例1:仅在一个活动中的位置

您可以在该活动的生命周期内安全地实例化,启动和停止管理器。

public MyActivity extends Activity implements LocationListener {

    private LocationManager locationManager;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        ...
        locationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    }

    @Override
    protected void onResume() {
        super.onResume();
        ...
        // Request GPS updates every second (careful: high battery drain)
        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 5, this);
    }

    @Override
    protected void onPause() {
        locationManager.removeUpdates(this);
        super.onPause();
    }

    @Override
    public void onLocationChanged(Location location) {
        // Do something with the location
    }

    // Implement other LocationListener interface methods here, handle provider status changes
}

案例2:多个活动中的位置

详细的代码示例超出了本答案的范围,但让我提供一个草图:

  • 创建一个自定义Geofencing API类,其中包含 LocationManager 实例,并使用应用程序生命周期启动/停止它。我已经编写了一个Application可以用于此(您可以阅读更多相关信息simple utility class)。
  • 应用程序类也可以实现 LocationListener 接口,尽管将该逻辑打包到您自己的类中可能更简洁(例如, LocationHelper 类)并从您的应用程序中启动和停止该类。
  • 最后,通过事件总线(例如hereGreen EventBus)分发位置更新,以便任何Activity,Fragment或其他类可以订阅这些更新,而无需知道这些位置来自何处。

检查地理围栏

为了简单起见,我们假设您只使用一个活动和一个地理围栏。然后,您可以检查包含/排除该地理围栏中的当前位置,如下所示:

public MyActivity extends Activity implements LocationListener {

    // Define a hard-coded POI and geofence radius
    private static final Location POI_A = new Location("dummy");
    static {
        POI_A.setLongitude(/* POI longitude */);
        POI_A.setLatitude(/* POI latitude */);
    }
    private static final int GEOFENCE_RADIUS = 50; // meters

    ...

    @Override
    public void onLocationChanged(Location location) {
        if (location.distanceTo(POI_A) <= GEOFENCE_RADIUS) {
            // Location is within geofence of point of interest A
        } else {
            // Location is outside the geofence of point of interest A
        }
    }

备注/提示

  • 您应该为GPS使用较高的更新间隔,以便当人们在您的展览中进入/离开地理围栏时,您的应用可以快速做出反应。但是,这会消耗大量电池,因此请务必在附近备用备用电池/充电器。

  • 如果没有任何连接,设备可能需要很长时间才能找到GPS修复程序(因为没有机会使用Otto)。 如果您可以在展览区域(例如,单个WiFi热点)提供任何类型的连接,这可以大大加快您的应用启动并获得一个位置所需的时间,即使您已经只使用GPS

  • 由于位置读数可能会跳跃几米,因此您应该建立具有滞后的地理围栏(例如,当用户距离小于40米时触发enter事件,并leave事件,当他们超过60米),以避免在POI圈的边缘重复过渡。