如何修复GeoFencing的Google ApiException?

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

标签: java android geolocation geocoding geofencing

我正在尝试自学Android位置和地理围栏;我正在创建一个简单的应用程序,根据您的位置创建地理围栏,但是我得到了一个我不理解的例外。

请注意我正在学习,所以如果你能用中间术语解释这个问题,我会非常感激!

首先,例外:

08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err: com.google.android.gms.common.api.ApiException
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzb.zzx(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzbi.zzy(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzbj.zzo(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzbbe.zzb(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzbbe.setResult(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.location.LocationServices$zza.setResult(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzcdk.zza(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzccy.onTransact(Unknown Source)
08-04 14:48:33.230 12871-12871/com.example.dubki.geofenceapp W/System.err:     at android.os.Binder.execTransact(Binder.java:565)

MainActivity.java:

import android.Manifest;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Looper;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.TextView;
import android.widget.Toast;
import com.google.android.gms.location.*;
import com.google.android.gms.tasks.OnFailureListener;
import com.google.android.gms.tasks.OnSuccessListener;

import java.util.ArrayList;

public class MainActivity extends AppCompatActivity {

    private static final String TAG = "MainActivity";

    private final int MY_PERMISSIONS_REQUEST_LOCATION = 54;

    private GeofencingClient mGeofencingClient;
    private FusedLocationProviderClient mFusedLocationProviderClient;
    private ArrayList<Geofence> mGeofenceList;
    private ArrayList<Location> mLocationArrayList;
    private PendingIntent mGeofencePendingIntent;

    private boolean hasLocationPermissions;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        Log.w(TAG, "onCreate: ");

        mGeofenceList = new ArrayList<>();
        mLocationArrayList = new ArrayList<>();

        mGeofencingClient = LocationServices.getGeofencingClient(this);
        mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);

        if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION)
                != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
                android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            Log.w(TAG, "onCreate: permissions request");
            ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                    MY_PERMISSIONS_REQUEST_LOCATION);
            return;
        }
        else {
            hasLocationPermissions = true;
            getCurrentLocation();
        }
    }

    private void buildGeofence(Location location) {
        mGeofenceList.add(new Geofence.Builder()
                .setRequestId("test")
                .setCircularRegion(
                        location.getLatitude(),
                        location.getLongitude(),
                        100)
                .setExpirationDuration(100000)
                .setTransitionTypes(
                        Geofence.GEOFENCE_TRANSITION_DWELL
                )
                .setLoiteringDelay(25000)
                .build()
        );
    }

    private GeofencingRequest getGeofencingRequest() {
        Log.w(TAG, "getGeofencingRequest: " + mGeofenceList.get(0).getRequestId());
        GeofencingRequest.Builder builder = new GeofencingRequest.Builder()
                .setInitialTrigger(GeofencingRequest.INITIAL_TRIGGER_DWELL)
                .addGeofences(mGeofenceList);
        return builder.build();
    }

    private PendingIntent getGeofencePendingIntent() {
        if (mGeofencePendingIntent != null) return mGeofencePendingIntent;
        Intent intent = new Intent(this, MyIntentService.class);
        mGeofencePendingIntent = PendingIntent.getService(this, 0,
                intent, PendingIntent.FLAG_UPDATE_CURRENT);
        return mGeofencePendingIntent;
    }

    @Override
    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
        switch (requestCode) {
            case MY_PERMISSIONS_REQUEST_LOCATION:
                if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                    Log.w(TAG, "onRequestPermissionsResult: results granted");
                    hasLocationPermissions = true;
                    getCurrentLocation();
                } else {
                    hasLocationPermissions = false;
                }
                break;
        }
    }

    private void getLastLocation() {
        Log.w(TAG, "getLastLocation:");
        if (hasLocationPermissions) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }
            mFusedLocationProviderClient.getLastLocation().addOnSuccessListener(
                    new OnSuccessListener<Location>() {
                        @Override
                        public void onSuccess(Location location) {
                            Log.w(TAG, "onSuccess: getLastLocation(), createGeofence");
                            if (location != null) {
                                mLocationArrayList.add(0, location);
                                updateLocation(location);
                            }
                        }
                    }
            );
        }

    }

    private void getCurrentLocation() {
        Log.w(TAG, "getCurrentLocation: ");
        final LocationRequest locationRequest = createLocationRequest();
        if (hasLocationPermissions) {
            if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
                    != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
                    Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                return;
            }

            Log.w(TAG, "getCurrentLocation: hasPermissions = true");

            getLastLocation();

            // Gets location updates
            mFusedLocationProviderClient.requestLocationUpdates(locationRequest,
                    new LocationCallback() {
                        @Override
                        public void onLocationResult(LocationResult locationResult) {
                            Log.w(TAG, "onLocationResult: ");
                            mLocationArrayList.add(0, locationResult.getLocations().get(0));
                            updateLocation(locationResult.getLocations().get(0));
                        }
                    }, Looper.myLooper());
        }
    }

    private void updateLocation(Location location) {
        Log.w(TAG, "updateLocation: ");
        TextView textView = (TextView) findViewById(R.id.location);
        textView.setText("latitude: " + location.getLatitude() + " \n"
                            + "longitude: " + location.getLongitude());
    }

    private LocationRequest createLocationRequest() {
        Log.w(TAG, "createLocationRequest: ");
        // Creates a location request
        LocationRequest locationRequest = new LocationRequest();
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        locationRequest.setInterval(2000);
        locationRequest.setFastestInterval(1000);
        return locationRequest;
    }

    public void addGeofencingOnClick(View view) {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_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;
        }

        buildGeofence(mLocationArrayList.get(0));
        mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
                .addOnSuccessListener(this, new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.w(TAG, "onSuccess: .addGeofences()");
                        Toast.makeText(getApplicationContext(), "Geofence created!", Toast.LENGTH_LONG).show();
                    }
                })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(getApplicationContext(), "Geofence error!", Toast.LENGTH_LONG).show();
                        Log.w(TAG, "onFailure: ");
                        e.printStackTrace();
                    }
                });
    }
}

MyIntentService.java:

import android.app.*;
import android.content.Intent;
import android.content.Context;
import android.util.Log;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.GeofencingEvent;


import java.util.List;


public class MyIntentService extends IntentService {
    private static final String TAG = "MyIntentService";

    public MyIntentService() {
        super(TAG);
    }

    @Override
    public void onCreate() {
        super.onCreate();
    }

    @Override
    protected void onHandleIntent(Intent intent) {
        GeofencingEvent mGeofencingEvent = GeofencingEvent.fromIntent(intent);
        if (mGeofencingEvent.hasError()) {
            Log.w(TAG, "onHandleIntent: Error.");
            return;
        }
        Log.w(TAG, "onHandleIntent: ");
        int geoType = mGeofencingEvent.getGeofenceTransition();
        if (geoType == Geofence.GEOFENCE_TRANSITION_DWELL) {
            List<Geofence> geofenceList = mGeofencingEvent.getTriggeringGeofences();

            String geoDetails = getGeofenceDetails(this, geoType, geofenceList);
            sendNotification(geoDetails);
        }
    }

    private void sendNotification(String geoDetailsString) {
        Log.w(TAG, "sendNotification: ");
        Notification.Builder builder = new Notification.Builder(this)
                .setContentTitle("Geofence")
                .setContentText(geoDetailsString)
                .setSmallIcon(R.mipmap.ic_launcher);

        Intent resultsIntent = new Intent(getApplicationContext(), MainActivity.class);
        TaskStackBuilder stackBuilder = TaskStackBuilder.create(this);
        stackBuilder.addParentStack(MainActivity.class);
        stackBuilder.addNextIntent(resultsIntent);

        PendingIntent pendingIntent = stackBuilder.getPendingIntent(0,
                PendingIntent.FLAG_UPDATE_CURRENT);
        builder.setContentIntent(pendingIntent);

        NotificationManager notificationManager =
                (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
        notificationManager.notify(0, builder.build());
    }

    private String getGeofenceDetails(Context context, int geoType, List<Geofence> geofences) {
        StringBuilder detailsString = new StringBuilder();
        for (Geofence geofence : geofences) {
            detailsString.append("Transition type: ").append(geoType).append(" ID: ")
                    .append(geofence.getRequestId()).append("\n");

        }
        return String.valueOf(detailsString);
    }
}

build.gradle - module:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 26
    buildToolsVersion "26.0.0"
    defaultConfig {
        applicationId "com.example.dubki.geofenceapp"
        minSdkVersion 25
        targetSdkVersion 26
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
        exclude group: 'com.android.support', module: 'support-annotations'
    })
    compile 'com.android.support:appcompat-v7:26.+'
    compile 'com.android.support.constraint:constraint-layout:1.0.2'
    testCompile 'junit:junit:4.12'

    compile 'com.google.android.gms:play-services-plus:11.0.4'
    compile 'com.google.android.gms:play-services-location:11.0.4'
}

我假设当我按下一个按钮时发生错误,该按钮调用addGeofencingOnClick(视图视图),该按钮使用存储在mLocationArrayList中的位置来创建地理栅栏。

buildGeofence(mLocationArrayList.get(0));
        mGeofencingClient.addGeofences(getGeofencingRequest(), getGeofencePendingIntent())
                .addOnSuccessListener(this, new OnSuccessListener<Void>() {
                    @Override
                    public void onSuccess(Void aVoid) {
                        Log.w(TAG, "onSuccess: .addGeofences()");
                        Toast.makeText(getApplicationContext(), "Geofence created!", Toast.LENGTH_LONG).show();
                    }
                })
                .addOnFailureListener(this, new OnFailureListener() {
                    @Override
                    public void onFailure(@NonNull Exception e) {
                        Toast.makeText(getApplicationContext(), "Geofence error!", Toast.LENGTH_LONG).show();
                        Log.w(TAG, "onFailure: ");
                        e.printStackTrace();
                    }
                });

screen shot of application UI.

logcat的:

08-04 18:37:46.641 4726-4726/? I/art: Not late-enabling -Xcheck:jni (already on)
08-04 18:37:46.641 4726-4726/? W/art: Unexpected CPU variant for X86 using defaults: x86
08-04 18:37:46.886 4726-4726/com.example.dubki.geofenceapp W/System: ClassLoader referenced unknown path: /data/app/com.example.dubki.geofenceapp-1/lib/x86
08-04 18:37:46.893 4726-4726/com.example.dubki.geofenceapp I/InstantRun: Starting Instant Run Server for com.example.dubki.geofenceapp
08-04 18:37:47.360 4726-4726/com.example.dubki.geofenceapp W/art: Before Android 4.1, method android.graphics.PorterDuffColorFilter android.support.graphics.drawable.VectorDrawableCompat.updateTintFilter(android.graphics.PorterDuffColorFilter, android.content.res.ColorStateList, android.graphics.PorterDuff$Mode) would have incorrectly overridden the package-private method in android.graphics.drawable.Drawable
08-04 18:37:47.475 4726-4726/com.example.dubki.geofenceapp W/MainActivity: onCreate: 
08-04 18:37:47.511 4726-4726/com.example.dubki.geofenceapp W/MainActivity: getCurrentLocation: 
08-04 18:37:47.511 4726-4726/com.example.dubki.geofenceapp W/MainActivity: createLocationRequest: 
08-04 18:37:47.513 4726-4726/com.example.dubki.geofenceapp W/MainActivity: getCurrentLocation: hasPermissions = true
08-04 18:37:47.513 4726-4726/com.example.dubki.geofenceapp W/MainActivity: getLastLocation:
08-04 18:37:47.579 4726-4783/com.example.dubki.geofenceapp I/OpenGLRenderer: Initialized EGL, version 1.4
08-04 18:37:47.579 4726-4783/com.example.dubki.geofenceapp D/OpenGLRenderer: Swap behavior 1
08-04 18:37:47.579 4726-4783/com.example.dubki.geofenceapp W/OpenGLRenderer: Failed to choose config with EGL_SWAP_BEHAVIOR_PRESERVED, retrying without...
08-04 18:37:47.579 4726-4783/com.example.dubki.geofenceapp D/OpenGLRenderer: Swap behavior 0
08-04 18:37:47.591 4726-4783/com.example.dubki.geofenceapp D/EGL_emulation: eglCreateContext: 0xb59052a0: maj 3 min 1 rcv 4
08-04 18:37:47.641 4726-4783/com.example.dubki.geofenceapp D/EGL_emulation: eglMakeCurrent: 0xb59052a0: ver 3 1 (tinfo 0xb5903250)
08-04 18:37:47.642 4726-4783/com.example.dubki.geofenceapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x000082da
08-04 18:37:47.642 4726-4783/com.example.dubki.geofenceapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008cdf
08-04 18:37:47.642 4726-4783/com.example.dubki.geofenceapp E/eglCodecCommon: glUtilsParamSize: unknow param 0x00008824
08-04 18:37:47.651 4726-4726/com.example.dubki.geofenceapp W/art: Before Android 4.1, method int android.support.v7.widget.ListViewCompat.lookForSelectablePosition(int, boolean) would have incorrectly overridden the package-private method in android.widget.ListView
08-04 18:37:47.680 4726-4783/com.example.dubki.geofenceapp D/EGL_emulation: eglMakeCurrent: 0xb59052a0: ver 3 1 (tinfo 0xb5903250)
08-04 18:37:47.883 4726-4726/com.example.dubki.geofenceapp W/MainActivity: onSuccess: getLastLocation(), createGeofence
08-04 18:37:47.883 4726-4726/com.example.dubki.geofenceapp W/MainActivity: updateLocation: 
08-04 18:37:53.810 4726-4726/com.example.dubki.geofenceapp W/MainActivity: addGeofencingOnClick: BUTTON CLICKED!
08-04 18:37:53.812 4726-4726/com.example.dubki.geofenceapp W/MainActivity: getGeofencingRequest: test
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/MainActivity: onFailure: 
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err: com.google.android.gms.common.api.ApiException
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzb.zzx(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzbi.zzy(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.common.internal.zzbj.zzo(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzbbe.zzb(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzbbe.setResult(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.location.LocationServices$zza.setResult(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzcdk.zza(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at com.google.android.gms.internal.zzccy.onTransact(Unknown Source)
08-04 18:37:53.840 4726-4726/com.example.dubki.geofenceapp W/System.err:     at android.os.Binder.execTransact(Binder.java:565)
08-04 18:37:53.988 4726-4783/com.example.dubki.geofenceapp D/EGL_emulation: eglMakeCurrent: 0xb59052a0: ver 3 1 (tinfo 0xb5903250)
08-04 18:37:54.122 4726-4783/com.example.dubki.geofenceapp D/EGL_emulation: eglMakeCurrent: 0xb59052a0: ver 3 1 (tinfo 0xb5903250)

0 个答案:

没有答案