监视库中的位置设置 [英] Monitoring Location Settings in a Library

查看:88
本文介绍了监视库中的位置设置的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用一个可用于监视Android设备上的地理围栏的库.我注意到,我在设备设置中关闭并重新打开定位服务后,在Google Play定位服务GeofencingApi类中注册的地理围栏丢失了.

我已经看到民间的建议我需要在我的AndroidManifest.xml文件中注册android.location.PROVIDERS_CHANGED广播接收器.我已经完成了-但是仅当我在测试应用程序中添加和删除测试提供程序时,才会调用此广播接收器.在设备设置中切换位置服务时,我什么都收不到.

我做错什么了吗?有谁知道如何可靠地确定用户何时在设备设置中切换位置服务?我希望能够在后台看到这些事件-即使我的应用未运行.

我认为我可以设置一个在后台运行的重复任务,并定期检查定位服务是否已切换,但这听起来很麻烦而且效率很低.

如果有帮助,我正在运行Android 4.4.2的Moto G上进行测试.到目前为止,我对地理围栏所做的一切都工作正常.

经过更多研究,我发现PROVIDERS_CHANGED广播的行为在很大程度上取决于电话版本和型号.我的运行Android 5.1的Nexus 5似乎可以正常运行-我能够非常定期地播放PROVIDERS_CHANGED广播.我也有运行4.4.x的Moto G和Moto X手机,他们从未为我制作过PROVIDERS_CHANGED广播. Android 4.2上的Samsung Galaxy S3会为我制作广播,但是在我将Google地图活动与测试位置提供商一起使用后,就停止了广播.

无论如何,我决定暂时停止解决此问题.我认为Android只是越野车.

解决方案

如果看不到代码做错了,就很难分辨,但是我只是得到了一个简单的示例,该示例通过使用此处指南,并对其进行修改以将BroadcastReceiver包含在库中.

注意事项:使用该库的应用程序需要在其AndroidManifest.xml中包含receiver. 参见此处此处都包含信息来自@CommonsWare.

在此处添加引号,以防链接出现问题:

图书馆项目可以通过任何方式独立注册 自己的清单文件中的接收者?

目前不在.

因此,使用您的库的任何应用都需要在其AndroidManifest.xml中添加receiver.

请注意,这已在Samsung S4的Android 4.4.4上进行了测试.

我在编译为aar的图书馆项目中使用BroadcastReceiver进行了这项工作.

使用在链接到库中BroadcastReceiver的主应用程序的AndroidManifest.xml中设置的receiver元素,当对位置设置进行任何更改时,我都能够接收到该事件:

  • 打开位置
  • 关闭位置
  • 将定位模式更改为高精度
  • 将位置模式更改为省电
  • 将位置模式"更改为仅GPS"

每次更改位置设置时,即使应用未运行,也会触发库中的BroadcastReceiver.

我使用了一个简单的测试,每次更改位置设置时,库中的BroadcastReceiver都会显示一条Toast消息.

这是库项目中的LocationProviderChangedReceiver.java:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;

public class LocationProviderChangedReceiver extends BroadcastReceiver {
    private final static String TAG = "LocationProviderChanged";

    boolean isGpsEnabled;
    boolean isNetworkEnabled;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
        {
            Log.i(TAG, "Location Providers changed");

            LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            Toast.makeText(context, "GPS Enabled: " + isGpsEnabled + " Network Location Enabled: " + isNetworkEnabled, Toast.LENGTH_LONG).show();
        }
    }

}

然后,在主应用程序中,我将编译后的myLibrary.aar放在libs文件夹中,并设置build.gradle来编译aar:

 repositories{
        flatDir{
            dirs 'libs'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:appcompat-v7:22.1.1"
    compile "com.google.android.gms:play-services:7.3.0"

    compile 'com.mylibrary.daniel:mylibrary:1.0@aar'

}

在主应用程序的AndroidManifest.xml中设置receiver:

    <receiver
        android:name="com.mylibrary.daniel.mylibrary.LocationProviderChangedReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="android.location.PROVIDERS_CHANGED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

然后,以几种不同的方式安装应用程序并修改位置设置.每次触发库中的BroadcastReceiver:

I'm working on a library that can be used to monitor geofences on Android devices. I've noticed that the geofences I register with Google Play Location Services GeofencingApi class are lost after I turn Location Services off and back on in the device settings.

I have seen folks suggesting that I need to register for the android.location.PROVIDERS_CHANGED broadcast receiver in my AndroidManifest.xml file. I've done that -- but this broadcast receiver only gets called when I add and remove test providers in my test application. I don't receive it at all when toggling Location Services in the device settings.

Am I doing something wrong? Does anyone know how to reliably determine when the user toggles Location Services in the device settings? I'd like to be able to see these events in the background -- even if my app is not running.

I figure I could set up an repeating task that runs in the background and periodically checks to see if Location Services has been toggled, but it sounds gross and inefficient.

If it helps, I'm testing on an Moto G running Android 4.4.2. Everything I have done with geofences has worked fine until now.

EDIT: After doing more research I have found that the behaviour of the PROVIDERS_CHANGED broadcast is highly variable depending on phone version and model. My Nexus 5 running Android 5.1 seems to work fine actually - I am able to get the PROVIDERS_CHANGED broadcast very regularly. I also have a Moto G and Moto X phone running 4.4.x and they never produced the PROVIDERS_CHANGED broadcast for me. A Samsung Galaxy S3 on Android 4.2 would produce the broadcast for me but stop doing it after I used my Map Activity with test location providers.

Anyways, I have decide to stop pursuing this problem for now. I think Android is just being buggy.

解决方案

It's hard to tell without seeing your code if you are doing anything wrong, but I just got a simple example working and tested by using the code from here as a guide, and adapting it to have the BroadcastReceiver in a library.

One thing to note: The app using the library will need to have the receiver in its AndroidManifest.xml. See here and here, both contain information from @CommonsWare.

Adding quote here just in case the link goes bad:

Is there any way for a library project to independently register for a receiver in it's own manifest file?

Not at the present time.

So, any app that uses your library will need to have the receiveradded in its AndroidManifest.xml.

Note that this was tested on Android 4.4.4 on a Samsung S4.

I got this working using a BroadcastReceiver in a library project compiled to a aar.

Using a receiver element set up in the AndroidManifest.xml of the main app that links to the BroadcastReceiver in the library, I was able to receive the event when any change is made to the Location settings:

  • Location toggle on
  • Location toggle off
  • Change Location Mode to High Accuracy
  • Change Location Mode to Power Saving
  • Change Location Mode to GPS only

Every time a change is made in the location settings, the BroadcastReceiver in the library is triggered, even if the app is not running.

I used a simple test where the BroadcastReceiver in the library shows a Toast message every time the location settings are changed.

Here is LocationProviderChangedReceiver.java in the library project:

import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.location.LocationManager;
import android.util.Log;
import android.widget.Toast;

public class LocationProviderChangedReceiver extends BroadcastReceiver {
    private final static String TAG = "LocationProviderChanged";

    boolean isGpsEnabled;
    boolean isNetworkEnabled;

    @Override
    public void onReceive(Context context, Intent intent) {
        if (intent.getAction().matches("android.location.PROVIDERS_CHANGED"))
        {
            Log.i(TAG, "Location Providers changed");

            LocationManager locationManager = (LocationManager) context.getSystemService(Context.LOCATION_SERVICE);
            isGpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);
            isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

            Toast.makeText(context, "GPS Enabled: " + isGpsEnabled + " Network Location Enabled: " + isNetworkEnabled, Toast.LENGTH_LONG).show();
        }
    }

}

Then, in the main app, I put the compiled myLibrary.aar in the libs folder, and set up the build.gradle to compile the aar:

 repositories{
        flatDir{
            dirs 'libs'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile "com.android.support:appcompat-v7:22.1.1"
    compile "com.google.android.gms:play-services:7.3.0"

    compile 'com.mylibrary.daniel:mylibrary:1.0@aar'

}

Set up the receiver in the AndroidManifest.xml of the main app:

    <receiver
        android:name="com.mylibrary.daniel.mylibrary.LocationProviderChangedReceiver"
        android:exported="false" >
        <intent-filter>
            <action android:name="android.location.PROVIDERS_CHANGED" />
            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>
    </receiver>

Then, installed the app, and modified location settings in a few different ways. The BroadcastReceiver in the library was triggered every time:

这篇关于监视库中的位置设置的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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