I am trying to make a new geofencing app that have a single button (Toast message "inside" or "outside"), but the app is crashing on startup.
Here is the code:
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)
When I launches the app, it just show a crash message.
Thank you.
Geofence.Builder.build()
throws an IllegalArgumentException
"if any parameters are not set or out of range".
You should try adding an expiration duration to the geofence when you build it. See the setExpirationDuration
method of Geofence.Builder
.
Example with suggested fix:
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());
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With