我正在尝试自学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();
}
});
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)