简体   繁体   中英

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.

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());

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM