从 onPause Android 调用删除更新时 GPS 图标不会消失

Posted

技术标签:

【中文标题】从 onPause Android 调用删除更新时 GPS 图标不会消失【英文标题】:GPS Icon wont dissapear when remove updates is called from onPause Android 【发布时间】:2015-08-15 00:00:21 【问题描述】:

您好,我遇到了一个问题,即在调用 location.removeUpdates 后位置图标不会消失。我遵循了这个解决方案。

public class GPSTracker extends Service implements LocationListener 

// Get Class Name
private static String TAG = GPSTracker.class.getName();

private final Context mContext;

// flag for GPS Status
boolean isGPSEnabled = false;

// flag for network status
boolean isNetworkEnabled = false;

// flag for GPS Tracking is enabled 
boolean isGPSTrackingEnabled = false;

Location location;
double latitude;
double longitude;

// How many Geocoder should return our GPSTracker
int geocoderMaxResults = 1;

// The minimum distance to change updates in meters
private static final long MIN_DISTANCE_CHANGE_FOR_UPDATES = 10; // 10 meters

// The minimum time between updates in milliseconds
private static final long MIN_TIME_BW_UPDATES = 1000 * 60 * 1; // 1 minute

// Declaring a Location Manager
protected LocationManager locationManager;

// Store LocationManager.GPS_PROVIDER or LocationManager.NETWORK_PROVIDER information
private String provider_info;

public GPSTracker(Context context) 
    this.mContext = context;
    //getLocation();


/**
 * Try to get my current location by GPS or Network Provider
 */
public void getLocation() 

    try 
        locationManager = (LocationManager) mContext.getSystemService(LOCATION_SERVICE);

        //getting GPS status
        isGPSEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER);

        //getting network status
        isNetworkEnabled = locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

        // Try to get location if you GPS Service is enabled
        if (isGPSEnabled) 
            this.isGPSTrackingEnabled = true;

            Log.d(TAG, "Application use GPS Service");

            /*
             * This provider determines location using
             * satellites. Depending on conditions, this provider may take a while to return
             * a location fix.
             */

            provider_info = LocationManager.GPS_PROVIDER;

         else if (isNetworkEnabled)  // Try to get location if you Network Service is enabled
            this.isGPSTrackingEnabled = true;

            Log.d(TAG, "Application use Network State to get GPS coordinates");

            /*
             * This provider determines location based on
             * availability of cell tower and WiFi access points. Results are retrieved
             * by means of a network lookup.
             */
            provider_info = LocationManager.NETWORK_PROVIDER;

         

        // Application can use GPS or Network Provider
        if (!provider_info.isEmpty()) 
            locationManager.requestLocationUpdates(
                provider_info,
                MIN_TIME_BW_UPDATES,
                MIN_DISTANCE_CHANGE_FOR_UPDATES, 
                this
            );

            if (locationManager != null) 
                location = locationManager.getLastKnownLocation(provider_info);
                updateGPSCoordinates();
            
        
    
    catch (Exception e)
    
        //e.printStackTrace();
        Log.e(TAG, "Impossible to connect to LocationManager", e);
    


/**
 * Update GPSTracker latitude and longitude
 */
public void updateGPSCoordinates() 
    if (location != null) 
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    


/**
 * GPSTracker latitude getter and setter
 * @return latitude
 */
public double getLatitude() 
    if (location != null) 
        latitude = location.getLatitude();
    

    return latitude;


/**
 * GPSTracker longitude getter and setter
 * @return
 */
public double getLongitude() 
    if (location != null) 
        longitude = location.getLongitude();
    

    return longitude;


/**
 * GPSTracker isGPSTrackingEnabled getter.
 * Check GPS/wifi is enabled
 */
public boolean getIsGPSTrackingEnabled() 

    return this.isGPSTrackingEnabled;


/**
 * Stop using GPS listener
 * Calling this method will stop using GPS in your app
 */
public void stopUsingGPS() 
    if (locationManager != null) 
        locationManager.removeUpdates(GPSTracker.this);
    


/**
 * Function to show settings alert dialog
 */
public void showSettingsAlert() 
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(mContext);

    //Setting Dialog Title
    alertDialog.setTitle(R.string.GPSAlertDialogTitle);

    //Setting Dialog Message
    alertDialog.setMessage(R.string.GPSAlertDialogMessage);

    //On Pressing Setting button
    alertDialog.setPositiveButton(R.string.action_settings, new DialogInterface.OnClickListener() 

        @Override
        public void onClick(DialogInterface dialog, int which) 
        
            Intent intent = new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS);
            mContext.startActivity(intent);
        
    );

    //On pressing cancel button
    alertDialog.setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() 

        @Override
        public void onClick(DialogInterface dialog, int which) 
        
            dialog.cancel();
        
    );

    alertDialog.show();


/**
 * Get list of address by latitude and longitude
 * @return null or List<Address>
 */
public List<Address> getGeocoderAddress(Context context) 
    if (location != null) 

        Geocoder geocoder = new Geocoder(context, Locale.ENGLISH);

        try 
            /**
             * Geocoder.getFromLocation - Returns an array of Addresses 
             * that are known to describe the area immediately surrounding the given latitude and longitude.
             */
            List<Address> addresses = geocoder.getFromLocation(latitude, longitude, this.geocoderMaxResults);

            return addresses;
         catch (IOException e) 
            //e.printStackTrace();
            Log.e(TAG, "Impossible to connect to Geocoder", e);
        
    

    return null;


/**
 * Try to get AddressLine
 * @return null or addressLine
 */
public String getAddressLine(Context context) 
    List<Address> addresses = getGeocoderAddress(context);

    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String addressLine = address.getAddressLine(0);

        return addressLine;
     else 
        return null;
    


/**
 * Try to get Locality
 * @return null or locality
 */
public String getLocality(Context context) 
    List<Address> addresses = getGeocoderAddress(context);

    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String locality = address.getLocality();

        return locality;
    
    else 
        return null;
    


/**
 * Try to get Postal Code
 * @return null or postalCode
 */
public String getPostalCode(Context context) 
    List<Address> addresses = getGeocoderAddress(context);

    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String postalCode = address.getPostalCode();

        return postalCode;
     else 
        return null;
    


/**
 * Try to get CountryName
 * @return null or postalCode
 */
public String getCountryName(Context context) 
    List<Address> addresses = getGeocoderAddress(context);
    if (addresses != null && addresses.size() > 0) 
        Address address = addresses.get(0);
        String countryName = address.getCountryName();

        return countryName;
     else 
        return null;
    


@Override
public void onLocationChanged(Location location) 


@Override
public void onStatusChanged(String provider, int status, Bundle extras) 


@Override
public void onProviderEnabled(String provider) 


@Override
public void onProviderDisabled(String provider) 


@Override
public IBinder onBind(Intent intent) 
    return null;

当我调用 stopUsingGPS 函数时,它会调用它但不会停止定位服务,它仍然会在操作栏中显示图标。

@Override
public void onPause() 
    super.onPause();
    GPSTracker gpsTracker = new GPSTracker(getActivity());
    gpsTracker.stopUsingGPS();

任何建议将不胜感激。谢谢。

【问题讨论】:

【参考方案1】:

您不能真正创建 GPSTracker 的新实例并在那里调用函数。因为您已经启动了Service。为此,您应该使用Binder 实现ServiceConnection

在您的服务中添加,

private final IBinder locationBinder = new LocationBinder();

@Override
public IBinder onBind(Intent intent) 
        return locationBinder;


public class LocationBinder extends Binder 
   public GPSTracker getService() 
        Log.v("Test", "GPSTracker: getService() called");
        return GPSTracker.this;
   

在你的活动中,

private GPSTracker gpsTracker;
private ServiceConnection serviceConnection = new ServiceConnection() 
    public void onServiceConnected(ComponentName className, IBinder baBinder) 
       gpsTracker = ((GPSTracker.LocationBinder) baBinder).getService();
    

    public void onServiceDisconnected(ComponentName className) 
       gpsTracker = null;
    
;

在你的活动中onCreate()

 Intent locationIntent = new Intent(this, GPSTracker.class);
 startService(locationIntent);
 bindService(locationIntent, serviceConnection, Context.BIND_AUTO_CREATE);

然后onPause()

@Override
public void onPause() 
    super.onPause();
    gpsTracker.stopUsingGPS();

然后onDestroy()

@Override
public void onDestroy() 
    super.onDestroy();
    unbindService(serviceConnection);

【讨论】:

非常感谢您的出色回答,不过我有一点问题,startService(location) 有一个无法解决方法错误,当我添加 gpsTracker.startService(location) 时它会抛出一个空指针。 你不应该打电话给gpsTracker.startService(location) 我解决了这个问题,因为我正在使用需要添加 getActivity().startService(location) 的片段。它仍然没有停止服务,我会在此期间进行调查。非常感谢您抽出宝贵的时间。如果我被卡住了,我会发消息给你。 :-)

以上是关于从 onPause Android 调用删除更新时 GPS 图标不会消失的主要内容,如果未能解决你的问题,请参考以下文章

在Android中销毁布局时覆盖的方法

Android:在啥情况下出现对话框会导致 onPause() 被调用?

Fragment 与 Parcel 一起崩溃:调用 onPause 方法时无法编组值错误

应用程序空闲时如何在android中停止GPS更新?

onPause 方法没有被调用

OnResume / OnPause多次调用