Android Geofece退出/输入地理围栏事件不触发

时间:2017-04-04 09:08:01

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

我在这个问题上坚持了一个多星期.Goefence事件不会触发进入或存在地理围栏。我已经在emulater上测试过几次了。

这是我的MainActivity

**

package com.example.internet.ytgeofence;

import android.Manifest;
import android.app.PendingIntent;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Build;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.annotation.RequiresApi;
import android.support.v4.app.ActivityCompat;
import android.support.v4.app.FragmentActivity;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GoogleApiAvailability;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.Api;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.PendingResult;
import com.google.android.gms.common.api.ResultCallback;
import com.google.android.gms.common.api.Status;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingRequest;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.io.FileDescriptor;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;

public class MainActivity extends AppCompatActivity {
    public static final String TAG = "MainActivity";
    GoogleApiClient googleApiClient = null;
    protected ArrayList<Geofence> mGeofenceList;
    private Context mContext ;
    Button startLocationMonitoring, startGeofenceMonitoring,     stopGeofenceMonitoring;
    TextView t;
    public List<Geofence> listGeofence;


@RequiresApi(api = Build.VERSION_CODES.M)
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    /*int resultCode =
            GooglePlayServicesUtil.
                    isGooglePlayServicesAvailable(this);*/
    mGeofenceList = new ArrayList<Geofence>();
    startLocationMonitoring = (Button) findViewById(R.id.button2);
    startGeofenceMonitoring = (Button) findViewById(R.id.button3);
    stopGeofenceMonitoring = (Button) findViewById(R.id.button4);
    t = (TextView) findViewById(R.id.textView2);
    mContext=getApplicationContext();

    startLocationMonitoring.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            StartLocationMonitoring();
        }
    });
    startGeofenceMonitoring.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            StartGeofenceMonitoring();
        }
    });
    stopGeofenceMonitoring.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            StopGeofenceMonitoring();
        }
    });

    googleApiClient = new GoogleApiClient.Builder(this).addApi(LocationServices.API)
            .addConnectionCallbacks(new GoogleApiClient.ConnectionCallbacks() {

                    @Override
                    public void onConnected(@Nullable Bundle bundle) {
                        Log.d(TAG, "Connected to google Api Client");
                    }

                    @Override
                    public void onConnectionSuspended(int i) {
                        Log.d(TAG, "suspended connection to google Api Client");
                    }
                })
                        .addOnConnectionFailedListener(new GoogleApiClient.OnConnectionFailedListener() {
                    @Override
                    public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
                        Log.d(TAG, "Failed to connect to google api client" + connectionResult.getErrorMessage());
                    }
            }).build();


    requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, 1234);
    googleApiClient.connect();
}

@Override
protected void onStart() {
    Log.d(TAG, "On start Called");
    Toast.makeText(this,"On start called" ,Toast.LENGTH_LONG).show();
    super.onStart();
    googleApiClient.reconnect();
}

@Override
protected void onStop() {
    Log.d(TAG, "On stop Called");
    super.onStop();
    googleApiClient.disconnect();
}

@Override
protected void onResume() {
    Log.d(TAG, "On Resume Called");
    super.onResume();
    int response = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(this);
    if (response != ConnectionResult.SUCCESS) {
        Log.d(TAG, "Google Paly Services not avaliable.show dialouge to download");
        GoogleApiAvailability.getInstance().getErrorDialog(this, response, 1).show();
    } else {
        Log.d(TAG, "Google Paly Services avaliable");
    }
}

private void StartLocationMonitoring() {
    Log.d(TAG, "Location Monitoring Start");
    try {
        LocationRequest locationRequest = LocationRequest.create()
                .setInterval(10000)
                .setFastestInterval(5000).setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, new LocationListener() {
            @Override
            public void onLocationChanged(Location location) {
                t = (TextView) findViewById(R.id.textView2);
                t.setText("Lat:" + location.getLatitude() + "Lng" + location.getLongitude());
                Log.d(TAG, "Location Lat/Lng" + location.getLongitude() + " " + location.getLongitude());
            }
        });


    } catch (Exception ex) {
        Log.d(TAG, "Exception in location Monitoring" + ex.toString());
    }

}

private void StartGeofenceMonitoring() {


    Geofence geofence = new Geofence.Builder().setRequestId("SAN Loaction")
            .setCircularRegion(48.848016, 2.346888, 200)
            .setExpirationDuration(Geofence.NEVER_EXPIRE).setNotificationResponsiveness(1000)
            .setTransitionTypes(Geofence.GEOFENCE_TRANSITION_ENTER | Geofence.GEOFENCE_TRANSITION_EXIT).build();
    mGeofenceList.add(geofence);


    GeofencingRequest geofencingRequest = getGeofencingRequest();

    Intent intent = new Intent(MainActivity.this, GeofenceService.class);
    PendingIntent pendingIntent = PendingIntent.getService(MainActivity.this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);

    try {


    if (!googleApiClient.isConnected()) {
        Log.d(TAG, "Google API Client Not Connected");
        Toast.makeText(getApplicationContext()
                ,"Google api client not connected",Toast.LENGTH_LONG);
    } else {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            return;
        }
        LocationServices.GeofencingApi.addGeofences(googleApiClient, geofencingRequest, pendingIntent).setResultCallback(new ResultCallback<Status>() {
            @Override
            public void onResult(@NonNull Status status) {
                if (status.isSuccess())
                {
                    Log.d(TAG,"Geofence added Successfully");
                    Toast.makeText(getApplicationContext(),"Geo fence added successfully",Toast.LENGTH_LONG).show();
                }
                else
                {
                    Log.d(TAG,"Failed to add Geofence"+status.getStatus());
                    Toast.makeText(getApplicationContext(),"Geofence not added successfully",Toast.LENGTH_LONG);
                }
            }
        });


    }
    }catch (SecurityException ex)
    {
        Log.d(TAG," Security Exception in api client");
        Toast.makeText(getApplicationContext(),"Geofence not added successfully"+ex.toString(),Toast.LENGTH_LONG);
    }
}
private void StopGeofenceMonitoring(){
    Log.d(TAG,"Stop geofence called");
    ArrayList<String> geofenceids=new ArrayList<String>();
    geofenceids.add("SAN Loaction");
    LocationServices.GeofencingApi.removeGeofences(googleApiClient,geofenceids);
}
private GeofencingRequest getGeofencingRequest() {
    Log.d(TAG,"Inside Getgeofencing request");
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER);
    builder.addGeofences(mGeofenceList);
    return builder.build();
}

}

Activity_main.xaml

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.example.internet.ytgeofence.MainActivity">

    <TextView
        android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintLeft_toLeftOf="parent"
    app:layout_constraintRight_toRightOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    android:id="@+id/textView" />

<Button
    android:id="@+id/button2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_below="@+id/textView"
    android:layout_marginLeft="59dp"
    android:layout_marginStart="59dp"
    android:layout_marginTop="75dp"
    android:layout_toEndOf="@+id/textView"
    android:layout_toRightOf="@+id/textView"
    android:text="Start Location Monitoring" />

<Button
    android:id="@+id/button3"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/button2"
    android:layout_alignStart="@+id/button2"
    android:layout_below="@+id/button2"
    android:layout_marginTop="22dp"
    android:text="Start Geofence Monitoring" />

<Button
    android:id="@+id/button4"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignLeft="@+id/button3"
    android:layout_alignStart="@+id/button3"
    android:layout_centerVertical="true"
    android:text="Stop Geofence Monitoring" />

<TextView
    android:id="@+id/textView2"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:layout_alignParentBottom="true"
    android:layout_centerHorizontal="true"
    android:layout_marginBottom="104dp"
    android:text="Status" />

GeofenceService     package com.example.internet.ytgeofence;

import android.app.IntentService;
import android.content.Intent;
import android.support.annotation.Nullable;
import android.util.Log;
import android.widget.Toast;

import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;

import java.util.List;

public class GeofenceService extends IntentService {

public static final String TAG="GeofenceService";

public GeofenceService() {

    super(TAG);
    Toast.makeText(this,"Inside Service",Toast.LENGTH_LONG).show();
    Log.d(TAG,"Inside Service Constructer");
}

@Override
protected void onHandleIntent(@Nullable Intent intent) {
    Log.d(TAG,"Inside IntentHandler");
    GeofencingEvent event=GeofencingEvent.fromIntent(intent);
    if(event.hasError())
    {

    }
    else
    {
        int transition=event.getGeofenceTransition();
        List<Geofence> geofences=event.getTriggeringGeofences();
        Geofence geofence=geofences.get(0);
        String RequestID=geofence.getRequestId();
        if(transition==Geofence.GEOFENCE_TRANSITION_ENTER)
        {
            Log.d(TAG,"Entering Geofence Area"+RequestID);
            Toast.makeText(this,"Entering Geofence Area",Toast.LENGTH_LONG);
        }
        else if(transition==Geofence.GEOFENCE_TRANSITION_ENTER)
        {
            Log.d(TAG,"Exiting Geofence Area"+RequestID);
            Toast.makeText(this,"Exiting Geofence Area",Toast.LENGTH_LONG);
        }
    }


}

}

Manifest.xaml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.internet.ytgeofence">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.INTERNET" />
<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <activity android:name=".MainActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <service android:name=".GeofenceService"/>
</application>

任何帮助都非常有用。

1 个答案:

答案 0 :(得分:2)

你的代码很好,只需使用真实的设备,并启用GPS,也提供应用程序位置权限,该设置,我使用emulater之前它没有与我合作。

<强>更新

我尝试使用您的代码,有一点需要解决此问题,首先在清单中添加此代码

<application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:roundIcon="@mipmap/ic_launcher_round"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <!-- add this -->
    <meta-data android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <activity android:name=".MainActivity">

在您的服务中删除Toast并使用日志只是因为它崩溃的应用程序,这就是结果 enter image description here

我为GeofencingRequest.INITIAL_TRIGGER_EXIT添加GeofencingRequest只是为了确保它能够完美运行

    private GeofencingRequest getGeofencingRequest() {
    Log.d(TAG,"Inside Getgeofencing request");
    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();
    builder.setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_ENTER | GeofencingRequest.INITIAL_TRIGGER_EXIT);
    builder.addGeofences(mGeofenceList);
    return builder.build();
}
清单中的

我添加了这个权限 - 我想你已经添加了它,只是放在案例中 - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>