地理围栏转换未发生

3
我正在尝试开发一款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文件中声明了接收者,并添加了适当的权限,但是它似乎没有生效。我是否漏掉了什么?为什么过渡没有被检测到?请帮忙。


但是你的意思是你的接收器收到了意图,但通知没有显示?还是你的意思是你接收到了所有广播,但过渡时没有接收到? - Carlos Robles
是的,我的意思是广播已经接收到了,但是转换从未被检测到。 - Parth Doshi
一些日志可以帮助理解问题。最后调用了哪个日志语句?你能提供一些输出吗? - Philipp Kuntschik
你说你收到了Intent,所以我假设你的handleEnterExit(Intent intent)方法被调用了。在你的transition变量中得到的是什么数字? - Basile Perrenoud
@PhilippKuntschik:我很快会添加日志。 - Parth Doshi
从Android文档中获取:如果意图未生成转换警报,则getGeofenceTransition返回-1;否则,返回在Geofence中定义的GEOFENCE_TRANSITION_标志值。 所以我猜你没有得到你期望的意图。你能尝试打印intent.getAction String和额外的值,这样你就可以确定这个意图是否是预期的吗? - Basile Perrenoud
3个回答

1

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

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

    mApiClient.connect();

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();


          }
   }
    }

1

1
示例项目使用IntentService而不是BroadcastReceiver。问题在于,当应用程序在后台运行时,IntentService方法会失败。http://davehiren.blogspot.co.uk/2015/01/android-geofence-stop-getting.html - Someone Somewhere

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接