1

我对此问题进行了一个多星期的研究。在进入或存在地理围栏时没有触发Goffence事件。我在仿真器上测试过几次。Android Geofece退出/输入地理围栏事件不触发

这里是我的MainActivity

**

package com.example.internet.ytgeofence; 

import android.Manifest; 
import android.app.PendingIntent; 
import android.content.Context; 
import android.content.Intent; 
import android.content.pm.PackageManager; 
import android.location.Location; 
import android.os.Build; 
import android.support.annotation.NonNull; 
import android.support.annotation.Nullable; 
import android.support.annotation.RequiresApi; 
import android.support.v4.app.ActivityCompat; 
import android.support.v4.app.FragmentActivity; 
import android.support.v7.app.AppCompatActivity; 
import android.os.Bundle; 
import android.util.Log; 
import android.view.View; 
import android.widget.Button; 
import android.widget.TextView; 
import android.widget.Toast; 

import com.google.android.gms.common.ConnectionResult; 
import com.google.android.gms.common.GoogleApiAvailability; 
import com.google.android.gms.common.GooglePlayServicesUtil; 
import com.google.android.gms.common.api.Api; 
import com.google.android.gms.common.api.GoogleApiClient; 
import com.google.android.gms.common.api.PendingResult; 
import com.google.android.gms.common.api.ResultCallback; 
import com.google.android.gms.common.api.Status; 
import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.GeofencingRequest; 
import com.google.android.gms.location.LocationListener; 
import com.google.android.gms.location.LocationRequest; 
import com.google.android.gms.location.LocationServices; 

import java.io.FileDescriptor; 
import java.io.PrintWriter; 
import java.util.ArrayList; 
import java.util.List; 
import java.util.concurrent.TimeUnit; 

public class MainActivity extends AppCompatActivity { 
    public static final String TAG = "MainActivity"; 
    GoogleApiClient googleApiClient = null; 
    protected ArrayList<Geofence> mGeofenceList; 
    private Context mContext ; 
    Button startLocationMonitoring, startGeofenceMonitoring,  stopGeofenceMonitoring; 
    TextView t; 
    public List<Geofence> listGeofence; 


@RequiresApi(api = Build.VERSION_CODES.M) 
@Override 
protected void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.activity_main); 
    /*int resultCode = 
      GooglePlayServicesUtil. 
        isGooglePlayServicesAvailable(this);*/ 
    mGeofenceList = new ArrayList<Geofence>(); 
    startLocationMonitoring = (Button) findViewById(R.id.button2); 
    startGeofenceMonitoring = (Button) findViewById(R.id.button3); 
    stopGeofenceMonitoring = (Button) findViewById(R.id.button4); 
    t = (TextView) findViewById(R.id.textView2); 
    mContext=getApplicationContext(); 

    startLocationMonitoring.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      StartLocationMonitoring(); 
     } 
    }); 
    startGeofenceMonitoring.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      StartGeofenceMonitoring(); 
     } 
    }); 
    stopGeofenceMonitoring.setOnClickListener(new View.OnClickListener() { 
     @Override 
     public void onClick(View v) { 
      StopGeofenceMonitoring(); 
     } 
    }); 

    googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API) 
      .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() { 

        @Override 
        public void onConnected(@Nullable Bundle bundle) { 
         Log.d(TAG, "Connected to google Api Client"); 
        } 

        @Override 
        public void onConnectionSuspended(int i) { 
         Log.d(TAG, "suspended connection to google Api Client"); 
        } 
       }) 
         .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() { 
        @Override 
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) { 
         Log.d(TAG, "Failed to connect to google api client" + connectionResult.getErrorMessage()); 
        } 
      }).build(); 


    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1234); 
    googleApiClient.connect(); 
} 

@Override 
protected void onStart() { 
    Log.d(TAG, "On start Called"); 
    Toast.makeText(this,"On start called" ,Toast.LENGTH_LONG).show(); 
    super.onStart(); 
    googleApiClient.reconnect(); 
} 

@Override 
protected void onStop() { 
    Log.d(TAG, "On stop Called"); 
    super.onStop(); 
    googleApiClient.disconnect(); 
} 

@Override 
protected void onResume() { 
    Log.d(TAG, "On Resume Called"); 
    super.onResume(); 
    int response = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this); 
    if (response != ConnectionResult.SUCCESS) { 
     Log.d(TAG, "Google Paly Services not avaliable.show dialouge to download"); 
     GoogleApiAvailability.getInstance().getErrorDialog(this, response, 1).show(); 
    } else { 
     Log.d(TAG, "Google Paly Services avaliable"); 
    } 
} 

private void StartLocationMonitoring() { 
    Log.d(TAG, "Location Monitoring Start"); 
    try { 
     LocationRequest locationRequest = LocationRequest.create() 
       .setInterval(10000) 
       .setFastestInterval(5000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 
     LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, new LocationListener() { 
      @Override 
      public void onLocationChanged(Location location) { 
       t = (TextView) findViewById(R.id.textView2); 
       t.setText("Lat:" + location.getLatitude() + "Lng" + location.getLongitude()); 
       Log.d(TAG, "Location Lat/Lng" + location.getLongitude() + " " + location.getLongitude()); 
      } 
     }); 


    } catch (Exception ex) { 
     Log.d(TAG, "Exception in location Monitoring" + ex.toString()); 
    } 

} 

private void StartGeofenceMonitoring() { 


    Geofence geofence = new Geofence.Builder().setRequestId("SAN Loaction") 
      .setCircularRegion(48.848016, 2.346888, 200) 
      .setExpirationDuration(Geofence.NEVER_EXPIRE).setNotificationResponsiveness(1000) 
      .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT).build(); 
    mGeofenceList.add(geofence); 


    GeofencingRequest geofencingRequest = getGeofencingRequest(); 

    Intent intent = new Intent(MainActivity.this, GeofenceService.class); 
    PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT); 

    try { 


    if (!googleApiClient.isConnected()) { 
     Log.d(TAG, "Google API Client Not Connected"); 
     Toast.makeText(getApplicationContext() 
       ,"Google api client not connected",Toast.LENGTH_LONG); 
    } else { 
     if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { 
      return; 
     } 
     LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(new ResultCallback<Status>() { 
      @Override 
      public void onResult(@NonNull Status status) { 
       if (status.isSuccess()) 
       { 
        Log.d(TAG,"Geofence added Successfully"); 
        Toast.makeText(getApplicationContext(),"Geo fence added successfully",Toast.LENGTH_LONG).show(); 
       } 
       else 
       { 
        Log.d(TAG,"Failed to add Geofence"+status.getStatus()); 
        Toast.makeText(getApplicationContext(),"Geofence not added successfully",Toast.LENGTH_LONG); 
       } 
      } 
     }); 


    } 
    }catch (SecurityException ex) 
    { 
     Log.d(TAG," Security Exception in api client"); 
     Toast.makeText(getApplicationContext(),"Geofence not added successfully"+ex.toString(),Toast.LENGTH_LONG); 
    } 
} 
private void StopGeofenceMonitoring(){ 
    Log.d(TAG,"Stop geofence called"); 
    ArrayList<String> geofenceids=new ArrayList<String>(); 
    geofenceids.add("SAN Loaction"); 
    LocationServices.GeofencingApi.removeGeofences(googleApiClient,geofenceids); 
} 
private GeofencingRequest getGeofencingRequest() { 
    Log.d(TAG,"Inside Getgeofencing request"); 
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER); 
    builder.addGeofences(mGeofenceList); 
    return builder.build(); 
} 

} 

的Activity_main.xaml是

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    xmlns:tools="http://schemas.android.com/tools" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent" 
    tools:context="com.example.internet.ytgeofence.MainActivity"> 

    <TextView 
     android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:text="Hello World!" 
    app:layout_constraintBottom_toBottomOf="parent" 
    app:layout_constraintLeft_toLeftOf="parent" 
    app:layout_constraintRight_toRightOf="parent" 
    app:layout_constraintTop_toTopOf="parent" 
    android:id="@+id/textView" /> 

<Button 
    android:id="@+id/button2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_below="@+id/textView" 
    android:layout_marginLeft="59dp" 
    android:layout_marginStart="59dp" 
    android:layout_marginTop="75dp" 
    android:layout_toEndOf="@+id/textView" 
    android:layout_toRightOf="@+id/textView" 
    android:text="Start Location Monitoring" /> 

<Button 
    android:id="@+id/button3" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignLeft="@+id/button2" 
    android:layout_alignStart="@+id/button2" 
    android:layout_below="@+id/button2" 
    android:layout_marginTop="22dp" 
    android:text="Start Geofence Monitoring" /> 

<Button 
    android:id="@+id/button4" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignLeft="@+id/button3" 
    android:layout_alignStart="@+id/button3" 
    android:layout_centerVertical="true" 
    android:text="Stop Geofence Monitoring" /> 

<TextView 
    android:id="@+id/textView2" 
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:layout_alignParentBottom="true" 
    android:layout_centerHorizontal="true" 
    android:layout_marginBottom="104dp" 
    android:text="Status" /> 

ŧ他GeofenceService是 package com.example.internet.ytgeofence;

import android.app.IntentService; 
import android.content.Intent; 
import android.support.annotation.Nullable; 
import android.util.Log; 
import android.widget.Toast; 

import com.google.android.gms.location.Geofence; 
import com.google.android.gms.location.GeofencingEvent; 

import java.util.List; 

public class GeofenceService extends IntentService { 

public static final String TAG="GeofenceService"; 

public GeofenceService() { 

    super(TAG); 
    Toast.makeText(this,"Inside Service",Toast.LENGTH_LONG).show(); 
    Log.d(TAG,"Inside Service Constructer"); 
} 

@Override 
protected void onHandleIntent(@Nullable Intent intent) { 
    Log.d(TAG,"Inside IntentHandler"); 
    GeofencingEvent event=GeofencingEvent.fromIntent(intent); 
    if(event.hasError()) 
    { 

    } 
    else 
    { 
     int transition=event.getGeofenceTransition(); 
     List<Geofence> geofences=event.getTriggeringGeofences(); 
     Geofence geofence=geofences.get(0); 
     String RequestID=geofence.getRequestId(); 
     if(transition==Geofence.GEOFENCE_TRANSITION_ENTER) 
     { 
      Log.d(TAG,"Entering Geofence Area"+RequestID); 
      Toast.makeText(this,"Entering Geofence Area",Toast.LENGTH_LONG); 
     } 
     else if(transition==Geofence.GEOFENCE_TRANSITION_ENTER) 
     { 
      Log.d(TAG,"Exiting Geofence Area"+RequestID); 
      Toast.makeText(this,"Exiting Geofence Area",Toast.LENGTH_LONG); 
     } 
    } 


} 

}

而Manifest.xaml是

<?xml version="1.0" encoding="utf-8"?> 
<manifest xmlns:android="http://schemas.android.com/apk/res/android" 
    package="com.example.internet.ytgeofence"> 
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 
<uses-permission android:name="android.permission.INTERNET" /> 
<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:roundIcon="@mipmap/ic_launcher_round" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <activity android:name=".MainActivity"> 
     <intent-filter> 
      <action android:name="android.intent.action.MAIN" /> 
      <category android:name="android.intent.category.LAUNCHER" /> 
     </intent-filter> 
    </activity> 
    <service android:name=".GeofenceService"/> 
</application> 

任何帮助高度Apperciated。

+0

?你是如何检查确切的?你如何模拟输入地理围栏? – greenapps

+0

如果您正在使用仿真器,然后根据您希望检测的选项设置仿真器的位置。如果它仍然导致问题,那么GPS功能可能无法在模拟器中工作,请尝试启用位置权限的实际设备。 –

回答

1

你的代码很好,只是使用真正的设备,并启用GPS,也给予应用程序的位置权限,设置,我使用emulater之前它没有与我合作。

更新

我试试你的代码,有一些点来解决这个问题,首先在清单

<application 
    android:allowBackup="true" 
    android:icon="@mipmap/ic_launcher" 
    android:label="@string/app_name" 
    android:roundIcon="@mipmap/ic_launcher_round" 
    android:supportsRtl="true" 
    android:theme="@style/AppTheme"> 
    <!-- add this --> 
    <meta-data android:name="com.google.android.gms.version" 
     android:value="@integer/google_play_services_version" /> 
    <activity android:name=".MainActivity"> 

在服务中添加此代码删除面包和使用日志只是因为它的崩溃应用程序,这是结果 enter image description here

我加GeofencingRequest.INITIAL_TRIGGER_EXITGeofencingRequest只是为了确保它能完美工作

private GeofencingRequest getGeofencingRequest() { 
    Log.d(TAG,"Inside Getgeofencing request"); 
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder(); 
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT); 
    builder.addGeofences(mGeofenceList); 
    return builder.build(); 
} 
在清单

我添加此权限 - 我想你已经添加它,如何使用模拟器的位置变化把刚刚在区分<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

+0

请记住,Google的Geofence API不仅仅使用GPS,而且很大程度上依赖于网络位置,以便降低功耗。仿真器允许GPS注入,但不适用于网络点。也就是说,我强烈建议使用真实设备来测试地理围栏,并使用仿真器来测试地理围栏应该触发的逻辑。 –

+0

我用我真实的设备测试这个应用程序。但不工作。我怎样才能严格使用GPS位置。 –

+0

我在我的设备中测试它,并用我的修复程序更新我的答案,我希望它能与您合作。 – 3zcs

相关问题