每次调用函数时,如何获取当前的GPS位置?

时间:2018-12-04 14:01:52

标签: java android geolocation

我要做的是每次调用函数时获取位置的纬度和经度。据我了解,执行此操作的最佳方法是将位置更新保留几秒钟以获取正确的修复,然后将其禁用,但是我无法使其在我的应用中正常工作。

到目前为止,我所管理的是每次调用displayData函数时都获得手机的最后一个已知位置,但是我无法克服尝试更改为时出现的所有错误。 requestLocationUpdates。我要做的就是在从蓝牙设备接收到数据时调用displayData函数,以获取位置并将数据+位置写入文件中。

有人可以帮我吗,因为所有指南都显示了位置更新时如何触发某些操作,但是我不想这样做。 我只想定期找一个正确的位置...

private void displayData(final byte[] byteArray) {
try {

    mFusedLocationClient.getLastLocation()
            .addOnSuccessListener(this, new OnSuccessListener<Location>() {
                @Override
                public void onSuccess(Location location) {
                    // Got last known location. In some rare situations this can be null.

                    if (byteArray != null) {
                        String data = new String(byteArray);
                        tv.setText(n/2 + " measurements since startup...");
                        n += 1;

                        if (location != null) {
                            double lat = location.getLatitude();
                            double lng = location.getLongitude();
                            latitude = String.valueOf(lat);
                            longitude = String.valueOf(lng);
                        }

                        try
                        {
                            FileWriter fw = new FileWriter(textfile,true); //the true will append the new data
                            if (writeDate()) {
                                fw.write("\n");
                                fw.write(stringDate);
                                fw.write(data); //appends the string to the file
                            }
                            else {
                                fw.write(data); //appends the string to the file
                                fw.write(" - ");
                                fw.write(latitude);
                                fw.write(",");
                                fw.write(longitude);
                            }
                            fw.close();
                        }
                        catch(IOException ioe)
                        {
                            System.err.println("IOException: " + ioe.getMessage());
                        }


                        // find the amount we need to scroll. This works by
                        // asking the TextView's internal layout for the position
                        // of the final line and then subtracting the TextView's height
                        final int scrollAmount = tv.getLayout().getLineTop(
                                tv.getLineCount())
                                - tv.getHeight();
                        // if there is no need to scroll, scrollAmount will be <=0
                        if (scrollAmount > 0)
                            tv.scrollTo(0, scrollAmount);
                        else
                            tv.scrollTo(0, 0);
                    }
                }
            });

} catch (SecurityException e) {
    // lets the user know there is a problem with the gps
}
}

2 个答案:

答案 0 :(得分:1)

这是我对您的问题的了解:

  • 您希望按需提供GPS定位,但是:
  • 您不希望GPS持续运行,并且:
  • 您接受GPS必须在短时间内运行

请不要以“返回手机当前位置的功能”来思考,因为这意味着它是一种简单的同步操作,可以无障碍地提供答案。我们在这里不能做到这一点。

相反,我建议您将其更多地看作是FSM,因为在您致电displayData()到时间之间您需要任意时间(也许几秒钟,也许更多)您开始获得实时GPS修复。换句话说,displayData()不会直接产生位置;它将引发一系列事件,最终导致您获得位置。

您将不得不使用requestLocationUpdates()(或类似方法):

private void displayData(final byte[] byteArray) {
    //This call turns the GPS on, and returns immediately:
    locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, new LocationListener() {

        //This function gets called some time after displayData() returns (possibly
        //*way* after). It executes on the UI thread.
        public void onLocationChanged(Location location) {
            locationManager.removeUpdates(this); //Shut down the GPS

            //(Execute the remainder of your onSuccess() logic here.)

            //Now our state machine is complete, and everything is cleaned up.
            //We are ready for the next call to displayData().
        }

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

        public void onProviderEnabled(String provider) {}

        public void onProviderDisabled(String provider) {}
    );
}

那样,

  • 我们不会阻止UI线程(displayData()立即返回)
  • 状态机最终收敛到一个答案(前提是GPS可以正常工作)
  • 获得所需信息后,GPS将关闭

您可能需要考虑对该方案进行一些改进:

  • 如果在先前的请求已解决之前调用requestLocationUpdates(),则避免重复调用displayData()的方法
  • 处理在onSuccess()方法中引用的UI元素不再可用的情况,因为在GPS请求“进行中”期间活动拥有onDestroy()'d
  • 如果需要清理等,则可以取消正在进行的请求。

答案 1 :(得分:0)

我遵循Markus Kauppinen的方法,要求在适合我的应用程序的时间间隔内更新位置,然后在收到来自蓝牙的数据时仅使用获取最后的已知位置。所以我在活动中添加了以下内容:

    LocationRequest mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(30000);
    mLocationRequest.setFastestInterval(10000);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);

    LocationCallback mLocationCallback = new LocationCallback();



// Register the listener with the Location Manager to receive location updates
    try {
        mFusedLocationClient.requestLocationUpdates(mLocationRequest,
                mLocationCallback,
                null /* Looper */);

    }
    catch (SecurityException e) {
        // lets the user know there is a problem with the gps
    }