我正在构建一个应用程序,以帮助您在外出时关注酒吧标签。我有一个功能,用户可以设置接近警报(地理围栏),以提醒他们关闭他们的标签,如果他们离开酒吧没有关闭。首先显示地图,然后将标记放在用户的位置,然后在标记周围显示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类设置位置和Geofence对象:
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
MapFragment是显示实际地图,标记和地理围栏的地方:
public class MapFragment extends Fragment {
protected SupportMapFragment mapFragment;
protected GoogleMap map;
protected Marker myPositionMarker;
Double latitude, longitude = 0.0;
Integer transition = 0;
float radius = 0;
long expiration = 0;
Handler handler;
HashMap<String, SimpleGeofence> geofences;
Button lobbyBtn, startTabBtn, settingsBtn;
private Bundle savedState = null;
Context mContext;
boolean mapOpen = false;
public static BroadcastReceiver mReceiver;
public static FragmentActivity fAct;
private BroadcastReceiver receiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Bundle bundle = intent.getExtras();
if (bundle != null) {
int resultCode = bundle.getInt("done");
if (resultCode == 1) {
latitude = bundle.getDouble("latitude");
longitude = bundle.getDouble("longitude");
updateMarker(latitude, longitude, context);
} // end if (resultCode == 1)
} // end if (bundle != null)
} // end onReceive(Context context, Intent intent)
}; // end BroadcastReceiver receiver = new BroadcastReceiver()
@Override
public void onCreate(Bundle savedInstanceState) {
setRetainInstance(true);
setHasOptionsMenu(true);
super.onCreate(savedInstanceState);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.fragment_map, container,
false);
mapFragment = SupportMapFragment.newInstance();
FragmentTransaction fragmentTransaction = getChildFragmentManager()
.beginTransaction();
fragmentTransaction.add(R.id.map_container, mapFragment);
fragmentTransaction.commit();
startTabBtn = (Button) rootView.findViewById(R.id.calculator_button);
lobbyBtn = (Button) rootView.findViewById(R.id.lobby_button);
settingsBtn = (Button) rootView.findViewById(R.id.settings_button);
lobbyBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent toLobby = new Intent(v.getContext(), Lobby.class);
startActivity(toLobby);
}
});
startTabBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent toCalc = new Intent(v.getContext(), CurrentTab.class);
startActivity(toCalc);
}
});
settingsBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Intent toCalc = new Intent(v.getContext(), StartTab.class);
startActivity(toCalc);
}
});
return rootView;
} // end onCreateView
// ON PAUSE
// ***********
@Override
public void onPause() {
super.onPause();
fAct = getActivity();
getActivity().unregisterReceiver(receiver);
}
// ON RESUME
// ************
@Override
public void onResume() {
super.onResume();
if (mapFragment != null) {
if (map != null)
map.animateCamera(CameraUpdateFactory.zoomTo(15));
mapFragment.getMapAsync(new OnMapReadyCallback() {
@Override
public void onMapReady(GoogleMap googleMap) {
map = googleMap;
map.animateCamera(CameraUpdateFactory.zoomTo(15));
} // end onMapReady(GoogleMap googleMap)
}); // end mapFragment.getMapAsync(new OnMapReadyCallback()
} // end if (mapFragment != null)
mReceiver = receiver;
getActivity().registerReceiver(
receiver,
new IntentFilter(
"com.diligencedojo.tabsitter.geolocation.service"));
} // end onResume()
// DISPLAY GEOFENCE
// *******************
protected void displayGeofences() {
geofences = SimpleGeofenceStore.getInstance().getSimpleGeofences();
// set circle around marker
for (Map.Entry<String, SimpleGeofence> item : geofences.entrySet()) {
SimpleGeofence sg = item.getValue();
CircleOptions circleOptions1 = new CircleOptions()
.center(new LatLng(sg.getLatitude(), sg.getLongitude()))
.radius(sg.getRadius()).strokeColor(Color.BLACK)
.strokeWidth(2).fillColor(0x500000ff);
map.addCircle(circleOptions1);
}
} // end displayGeofences()
// CREATE MARKER
// ****************
protected void createMarker(Double latitude, Double longitude,
Context context) {
LatLng latLng = new LatLng(latitude, longitude);
myPositionMarker = map.addMarker(new MarkerOptions().position(latLng));
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
// display the geofence after the marker is placed to ensure that the
// map is being displayed successfully
displayGeofences();
// save the state of the map (if it's open or not)
TinyDB tinydb = new TinyDB(context);
tinydb.putBoolean("mapOpen", true);
tinydb.putDouble("latitude", latitude);
tinydb.putDouble("longitude", longitude);
}
// UPDATE MARKER
// ****************
protected void updateMarker(Double latitude, Double longitude,
Context context) {
if (myPositionMarker == null)
createMarker(latitude, longitude, context);
LatLng latLng = new LatLng(latitude, longitude);
myPositionMarker.setPosition(latLng);
map.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}
// ON CREATE OPTIONS MENU
// *************************
@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
super.onCreateOptionsMenu(menu, inflater);
inflater.inflate(R.menu.menu_map, menu);
}
// ON OPTIONS SELECTED
// **********************
@Override
public boolean onOptionsItemSelected(MenuItem item) {
return super.onOptionsItemSelected(item);
}
} // end MapFragment Class
CloseTab活动是我想停止应用正在使用的任何GPS服务的地方。我尝试了很多不同的方法,所以请耐心等待。
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;
SimpleGeofence sg;
LocationListener mlocListener;
LocationManager locationManager;
android.location.LocationListener mlocListenerProvider;
PendingIntent mPendingIntent;
ConnectionCallbacks mConnCallbacks;
OnConnectionFailedListener mConnFailedListener;
BroadcastReceiver mReceiver;
FragmentActivity fAct;
@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.mGoogleApiClientStatic;
if (mGoogleApiClient.isConnected()) {
mlocListener = GeolocationService.mlocListener;
locationManager = GeolocationService.mlocManager;
mlocListenerProvider = GeolocationService.mlocListenerProvider;
mPendingIntent = GeolocationService.pendingIntent;
mConnCallbacks = GeolocationService.connCallbacks;
mConnFailedListener = GeolocationService.connFailedListener;
LocationServices.FusedLocationApi.removeLocationUpdates(
mGoogleApiClient, mlocListener);
LocationServices.GeofencingApi.removeGeofences(
mGoogleApiClient, mPendingIntent);
locationManager.removeUpdates(mlocListenerProvider);
mGoogleApiClient
.unregisterConnectionCallbacks(mConnCallbacks);
mGoogleApiClient
.unregisterConnectionFailedListener(mConnFailedListener);
// mGoogleApiClient.stopAutoManage(f);
// mReceiver.abortBroadcast();
// fAct = MapFragment.fAct;
// mGoogleApiClient.stopAutoManage(fAct);
// mReceiver = MapFragment.mReceiver;
// fAct.unregisterReceiver(mReceiver);
mGoogleApiClient.disconnect();
}
turnGPSOff();
Intent intent = new Intent(
"android.location.GPS_ENABLED_CHANGE");
intent.putExtra("enabled", false);
sendBroadcast(intent);
ActivityManager am = (ActivityManager) getSystemService(Activity.ACTIVITY_SERVICE);
am.killBackgroundProcesses("com.diligencedojo.tabsitter");
am.getRunningServices(100).clear();
am.getRunningAppProcesses().clear();
// clear all saved values
TinyDB tinydb = new TinyDB(getApplicationContext());
tinydb.clear();
finish();
startActivity(getIntent());
Intent toLobby = new Intent(v.getContext(), Lobby.class);
startActivity(toLobby);
}
});
} // end onCreate
// automatic turn off the gps
public void turnGPSOff() {
Context ctx = getApplicationContext();
// CloseTab.this
String provider = Settings.Secure.getString(ctx.getContentResolver(),
Settings.Secure.LOCATION_PROVIDERS_ALLOWED);
if (provider.contains("gps")) { // if gps is enabled
// Toast.makeText(getApplicationContext(),
// "in->provider.contains(gps)", Toast.LENGTH_SHORT).show();
final Intent poke = new Intent();
poke.setClassName("com.android.settings",
"com.android.settings.widget.SettingsAppWidgetProvider");
poke.addCategory(Intent.CATEGORY_ALTERNATIVE);
poke.setData(Uri.parse("3"));
ctx.sendBroadcast(poke);
// CloseTab.this.sendBroadcast(poke);
}
}
..........
这些是我用于地理围栏的课程:
SimpleGeofence类
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
答案 0 :(得分:0)
要在按钮上单击其他活动时禁用位置服务和进程,我按照以下步骤操作。首先,我将GeolocationServices.java中的位置变量定义为public和static。这允许您在其他活动中访问它们。接下来,我把一个布尔变量&#34; tabClosed&#34;在断开连接后可能重新连接GoogleApiClient的所有内容。我不完全确定我需要这个。
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
现在在CloseTab.java中,我检索了我在GeolocationService.java中声明了public static的变量。禁用位置服务时,使用相同的待处理意图作为参数非常重要。首先,我删除了地理围栏,然后更新了位置,然后我将google api客户端全部断开连接。最后,我使用stopService(intent)删除任何延迟服务(例如在我的MapFragment.java中启动的服务)。
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
希望这会帮助别人。