我正在尝试创建一个具有单个按钮的新地理围栏应用程序(Toast消息"内部"或"外部"),但应用程序在启动时崩溃。
以下是代码:
MainActivity.java
package com.example.geofencing;
import java.util.ArrayList;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.Geofence;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import android.app.Activity;
import android.app.PendingIntent;
import android.content.Intent;
import android.content.IntentSender;
import android.location.Location;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Toast;
public class MainActivity extends Activity implements
GoogleApiClient.ConnectionCallbacks,
GoogleApiClient.OnConnectionFailedListener {
// save the string that represent the geofence status
private static String DWELL = "Default";
private GoogleApiClient mGoogleClient;
// mock laoctions variables
private static final String PROVIDER = "flp";
private static final double LAT = 37.377166;
private static final double LNG = -122.086966;
private static final float ACCURACY = 3.0f;
// for mock locations (testing)
public Location mockLocation(double lat, double lng, float accuracy) {
// Create a new Location
Location newLocation = new Location(PROVIDER);
newLocation.setLatitude(lat);
newLocation.setLongitude(lng);
newLocation.setAccuracy(accuracy);
return newLocation;
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// you can also add more APIs and scopes here
mGoogleClient = new GoogleApiClient.Builder(this, this, this).addApi(
LocationServices.API).build();
}
@Override
protected void onStart() {
super.onStart();
mGoogleClient.connect();
}
@Override
protected void onStop() {
mGoogleClient.disconnect();
super.onStop();
}
@Override
public void onConnected(Bundle connectionHint) {
// have to extend it with if statement - *for future use*
Location location = LocationServices.FusedLocationApi
.getLastLocation(mGoogleClient);
// adds geofencing
ArrayList<Geofence> geofences = new ArrayList<Geofence>();
geofences.add(new Geofence.Builder()
.setRequestId("unique-geofence-id")
.setCircularRegion(
mockLocation(LAT, LNG, ACCURACY).getLatitude(),
mockLocation(LAT, LNG, ACCURACY).getLongitude(), 1000)
.setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER // if the activity is
// enter the square
// -
// setTransitionTypes
// is 1. if not - 2.
// if the same like
// the last check -
// 4.
| Geofence.GEOFENCE_TRANSITION_DWELL
| Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(30000) // check every 30 seconds
.build());
LocationRequest locationRequest = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY)
.setFastestInterval(5000L).setInterval(10000L)
.setSmallestDisplacement(75.0F);
PendingIntent pendingIntent = PendingIntent.getService(this, 0,
new Intent(this, MyLocationHandler.class),
PendingIntent.FLAG_UPDATE_CURRENT);
LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleClient,
locationRequest, pendingIntent);
// for mock locations
LocationServices.FusedLocationApi.setMockMode(mGoogleClient, true);
LocationServices.FusedLocationApi.setMockLocation(mGoogleClient,
mockLocation(LAT, LNG, ACCURACY));
}
@Override
public void onConnectionSuspended(int cause) {
// this callback will be invoked when the client is disconnected
// it might happen e.g. when Google Play service crashes
// when this happens, all requests are canceled,
// and you must wait for it to be connected again
}
@Override
public void onConnectionFailed(ConnectionResult connectionResult) {
// this callback will be invoked when the connection attempt fails
if (connectionResult.hasResolution()) {
// Google Play services can fix the issue
// e.g. the user needs to enable it, updates to latest version
// or the user needs to grant permissions to it
try {
connectionResult.startResolutionForResult(this, 0);
} catch (IntentSender.SendIntentException e) {
// it happens if the resolution intent has been canceled,
// or is no longer able to execute the request
}
} else {
// Google Play services has no idea how to fix the issue
}
}
public void getGeofenceValue(View view) {
MyLocationHandler handler = new MyLocationHandler();
int check = handler.geofencingEvent.getGeofenceTransition();
if (check == 1) {
Toast.makeText(getApplicationContext(), "Inside",
Toast.LENGTH_SHORT).show();
DWELL = "Inside";
} else {
if (check == 2) {
Toast.makeText(getApplicationContext(), "Outside",
Toast.LENGTH_SHORT).show();
DWELL = "Outside";
} else {
Toast.makeText(getApplicationContext(), "DWELL",
Toast.LENGTH_SHORT).show();
}
}
}
}
AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.geofencing"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="10"
android:targetSdkVersion="21" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- for mock locations -->
<uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
logcat的
12-24 18:18:22.946: D/libEGL(27774): loaded /system/lib/egl/libEGL_mali.so
12-24 18:18:22.961: D/libEGL(27774): loaded /system/lib/egl/libGLESv1_CM_mali.so
12-24 18:18:22.966: D/libEGL(27774): loaded /system/lib/egl/libGLESv2_mali.so
12-24 18:18:22.971: E/(27774): Device driver API match
12-24 18:18:22.971: E/(27774): Device driver API version: 23
12-24 18:18:22.971: E/(27774): User space API version: 23
12-24 18:18:22.971: E/(27774): mali: REVISION=Linux-r3p2-01rel3 BUILD_DATE=Wed Oct 9 21:05:57 KST 2013
12-24 18:18:23.061: D/OpenGLRenderer(27774): Enabling debug mode 0
12-24 18:18:23.081: D/AndroidRuntime(27774): Shutting down VM
12-24 18:18:23.081: W/dalvikvm(27774): threadid=1: thread exiting with uncaught exception (group=0x41d5c700)
12-24 18:18:23.086: E/AndroidRuntime(27774): FATAL EXCEPTION: main
12-24 18:18:23.086: E/AndroidRuntime(27774): java.lang.IllegalArgumentException: Expiration not set.
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.location.Geofence$Builder.build(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.example.geofencing.MainActivity.onConnected(MainActivity.java:85)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jm.f(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.common.api.c.gJ(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.common.api.c.d(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.common.api.c$2.onConnected(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jm.f(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jm.dU(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jl$h.b(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jl$h.g(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jl$b.hy(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.google.android.gms.internal.jl$a.handleMessage(Unknown Source)
12-24 18:18:23.086: E/AndroidRuntime(27774): at android.os.Handler.dispatchMessage(Handler.java:99)
12-24 18:18:23.086: E/AndroidRuntime(27774): at android.os.Looper.loop(Looper.java:176)
12-24 18:18:23.086: E/AndroidRuntime(27774): at android.app.ActivityThread.main(ActivityThread.java:5419)
12-24 18:18:23.086: E/AndroidRuntime(27774): at java.lang.reflect.Method.invokeNative(Native Method)
12-24 18:18:23.086: E/AndroidRuntime(27774): at java.lang.reflect.Method.invoke(Method.java:525)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1046)
12-24 18:18:23.086: E/AndroidRuntime(27774): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:862)
12-24 18:18:23.086: E/AndroidRuntime(27774): at dalvik.system.NativeStart.main(Native Method)
当我启动应用程序时,它只会显示崩溃消息。
谢谢。
答案 0 :(得分:11)
Geofence.Builder.build()
会引发IllegalArgumentException
"if any parameters are not set or out of range"。
您应该尝试在构建地理栅栏时为其添加到期时间。请参阅Geofence.Builder
的{{3}}方法。
建议修复的示例:
geofences.add(new Geofence.Builder()
.setExpirationDuration(Geofence.NEVER_EXPIRE)
.setRequestId("unique-geofence-id")
.setCircularRegion(
mockLocation(LAT, LNG, ACCURACY).getLatitude(),
mockLocation(LAT, LNG, ACCURACY).getLongitude(), 1000)
.setTransitionTypes(
Geofence.GEOFENCE_TRANSITION_ENTER
| Geofence.GEOFENCE_TRANSITION_DWELL
| Geofence.GEOFENCE_TRANSITION_EXIT)
.setLoiteringDelay(30000)
.build());