GPS LocationManager and ListenerManager Management in a Base Activity
My need is that, all most of my activities need location of user to get updated data which is based on location. So, instead of define in all activities seperately I define a base activity (BaseActivity.java) and declared all activities have to inherite this class.
For example:
package com.example;
import com.example.tools.Utilities;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.MenuItem.OnMenuItemClickListener;
import android.view.Window;
public class BaseActivity extends Activity {
protected static final String GpsTag = "GPS";
private static LocationManager mLocManager;
private static LocationListener mLocListener;
private static double mDefaultLatitude = 41.0793;
private static double mDefaultLongtitude = 29.0461;
private Location CurrentBestLocation;
private float mMinDistanceForGPSProvider = 200;
private float mMinDistanceForNetworkProvider = 1000;
private float mMinDistanceForPassiveProvider = 3000;
private long mMinTime = 0;
private UserLocation mCurrentLocation = new UserLocation(mDefaultLatitude,
mDefaultLongtitude);
private Boolean showLocationNotification = false;
protected Activity mActivity;
private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
UserManagement.logOut(getApplication());
Utilities.setApplicationTitle(mActivity);
// finish();
}
};
private BroadcastReceiver mLoggedInReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
Utilities.setApplicationTitle(mActivity);
// finish();
}
};
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE);
super.registerReceiver(mLoggedOutReceiver, new IntentFilter(
Utilities.LOG_OUT_ACTION));
super.registerReceiver(mLoggedInReceiver, new IntentFilter(
Utilities.LOG_IN_ACTION));
mActivity = this;
if (mLocManager == null || mLocListener == null) {
mLocManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);
mLocListener = new LocationListener() {
@Override
public void onLocationChanged(Location location) {
Log.i(GpsTag, "Location Changed");
if (isBetterLocation(location, CurrentBestLocation)) {
sendBroadcast(new Intent(
Utilities.LOCATION_CHANGED_ACTION));
mCurrentLocation.Latitude = location.getLatitude();
mCurrentLocation.Longtitude = location.getLongitude();
if (location.hasAccuracy()) {
mCurrentLocation.Accuracy = location.getAccuracy();
}
UserManagement.UserLocation = mCurrentLocation;
mCurrentLocation.Latitude = location.getLatitude();
mCurrentLocation.Longtitude = location.getLongitude();
if (location.hasAccuracy()) {
mCurrentLocation.Accuracy = location.getAccuracy();
}
UserManagement.UserLocation = mCurrentLocation;
CurrentBestLocation = location;
}
}
@Override
public void onProviderDisabled(String provider) {
chooseProviderAndSetLocation();
}
@Override
public void onProviderEnabled(String provider) {
chooseProviderAndSetLocation();
}
@Override
public void onStatusChanged(String provider, int status,
Bundle extras) {
}
};
chooseProviderAndSetLocation();
}
}
private void chooseProviderAndSetLocation() {
Location loc = null;
if (mLocManager == null)
return;
mLocManager.removeUpdates(mLocListener);
if (mLocManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)) {
loc = mLocManager
.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
} else if (mLocManager.isProviderEnabled(LocationManager.GPS_PROVIDER)) {
loc = mLocManager
.getLastKnownLocation(LocationManager.GPS_PROVIDER);
}
for (String providerName : mLocManager.getProviders(true)) {
float minDistance = mMinDistanceForPassiveProvider;
if (providerName.equals("network"))
minDistance = mMinDistanceForNetworkProvider;
else if (providerName.equals("gps"))
minDistance = mMinDistanceForGPSProvider;
mLocManager.requestLocationUpdates(providerName, mMinTime,
minDistance, mLocListener);
Log.i(GpsTag, providerName + " listener binded...");
}
if (loc != null) {
if (mCurrentLocation == null)
mCurrentLocation = new UserLocation(mDefaultLatitude,
mDefaultLongtitude);
mCurrentLocation.Latitude = loc.getLatitude();
mCurrentLocation.Longtitude = loc.getLongitude();
mCurrentLocation.Accuracy = loc.hasAccuracy() ? loc.getAccuracy()
: 0;
UserManagement.UserLocation = mCurrentLocation;
CurrentBestLocation = loc;
} else {
if (showLocationNotification) {
Utilities
.warnUserWithToast(
getApplication(),
"Default Location");
}
UserManagement.UserLocation = new UserLocation(mDefaultLatitude,
mDefaultLongtitude);
}
}
private static final int TWO_MINUTES = 1000 * 60 * 2;
protected boolean isBetterLocation(Location location,
Location currentBestLocation) {
if (currentBestLocation == null) {
// A new location is always better than no location
return true;
}
// Check whether the new location fix is newer or older
long timeDelta = location.getTime() - currentBestLocation.getTime();
boolean isSignificantlyNewer = timeDelta > TWO_MINUTES;
boolean isSignificantlyOlder = timeDelta < -TWO_MINUTES;
boolean isNewer = timeDelta > 0;
// If it's been more than two minutes since the current location, use
// the new location
// because the user has likely moved
if (isSignificantlyNewer) {
return true;
// If the new location is more than two minutes older, it must be
// worse
} else if (isSignificantlyOlder) {
return false;
}
// Check whether the new location fix is more or less accurate
int accuracyDelta = (int) (location.getAccuracy() - currentBestLocation
.getAccuracy());
boolean isLessAccurate = accuracyDelta > 0;
boolean isMoreAccurate = accuracyDelta < 0;
boolean isSignificantlyLessAccurate = accuracyDelta > 200;
// Check if the old and new location are fr开发者_StackOverflowom the same providerl
boolean isFromSameProvider = isSameProvider(location.getProvider(),
currentBestLocation.getProvider());
// Determine location quality using a combination of timeliness and
// accuracy
if (isMoreAccurate) {
return true;
} else if (isNewer && !isLessAccurate) {
return true;
} else if (isNewer && !isSignificantlyLessAccurate
&& isFromSameProvider) {
return true;
}
return false;
}
private boolean isSameProvider(String provider1, String provider2) {
if (provider1 == null) {
return provider2 == null;
}
return provider1.equals(provider2);
}
@Override
public boolean moveTaskToBack(boolean nonRoot) {
Utilities.warnUserWithToast(getApplicationContext(), "moveTaskToBack: " + nonRoot);
return super.moveTaskToBack(nonRoot);
}
@Override
protected void onDestroy() {
super.onDestroy();
mLocManager.removeUpdates(mLocListener);
super.unregisterReceiver(mLoggedOutReceiver);
super.unregisterReceiver(mLoggedInReceiver);
}
@Override
protected void onRestart() {
super.onRestart();
Utilities.warnUserWithToast(getApplicationContext(), "onRestart: " + getPackageName());
}
@Override
protected void onPause() {
super.onPause();
mLocManager.removeUpdates(mLocListener);
Utilities.warnUserWithToast(getApplicationContext(), "onPause: " + getPackageName());
}
@Override
protected void onResume() {
super.onResume();
Utilities.warnUserWithToast(getApplicationContext(), "onResume: " );
chooseProviderAndSetLocation();
}
@Override
protected void finalize() throws Throwable {
Utilities.warnUserWithToast(getApplicationContext(), "finalize: " );
super.finalize();
}
@Override
protected void onPostResume() {
Utilities.warnUserWithToast(getApplicationContext(), "onPostResume: ");
super.onPostResume();
}
@Override
protected void onStart() {
Utilities.warnUserWithToast(getApplicationContext(), "onStart: " );
super.onStart();
}
@Override
protected void onStop() {
Utilities.warnUserWithToast(getApplicationContext(), "onStop: ");
super.onStop();
}
public void setLocationNotification(Boolean show) {
this.showLocationNotification = show;
}
@Override
public boolean onCreateOptionsMenu(final Menu menu) {
if (menu != null && UserManagement.CurrentUser != null) {
final MenuItem miExit = menu.add("Log Out");
miExit.setIcon(R.drawable.menu_exit);
miExit.setOnMenuItemClickListener(new OnMenuItemClickListener() {
@Override
public boolean onMenuItemClick(MenuItem item) {
sendBroadcast(new Intent(Utilities.LOG_OUT_ACTION));
menu.removeItem(miExit.getItemId());
return true;
}
});
}
return super.onCreateOptionsMenu(menu);
}
}
public class MainActivity extends BaseActivity {
}
This made obtain to manage common events handling such as LocationManager, onCreateOptionsMenu
It works very good. But there is a little problem. onPause, onResume, onRestart I bind and unbind locationlistener event so Gps sometime doesn't have enough time to throw the locationchanged event becuase user can pass quickly between activity and there are bind and unbind events for GPS. So I made my LocationManager and LocationListener variables to static. Now it's perfect. In all activities I have the latest location of user. It's great! But the GPS is runing ON always.
And here is the I want the thing how can I know the user send the application to back. I mean quit or pause it.
P.S: onPause, onResume events run in all activities. I need something general about the whole application.
Try this....
You can make use of a Service
, which will run in background.
When ever your application is about to finish the service destroys.
So, place your ending logic in onDestroy() method of that Service.
@Override
public void onDestroy() {
// ending logic.
}
:)
Here is the code sample for Service
package com.test.examppplee;
import android.app.Service;
import android.content.Intent;
import android.os.IBinder;
import android.widget.Toast;
public class LocationService extends Service{
@Override
public void onCreate() {
Toast.makeText(getApplicationContext(), "onCreate", Toast.LENGTH_LONG).show();
super.onCreate();
}
@Override
public void onDestroy() {
Toast.makeText(getApplicationContext(), "onDestroy", Toast.LENGTH_LONG).show();
super.onDestroy();
}
@Override
public void onStart(Intent intent, int startId) {
Toast.makeText(getApplicationContext(), "onStart", Toast.LENGTH_LONG).show();
super.onStart(intent, startId);
}
@Override
public IBinder onBind(Intent intent) {
// TODO Auto-generated method stub
return null;
}
}
package com.test.examppplee;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
startService(new Intent(getApplicationContext(), LocationService.class));
}
public void finish(View v){
finish();
}
public void start(View v){
startActivity(new Intent(getApplicationContext(), ServiceTestActivity.class));
}
}
package com.test.examppplee;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
public class ServiceTestActivity extends Activity {
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
public void finish(View v){
finish();
}
public void start(View v){
startActivity(new Intent(getApplicationContext(), ServiceTestActivity2.class));
}
}
精彩评论