Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/211.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Android 停止GPS并禁用GoogleAppClient_Android_Google Maps - Fatal编程技术网

Android 停止GPS并禁用GoogleAppClient

Android 停止GPS并禁用GoogleAppClient,android,google-maps,Android,Google Maps,我正在开发一个应用程序,在你外出购物时帮助你跟上酒吧账单。我有一个功能,用户可以设置一个接近报警(地理围栏),提醒他们在离开酒吧而不关门时关闭标签。首先显示地图,然后在用户位置放置一个标记,然后在标记周围显示一个100米的地理围栏。用户的位置会定期更新,因此它会在后台线程上运行 我的问题是,当用户关闭他们的选项卡时,我想通过单击按钮停止禁用应用程序正在使用的位置服务。此按钮单击在启动地图和地理定位服务的单独活动中进行。任何帮助都将不胜感激 PS-我试图包括尽可能多的代码,所以请原谅我的混乱 此映

我正在开发一个应用程序,在你外出购物时帮助你跟上酒吧账单。我有一个功能,用户可以设置一个接近报警(地理围栏),提醒他们在离开酒吧而不关门时关闭标签。首先显示地图,然后在用户位置放置一个标记,然后在标记周围显示一个100米的地理围栏。用户的位置会定期更新,因此它会在后台线程上运行

我的问题是,当用户关闭他们的选项卡时,我想通过单击按钮停止禁用应用程序正在使用的位置服务。此按钮单击在启动地图和地理定位服务的单独活动中进行。任何帮助都将不胜感激

PS-我试图包括尽可能多的代码,所以请原谅我的混乱

此映射在此活动中从addBtn启动:

public class Alarm extends ActionBarActivity {
public static String TAG = "lstech.aos.debug";

static public boolean geofencesAlreadyRegistered = false;
Button addBtn, lobbyBtn, startTabBtn, settingsBtn;
boolean mapOpen = false;
double latitude, longitude = 0.0;
protected GoogleMap map;
ActionBar actionBar;
Fragment f;
FragmentManager fragmentManager;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.alarm_layout);

    actionBar = getSupportActionBar();
    actionBar.hide();

    addBtn = (Button) findViewById(R.id.add_geo_button);
    startTabBtn = (Button) findViewById(R.id.calculator_button);
    lobbyBtn = (Button) findViewById(R.id.lobby_button);
    settingsBtn = (Button) findViewById(R.id.settings_button);

    TinyDB tinydb = new TinyDB(this);
    mapOpen = tinydb.getBoolean("mapOpen");

    if (mapOpen)
        addBtn.setText(R.string.view_map_button);
    else
        addBtn.setText(R.string.set_gps_alert);

    fragmentManager = getSupportFragmentManager();
    f = fragmentManager.findFragmentByTag("uniqueTag");

    // SET MAP MARKER AND GEOFENCE
    addBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            // create a map instance if one doesn't exist
            if (f == null) {
                fragmentManager
                        .beginTransaction()
                        .replace(android.R.id.content, new MapFragment(),
                                "uniqueTag").commit();

            } // keep instance of map if it's already showing
            else {
                fragmentManager.beginTransaction()
                        .replace(android.R.id.content, f, "uniqueTag")
                        .commit();
            }

            fragmentManager.executePendingTransactions();

            startService(new Intent(getApplicationContext(),
                    GeolocationService.class));
        }
    });
GeolocationService类设置位置和地理围栏对象:

public class GeolocationService extends Service implements ConnectionCallbacks,
    OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
// TinyDB saved value handles: (boolean)"mapReady"
LocationListener listener;
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12;
private static final long RADIUS = 100;
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS
        * DateUtils.HOUR_IN_MILLIS;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 5;
protected GoogleApiClient mGoogleApiClient;
public static GoogleApiClient mGoogleApiClientStatic;
protected LocationRequest mLocationRequest;
private PendingIntent mPendingIntent;
List<Geofence> mGeofenceList;
static public List<Geofence> mGeofenceListPass;
SimpleGeofence simpleGeo;
static public SimpleGeofence geoFence;
Location mLocation, newLocation;
Intent intent;
public static LocationManager mlocManager;
public static LocationListener mlocListener;
public static android.location.LocationListener mlocListenerProvider;
public static PendingIntent pendingIntent;
public static ConnectionCallbacks connCallbacks;
public static OnConnectionFailedListener connFailedListener;

// ON START
// ***********
@Override
public void onStart(Intent intent, int startId) {
    buildGoogleApiClient();
    mGoogleApiClient.connect();
    mGoogleApiClientStatic = mGoogleApiClient;
    mlocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
    mlocListener = this;
    mlocListenerProvider = new android.location.LocationListener() {

        @Override
        public void onLocationChanged(Location arg0) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onStatusChanged(String provider, int status,
                Bundle extras) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onProviderEnabled(String provider) {
            // TODO Auto-generated method stub
        }

        @Override
        public void onProviderDisabled(String provider) {
            // TODO Auto-generated method stub
        }
    };

    mlocManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0L,
            0f, mlocListenerProvider);
}

// ON DESTROY
// *************
@Override
public void onDestroy() {
    super.onDestroy();

    if (mGoogleApiClient.isConnected())
        mGoogleApiClient.disconnect();
}

// REGISTER GEOFENCES
// *********************
protected void registerGeofences(Location location) {
    if (Alarm.geofencesAlreadyRegistered)
        return;

    Log.d(Alarm.TAG, "Registering Geofences");

    String geoId = "geoId";
    simpleGeo = new SimpleGeofence(geoId, location.getLatitude(),
            location.getLongitude(), RADIUS,
            GEOFENCE_EXPIRATION_IN_MILLISECONDS,
            Geofence.GEOFENCE_TRANSITION_ENTER
                    | Geofence.GEOFENCE_TRANSITION_DWELL
                    | Geofence.GEOFENCE_TRANSITION_EXIT);

    // mGeofenceList.add(new Geofence.Builder()

    HashMap<String, SimpleGeofence> geofences = SimpleGeofenceStore
            .getInstance().getSimpleGeofences();

    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();

    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) {
        SimpleGeofence sg = item.getValue();
        sg.setLatitude(simpleGeo.getLatitude());
        sg.setLongitude(simpleGeo.getLongitude());
        builder.addGeofence(sg.toGeofence());

        SimpleGeofenceStore store = SimpleGeofenceStore.getInstance();
        store.setLatLong(simpleGeo.getLatitude(), simpleGeo.getLongitude());
        // Log.d(Alarm.TAG, sg.getLatitude() + " " + sg.getLongitude());
    }

    TinyDB tinydb = new TinyDB(getApplicationContext());
    tinydb.putBoolean("mapReady", false);

    GeofencingRequest geofencingRequest = builder.build();

    mPendingIntent = requestPendingIntent();
    pendingIntent = mPendingIntent;

    LocationServices.GeofencingApi.addGeofences(mGoogleApiClient,
            geofencingRequest, mPendingIntent).setResultCallback(this);

    Alarm.geofencesAlreadyRegistered = true;
} // end registerGeofences()

// REQUEST PENDING INTENT
// *************************
private PendingIntent requestPendingIntent() {

    if (null != mPendingIntent)
        return mPendingIntent;

    Intent intent = new Intent(this, GeofenceReceiver.class);
    return PendingIntent.getService(this, 0, intent,
            PendingIntent.FLAG_UPDATE_CURRENT);

} // end requestPendingIntent()

// START LOCATION UPDATES
// *************************
protected void startLocationUpdates() {
    LocationServices.FusedLocationApi.requestLocationUpdates(
            mGoogleApiClient, mLocationRequest, this);
} // end startLocationUpdates()

// STOP LOCATION UPDATES
// ************************
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
} // end stopLocationUpdates()

// ON CONNECTED
// ***************
@Override
public void onConnected(Bundle connectionHint) {
    Log.i(Alarm.TAG, "Connected to GoogleApiClient");
    startLocationUpdates();
} // end onConnected(Bundle connectionHint)

// ON LOCATION CHANGED
// **********************
@Override
public void onLocationChanged(Location location) {
    Log.d(Alarm.TAG, "new location : " + location.getLatitude() + ", "
            + location.getLongitude() + ". " + location.getAccuracy());
    broadcastLocationFound(location);

    if (!Alarm.geofencesAlreadyRegistered)
        registerGeofences(location);

} // end onLocationChanged(Location location)

// ON CONNECTION SUSPENDED
// **************************
@Override
public void onConnectionSuspended(int cause) {
    Log.i(Alarm.TAG, "Connection suspended");
    mGoogleApiClient.connect();
} // end onConnectionSuspended(int cause)

// ON CONNECTION FAILED
// ***********************
@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(Alarm.TAG,
            "Connection failed: ConnectionResult.getErrorCode() = "
                    + result.getErrorCode());
} // end onConnectionFailed(ConnectionResult result)

// BUILD GOOGLE API CLIENT
// **************************
protected synchronized void buildGoogleApiClient() {
    Log.i(Alarm.TAG, "Building GoogleApiClient");

    mlocListener = this;
    connCallbacks = this;
    connFailedListener = this;

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API).build();

    createLocationRequest();
} // end buildGoogleApiClient()

// CREATE LOCATION REQUEST
// **************************
protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest
            .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
} // end createLocationRequest()

// ON BIND
// **********
@Override
public IBinder onBind(Intent intent) {
    return null;
}

// BROADCAST LOCATION FOUND
// ***************************
public void broadcastLocationFound(Location location) {
    Intent intent = new Intent(
            "com.diligencedojo.tabsitter.geolocation.service");
    intent.putExtra("latitude", location.getLatitude());
    intent.putExtra("longitude", location.getLongitude());
    intent.putExtra("done", 1);
    // // 
    sendBroadcast(intent);
} // end broadcastLocationFound(Location location)

// ON RESULT
// ************
public void onResult(Status status) {
    if (status.isSuccess()) {
        Toast.makeText(getApplicationContext(),
                getString(R.string.geofences_added), Toast.LENGTH_SHORT)
                .show();

        TinyDB tinydb = new TinyDB(getApplicationContext());
        tinydb.putBoolean("mapReady", true);
    } else {
        Alarm.geofencesAlreadyRegistered = false;
        String errorMessage = getErrorString(this, status.getStatusCode());
        Toast.makeText(getApplicationContext(), errorMessage,
                Toast.LENGTH_SHORT).show();
    }
} // end onResult(Status status)

// GET ERROR STRING
// *******************
public static String getErrorString(Context context, int errorCode) {
    Resources mResources = context.getResources();

    switch (errorCode) {
    case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
        return mResources.getString(R.string.geofence_not_available);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
        return mResources.getString(R.string.geofence_too_many_geofences);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
        return mResources
                .getString(R.string.geofence_too_many_pending_intents);
    default:
        return mResources.getString(R.string.unknown_geofence_error);

    } // end switch (errorCode)
} // end getErrorString(Context context, int errorCode)

} // end GeolocationService Class
以下是我用于geofence的类:

simplegofence类

public class SimpleGeofence {
private final String id;
private double latitude;
private double longitude;
private final float radius;
private long expirationDuration;
private int transitionType;
private int loiteringDelay = 60000;

public SimpleGeofence(String geofenceId, double latitude, double longitude,
        float radius, long expiration, int transition) {
    this.id = geofenceId;
    this.latitude = latitude;
    this.longitude = longitude;
    this.radius = radius;
    this.expirationDuration = expiration;
    this.transitionType = transition;
}

public String getId() {
    return id;
}

public void setLatitude(Double mLat) {
    this.latitude = mLat;
}

public double getLatitude() {
    return latitude;
}

public void setLongitude(Double mLong) {
    this.longitude = mLong;
}

public double getLongitude() {
    return longitude;
}

public float getRadius() {
    return radius;
}

public void setExpirationDuration(long mExpirationDuration) {
    this.expirationDuration = mExpirationDuration;
}

public long getExpirationDuration() {
    return expirationDuration;
}

public int getTransitionType() {
    return transitionType;
}

public Geofence toGeofence() {
    Geofence g = new Geofence.Builder().setRequestId(getId())
            .setTransitionTypes(transitionType)
            .setCircularRegion(getLatitude(), getLongitude(), getRadius())
            .setExpirationDuration(expirationDuration)
            .setLoiteringDelay(loiteringDelay).build();
    return g;
}

} // end SimpleGefence Class
SimpleGeofenceStore类

public class SimpleGeofenceStore {
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12;
private static final long RADIUS = 100;
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS =    GEOFENCE_EXPIRATION_IN_HOURS
        * DateUtils.HOUR_IN_MILLIS;
protected HashMap<String, SimpleGeofence> geofences = new HashMap<String, SimpleGeofence>();
private static SimpleGeofenceStore instance = new SimpleGeofenceStore();
private double latitude;
private double longitude;

public static SimpleGeofenceStore getInstance() {
    // mContext = context;
    return instance;
}

public void setLatLong(Double mLat, Double mLong) {
    this.latitude = mLat;
    this.longitude = mLong;
}

public Double getLatitude() {
    return latitude;
}

public Double getLongitude() {
    return longitude;
}

private SimpleGeofenceStore() {

    geofences.put("My House", new SimpleGeofence("My House", getLatitude(),
            getLongitude(), RADIUS, GEOFENCE_EXPIRATION_IN_MILLISECONDS,
            Geofence.GEOFENCE_TRANSITION_ENTER
                    | Geofence.GEOFENCE_TRANSITION_DWELL
                    | Geofence.GEOFENCE_TRANSITION_EXIT));

}

public HashMap<String, SimpleGeofence> getSimpleGeofences() {
    return this.geofences;
}

} // end SimpleGeofenceStore Class
公共类simplegofencestore{
专用静态最终长土工围栏\u到期时间\u小时=12;
专用静态最终长半径=100;
公共静态最终长地理围栏\u过期\u(毫秒)=地理围栏\u过期\u(小时)
*DateUtils.HOUR_IN_MILLIS;
受保护的HashMap Geofines=新HashMap();
私有静态SimpleGeoFunceStore实例=新SimpleGeoFunceStore();
私人双纬度;
私人双经度;
公共静态SimpleGeofenceStore getInstance(){
//mContext=上下文;
返回实例;
}
公共无效设置长度(双倍最大长度,双倍最大长度){
这个纬度=mLat;
this.longitude=mLong;
}
公共双纬度(){
返回纬度;
}
公共双getLongitude(){
返回经度;
}
私有simplegofencestore(){
geofences.put(“我的房子”),new SimpleGence(“我的房子”,getLatitude(),
Get经度(),半径,地理围栏(以毫秒为单位),
Geofence.Geofence\u过渡\u输入
|土工围栏。土工围栏\过渡\居住
|土工围栏。土工围栏(过渡段(出口));
}
公共HashMap GetSimpleGoFences(){
把这个还给我;
}
}//结束simplegofencestore类

要禁用来自不同活动的按钮点击的定位服务和流程,我遵循以下步骤。首先,我将GeolocationServices.java中的位置变量定义为public和static。这允许您在其他活动中访问它们。接下来,我将布尔变量“tabClosed”放在所有可能在断开连接后重新连接GoogleAppClient的对象周围。我不完全确定我是否需要这个

GeolocationServices.java

public class GeolocationService extends Service implements ConnectionCallbacks,
    OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
// TinyDB saved value handles: (boolean)"mapReady"
LocationListener listener;
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12;
private static final long RADIUS = 100;
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS
        * DateUtils.HOUR_IN_MILLIS;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 5;
// protected GoogleApiClient mGoogleApiClient;
public static GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
// private PendingIntent mPendingIntent;
public static PendingIntent mPendingIntent;
List<Geofence> mGeofenceList;
SimpleGeofence simpleGeo;
Location mLocation, newLocation;
public static LocationManager mlocManager;
public static LocationListener mlocListener;
public static ConnectionCallbacks connCallbacks;
public static OnConnectionFailedListener connFailedListener;
public static ResultCallback<Status> mGeoCallback;

// ON START
// ***********
@Override
public void onStart(Intent intent, int startId) {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }
}

// ON DESTROY
// *************
@Override
public void onDestroy() {
    // super.onDestroy();

    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
        mlocManager.removeUpdates(mPendingIntent);
        mlocManager.removeProximityAlert(mPendingIntent);
        mPendingIntent.cancel();
    }

    super.onDestroy();
}

// REGISTER GEOFENCES
// *********************
protected void registerGeofences(Location location) {
    if (Alarm.geofencesAlreadyRegistered)
        return;

    Log.d(Alarm.TAG, "Registering Geofences");

    String geoId = "geoId";
    simpleGeo = new SimpleGeofence(geoId, location.getLatitude(),
            location.getLongitude(), RADIUS,
            GEOFENCE_EXPIRATION_IN_MILLISECONDS,
            Geofence.GEOFENCE_TRANSITION_ENTER
                    | Geofence.GEOFENCE_TRANSITION_DWELL
                    | Geofence.GEOFENCE_TRANSITION_EXIT);

    // //
    HashMap<String, SimpleGeofence> geofences = SimpleGeofenceStore
            .getInstance().getSimpleGeofences();

    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();

    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) {
        SimpleGeofence sg = item.getValue();
        sg.setLatitude(simpleGeo.getLatitude());
        sg.setLongitude(simpleGeo.getLongitude());
        builder.addGeofence(sg.toGeofence());

        SimpleGeofenceStore store = SimpleGeofenceStore.getInstance();
        store.setLatLong(simpleGeo.getLatitude(), simpleGeo.getLongitude());
        // Log.d(Alarm.TAG, sg.getLatitude() + " " + sg.getLongitude());
    }

    TinyDB tinydb = new TinyDB(getApplicationContext());
    tinydb.putBoolean("mapReady", false);

    GeofencingRequest geofencingRequest = builder.build();

    mPendingIntent = requestPendingIntent();

    mGeoCallback = this;

    LocationServices.GeofencingApi.addGeofences(mGoogleApiClient,
            geofencingRequest, mPendingIntent).setResultCallback(
            mGeoCallback);

    Alarm.geofencesAlreadyRegistered = true;
} // end registerGeofences()

// REQUEST PENDING INTENT
// *************************
private PendingIntent requestPendingIntent() {
    PendingIntent tempPendingIntent = null;

    if (null != mPendingIntent)
        return mPendingIntent;

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        Intent intent = new Intent(this, GeofenceReceiver.class);
        tempPendingIntent = PendingIntent.getService(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    return tempPendingIntent;

} // end requestPendingIntent()

// BROADCAST LOCATION FOUND
// ***************************
public void broadcastLocationFound(Location location) {
    Intent intent = new Intent(
            "com.diligencedojo.tabsitter.geolocation.service");
    intent.putExtra("latitude", location.getLatitude());
    intent.putExtra("longitude", location.getLongitude());
    intent.putExtra("done", 1);

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        sendBroadcast(intent);

} // end broadcastLocationFound(Location location)

// START LOCATION UPDATES
// *************************
protected void startLocationUpdates() {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) { //
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }
} // end startLocationUpdates()

// STOP LOCATION UPDATES
// ************************
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
} // end stopLocationUpdates()

// ON CONNECTED
// ***************
@Override
public void onConnected(Bundle connectionHint) {
    Log.i(Alarm.TAG, "Connected to GoogleApiClient");
    startLocationUpdates();
} // end onConnected(Bundle connectionHint)

// ON LOCATION CHANGED
// **********************
@Override
public void onLocationChanged(Location location) {
    Log.d(Alarm.TAG, "new location : " + location.getLatitude() + ", "
            + location.getLongitude() + ". " + location.getAccuracy());

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        broadcastLocationFound(location);

    if (!Alarm.geofencesAlreadyRegistered)
        registerGeofences(location);

} // end onLocationChanged(Location location)

// ON CONNECTION SUSPENDED
// **************************
@Override
public void onConnectionSuspended(int cause) {
    Log.i(Alarm.TAG, "Connection suspended");

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        mGoogleApiClient.connect();

} // end onConnectionSuspended(int cause)

// ON CONNECTION FAILED
// ***********************
@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(Alarm.TAG,
            "Connection failed: ConnectionResult.getErrorCode() = "
                    + result.getErrorCode());
} // end onConnectionFailed(ConnectionResult result)

// BUILD GOOGLE API CLIENT
// **************************
protected synchronized void buildGoogleApiClient() {
    Log.i(Alarm.TAG, "Building GoogleApiClient");

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        mlocListener = this;
        connCallbacks = this;
        connFailedListener = this;

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(connCallbacks)
                .addOnConnectionFailedListener(connFailedListener)
                .addApi(LocationServices.API).build();

        createLocationRequest();
    }

} // end buildGoogleApiClient()

// CREATE LOCATION REQUEST
// **************************
protected void createLocationRequest() {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest
                .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

} // end createLocationRequest()

// ON BIND
// **********
@Override
public IBinder onBind(Intent intent) {
    return null;
}

// ON RESULT
// ************
public void onResult(Status status) {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {

        if (status.isSuccess()) {
            Toast.makeText(getApplicationContext(),
                    getString(R.string.geofences_added), Toast.LENGTH_SHORT)
                    .show();

            tinydb.putBoolean("mapReady", true);
        } else {
            Alarm.geofencesAlreadyRegistered = false;
            String errorMessage = getErrorString(this,
                    status.getStatusCode());
            Toast.makeText(getApplicationContext(), errorMessage,
                    Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(getApplicationContext(),
                "Tab closed, do not add geofence.", Toast.LENGTH_SHORT)
                .show();
    }

} // end onResult(Status status)

// GET ERROR STRING
// *******************
public static String getErrorString(Context context, int errorCode) {
    Resources mResources = context.getResources();

    switch (errorCode) {
    case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
        return mResources.getString(R.string.geofence_not_available);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
        return mResources.getString(R.string.geofence_too_many_geofences);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
        return mResources
                .getString(R.string.geofence_too_many_pending_intents);
    default:
        return mResources.getString(R.string.unknown_geofence_error);

    } // end switch (errorCode)
} // end getErrorString(Context context, int errorCode)

} // end GeolocationService Class
公共类GeolocationService扩展服务实现ConnectionCallbacks,
OnConnectionFailedListener、LocationListener、ResultCallback{
//TinyDB保存值句柄:(布尔)“mapReady”
位置监听器;
专用静态最终长土工围栏\u到期时间\u小时=12;
专用静态最终长半径=100;
公共静态最终长地理围栏\u过期\u(毫秒)=地理围栏\u过期\u(小时)
*DateUtils.HOUR_IN_MILLIS;
公共静态最终长更新间隔(以毫秒为单位)=10000;
public static final long faster_UPDATE_INTERVAL_IN_毫秒=UPDATE_INTERVAL_IN_毫秒/5;
//受保护的GoogleapClient MGoogleapClient;
公共静态GoogleapClient MGoogleapClient;
受保护的位置请求mLocationRequest;
//私人悬而未决的侵权行为;
公共静电悬挂;
列表管理列表;
简单化简单化;
位置M位置,新位置;
公共静态位置管理器mlocManager;
公共静态位置侦听器mlocListener;
公共静态连接回调conn回调;
公共静态OnConnectionFailedListener connFailedListener;
公共静态结果回调mGeoCallback;
//一开始
// ***********
@凌驾
公共无效启动(Intent Intent,int startId){
TinyDB TinyDB=新的TinyDB(getApplicationContext());
boolean tabClosed=tinydb.getBoolean(“tabClosed”);
如果(!tabClosed){
buildGoogleAppClient();
mGoogleApiClient.connect();
}
}
//论毁灭
// *************
@凌驾
公共空间{
//super.ondestory();
if(mgoogleapClient.isConnected()){
mGoogleApiClient.disconnect();
mlocManager.RemoveUpdate(mpendingContent);
mlocManager.removeProximityAlert(mpendingent);
mpendingent.cancel();
}
super.ondestory();
}
//登记土工围栏
// *********************
受保护的无效注册表GeoFences(位置){
如果(报警。地理围栏已注册)
回来
Log.d(Alarm.TAG,“注册地理围栏”);
字符串geoId=“geoId”;
simpleGeo=新SimpleGeofence(大地水准面,位置.getLatitude(),
location.getLongitude(),半径,
土工围栏(以毫秒为单位),
Geofence.Geofence\u过渡\u输入
|土工围栏。土工围栏\过渡\居住
|土工围栏。土工围栏(过渡段和出口);
// //
HashMap geofences=SimpleGeofenceStore
.getInstance().GetSimpleGoFences();
GeofencingRequest.Builder=新的GeofencingRequest.Builder();
对于(Map.Entry项:geofenses.entrySet()){
simplegofence sg=item.getValue();
sg.setLatitude(simpleGeo.getLatitude());
sg.setLongitude(simpleGeo.getLongitude());
builder.addGeofence(sg.toGeofence());
SimpleGeofenceStore=SimpleGeofenceStore.getInstance();
setLatLong(simpleGeo.getLatitude(),simpleGeo.getLatitude());
//Log.d(Alarm.TAG,sg.getLatitude()+“”+sg.getLatitude());
}
TinyDB TinyDB=新的TinyDB(getApplicationContext());
tinydb.putBoolean(“mapredy”,false);
GeofencingRequest GeofencingRequest=bui
public class SimpleGeofenceStore {
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12;
private static final long RADIUS = 100;
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS =    GEOFENCE_EXPIRATION_IN_HOURS
        * DateUtils.HOUR_IN_MILLIS;
protected HashMap<String, SimpleGeofence> geofences = new HashMap<String, SimpleGeofence>();
private static SimpleGeofenceStore instance = new SimpleGeofenceStore();
private double latitude;
private double longitude;

public static SimpleGeofenceStore getInstance() {
    // mContext = context;
    return instance;
}

public void setLatLong(Double mLat, Double mLong) {
    this.latitude = mLat;
    this.longitude = mLong;
}

public Double getLatitude() {
    return latitude;
}

public Double getLongitude() {
    return longitude;
}

private SimpleGeofenceStore() {

    geofences.put("My House", new SimpleGeofence("My House", getLatitude(),
            getLongitude(), RADIUS, GEOFENCE_EXPIRATION_IN_MILLISECONDS,
            Geofence.GEOFENCE_TRANSITION_ENTER
                    | Geofence.GEOFENCE_TRANSITION_DWELL
                    | Geofence.GEOFENCE_TRANSITION_EXIT));

}

public HashMap<String, SimpleGeofence> getSimpleGeofences() {
    return this.geofences;
}

} // end SimpleGeofenceStore Class
public class GeolocationService extends Service implements ConnectionCallbacks,
    OnConnectionFailedListener, LocationListener, ResultCallback<Status> {
// TinyDB saved value handles: (boolean)"mapReady"
LocationListener listener;
private static final long GEOFENCE_EXPIRATION_IN_HOURS = 12;
private static final long RADIUS = 100;
public static final long GEOFENCE_EXPIRATION_IN_MILLISECONDS = GEOFENCE_EXPIRATION_IN_HOURS
        * DateUtils.HOUR_IN_MILLIS;
public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;
public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS = UPDATE_INTERVAL_IN_MILLISECONDS / 5;
// protected GoogleApiClient mGoogleApiClient;
public static GoogleApiClient mGoogleApiClient;
protected LocationRequest mLocationRequest;
// private PendingIntent mPendingIntent;
public static PendingIntent mPendingIntent;
List<Geofence> mGeofenceList;
SimpleGeofence simpleGeo;
Location mLocation, newLocation;
public static LocationManager mlocManager;
public static LocationListener mlocListener;
public static ConnectionCallbacks connCallbacks;
public static OnConnectionFailedListener connFailedListener;
public static ResultCallback<Status> mGeoCallback;

// ON START
// ***********
@Override
public void onStart(Intent intent, int startId) {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        buildGoogleApiClient();
        mGoogleApiClient.connect();
    }
}

// ON DESTROY
// *************
@Override
public void onDestroy() {
    // super.onDestroy();

    if (mGoogleApiClient.isConnected()) {
        mGoogleApiClient.disconnect();
        mlocManager.removeUpdates(mPendingIntent);
        mlocManager.removeProximityAlert(mPendingIntent);
        mPendingIntent.cancel();
    }

    super.onDestroy();
}

// REGISTER GEOFENCES
// *********************
protected void registerGeofences(Location location) {
    if (Alarm.geofencesAlreadyRegistered)
        return;

    Log.d(Alarm.TAG, "Registering Geofences");

    String geoId = "geoId";
    simpleGeo = new SimpleGeofence(geoId, location.getLatitude(),
            location.getLongitude(), RADIUS,
            GEOFENCE_EXPIRATION_IN_MILLISECONDS,
            Geofence.GEOFENCE_TRANSITION_ENTER
                    | Geofence.GEOFENCE_TRANSITION_DWELL
                    | Geofence.GEOFENCE_TRANSITION_EXIT);

    // //
    HashMap<String, SimpleGeofence> geofences = SimpleGeofenceStore
            .getInstance().getSimpleGeofences();

    GeofencingRequest.Builder builder = new GeofencingRequest.Builder();

    for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) {
        SimpleGeofence sg = item.getValue();
        sg.setLatitude(simpleGeo.getLatitude());
        sg.setLongitude(simpleGeo.getLongitude());
        builder.addGeofence(sg.toGeofence());

        SimpleGeofenceStore store = SimpleGeofenceStore.getInstance();
        store.setLatLong(simpleGeo.getLatitude(), simpleGeo.getLongitude());
        // Log.d(Alarm.TAG, sg.getLatitude() + " " + sg.getLongitude());
    }

    TinyDB tinydb = new TinyDB(getApplicationContext());
    tinydb.putBoolean("mapReady", false);

    GeofencingRequest geofencingRequest = builder.build();

    mPendingIntent = requestPendingIntent();

    mGeoCallback = this;

    LocationServices.GeofencingApi.addGeofences(mGoogleApiClient,
            geofencingRequest, mPendingIntent).setResultCallback(
            mGeoCallback);

    Alarm.geofencesAlreadyRegistered = true;
} // end registerGeofences()

// REQUEST PENDING INTENT
// *************************
private PendingIntent requestPendingIntent() {
    PendingIntent tempPendingIntent = null;

    if (null != mPendingIntent)
        return mPendingIntent;

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        Intent intent = new Intent(this, GeofenceReceiver.class);
        tempPendingIntent = PendingIntent.getService(this, 0, intent,
                PendingIntent.FLAG_UPDATE_CURRENT);
    }

    return tempPendingIntent;

} // end requestPendingIntent()

// BROADCAST LOCATION FOUND
// ***************************
public void broadcastLocationFound(Location location) {
    Intent intent = new Intent(
            "com.diligencedojo.tabsitter.geolocation.service");
    intent.putExtra("latitude", location.getLatitude());
    intent.putExtra("longitude", location.getLongitude());
    intent.putExtra("done", 1);

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        sendBroadcast(intent);

} // end broadcastLocationFound(Location location)

// START LOCATION UPDATES
// *************************
protected void startLocationUpdates() {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) { //
        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);
    }
} // end startLocationUpdates()

// STOP LOCATION UPDATES
// ************************
protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
} // end stopLocationUpdates()

// ON CONNECTED
// ***************
@Override
public void onConnected(Bundle connectionHint) {
    Log.i(Alarm.TAG, "Connected to GoogleApiClient");
    startLocationUpdates();
} // end onConnected(Bundle connectionHint)

// ON LOCATION CHANGED
// **********************
@Override
public void onLocationChanged(Location location) {
    Log.d(Alarm.TAG, "new location : " + location.getLatitude() + ", "
            + location.getLongitude() + ". " + location.getAccuracy());

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        broadcastLocationFound(location);

    if (!Alarm.geofencesAlreadyRegistered)
        registerGeofences(location);

} // end onLocationChanged(Location location)

// ON CONNECTION SUSPENDED
// **************************
@Override
public void onConnectionSuspended(int cause) {
    Log.i(Alarm.TAG, "Connection suspended");

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed)
        mGoogleApiClient.connect();

} // end onConnectionSuspended(int cause)

// ON CONNECTION FAILED
// ***********************
@Override
public void onConnectionFailed(ConnectionResult result) {
    Log.i(Alarm.TAG,
            "Connection failed: ConnectionResult.getErrorCode() = "
                    + result.getErrorCode());
} // end onConnectionFailed(ConnectionResult result)

// BUILD GOOGLE API CLIENT
// **************************
protected synchronized void buildGoogleApiClient() {
    Log.i(Alarm.TAG, "Building GoogleApiClient");

    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        mlocListener = this;
        connCallbacks = this;
        connFailedListener = this;

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(connCallbacks)
                .addOnConnectionFailedListener(connFailedListener)
                .addApi(LocationServices.API).build();

        createLocationRequest();
    }

} // end buildGoogleApiClient()

// CREATE LOCATION REQUEST
// **************************
protected void createLocationRequest() {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest
                .setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest
                .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

} // end createLocationRequest()

// ON BIND
// **********
@Override
public IBinder onBind(Intent intent) {
    return null;
}

// ON RESULT
// ************
public void onResult(Status status) {
    TinyDB tinydb = new TinyDB(getApplicationContext());
    boolean tabClosed = tinydb.getBoolean("tabClosed");

    if (!tabClosed) {

        if (status.isSuccess()) {
            Toast.makeText(getApplicationContext(),
                    getString(R.string.geofences_added), Toast.LENGTH_SHORT)
                    .show();

            tinydb.putBoolean("mapReady", true);
        } else {
            Alarm.geofencesAlreadyRegistered = false;
            String errorMessage = getErrorString(this,
                    status.getStatusCode());
            Toast.makeText(getApplicationContext(), errorMessage,
                    Toast.LENGTH_SHORT).show();
        }
    } else {
        Toast.makeText(getApplicationContext(),
                "Tab closed, do not add geofence.", Toast.LENGTH_SHORT)
                .show();
    }

} // end onResult(Status status)

// GET ERROR STRING
// *******************
public static String getErrorString(Context context, int errorCode) {
    Resources mResources = context.getResources();

    switch (errorCode) {
    case GeofenceStatusCodes.GEOFENCE_NOT_AVAILABLE:
        return mResources.getString(R.string.geofence_not_available);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_GEOFENCES:
        return mResources.getString(R.string.geofence_too_many_geofences);
    case GeofenceStatusCodes.GEOFENCE_TOO_MANY_PENDING_INTENTS:
        return mResources
                .getString(R.string.geofence_too_many_pending_intents);
    default:
        return mResources.getString(R.string.unknown_geofence_error);

    } // end switch (errorCode)
} // end getErrorString(Context context, int errorCode)

} // end GeolocationService Class
public class CloseTab extends Activity {
Button numDrinksBtn, estBillBtn, avgCostBtn, tipAmtBtn, totBillBtn,
        dismissBtn;
TextView tipExpl;
int currDrinkTotal = 0;
double currTabTotal, currTipTotal, tipAmt = 0.0;
boolean isSobriety, isSaver, isCount = false;
GoogleApiClient mGoogleApiClient;
PendingIntent mPendingIntent;
ResultCallback<Status> mGeoCallback;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.close_tab_layout);

    numDrinksBtn = (Button) findViewById(R.id.num_drinks_amout);
    estBillBtn = (Button) findViewById(R.id.est_bill_amout);
    avgCostBtn = (Button) findViewById(R.id.avg_cost_amout);
    tipExpl = (TextView) findViewById(R.id.tip_expl_text);
    tipAmtBtn = (Button) findViewById(R.id.total_tip_amount);
    totBillBtn = (Button) findViewById(R.id.total_bill_amout);
    dismissBtn = (Button) findViewById(R.id.dismiss_button);

    getSavedValues(); // populate view with saved values

    // DISMISS BUTTON
    dismissBtn.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {

            mGoogleApiClient = GeolocationService.mGoogleApiClient;
            if (mGoogleApiClient.isConnected()) {
                // Log.d("DBG", "mGoogleApiClient.isConnected()");

                mPendingIntent = GeolocationService.mPendingIntent;
                mGeoCallback = GeolocationService.mGeoCallback;

                try { // Log.d("DBG", "try hit in CloseTab");

                    // use the same pending intent set in GeolocationService
                    // to identify the right things to disable

                    // Remove geofence
                    LocationServices.GeofencingApi.removeGeofences(
                            mGoogleApiClient, mPendingIntent)
                            .setResultCallback(mGeoCallback);
                    // Remove location updates
                    LocationServices.FusedLocationApi
                            .removeLocationUpdates(mGoogleApiClient,
                                    mPendingIntent);
                    // Disconnect google client
                    mGoogleApiClient.disconnect();

                    // Remove any lingering services
                    Intent intent = new Intent(getApplicationContext(),
                            GeolocationService.class);
                    stopService(intent);

                } catch (SecurityException securityException) {
                    // Catch exception generated if the app does not use
                    // ACCESS_FINE_LOCATION permission.
                    Log.d("DBG", "catch hit in CloseTab");
                }
            }

            // clear all saved values
            TinyDB tinydb = new TinyDB(getApplicationContext());
            tinydb.clear();
            // tab has been closed. this is used as a condition to determine
            // if gps should be allowed to reconnect on it's own
            tinydb.putBoolean("tabClosed", true);

            Intent toLobby = new Intent(v.getContext(), Lobby.class);
            startActivity(toLobby);
        }
    });

}// end onCreate