【问题标题】:GPS LocationManager and ListenerManager Management in a Base Activity基础活动中的 GPS LocationManager 和 ListenerManager 管理
【发布时间】:2011-09-27 08:19:49
【问题描述】:

我的需要是, 我的所有大部分活动都需要用户的位置来获取基于位置的更新数据。因此,我没有在所有活动中单独定义,而是定义了一个基本活动(BaseActivity.java)并声明所有活动都必须继承这个类。

例如:

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 from 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 {
        }

这使得获取管理常用事件处理,例如LocationManager,onCreateOptionsMenu

效果很好。但是有一个小问题。 onPause,onResume,onRestart 我绑定和取消绑定 locationlistener 事件,所以 Gps 有时没有足够的时间来抛出 locationchanged 事件,因为用户可以在活动之间快速传递,并且 GPS 有绑定和取消绑定事件。所以我将我的 LocationManager 和 LocationListener 变量设置为静态的。现在它很完美。在所有活动中,我都有用户的最新位置。这很棒!但是 GPS 一直在运行。

这是我想要的东西,我如何知道用户将应用程序发送回。我的意思是退出或暂停它。

P.S:onPause、onResume 事件在所有活动中运行。我需要有关整个应用程序的一般信息。

【问题讨论】:

    标签: android gps memory-management


    【解决方案1】:

    试试这个....

    您可以使用Service,它将在后台运行。

    当您的应用程序即将完成服务销毁时。

    因此,将结束逻辑放在该服务的 onDestroy() 方法中。

    @Override
        public void onDestroy() {
            // ending logic.
        }
    

    :)

    【讨论】:

    • 我刚刚尝试了一个示例应用程序来测试它。但它与下面的相同。我想知道用户已通过按主页按钮或任何其他操作以传递新应用程序(如电子邮件或其他任何内容)退出应用程序......因为我不想因为电池而一直保持 GPS 开启。
    • 不要忘记将您的服务绑定到您在应用程序中启动的所有活动..!
    • 如果您的意思是在活动的 onCreate 事件中启动服务,是的,我做到了。我的示例如下所示:marakana.com/forums/android/examples/60.html
    • 在应用程序的第一个活动中启动您的服务。然后在移动到任何活动时将您的服务“绑定”到该特定活动。
    • 服务始终运行 :) 永远不会停止,直到您从任务管理器停止 :)
    【解决方案2】:

    这是服务的代码示例

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

    【讨论】:

    • 在ServiceTestActivity和ServiceTestActivity2中绑定你的服务
    • 好的,诺比,现在我明白你的意思了。在这个示例中,这就是您要告诉我的。 ozdroid.com/#!BLOG/2010/12/19/… 但我不想在所有活动中重复我的代码。在服务之前,它与我当前的代码无关。服务将始终在后台运行。 GPS 将始终开启。我的需要正是我想在我的应用程序进入后台或完成时删除更新(实际上,如果完成所有活动都将完成 - 不需要)。只想在我的应用程序运行时只打开 GPS
    • Noby 我绑定了它,但什么也没发生!
    猜你喜欢
    • 2016-02-15
    • 2013-06-14
    • 2013-06-19
    • 2011-10-19
    • 2021-05-03
    • 2021-03-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多