监控库中的位置设置

时间:2015-05-26 20:03:19

标签: android android-geofence

我正在开发一个可用于监控Android设备上的地理围栏的库。我注意到,我在设备设置中关闭并重新启用了位置服务后,我在Google Play位置服务GeofencingApi课程中注册的地理围栏会丢失。

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

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

我想我可以设置一个在后台运行的重复任务,并定期检查位置服务是否已切换,但听起来很粗糙且效率低。

如果有帮助,我会在运行Android 4.4.2的Moto G上进行测试。我对地理围栏所做的一切工作到目前为止一直很好。

编辑:经过更多研究后,我发现PROVIDERS_CHANGED广播的行为变化很大,具体取决于手机版本和型号。我的Nexus 5运行Android 5.1似乎工作得很好 - 我能够定期收看PROVIDERS_CHANGED广播。我还有一台运行4.4.x的Moto G和Moto X手机,他们从未为我制作PROVIDERS_CHANGED广播。 Android 4.2上的三星Galaxy S3会为我制作广播,但在我将Map Activity与测试位置提供商一起使用后就停止播放。

无论如何,我现在决定停止追求这个问题。我认为Android只是个错误。

2 个答案:

答案 0 :(得分:7)

如果你做错了什么而没有看到你的代码很难说,但我只是通过使用来自here的代码作为指导并使其适应的一个简单示例工作和测试将BroadcastReceiver放在库中。

需要注意的一点是:使用该库的应用需要在其AndroidManifest.xml中包含receiver。 请参阅herehere,两者都包含来自@CommonsWare的信息。

在这里添加引用,以防链接变坏:

  
    

库项目有没有办法独立注册a     接收器里面有自己的清单文件?

  
     

目前不在。

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

请注意,这是在Samsung S4上的Android 4.4.4上测试的。

我使用编译为aar的库项​​目中的BroadcastReceiver工作。

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

  • 位置切换
  • 位置关闭
  • 将位置模式更改为高准确度
  • 将位置模式更改为省电
  • 仅将位置模式更改为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:

enter image description here

enter image description here

enter image description here

enter image description here

答案 1 :(得分:0)

实际上,您可以使用location.MODE_CHANGED然后注册您的接收器以接收来自它的广播

<receiver android:name=".Receivers.LocationModeReceiver">
    <intent-filter>
        <action android:name="android.location.MODE_CHANGED" />
    </intent-filter>
</receiver>