GPS Android - 仅获取一次定位

38
有没有一种方法可以一次性访问GPS,而不是不断检查位置更新的循环程序?
在我的场景中,我只关心找到当前坐标,而不是与GPS卫星进行持续连接。有人有任何想法如何做到这一点吗?提前谢谢。
2个回答

42

不要使用getLastKnownLocation方法,因为它可能会返回null或旧数据。

此代码仅在按下按钮时获取位置一次,而不是每次都获取。人们过去通常会在每个实例中保持位置监听器处于监听状态,这会消耗电池寿命,所以请使用我通过大量研究发布的代码片段:

// get the text view and buttons from the xml layout
Button button = (Button) findViewById(R.id.btnGetLocation);
final TextView latitude = (TextView) findViewById(R.id.textview4);
final TextView longitude = (TextView) findViewById(R.id.textview5);
final LocationListener locationListener = new LocationListener() {
        @Override
        public void onLocationChanged(Location location) {
            mlocation = location;
            Log.d("Location Changes", location.toString());
            latitude.setText(String.valueOf(location.getLatitude()));
            longitude.setText(String.valueOf(location.getLongitude()));
        }

        @Override
        public void onStatusChanged(String provider, int status, Bundle extras) {
            Log.d("Status Changed", String.valueOf(status));
        }

        @Override
        public void onProviderEnabled(String provider) {
            Log.d("Provider Enabled", provider);
        }

        @Override
        public void onProviderDisabled(String provider) {
            Log.d("Provider Disabled", provider);
        }
    };

    // Now first make a criteria with your requirements
    // this is done to save the battery life of the device
    // there are various other other criteria you can search for..
    Criteria criteria = new Criteria();
    criteria.setAccuracy(Criteria.ACCURACY_COARSE);
    criteria.setPowerRequirement(Criteria.POWER_LOW);
    criteria.setAltitudeRequired(false);
    criteria.setBearingRequired(false);
    criteria.setSpeedRequired(false);
    criteria.setCostAllowed(true);
    criteria.setHorizontalAccuracy(Criteria.ACCURACY_HIGH);
    criteria.setVerticalAccuracy(Criteria.ACCURACY_HIGH);

    // Now create a location manager
    final LocationManager locationManager = (LocationManager)getSystemService(Context.LOCATION_SERVICE);

   // This is the Best And IMPORTANT part
    final Looper looper = null;

   // Now whenever the button is clicked fetch the location one time
   button.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            locationManager.requestSingleUpdate(criteria, locationListener, looper);
       }
   });

2
那太好了。 - Udara Kasun
1
@msmukesh4 只是为了明确起见,这个位置监听器只会工作一次,对吧?我的意思是...如果我点击按钮一次,它将给出一个单独的更新,并且即使位置发生变化,它也不会再次更新,对吧? - Mohd Naved
1
那是一个非常好的答案。非常感谢你。 - user1222936
1
兄弟,你救了我的命。我不知道为什么这个答案没有被采纳。非常感谢! - CodeAlo
@msmukesh4 回答很好,但这会冻结用户界面(主线程负载过重),而使用异步调用无法获取位置更新。 - Deepak Kumar
显示剩余3条评论

40

首先检查最近的已知位置是否仍然有效。如果不是,我认为您必须设置onLocationChanged监听器,但一旦您获得第一个有效位置,就可以始终停止更新流。

附加说明

public class Example extends Activity implements LocationListener {
    LocationManager mLocationManager;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);

        mLocationManager = (LocationManager) getSystemService(Context.LOCATION_SERVICE);

        Location location = mLocationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);
        if(location != null && location.getTime() > Calendar.getInstance().getTimeInMillis() - 2 * 60 * 1000) {
            // Do something with the recent location fix
            //  otherwise wait for the update below
        }
        else {
            mLocationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, this);
        }
    }

    public void onLocationChanged(Location location) {
        if (location != null) {
            Log.v("Location Changed", location.getLatitude() + " and " + location.getLongitude());
            mLocationManager.removeUpdates(this);
        }
    }

    // Required functions    
    public void onProviderDisabled(String arg0) {}
    public void onProviderEnabled(String arg0) {}
    public void onStatusChanged(String arg0, int arg1, Bundle arg2) {}
}

是的,这正是我的问题,我设置了一个 onLocationChanged,我想只获取一个有效的位置..如何停止更新流?有什么命令吗?谢谢。 - progdoc
简短回答是LocationManager.removeUpdates()。更详细的答案,请看我的更新。 - Sam
在上面的if条件语句中,location.getTime() > Calendar.getInstance().getTimeInMillis() - 2 * 60 * 1000 是什么意思? - Om3ga
2
由于时间以毫秒为单位计量,乘以1000即可得到秒数,再乘以60即可得到1分钟,再次乘以2即可得到总共2分钟的时间。因此,if语句检查位置是否在2分钟前接收到。 - Ymabob
一种好的方法,但我在自己的项目中注意到的是,如果最后已知的位置没有改变(即使从时间上来看它已经过期),那么 onLocationChanged 事件将不会触发。因此,如果你只依赖于这个调用来做任何事情,它将无法被执行,因为事件没有被触发。 - mcy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接