我正在尝试实施一个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权限声明了接收器。所以我还没有发布。 我错过了什么......为什么没有检测到过渡?请帮忙
答案 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();