我知道这个问题已经被问到,但是我尝试了很多建议的解决方案,但它没有用。
我的地理围栏代码在应用程序运行时有效,但一旦应用程序被终止,即使BroadcastReceiver
,通知也不会再出现你可以在这里找到与活动相关的代码,btn_reservation是开始添加地理围栏的按钮。
public class DetailsActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener,
ResultCallback<Status> {
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = 12 * 60 * 60 * 1000;
public static final float GEOFENCE_RADIUS_IN_METERS = 500
private List<Geofence> mGeofenceList;
private GoogleApiClient mGoogleApiClient;
private Button btn_reservation;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_details);
btn_reservation = (Button) findViewById(R.id.reserver);
mGeofenceList = new ArrayList<Geofence>();
mGeofenceList.add(new Geofence.Builder()
.setRequestId("1")
.setCircularRegion(
MapsActivity.getLatitude(),
MapsActivity.getLongitude(),
GEOFENCE_RADIUS_IN_METERS
)
.setExpirationDuration(GEOFENCE_EXPIRATION_IN_MILLISECONDS)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER)
.build());
// Create an instance of GoogleAPIClient.
if (mGoogleApiClient == null) {
mGoogleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
btn_reservation.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (!mGoogleApiClient.isConnected()) {
Toast.makeText(getApplicationContext(), "Google API Client not connected!", Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(
mGoogleApiClient,
getGeofencingRequest(),
getGeofencePendingIntent()
).setResultCallback(DetailsActivity.this); // Result processed in onResult().
} catch (SecurityException securityException) {
// Catch exception generated if the app does not use ACCESS_FINE_LOCATION permission.
Toast.makeText(getApplicationContext(), "ACCESS_FINE_LOCATION permission unused ", Toast.LENGTH_SHORT).show();
}
}
});
}
private GeofencingRequest getGeofencingRequest() {
GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
builder.addGeofences(mGeofenceList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent() {
Intent intent = new Intent("ACTION_RECEIVE_GEOFENCE");
return PendingIntent.getBroadcast(
getApplicationContext(),
0,
intent,
PendingIntent.FLAG_UPDATE_CURRENT);
}
@Override
protected void onStart() {
super.onStart();
if (!mGoogleApiClient.isConnecting() || !mGoogleApiClient.isConnected()) {
mGoogleApiClient.connect();
}
}
@Override
protected void onStop() {
super.onStop();
if (mGoogleApiClient.isConnecting() || mGoogleApiClient.isConnected()) {
mGoogleApiClient.disconnect();
}
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Override
public void onConnected(Bundle bundle) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return;
}
Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
mGoogleApiClient);
if (mLastLocation != null) {
System.out.println("My lat " +String.valueOf(mLastLocation.getLatitude()));
System.out.println("My lon " +String.valueOf(mLastLocation.getLongitude()));
}
}
@Override
public void onConnectionSuspended(int i) {
mGoogleApiClient.connect();
}
@Override
public void onResult(Status status) {
if (status.isSuccess()) {
System.out.println("Geofences Added");
} else {
System.out.println(status.getStatusCode());
}
}
这是我的GeofenceReceiver.java
public class GeofenceReceiver extends BroadcastReceiver {
Context context;
Intent broadcastIntent = new Intent();
@Override
public void onReceive(Context context, Intent intent) {
this.context = context;
broadcastIntent.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
if (event.hasError()) {
handleError(intent);
} else {
handleEnterExit(intent);
}
}
private void handleError(Intent intent){
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
// Get the error code
int errorCode = event.getErrorCode();
// Get the error message
String errorMessage = LocationServiceErrorMessages.getErrorString(
context, errorCode);
// Log the error
Log.e(GeofenceUtils.APPTAG,
"geofence_transition_error_detail"+
errorMessage);
// Set the action and error message for the broadcast intent
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_ERROR)
.putExtra(GeofenceUtils.EXTRA_GEOFENCE_STATUS, errorMessage);
// Broadcast the error *locally* to other components in this app
LocalBroadcastManager.getInstance(context).sendBroadcast(
broadcastIntent);
}
private void handleEnterExit(Intent intent) {
GeofencingEvent event = GeofencingEvent.fromIntent(intent);
int transition = event.getGeofenceTransition();
// Test that a valid transition was reported
if ((transition == Geofence.GEOFENCE_TRANSITION_ENTER)
|| (transition == Geofence.GEOFENCE_TRANSITION_EXIT)) {
// Post a notification
List<Geofence> geofences = event
.getTriggeringGeofences();
String[] geofenceIds = new String[geofences.size()];
String ids = TextUtils.join(GeofenceUtils.GEOFENCE_ID_DELIMITER,
geofenceIds);
int tran = Geofence.GEOFENCE_TRANSITION_ENTER;
String transitionType = String.valueOf(tran);
// Create an Intent to broadcast to the app
broadcastIntent
.setAction(GeofenceUtils.ACTION_GEOFENCE_TRANSITION)
.addCategory(GeofenceUtils.CATEGORY_LOCATION_SERVICES);
LocalBroadcastManager.getInstance(context)
.sendBroadcast(broadcastIntent);
// Log the transition type and a message
Log.d(GeofenceUtils.APPTAG, transitionType + ": " + ids);
Log.d(GeofenceUtils.APPTAG,
context.getString(R.string.geofence_transition_notification_text));
// In debug mode, log the result
Log.d(GeofenceUtils.APPTAG, "transition");
// An invalid transition was reported
} else {
// Always log as an error
Log.e(GeofenceUtils.APPTAG,
"geofence_transition_invalid_type"
+ transition);
}
sendNotification(String.valueOf(Geofence.GEOFENCE_TRANSITION_ENTER), "here");
}
private void sendNotification(String transitionType, String locationName) {
// Create an explicit content Intent that starts the main Activity
Intent notificationIntent = new Intent(context, TicketActivity.class);
// Construct a task stack
TaskStackBuilder stackBuilder = TaskStackBuilder.create(context);
// Adds the main Activity to the task stack as the parent
stackBuilder.addParentStack(TicketActivity.class);
// Push the content Intent onto the stack
stackBuilder.addNextIntent(notificationIntent);
// Get a PendingIntent containing the entire back stack
PendingIntent notificationPendingIntent = stackBuilder
.getPendingIntent(0, PendingIntent.FLAG_UPDATE_CURRENT);
// Get a notification builder that's compatible with platform versions
// >= 4
NotificationCompat.Builder builder = new NotificationCompat.Builder(
context);
// Set the notification contents
builder.setSmallIcon(R.drawable.cast_ic_notification_0)
.setContentTitle(transitionType + ": " + locationName)
.setContentText(
context.getString(R.string.geofence_transition_notification_text))
.setContentIntent(notificationPendingIntent);
// Get an instance of the Notification manager
NotificationManager mNotificationManager = (NotificationManager) context
.getSystemService(Context.NOTIFICATION_SERVICE);
// Issue the notification
mNotificationManager.notify(0, builder.build());
System.out.println("in radius");
}
}
这是清单中的接收者
<receiver android:name="tn.odc.noq.receiver.GeofenceReceiver" android:exported="false">
<intent-filter >
<action android:name="tn.odc.noq.receiver.ACTION_RECEIVE_GEOFENCE"/>
<category android:name="tn.odc.noq.receiver" />
</intent-filter>
</receiver>
答案 0 :(得分:0)
从头开始使用地理围栏真的很难,我一直都在尝试这样做,但我没有得到一个好的存根。所以我采用了一些libs
这里有一些很棒的库:
例如:
GeofenceModel mestalla = new GeofenceModel.Builder("id_mestalla")
.setTransition(Geofence.GEOFENCE_TRANSITION_ENTER)
.setLatitude(39.47453120000001)
.setLongitude(-0.358065799999963)
.setRadius(500)
.build();
RxGeoFence.with(this) //context
.dbUrl(GEO_FIRE_DB) //String
.geoFenceSource(...) // rx.Observable<List<Place>>
.locationSource(...) // rx.Observable<LatLng>
.build()
.subscribe(geoFenceEvent -> {
// do what you wanna do with the event
});
Geofence geofence = new Geofence.Builder()
.setRequestId("GEOFENCE")
.setCircularRegion(latitude, longitude, radius)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT)
.build();
我实际上指出使用libs,因为有大量的开发人员正在努力解决所有问题,并且协商异常。