我需要通过GPS程序获得我的当前位置。 我怎样才能做到呢?


当前回答

自2020年9月23日起,play-services-location版本17.1.0包含了FusedLocationProviderClient.getCurrentLocation()方法,这是获得当前位置的推荐和直接的方法:

返回设备上的单个当前位置固定。与返回缓存位置的getLastLocation()不同,此方法可能导致设备上的活动位置计算。如果能在合理的时间内(几十秒)确定设备位置,将返回一个新的位置,否则将返回null。

关于详细的例子,看看codingjeremy的回答和GitHub上的官方Android位置示例- Current location (Kotlin)。

其他回答

既然谷歌Play位置服务已经推出,我建议开发者开始使用新的融合位置提供商。你会发现它更容易使用和更准确。请观看谷歌I/O视频《超越蓝点:Android位置的新功能》,由两位创建了新的谷歌Play位置服务API的人制作。

I've been working with location APIs on a number of mobile platforms, and I think what these two guys have done is really revolutionary. It's gotten rid of a huge amount of the complexities of using the various providers. Stack Overflow is littered with questions about which provider to use, whether to use last known location, how to set other properties on the LocationManager, etc. This new API that they have built removes most of those uncertainties and makes the location services a pleasure to use.

I've written an Android app that periodically gets the location using Google Play location services and sends the location to a web server where it is stored in a database and can be viewed on Google Maps. I've written both the client software (for Android, iOS, Windows Phone and Java ME) and the server software (for ASP.NET and SQL Server or PHP and MySQL). The software is written in the native language on each platform and works properly in the background on each. Lastly, the software has the MIT License. You can find the Android client here:

https://github.com/nickfox/GpsTracker/tree/master/phoneClients/android

通过-获取gps位置

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

LocationListener locationListener = new LocationListener() 
{

            @Override
            public void onStatusChanged(String provider, int status, Bundle extras) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderEnabled(String provider) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onProviderDisabled(String provider) {
                // TODO Auto-generated method stub

            }

            @Override
            public void onLocationChanged(Location location) {
                // TODO Auto-generated method stub
                double latitude = location.getLatitude();
                double longitude = location.getLongitude();
                double speed = location.getSpeed(); //spedd in meter/minute
                speed = (speed*3600)/1000;      // speed in km/minute               Toast.makeText(GraphViews.this, "Current speed:" + location.getSpeed(),Toast.LENGTH_SHORT).show();
            }
        };

        locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListener);

}

简单的找到写代码在位置方法

public void onLocationChanged(Location location) {
    if (mCurrLocationMarker != null) {
        mCurrLocationMarker.remove();
    }


    //Place current location marker
    LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());
    MarkerOptions markerOptions = new MarkerOptions();
    markerOptions.position(latLng);
    markerOptions.title("Current Position");
    markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_RED));
    mCurrLocationMarker = mMap.addMarker(markerOptions);

    //move map camera
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
    mMap.animateCamera(CameraUpdateFactory.zoomTo(18));

    PolylineOptions pOptions = new PolylineOptions()
            .width(5)
            .color(Color.GREEN)
            .geodesic(true);
    for (int z = 0; z < routePoints.size(); z++) {
        LatLng point = routePoints.get(z);
        pOptions.add(point);
    }
    line = mMap.addPolyline(pOptions);
    routePoints.add(latLng);
}

如果你正在为Android创建新的位置项目,你应该使用新的谷歌Play位置服务。它更准确,使用起来更简单。

几年来,我一直致力于一个开源的GPS跟踪器项目,GpsTracker。我最近更新了它,以处理来自Android、iOS、Windows Phone和Java ME手机的定期更新。它功能齐全,可以满足您的需要,并且拥有MIT许可证。

GpsTracker中的Android项目使用了新的谷歌播放服务,还有两个服务器堆栈(ASP。NET和PHP)来让你追踪这些手机。

因为我不喜欢其他答案中的一些代码,下面是我的简单解决方案。这个解决方案意味着在活动或服务中可用来跟踪位置。它确保它永远不会返回太陈旧的数据,除非您显式地请求陈旧的数据。它既可以在回调模式下运行,以便在我们收到更新时获得更新,也可以在轮询模式下运行,以便轮询最新的信息。

通用LocationTracker接口。允许我们有多种类型的位置跟踪器,并轻松插入适当的一个:

package com.gabesechan.android.reusable.location;

import android.location.Location;

public interface LocationTracker {
    public interface LocationUpdateListener{
        public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime);
    }

    public void start();
    public void start(LocationUpdateListener update);

    public void stop();

    public boolean hasLocation();

    public boolean hasPossiblyStaleLocation();

    public Location getLocation();

    public Location getPossiblyStaleLocation();

}

ProviderLocationTracker——这个类将跟踪GPS或NETWORK的位置。

package com.gabesechan.android.reusable.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationListener;
import android.location.LocationManager;
import android.os.Bundle;

public class ProviderLocationTracker implements LocationListener, LocationTracker {

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

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

    private LocationManager lm;

    public enum ProviderType{
        NETWORK,
        GPS
    };    
    private String provider;

    private Location lastLocation;
    private long lastTime;

    private boolean isRunning;

    private LocationUpdateListener listener;

    public ProviderLocationTracker(Context context, ProviderType type) {
        lm = (LocationManager)context.getSystemService(Context.LOCATION_SERVICE);
        if(type == ProviderType.NETWORK){
            provider = LocationManager.NETWORK_PROVIDER;
        }
        else{
            provider = LocationManager.GPS_PROVIDER;
        }
    }

    public void start(){
        if(isRunning){
            //Already running, do nothing
            return;
        }

        //The provider is on, so start getting updates.  Update current location
        isRunning = true;
        lm.requestLocationUpdates(provider, MIN_UPDATE_TIME, MIN_UPDATE_DISTANCE, this);
        lastLocation = null;
        lastTime = 0;
        return;
    }

    public void start(LocationUpdateListener update) {
        start();
        listener = update;

    }


    public void stop(){
        if(isRunning){
            lm.removeUpdates(this);
            isRunning = false;
            listener = null;
        }
    }

    public boolean hasLocation(){
        if(lastLocation == null){
            return false;
        }
        if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
            return false; //stale
        }
        return true;
    }

    public boolean hasPossiblyStaleLocation(){
        if(lastLocation != null){
            return true;
        }
        return lm.getLastKnownLocation(provider)!= null;
    }

    public Location getLocation(){
        if(lastLocation == null){
            return null;
        }
        if(System.currentTimeMillis() - lastTime > 5 * MIN_UPDATE_TIME){
            return null; //stale
        }
        return lastLocation;
    }

    public Location getPossiblyStaleLocation(){
        if(lastLocation != null){
            return lastLocation;
        }
        return lm.getLastKnownLocation(provider);
    }

    public void onLocationChanged(Location newLoc) {
        long now = System.currentTimeMillis();
        if(listener != null){
            listener.onUpdate(lastLocation, lastTime, newLoc, now);
        }
        lastLocation = newLoc;
        lastTime = now;
    }

    public void onProviderDisabled(String arg0) {

    }

    public void onProviderEnabled(String arg0) {

    }

    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {
    }
}

这是FallbackLocationTracker,它将通过GPS和NETWORK进行跟踪,并使用任何更准确的位置。

package com.gabesechan.android.reusable.location;

import android.content.Context;
import android.location.Location;
import android.location.LocationManager;

public class FallbackLocationTracker  implements LocationTracker, LocationTracker.LocationUpdateListener {


    private boolean isRunning;

    private ProviderLocationTracker gps;
    private ProviderLocationTracker net;

    private LocationUpdateListener listener;

    Location lastLoc;
    long lastTime;

    public FallbackLocationTracker(Context context) {
        gps = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.GPS);
        net = new ProviderLocationTracker(context, ProviderLocationTracker.ProviderType.NETWORK);
    }

    public void start(){
        if(isRunning){
            //Already running, do nothing
            return;
        }

        //Start both
        gps.start(this);
        net.start(this);
        isRunning = true;
    }

    public void start(LocationUpdateListener update) {
        start();
        listener = update;
    }


    public void stop(){
        if(isRunning){
            gps.stop();
            net.stop();
            isRunning = false;
            listener = null;
        }
    }

    public boolean hasLocation(){
        //If either has a location, use it
        return gps.hasLocation() || net.hasLocation();
    }

    public boolean hasPossiblyStaleLocation(){
        //If either has a location, use it
        return gps.hasPossiblyStaleLocation() || net.hasPossiblyStaleLocation();
    }

    public Location getLocation(){
        Location ret = gps.getLocation();
        if(ret == null){
            ret = net.getLocation();
        }
        return ret;
    }

    public Location getPossiblyStaleLocation(){
        Location ret = gps.getPossiblyStaleLocation();
        if(ret == null){
            ret = net.getPossiblyStaleLocation();
        }
        return ret;
    }

    public void onUpdate(Location oldLoc, long oldTime, Location newLoc, long newTime) {
        boolean update = false;

        //We should update only if there is no last location, the provider is the same, or the provider is more accurate, or the old location is stale
        if(lastLoc == null){
            update = true;
        }
        else if(lastLoc != null && lastLoc.getProvider().equals(newLoc.getProvider())){
            update = true;
        }
        else if(newLoc.getProvider().equals(LocationManager.GPS_PROVIDER)){
            update = true;
        }
        else if (newTime - lastTime > 5 * 60 * 1000){
            update = true;
        }

        if(update){
            if(listener != null){
                listener.onUpdate(lastLoc, lastTime, newLoc, newTime);                  
            }
            lastLoc = newLoc;
            lastTime = newTime;
        }

    }
}

由于两者都实现了LocationTracker接口,您可以很容易地改变使用哪一个的想法。要在轮询模式下运行类,只需调用start()。要在更新模式下运行它,请调用start(Listener)。

还可以看看我关于代码的博客文章