开发者

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

    }
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜