Android位置管理器,获取GPS位置,如果没有GPS,则转到网络提供商位置

时间:2013-11-26 07:06:08

标签: android gps android-location

我使用下面给出的代码来获取位置:

public Location getLocation() {
        try {
            mLocationManager = (LocationManager) context.getSystemService(LOCATION_SERVICE);

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

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

            if (!isGPSEnabled && !isNetworkEnabled) {
                // no network provider is enabled
            } else {
                // First get location from Network Provider
                if (isNetworkEnabled) {
                    mLocationManager.requestLocationUpdates( LocationManager.NETWORK_PROVIDER,  MIN_TIME_BW_UPDATES,  MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (mLocationManager != null) {
                        location = mLocationManager.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (location != null) {
                            lat = location.getLatitude();
                            lng = location.getLongitude();
                        }
                    }
                }
                //get the location by gps
                if (isGPSEnabled) {
                    if (location == null) {
                        mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER,MIN_TIME_BW_UPDATES,MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                        Log.d("GPS Enabled", "GPS Enabled");
                        if (mLocationManager != null) {location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
                            if (location != null) {
                                lat = location.getLatitude();
                                lng = location.getLongitude();
                            }
                        }
                    }
                }
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return location;
    }

它工作正常,但我想首先获得GPS位置,如果它不可用,位置管理员应该查询网络提供商,我遇到了麻烦。

请推荐我这样做的好方法。

7 个答案:

答案 0 :(得分:18)

你说你首先需要GPS位置,但你所做的是首先从网络提供商那里获得位置,然后从GPS获得位置。如果两者都可用,这将从网络和GPS获得位置。您可以做的是,将这些案例写在 if..else if 块中。与 -

类似
if( !isGPSEnabled && !isNetworkEnabled) {

// Can't get location by any way

} else {

    if(isGPSEnabled) {

    // get location from GPS

    } else if(isNetworkEnabled) {

    // get location from Network Provider

    }
}

因此,这将首先从GPS获取位置(如果可用),否则它将尝试从网络提供商处获取位置。

修改

为了让它更好,我会发布一个片段。请考虑它位于 try-catch

boolean gps_enabled = false;
boolean network_enabled = false;

LocationManager lm = (LocationManager) mCtx
                .getSystemService(Context.LOCATION_SERVICE);

gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);

Location net_loc = null, gps_loc = null, finalLoc = null;

if (gps_enabled)
    gps_loc = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
if (network_enabled)
    net_loc = lm.getLastKnownLocation(LocationManager.NETWORK_PROVIDER);

if (gps_loc != null && net_loc != null) {

    //smaller the number more accurate result will
    if (gps_loc.getAccuracy() > net_loc.getAccuracy()) 
        finalLoc = net_loc;
    else
        finalLoc = gps_loc;

        // I used this just to get an idea (if both avail, its upto you which you want to take as I've taken location with more accuracy)

} else {

    if (gps_loc != null) {
        finalLoc = gps_loc;
    } else if (net_loc != null) {
        finalLoc = net_loc;
    }
}

现在,您检查finalLoc null,如果不是return。 您可以在函数中编写上述代码,该函数返回所需的(finalLoc)位置。我认为这可能有所帮助。

答案 1 :(得分:5)

建议的方法是使用LocationClient

首先,定义位置更新间隔值。根据您的需要进行调整。

private static final int MILLISECONDS_PER_SECOND = 1000;
private static final long UPDATE_INTERVAL = MILLISECONDS_PER_SECOND * UPDATE_INTERVAL_IN_SECONDS;
private static final int FASTEST_INTERVAL_IN_SECONDS = 1;
private static final long FASTEST_INTERVAL = MILLISECONDS_PER_SECOND * FASTEST_INTERVAL_IN_SECONDS;

让您Activity实施GooglePlayServicesClient.ConnectionCallbacksGooglePlayServicesClient.OnConnectionFailedListenerLocationListener

public class LocationActivity extends Activity implements 
GooglePlayServicesClient.ConnectionCallbacks, GooglePlayServicesClient.OnConnectionFailedListener, LocationListener {}

然后,在LocationClient的{​​{1}}方法中设置onCreate()

Activity

将所需方法添加到public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mLocationClient = new LocationClient(this, this, this); mLocationRequest = LocationRequest.create(); mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY); mLocationRequest.setInterval(UPDATE_INTERVAL); mLocationRequest.setFastestInterval(FASTEST_INTERVAL); } ; ActivityonConnected()连接时调用的方法。 LocationClient是您可以检索最新位置的地方。

onLocationChanged()

请确保连接/断开@Override public void onConnectionFailed(ConnectionResult connectionResult) { Log.w(TAG, "Location client connection failed"); } @Override public void onConnected(Bundle dataBundle) { Log.d(TAG, "Location client connected"); mLocationClient.requestLocationUpdates(mLocationRequest, this); } @Override public void onDisconnected() { Log.d(TAG, "Location client disconnected"); } @Override public void onLocationChanged(Location location) { if (location != null) { Log.d(TAG, "Updated Location: " + Double.toString(location.getLatitude()) + "," + Double.toString(location.getLongitude())); } else { Log.d(TAG, "Updated location NULL"); } } ,以便在绝对必要时仅使用额外的电池,因此GPS无法无限期运行。必须连接LocationClient才能从中获取数据。

LocationClient

获取用户的位置。首先尝试使用public void onResume() { super.onResume(); mLocationClient.connect(); } public void onStop() { if (mLocationClient.isConnected()) { mLocationClient.removeLocationUpdates(this); } mLocationClient.disconnect(); super.onStop(); } ;如果失败,请回到LocationClient

LocationManager

答案 2 :(得分:2)

使用谷歌开发人员开发的融合API,GPS传感器,磁力计,加速度计的融合也使用Wifi或小区位置来计算或估计位置。它还能够准确地在建筑物内提供位置更新。

package com.example.ashis.gpslocation;

import android.app.Activity;
import android.location.Location;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.widget.TextView;
import android.widget.Toast;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.GooglePlayServicesUtil;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;

import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * Location sample.
 *
 * Demonstrates use of the Location API to retrieve the last known location for a device.
 * This sample uses Google Play services (GoogleApiClient) but does not need to authenticate a user.
 * See https://github.com/googlesamples/android-google-accounts/tree/master/QuickStart if you are
 * also using APIs that need authentication.
 */

public class MainActivity extends Activity implements LocationListener,
        GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener {

    private static final long ONE_MIN = 500;
    private static final long TWO_MIN = 500;
    private static final long FIVE_MIN = 500;
    private static final long POLLING_FREQ = 1000 * 20;
    private static final long FASTEST_UPDATE_FREQ = 1000 * 5;
    private static final float MIN_ACCURACY = 1.0f;
    private static final float MIN_LAST_READ_ACCURACY = 1;

    private LocationRequest mLocationRequest;
    private Location mBestReading;
TextView tv;
    private GoogleApiClient mGoogleApiClient;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);

        if (!servicesAvailable()) {
            finish();
        }

        setContentView(R.layout.activity_main);
tv= (TextView) findViewById(R.id.tv1);
        mLocationRequest = LocationRequest.create();
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRequest.setInterval(POLLING_FREQ);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_FREQ);

        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addApi(LocationServices.API)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .build();


        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onResume() {
        super.onResume();

        if (mGoogleApiClient != null) {
            mGoogleApiClient.connect();
        }
    }

    @Override
    protected void onPause() {d
        super.onPause();

        if (mGoogleApiClient != null && mGoogleApiClient.isConnected()) {
            mGoogleApiClient.disconnect();
        }
    }


        tv.setText(location + "");
        // Determine whether new location is better than current best
        // estimate
        if (null == mBestReading || location.getAccuracy() < mBestReading.getAccuracy()) {
            mBestReading = location;


            if (mBestReading.getAccuracy() < MIN_ACCURACY) {
                LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
            }
        }
    }

    @Override
    public void onConnected(Bundle dataBundle) {
        // Get first reading. Get additional location updates if necessary
        if (servicesAvailable()) {

            // Get best last location measurement meeting criteria
            mBestReading = bestLastKnownLocation(MIN_LAST_READ_ACCURACY, FIVE_MIN);

            if (null == mBestReading
                    || mBestReading.getAccuracy() > MIN_LAST_READ_ACCURACY
                    || mBestReading.getTime() < System.currentTimeMillis() - TWO_MIN) {

                LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);

               //Schedule a runnable to unregister location listeners

                    @Override
                    public void run() {
                        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, MainActivity.this);

                    }

                }, ONE_MIN, TimeUnit.MILLISECONDS);

            }

        }
    }

    @Override
    public void onConnectionSuspended(int i) {

    }


    private Location bestLastKnownLocation(float minAccuracy, long minTime) {
        Location bestResult = null;
        float bestAccuracy = Float.MAX_VALUE;
        long bestTime = Long.MIN_VALUE;

        // Get the best most recent location currently available
        Location mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        //tv.setText(mCurrentLocation+"");
        if (mCurrentLocation != null) {
            float accuracy = mCurrentLocation.getAccuracy();
            long time = mCurrentLocation.getTime();

            if (accuracy < bestAccuracy) {
                bestResult = mCurrentLocation;
                bestAccuracy = accuracy;
                bestTime = time;
            }
        }

        // Return best reading or null
        if (bestAccuracy > minAccuracy || bestTime < minTime) {
            return null;
        }
        else {
            return bestResult;
        }
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    private boolean servicesAvailable() {
        int resultCode = GooglePlayServicesUtil.isGooglePlayServicesAvailable(this);

        if (ConnectionResult.SUCCESS == resultCode) {
            return true;
        }
        else {
            GooglePlayServicesUtil.getErrorDialog(resultCode, this, 0).show();
            return false;
        }
    }
}

答案 3 :(得分:2)

如果您想在后台服务中运行并使用前面的数据,请使用下面的数据进行测试和验证。

public class MyService extends Service 
        implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, 
        GoogleApiClient.OnConnectionFailedListener, 
        com.google.android.gms.location.LocationListener {


    private static final int ASHIS = 1234;
    Intent intentForPendingIntent;
    HandlerThread handlerThread;
    Looper looper;
    GoogleApiClient mGoogleApiClient;
    private LocationRequest mLocationRrequest;
    private static final int UPDATE_INTERVAL = 1000;
    private static final int FASTEST_INTERVAL = 100;
    private static final int DSIPLACEMENT_UPDATES = 1;
    ;
    private Handler handler1;
    private Runnable runable1;
    private Location mLastLocation;
    private float waitingTime;
    private int waiting2min;
    private Location locationOld;
    private double distance;
    private float totalWaiting;
    private float speed;
    private long timeGpsUpdate;
    private long timeOld;
    private NotificationManager mNotificationManager;
    Notification notification;
    PendingIntent resultPendingIntent;
    NotificationCompat.Builder mBuilder;


    // Sets an ID for the notification
    int mNotificationId = 001;
    private static final String TAG = "BroadcastService";
    public static final String BROADCAST_ACTION = "speedExceeded";
    private final Handler handler = new Handler();
    Intent intentforBroadcast;
    int counter = 0;
    private Runnable sendUpdatesToUI;

    @Nullable
    @Override
    public IBinder onBind(Intent intent) {
        Toast.makeText(MyService.this, "binder", Toast.LENGTH_SHORT).show();

        return null;
    }


    @Override
    public void onCreate() {
        showNotification();
        intentforBroadcast  = new Intent(BROADCAST_ACTION);

        Toast.makeText(MyService.this, "created", Toast.LENGTH_SHORT).show();

        if (mGoogleApiClient == null) {
            mGoogleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();
        }
        createLocationRequest();
        mGoogleApiClient.connect();


    }

    @TargetApi(Build.VERSION_CODES.JELLY_BEAN)
    private void showNotification() {

        mBuilder =
                (NotificationCompat.Builder) new NotificationCompat.Builder(this)
                        .setSmallIcon(R.drawable.ic_media_play)
                        .setContentTitle("Total Waiting Time")
                        .setContentText(totalWaiting+"");


        Intent resultIntent = new Intent(this, trackingFusion.class);

        // Because clicking the notification opens a new ("special") activity, there's
        // no need to create an artificial back stack.
        PendingIntent resultPendingIntent =
                PendingIntent.getActivity(
                        this,
                        0,
                        resultIntent,
                        PendingIntent.FLAG_UPDATE_CURRENT
                );
        mBuilder.setContentIntent(resultPendingIntent);
        NotificationManager mNotifyMgr =
                (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
        // Builds the notification and issues it.

        mNotifyMgr.notify(mNotificationId, mBuilder.build());


        startForeground(001, mBuilder.getNotification());
    }


    @Override
    public void onLocationChanged(Location location) {

        //handler.removeCallbacks(runable);

        Toast.makeText(MyService.this, "speed" + speed, Toast.LENGTH_SHORT).show();
        timeGpsUpdate = location.getTime();
        float delta = (timeGpsUpdate - timeOld) / 1000;
        if (location.getAccuracy() < 100) {
            speed = location.getSpeed();
            distance += mLastLocation.distanceTo(location);
            Log.e("distance", "onLocationChanged: " + distance);
            //mLastLocation = location;
            //newLocation = mLastLocation;

            Log.e("location:", location + "");


            //speed = (long) (distance / delta);


            locationOld = location;
            mLastLocation = location;

            diaplayViews();
        }

        diaplayViews();
     /*if (map != null) {
         map.addMarker(new MarkerOptions()
                 .position(new LatLng(location.getLatitude(), location.getLongitude()))
                 .title("Hello world"));


     }*/
    }


    private void createLocationRequest() {

        mLocationRrequest = new LocationRequest();

        mLocationRrequest.setInterval(UPDATE_INTERVAL);
        mLocationRrequest.setFastestInterval(FASTEST_INTERVAL);
        mLocationRrequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
        mLocationRrequest.setSmallestDisplacement(DSIPLACEMENT_UPDATES);

    }


    private void methodToCalculateWaitingTime() {


        if (handler1 != null) {
            handler1.removeCallbacks(runable1);

        }


        Log.e("Here", "here1");
        handler1 = new Handler(Looper.getMainLooper());
        runable1 = new Runnable() {
            public void run() {

                Log.e("Here", "here2:" + mLastLocation.getSpeed());


                if (mLastLocation != null) {
                    diaplayViews();
                    if ((mLastLocation.getSpeed() == 0.0)) {

                        increaseTime();

                    } else {
                        if (waitingTime <= 120) {
                            waiting2min = 0;

                        }
                    }
                    handler1.postDelayed(this, 10000);
                } else {
                    if (ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(MyService.this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
                        // TODO: Consider calling
                        //    ActivityCompat#requestPermissions
                        // here to request the missing permissions, and then overriding
                        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
                        //                                          int[] grantResults)
                        // to handle the case where the user grants the permission. See the documentation
                        // for ActivityCompat#requestPermissions for more details.
                        return;
                    }

                    locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
                    mLastLocation = locationOld;

                }
            }
        };

        handler1.postDelayed(runable1, 10000);


    }

    private void diaplayViews() {
        float price = (float) (14 + distance * 0.5);

        //textDistance.setText(waitingTime);a
    }


    private void increaseTime() {
        waiting2min = waiting2min + 10;
        if (waiting2min >= 120)

        {
            if (waiting2min == 120) {
                waitingTime = waitingTime + 2 * 60;


            } else {
                waitingTime = waitingTime + 10;
            }


            totalWaiting = waitingTime / 60;
            showNotification();
            Log.e("waiting Time", "increaseTime: " + totalWaiting);
        }


    }

    @Override
    public void onDestroy() {
        Toast.makeText(MyService.this, "distroyed", Toast.LENGTH_SHORT).show();
        if (mGoogleApiClient.isConnected()) {

            mGoogleApiClient.disconnect();
        }
        mGoogleApiClient.disconnect();

    }

    @Override
    public void onConnected(Bundle bundle) {
        Log.e("Connection_fusion", "connected");

        startLocationUpdates();


    }


    @Override
    public void onConnectionSuspended(int i) {

    }

    private void startLocationUpdates() {
        Location location = plotTheInitialMarkerAndGetInitialGps();
        if (location == null) {
            plotTheInitialMarkerAndGetInitialGps();


        } else {

            mLastLocation = location;
            methodToCalculateWaitingTime();
        }
    }

    private Location plotTheInitialMarkerAndGetInitialGps() {
        if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
            // TODO: Consider calling
            //    ActivityCompat#requestPermissions
            // here to request the missing permissions, and then overriding
            //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
            //                                          int[] grantResults)
            // to handle the case where the user grants the permission. See the documentation
            // for ActivityCompat#requestPermissions for more details.
            return null;
        }
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRrequest, this);
        locationOld = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if ((locationOld != null)) {
            mLastLocation = locationOld;

            timeOld = locationOld.getTime();
        } else {
            startLocationUpdates();
        }

        return mLastLocation;
    }


    @Override
    public int onStartCommand(Intent intent, int flags, int startId) {
        onStart(intent, startId);
        Toast.makeText(MyService.this, "start command", Toast.LENGTH_SHORT).show();

        sendUpdatesToUI = new Runnable() {
            public void run() {
                DisplayLoggingInfo();
                handler.postDelayed(this, 10000); // 5 seconds
            }
        };
        handler.postDelayed(sendUpdatesToUI, 10000); // 1 second
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        return START_NOT_STICKY;
    }

    @Override
    public void onStart(Intent intent, int startId) {
        sendUpdatesToUI = new Runnable() {
            public void run() {
                Log.e("sent", "sent");
                DisplayLoggingInfo();
                handler.postDelayed(this, 5000); // 5 seconds
            }
        };
        handler.postDelayed(sendUpdatesToUI, 1000); // 1 second
        Log.i("LocalService", "Received start id " + startId + ": " + intent);
        super.onStart(intent, startId);
    }

    private void DisplayLoggingInfo() {
        Log.d(TAG, "entered DisplayLoggingInfo");
        intentforBroadcast.putExtra("distance", distance);
        LocalBroadcastManager.getInstance(this).sendBroadcast(intentforBroadcast);
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {

    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

    }
}

答案 4 :(得分:1)

我在上面的代码中进行了一些更改,以便通过GPS和网络寻找定位修复大约5秒,并从中获取最知名的位置。

public class LocationService implements LocationListener {

    boolean isGPSEnabled = false;

    boolean isNetworkEnabled = false;

    boolean canGetLocation = false;

    final static long MIN_TIME_INTERVAL = 60 * 1000L;

    Location location;


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

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

    protected LocationManager locationManager;

    private CountDownTimer timer = new CountDownTimer(5 * 1000, 1000) {

        public void onTick(long millisUntilFinished) {

        }

        public void onFinish() {
            stopUsingGPS();
        }
    };

    public LocationService() {
        super(R.id.gps_service_id);
    }


    public void start() {
        if (Utils.isNetworkAvailable(context)) {

            try {


                timer.start();


                locationManager = (LocationManager) context
                        .getSystemService(Context.LOCATION_SERVICE);

                isGPSEnabled = locationManager
                        .isProviderEnabled(LocationManager.GPS_PROVIDER);

                isNetworkEnabled = locationManager
                        .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
                this.canGetLocation = true;
                if (isNetworkEnabled) {
                    locationManager.requestLocationUpdates(
                            LocationManager.NETWORK_PROVIDER,
                            MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("Network", "Network");
                    if (locationManager != null) {
                        Location tempLocation = locationManager
                                .getLastKnownLocation(LocationManager.NETWORK_PROVIDER);
                        if (tempLocation != null
                                && isBetterLocation(tempLocation,
                                        location))
                            location = tempLocation;
                    }
                }
                if (isGPSEnabled) {

                    locationManager.requestSingleUpdate(
                            LocationManager.GPS_PROVIDER, this, null);
                    locationManager.requestLocationUpdates(
                            LocationManager.GPS_PROVIDER, MIN_TIME_BW_UPDATES,
                            MIN_DISTANCE_CHANGE_FOR_UPDATES, this);
                    Log.d("GPS Enabled", "GPS Enabled");
                    if (locationManager != null) {
                        Location tempLocation = locationManager
                                .getLastKnownLocation(LocationManager.GPS_PROVIDER);
                        if (tempLocation != null
                                && isBetterLocation(tempLocation,
                                        location))
                            location = tempLocation;
                    }
                }

            } catch (Exception e) {
                onTaskError(e.getMessage());
                e.printStackTrace();
            }
        } else {
            onOfflineResponse(requestData);
        }
    }

    public void stopUsingGPS() {
        if (locationManager != null) {
            locationManager.removeUpdates(LocationService.this);
        }
    }

    public boolean canGetLocation() {
        locationManager = (LocationManager) context
                .getSystemService(Context.LOCATION_SERVICE);
        isGPSEnabled = locationManager
                .isProviderEnabled(LocationManager.GPS_PROVIDER);

        // getting network status
        isNetworkEnabled = locationManager
                .isProviderEnabled(LocationManager.NETWORK_PROVIDER);
        return isGPSEnabled || isNetworkEnabled;
    }

    @Override
    public void onLocationChanged(Location location) {

        if (location != null
                && isBetterLocation(location, this.location)) {

            this.location = location;

        }
    }

    @Override
    public void onProviderDisabled(String provider) {
    }

    @Override
    public void onProviderEnabled(String provider) {
    }

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

    @Override
    public Object getResponseObject(Object location) {
        return location;
    }

    public static 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 > MIN_TIME_INTERVAL;
        boolean isSignificantlyOlder = timeDelta < -MIN_TIME_INTERVAL;
        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 provider
        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;
    }

}

在上面的课程中,我正在为GPS和网络注册一个位置监听器,因此onLocationChanged回调可以被其中一个或两个调用多次,我们只是将新的位置定位与我们已经拥有并保持最好的一个。

答案 5 :(得分:1)

主类:

public class AndroidLocationActivity extends Activity {

Button btnGPSShowLocation;
Button btnNWShowLocation;

AppLocationService appLocationService;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    appLocationService = new AppLocationService(
            AndroidLocationActivity.this);

    btnGPSShowLocation = (Button) findViewById(R.id.btnGPSShowLocation);
    btnGPSShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location gpsLocation = appLocationService
                    .getLocation(LocationManager.GPS_PROVIDER);

            if (gpsLocation != null) {
                double latitude = gpsLocation.getLatitude();
                double longitude = gpsLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (GPS): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();
            } else {
                showSettingsAlert("GPS");
            }

        }
    });

    btnNWShowLocation = (Button) findViewById(R.id.btnNWShowLocation);
    btnNWShowLocation.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View arg0) {

            Location nwLocation = appLocationService
                    .getLocation(LocationManager.NETWORK_PROVIDER);

            if (nwLocation != null) {
                double latitude = nwLocation.getLatitude();
                double longitude = nwLocation.getLongitude();
                Toast.makeText(
                        getApplicationContext(),
                        "Mobile Location (NW): \nLatitude: " + latitude
                                + "\nLongitude: " + longitude,
                        Toast.LENGTH_LONG).show();

            } else {
                showSettingsAlert("NETWORK");
            }

        }
    });

}

public void showSettingsAlert(String provider) {
    AlertDialog.Builder alertDialog = new AlertDialog.Builder(
            AndroidLocationActivity.this);

    alertDialog.setTitle(provider + " SETTINGS");

    alertDialog.setMessage(provider
            + " is not enabled! Want to go to settings menu?");

    alertDialog.setPositiveButton("Settings",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    Intent intent = new Intent(
                            Settings.ACTION_LOCATION_SOURCE_SETTINGS);
                    AndroidLocationActivity.this.startActivity(intent);
                }
            });

    alertDialog.setNegativeButton("Cancel",
            new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int which) {
                    dialog.cancel();
                }
            });

    alertDialog.show();
}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.main, menu);
    return true;

}

}

下一课:

public class AppLocationService extends Service implements LocationListener {

protected LocationManager locationManager;
Location location;

private static final long MIN_DISTANCE_FOR_UPDATE = 10;
private static final long MIN_TIME_FOR_UPDATE = 1000 * 60 * 2;

public AppLocationService(Context context) {
    locationManager = (LocationManager) context
            .getSystemService(LOCATION_SERVICE);
}

public Location getLocation(String provider) {
    if (locationManager.isProviderEnabled(provider)) {
        locationManager.requestLocationUpdates(provider,
                MIN_TIME_FOR_UPDATE, MIN_DISTANCE_FOR_UPDATE, this);
        if (locationManager != null) {
            location = locationManager.getLastKnownLocation(provider);
            return location;
        }
    }
    return null;
}

@Override
public void onLocationChanged(Location location) {
}

@Override
public void onProviderDisabled(String provider) {
}

@Override
public void onProviderEnabled(String provider) {
}

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

@Override
public IBinder onBind(Intent arg0) {
    return null;
}

}

不要忘记添加你的清单。

<!-- to get location using GPS -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

<!-- to get location using NetworkProvider -->
<uses-permission android:name="android.permission.INTERNET" />

答案 6 :(得分:-3)

有更好的方法来实现它在android开发者网站上提到的 http://developer.android.com/guide/topics/location/strategies.html