Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android geofencing app crashing on startup

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.

like image 473
o_b7 Avatar asked Dec 24 '14 22:12

o_b7


1 Answers

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());
like image 152
stkent Avatar answered Sep 21 '22 15:09

stkent