Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android地理围栏广播接收机_Android_Google Api Client_Geofencing_Android Geofence - Fatal编程技术网

Android地理围栏广播接收机

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事件

我已经使用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>