Android地理围栏退出/进入地理围栏事件未触发

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

我被这个问题困扰了一个多星期。Goefence 事件不会在进入或存在 Geofence 时触发。我已经在模拟器上测试了几次。

这是我的 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" />

地理围栏服务是 包 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>

非常感谢任何帮助。

最佳答案

您的代码很好,只需使用真实设备,并启用 GPS,还授予应用位置权限,设置,我使用模拟器之前它不适合我。

更新

我试过你的代码,有一些地方可以解决这个问题,首先在 list 中添加这段代码

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

在 list 中我添加了这个权限 - 我想你已经添加了它,以防万一 - <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>

关于Android地理围栏退出/进入地理围栏事件未触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43202796/

相关文章:

java - 如何使用 Java 将 json 数组转换为 CSV 文件

java - 如何列出所有根集合并获取所有产品?

android - 无法解析方法 getProjection() 和 getMapCenter()

java - Logcat : Binary XML file line #18 : Error inflating class android. widget.TextView

java - 如何设置离线 map 的最大缩放级别?

android - 自定义 RecyclerViewAdapter 中的 MapView

android - LayerList 作为 Google map v2 中标记上的图标

java - 创建帐户按钮始终会转到登录 Gmail 帐户的浏览器。它怎么总是会请求谷歌的许可呢?

android - 连接到 Google API 客户端时 Android Activity 生命周期的奇怪行为

javascript - 如何使用 google-api-javascript-client 或 "Contacts API version 3.0"从 gmail 导入联系人?