我在我的应用中使用最新的geofence api,然后按Google's sample code构建应用。但是当应用被杀死时它不起作用。我必须再次点击添加地理围栏按钮来触发地理围栏。我希望始终触发地理围栏。我该怎么办? 这是我的代码:
主要活动
public class MainActivity extends AppCompatActivity implements GoogleApiClient.ConnectionCallbacks
, GoogleApiClient.OnConnectionFailedListener,ResultCallback<Status> {
protected GoogleApiClient googleApiClient;
protected ArrayList<Geofence> geofenceArrayList;
private Button button;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
button= (Button) findViewById(R.id.button);
geofenceArrayList = new ArrayList<>();
populateGeofenceList();
buildGoogleApiClient();
}
protected synchronized void buildGoogleApiClient() {
googleApiClient = new GoogleApiClient.Builder(this)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.addApi(LocationServices.API)
.build();
}
@Override
protected void onStart() {
super.onStart();
if (!googleApiClient.isConnected() || !googleApiClient.isConnecting()) {
googleApiClient.connect();
}
}
@Override
protected void onStop() {
super.onStop();
if (googleApiClient.isConnected() || googleApiClient.isConnecting()) {
googleApiClient.disconnect();
}
}
public void populateGeofenceList() {
for (Map.Entry<String, LatLng> entry : Constants.MY_LANDMARKS.entrySet()) {
geofenceArrayList.add(new Geofence.Builder()
.setRequestId(entry.getKey())
.setCircularRegion(entry.getValue().latitude, entry.getValue().longitude, 100)
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_DWELL | Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(300000)
.build());
}
}
private GeofencingRequest getGeofencingRequest(){
GeofencingRequest.Builder builder=new GeofencingRequest.Builder();
builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER)
.addGeofences(geofenceArrayList);
return builder.build();
}
private PendingIntent getGeofencePendingIntent(){
Intent intent=new Intent(this,GeofenceTransitionService.class);
return PendingIntent.getService(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
}
public void addGeofencesButtonHandler(View view){
if(!googleApiClient.isConnected()){
Toast.makeText(this,"Client not connected",Toast.LENGTH_SHORT).show();
return;
}
try {
LocationServices.GeofencingApi.addGeofences(googleApiClient,getGeofencingRequest(),getGeofencePendingIntent()).setResultCallback(this);
}catch (SecurityException securityException){
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
@Override
public void onConnected(Bundle bundle) {
}
@Override
public void onConnectionSuspended(int i) {
googleApiClient.connect();
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
}
@Override
public void onResult(Status status) {
if(status.isSuccess()){
Toast.makeText(this,"Geofence added",Toast.LENGTH_SHORT).show();
}
else {
String errorMessage=GeofenceErrorMessages.getErrorString(this,status.getStatusCode());
Log.e("MainActivity",errorMessage);
}
}
}
意向服务
public class GeofenceTransitionService extends IntentService {
/**
* Creates an IntentService. Invoked by your subclass's constructor.
*
* @param name Used to name the worker thread, important only for debugging.
*/
public static final String TAG="GeofenceService";
@Override
public void onCreate() {
super.onCreate();
}
public GeofenceTransitionService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
GeofencingEvent geofencingEvent=GeofencingEvent.fromIntent(intent);
if(geofencingEvent.hasError()){
String errorMsg=GeofenceErrorMessages.getErrorString(this,geofencingEvent.getErrorCode());
Log.e(TAG,errorMsg);
return;
}
int geofenceTransition=geofencingEvent.getGeofenceTransition();
if(geofenceTransition== Geofence.GEOFENCE_TRANSITION_ENTER||geofenceTransition==Geofence.GEOFENCE_TRANSITION_DWELL
||geofenceTransition==Geofence.GEOFENCE_TRANSITION_EXIT){
List<Geofence> triggeringGeofences=geofencingEvent.getTriggeringGeofences();
String geofenceTransitionDetails=getGeofenceTransiionDetails(this,geofenceTransition,triggeringGeofences);
sendNotification(geofenceTransitionDetails);
Log.i(TAG,geofenceTransitionDetails);
}
else {
Log.e(TAG,"Invalid Transition : "+geofenceTransition);
}
}
private String getGeofenceTransiionDetails(Context context,int transition,List<Geofence> triggeringGeofences){
String geofenceTransitionString=getTransitionString(transition);
ArrayList GeofenceIdsList=new ArrayList();
for(Geofence geofence:triggeringGeofences){
GeofenceIdsList.add(geofence.getRequestId());
}
String geofencesIdsString= TextUtils.join(", ", GeofenceIdsList);
return geofenceTransitionString+": "+geofencesIdsString;
}
private String getTransitionString(int transitionType){
switch (transitionType){
case Geofence.GEOFENCE_TRANSITION_ENTER:
return "Entered the geofence";
case Geofence.GEOFENCE_TRANSITION_DWELL:
return "Dwelling in the geofence";
case Geofence.GEOFENCE_TRANSITION_EXIT:
return "Exited the geofence";
default:return "Unknown Transition";
}
}
private void sendNotification(String notificationDetails){
Intent notificationIntent=new Intent(getApplicationContext(),MainActivity.class);
TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
stackBuilder.addParentStack(MainActivity.class);
stackBuilder.addNextIntent(notificationIntent);
PendingIntent notificationPendingIntent=stackBuilder.getPendingIntent(0,PendingIntent.FLAG_UPDATE_CURRENT);
NotificationCompat.Builder builder=new NotificationCompat.Builder(this);
builder.setSmallIcon(R.mipmap.ic_launcher)
.setContentTitle(notificationDetails)
.setContentText("Click to return to app")
.setContentIntent(notificationPendingIntent);
builder.setAutoCancel(true);
NotificationManager manager= (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
manager.notify(0,builder.build());
}
}