地理围栏过渡没有发生

时间:2013-12-04 15:37:43

标签: android google-maps-android-api-2

我正在尝试实施一个Android应用,当我进入/退出地理围栏时触发通知。我正在测试真实设备并使用模拟位置进行测试。

这是我的代码。

public class TestMapActivity extends FragmentActivity implements OnMapLongClickListener,OnMapClickListener,OnMarkerDragListener,ConnectionCallbacks, OnConnectionFailedListener,OnAddGeofencesResultListener, LocationListener {

private GoogleMap map;
private LocationClient mLocationClient;
private static PendingIntent mGeofencePendingIntent;
private SimpleGeoFence fence;
private boolean mIsInDebug = true;
private Location mMockLocation;
private Marker mMockMarker;
private GeofenceReceiver mBroadcastReceiver;
private IntentFilter mIntentFilter;

@Override
protected void onCreate(Bundle saveInstance)
{
        super.onCreate(saveInstance);
        setContentView(R.layout.activity_map);
        map = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();

        CameraPosition INIT = new CameraPosition.Builder()
            .target(new LatLng(21.12326, 79.05155))
            .zoom( 17.5F )
            .bearing( 300F) // orientation
            .tilt( 50F) // viewing angle
            .build();

        map.setOnMarkerDragListener(this);
        map.setOnMapLongClickListener(this);
        map.setOnMapClickListener(this);

        mBroadcastReceiver = new GeofenceReceiver();

        mIntentFilter = new IntentFilter();
        mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCES_ADDED);
        mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCES_REMOVED);
        mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCE_ERROR);
        mIntentFilter.addAction(GeofenceUtils.ACTION_RECEIVE_GEOFENCE);
        mIntentFilter.addAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION);     
        mIntentFilter.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);

        fence = new SimpleGeoFence("1", 19.0222, 72.8666, 50f,Geofence.NEVER_EXPIRE, Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT);

     }


 @Override
    protected void onResume() {
        super.onResume();

        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);
        if (ConnectionResult.SUCCESS == resultCode) 
        // In debug mode, log the status
        Log.d("App","Google Play services is available.");

        LocalBroadcastManager.getInstance(this).registerReceiver(mBroadcastReceiver, mIntentFilter);

        mLocationClient = new LocationClient(this, this, this);
        mLocationClient.connect();
    }

    @Override
    protected void onPause() {
        super.onPause();
         mLocationClient.removeLocationUpdates(this);
         mLocationClient.disconnect();
    }




@Override
public void onConnectionFailed(ConnectionResult arg0) {
    // TODO Auto-generated method stub

}


@Override
public void onConnected(Bundle arg0) {
    // TODO Auto-generated method stub

    // assuming many connections for resume/pause so if mPendingIntent is
    // not null I have set up geofencing before.
    Log.i("App", ""+mGeofencePendingIntent);

    if (mGeofencePendingIntent == null) {
        // need to set up a geofence
        ArrayList<Geofence> geofences = new ArrayList<Geofence>();
        mGeofencePendingIntent= createRequestPendingIntent();
        geofences.add(fence.toGeofence());
        mLocationClient.addGeofences(geofences, mGeofencePendingIntent, this);
    }

     Log.i("App","Setting mock mode");
     mLocationClient.setMockMode(mIsInDebug);
     mLocationClient.requestLocationUpdates(LocationRequest.create().setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
    .setFastestInterval(5000).setInterval(1000), this);

     }


@Override
public void onDisconnected() {
    // TODO Auto-generated method stub
    mLocationClient=null;
}

private PendingIntent createRequestPendingIntent() {


    if (mGeofencePendingIntent != null)
    {
        System.out.println("waiting for intent" +mGeofencePendingIntent);

        return mGeofencePendingIntent;
    }

    Intent intent = new Intent("com.example.ACTION_GEOFENCE_TRANSITION");
    //Intent intent = new Intent(this, ReceiveTransitionsIntentService.class);
    mGeofencePendingIntent =PendingIntent.getBroadcast(this,0,intent, PendingIntent.FLAG_UPDATE_CURRENT);


    return mGeofencePendingIntent;

}

@Override
public void onAddGeofencesResult(int arg0, String[] arg1) {
    // TODO Auto-generated method stub

    Intent broadcastIntent = new Intent();


        if (arg0 == LocationStatusCodes.SUCCESS) {
        Log.i("App", "great we have geofence ready!");
        // also let the user see the geofence visual represntation
        CircleOptions circleOptions = new CircleOptions()
                .center(new LatLng(fence.getLatitude(), fence.getLongitude())).radius(fence.getRadius())
                .fillColor(0x40ff0000).strokeColor(Color.TRANSPARENT)
                .strokeWidth(2);
        map.addCircle(circleOptions);
        map.addMarker(
                new MarkerOptions()
                        .position(
                                new LatLng(fence.getLatitude(),
                                        fence.getLongitude()))
                        .title("Fence " )
                        .snippet("Radius: " + fence.getRadius()))
                .showInfoWindow();

         broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
         .addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);


    } else
        Log.e("App", "something went wrong...");

    LocalBroadcastManager.getInstance(this).sendBroadcast(broadcastIntent);

}


@Override
public void onMapClick(LatLng latLng) {
    // TODO Auto-generated method stub
    Log.d("App","Debug"+mIsInDebug);


    if (mIsInDebug) {
        if (mMockLocation == null) {

            mMockLocation = new Location("gps");
            mMockLocation.setLatitude(latLng.latitude);
            mMockLocation.setLongitude(latLng.longitude);
            mMockLocation.setAccuracy(100f);
            Log.i("Mock Location",""+mMockLocation);
        }

        mMockLocation.setLatitude(latLng.latitude);
        mMockLocation.setLongitude(latLng.longitude);
        mMockLocation.setTime(System.currentTimeMillis());
        //Log.i("Setting Mock Location",""+mMockLocation);
        mLocationClient.setMockLocation(mMockLocation);
    }
}




public void onLocationChanged(Location location) {
    LatLng latLng = new LatLng(location.getLatitude(),
            location.getLongitude());
    String snippet = "Radius: " + location.getAccuracy();



    if (mMockMarker == null) {
        // create new marker.
        mMockMarker = map.addMarker(new MarkerOptions().position(latLng)
                .title("Me").snippet(snippet).icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_YELLOW)));
    } else {
        mMockMarker.setPosition(latLng);
        mMockMarker.setSnippet(snippet);
    }       
     }

但是不显示通知。我可以在接下来的接收器类中正确接收Intent。

 public class GeofenceReceiver extends BroadcastReceiver
  {

@Override
public void onReceive(Context context, Intent intent)
{
    // TODO Auto-generated method stub

    Log.i("Broadcast","Received Broadcast");

    String action= intent.getAction();
    Log.i("ACTION", ""+action);

    if (LocationClient.hasError(intent)) {
        Log.i("info", "Some errors found..");
    } 
    else 
    {
        handleEnterExit(intent);
    }
}

private void handleEnterExit(Intent intent) {


    int transition = LocationClient.getGeofenceTransition(intent);
    Log.i("MODE",""+transition);

    // Test that a valid transition was reported
    if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
            || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {

        Log.i("TRANSITION","GEOFENCE ENTERED");
        //Toast.makeText(context, "I have entered/exited a geofence",Toast.LENGTH_LONG).show();


          }
   }
    }

我在Manifest.xml文件中使用approprite权限声明了接收器。所以我还没有发布。 我错过了什么......为什么没有检测到过渡?请帮忙

3 个答案:

答案 0 :(得分:1)

Google Play Example for Geofence Detection非常彻底。你可以尝试一下。还有一个完整的Sample Project,对我来说效果很好。

答案 1 :(得分:1)

编辑 BroadcastReceiver 类,如下所示:

public class GeofenceReceiver extends BroadcastReceiver
  {
Intent broadcastIntent = new Intent();
@Override
public void onReceive(Context context, Intent intent)
{
    // TODO Auto-generated method stub
   broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICE);

    Log.i("Broadcast","Received Broadcast");

    String action= intent.getAction();
    Log.i("ACTION", ""+action);

    if (LocationClient.hasError(intent)) {
        Log.i("info", "Some errors found..");
    } 
    else 
    {
        handleEnterExit(intent);
    }
}

private void handleEnterExit(Intent intent) {


    int transition = LocationClient.getGeofenceTransition(intent);
    Log.i("MODE",""+transition);

    // Test that a valid transition was reported
    if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
            || (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {

broadcastIntent.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
                .addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICE)

                .putExtra(GeofenceUtils.EXTRA_GEOFENCE_TRANSITION_TYPE,
                        transitionType);

        LocalBroadcastManager.getInstance(context)
                .sendBroadcast(broadcastIntent);

        Log.i("TRANSITION","GEOFENCE ENTERED");
        //Toast.makeText(context, "I have entered/exited a geofence",Toast.LENGTH_LONG).show();


          }
   }
    }

答案 2 :(得分:1)

您应该在 onCreate()方法中实例化GoogleApiClient:

    mApiClient = new GoogleApiClient.Builder(this)
            .addApi(LocationServices.API)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .build();

    mApiClient.connect();