Android地理围栏广播接收机
我已经使用GoogleAppClient->实现了GeoFence,当触发时,一个服务连接到GoogleAppClient并添加几个GeoFence 在我将另一个IntentService注册为geofence事件的“回调”之前。这或多或少起作用,但只有在应用程序处于前台时才起作用。由于我想在应用程序处于后台/关闭状态时获取geofence事件,我搜索了一下,将回调从IntentService移动到了BroadcastReceiver,现在当应用程序处于前台时,我甚至没有获取geofence事件 我已经向互联网寻求解决方案(最常见的答案是:将事件侦听器从服务更改为广播接收器-但这会让事情变得更糟) 以下是我的设置: 舱单:Android地理围栏广播接收机,android,google-api-client,geofencing,android-geofence,Android,Google Api Client,Geofencing,Android Geofence,我已经使用GoogleAppClient->实现了GeoFence,当触发时,一个服务连接到GoogleAppClient并添加几个GeoFence 在我将另一个IntentService注册为geofence事件的“回调”之前。这或多或少起作用,但只有在应用程序处于前台时才起作用。由于我想在应用程序处于后台/关闭状态时获取geofence事件,我搜索了一下,将回调从IntentService移动到了BroadcastReceiver,现在当应用程序处于前台时,我甚至没有获取geofence事件
<receiver
android:name=".service.GeofenceReceiver">
<intent-filter>
<action android:name="com.example.geofence.ACTION_RECEIVE" />
</intent-filter>
</receiver>
<receiver android:name=".service.BootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<service
android:name=".service.GeofenceRegistrationService"
android:enabled="true"
android:exported="false" />
地理接收器:
public class GeofenceReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
Logger.e(this, "GeofenceReceiver called");
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
Logger.e(this, String.valueOf(geofencingEvent.getErrorCode()));
} else {
Logger.i(this, geofencingEvent.getTriggeringLocation().getLatitude() + ", " +geofencingEvent.getTriggeringLocation().getLongitude());
}
}
}
GeofenceRegistrationService:
public class GeofenceRegistrationService extends Service implements ConnectionCallbacks, OnConnectionFailedListener, ResultCallback<Status> {
public static final String KEY_FORCE_CLEAN = "FORCE_CLEAN";
public static void startService(Context context, boolean forceClean) {
Intent intent = new Intent(context, GeofenceRegistrationService.class);
intent.putExtra(KEY_FORCE_CLEAN, forceClean);
context.startService(intent);
}
private GoogleApiClient mGoogleApiClient;
private PendingIntent mGeofencePendingIntent;
@Nullable
@Override
public IBinder onBind(Intent intent) {
return null;
}
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (isLocationPermissionGranted() && intent != null) {
startGeofenceRegistration();
} else {
this.stopSelf(startId);
}
return START_REDELIVER_INTENT;
}
public void startGeofenceRegistration() {
if (mGoogleApiClient == null) {
mGoogleApiClient = buildAPIClient();
}
if (!mGoogleApiClient.isConnected() && !mGoogleApiClient.isConnecting()) {
mGoogleApiClient.connect();
} else {
registerGeofences();
}
}
private boolean isLocationPermissionGranted() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED;
}
private synchronized GoogleApiClient buildAPIClient() {
return new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
private void addGeoFences() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
createGeofencesRequest(),
getGeofencePendingIntent()
).setResultCallback(this);
} catch (SecurityException securityException) {
Logger.e(this, securityException);
}
}
}
private void removeGeoFences() {
if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
try {
LocationServices.GeofencingApi.removeGeofences(
mGoogleApiClient,
getGeofencePendingIntent()
).setResultCallback(this);
} catch (SecurityException securityException) {
Logger.e(this, securityException);
}
}
}
private PendingIntent getGeofencePendingIntent() {
if (mGeofencePendingIntent != null) {
return mGeofencePendingIntent;
}
//Intent intent = new Intent(this, GeofenceEventHandlingService.class);
Intent intent = new Intent("com.example.geofence.ACTION_RECEIVE");
mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Logger.d(this, "CONNECTION_FAILED");
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Logger.d(this, "CONNECTED");
registerGeofences();
}
private void registerGeofences() {
removeGeoFences();
addGeoFences();
}
@Override
public void onConnectionSuspended(int i) {
Logger.d(this, "connection suspended");
}
private GeofencingRequest createGeofencesRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
List<Poi> pois = Config.getPersistenceService().getPois();
int counter = 0;
for (Poi p : pois) {
if (p.isCoordinateSet()) {
Geofence fence = new Geofence.Builder()
.setRequestId(String.valueOf(p.getId()))
.setCircularRegion(p.getLat(), p.getLon(), 2500) // TODO
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.build();
builder.addGeofence(fence);
counter++;
}
}
Logger.i(this, "added geofences: " + counter);
return builder.build();
}
@Override
public void onDestroy() {
if (mGoogleApiClient != null && (mGoogleApiClient.isConnected() || mGoogleApiClient.isConnecting())) {
mGoogleApiClient.disconnect();
}
super.onDestroy();
}
@Override
public void onResult(@NonNull Status status) {
if (status.isSuccess()) {
Logger.d(this, "Geofences added");
} else {
Logger.d(this, "Failed to add geofences");
}
}
}
公共类GeofenceRegistrationService扩展服务实现ConnectionCallbacks、OnConnectionFailedListener、ResultCallback{
公共静态最终字符串键\u FORCE\u CLEAN=“FORCE\u CLEAN”;
公共静态void startService(上下文上下文,布尔forceClean){
意向意向=新意向(上下文,GeofenceRegistrationService.class);
意图。额外(键力清洁,力清洁);
上下文。startService(意图);
}
私人GoogleapClient MGoogleapClient;
私人吊挂帐篷管理围栏吊挂帐篷;
@可空
@凌驾
公共IBinder onBind(意向){
返回null;
}
@凌驾
公共int onStartCommand(Intent Intent、int标志、int startId){
if(isLocationPermissionGrated()&&intent!=null){
startGeofenceRegistration();
}否则{
这是stopSelf(startId);
}
返回启动\u重新交付\u意图;
}
公共作废startGeofenceRegistration(){
if(mGoogleApiClient==null){
mGoogleApiClient=buildAPIClient();
}
如果(!mgoogleapclient.isConnected()&&!mgoogleapclient.isConnecting()){
mGoogleApiClient.connect();
}否则{
registerGeofences();
}
}
私有布尔值IsLocationPermissionGrated(){
返回ContextCompat.checkSelfPermission(此,Manifest.permission.ACCESS\u FINE\u LOCATION)==PackageManager.permission\u已授予;
}
私有同步的GoogleAppClient BuildApicClient(){
返回新的GoogleAppClient.Builder(此)
.addConnectionCallbacks(此)
.addOnConnectionFailedListener(此)
.addApi(LocationServices.API)
.build();
}
私有void addgeofenses(){
if(mGoogleApiClient!=null&&mGoogleApiClient.isConnected(){
试一试{
LocationServices.GeofencingApi.AddGeofines(
MGoogleapClient,
createGeofencesRequest(),
getGeofencePendingIntent()
).setResultCallback(此);
}捕获(SecurityException SecurityException){
Logger.e(这是securityException);
}
}
}
私有void removeGeoFences(){
if(mGoogleApiClient!=null&&mGoogleApiClient.isConnected(){
试一试{
LocationServices.GeofencingApi.removeGeofences(
MGoogleapClient,
getGeofencePendingIntent()
).setResultCallback(此);
}捕获(SecurityException SecurityException){
Logger.e(这是securityException);
}
}
}
私有PendingEvent GetGeoFencePendingEvent(){
if(mgeofencependingent!=null){
返回mgeofencependingent;
}
//Intent Intent=新Intent(这是GeofenceEventHandlingService.class);
意向意向=新意向(“com.example.geopfence.ACTION_RECEIVE”);
mgeofencependingent=pendingent.getService(this,0,intent,pendingent.FLAG_UPDATE_CURRENT);
返回mgeofencependingent;
}
@凌驾
public void onconnection失败(@NonNull ConnectionResult ConnectionResult){
Logger.d(这是“连接失败”);
}
@凌驾
未连接的公共无效(@Nullable Bundle){
Logger.d(本“已连接”);
registerGeofences();
}
私有无效注册表GeoFences(){
拆除围栏();
添加地理围栏();
}
@凌驾
公共空间连接暂停(int i){
Logger.d(该“连接暂停”);
}
私有GeofencingRequest createGeofencesRequest(){
GeofencingRequest.Builder=新的GeofencingRequest.Builder();
List pois=Config.getPersistenceService().getPois();
int计数器=0;
对于(Poi p:Poi){
if(p.iscoordinareset()){
Geofence fence=新建Geofence.Builder()
.setRequestId(String.valueOf(p.getId()))
.setCircularRegion(p.getLat(),p.getLon(),2500)//TODO
.setExpirationDuration(地理围栏永不过期)
.setTransitionTypes(地理围栏.地理围栏\转换\输入)
.build();
建造商。添加土工围栏(围栏);
计数器++;
}
}
Logger.i(此“添加了geofences:+计数器”);
返回builder.build();
}
@凌驾
公共空间{
if(mGoogleApiClient!=null&(mGoogleApiClient.isConnected()| | mGoogleApiClient.isConnecting()){
mGoogleApiClient.disconnect();
}
super.ondestory();
}
@凌驾
public void onResult(@NonNull状态){
if(status.issucess()){
Logger.d(本“Geofenses补充”);
}否则{
Logger.d(这是“未能添加地理围栏”);
}
}
}
我做错了什么?我该监督什么?以下是我的工作内容,但请记住,我在活动中添加和删除我的地理围栏,并在IntentService中接收地理围栏转换 我认为您应该尝试构建您的
意图
指定新意图(上下文,您的接收者类)
并使用pendingent.getBroadcast()
创建您的pendingent
。以下是我使用的方法:
private PendingIntent getGeofencePendingIntent(){
// Re-use the Pending Intent if it already exists
if(mGeofencePendingIntent != null){
return mGeofencePendingIntent;
}
// The intent for the IntentService to receive the transitions
Intent intent = new Intent(getContext(), GeofenceTransitionsIntentService.class);
// Create the pending intent
mGeofencePendingIntent = PendingIntent
.getService(getContext(), 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
return mGeofencePendingIntent;
}
在我的IntentService中:
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.getErrorCode());
Log.e(LOG_TAG, errorMessage);
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
// Test that the reported transition was of interest.
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
// Get the geofences that were triggered. A single event can trigger multiple geofences.
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Do something with geofences
}
}
@覆盖
保护
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent = GeofencingEvent.fromIntent(intent);
if (geofencingEvent.hasError()) {
String errorMessage = GeofenceErrorMessages.getErrorString(this,
geofencingEvent.getErrorCode());
Log.e(LOG_TAG, errorMessage);
return;
}
// Get the transition type.
int geofenceTransition = geofencingEvent.getGeofenceTransition();
// Test that the reported transition was of interest.
if (geofenceTransition == Geofence.GEOFENCE_TRANSITION_ENTER ||
geofenceTransition == Geofence.GEOFENCE_TRANSITION_EXIT) {
// Get the geofences that were triggered. A single event can trigger multiple geofences.
List<Geofence> triggeringGeofences = geofencingEvent.getTriggeringGeofences();
// Do something with geofences
}
}
private PendingIntent getGeofencePendingIntent() {
(...)
mGeofencePendingIntent = PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
(...)
}
mGeofencePendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
<receiver
android:name=".service.GeofenceReceiver">
<intent-filter>
<action android:name="com.example.geofence.ACTION_RECEIVE" />
</intent-filter>
</receiver>
<receiver
android:name=".service.GeofenceReceiver">
<intent-filter>
<action android:name="com.example.geofence.ACTION_RECEIVE_GEOFENCE" />
</intent-filter>
</receiver>