有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何在每次调用函数时获取当前gps位置?

我想做的是在每次调用函数时获取位置纬度和经度。据我所知,最好的方法是将位置更新保留几秒钟,以获得正确的修复,然后禁用它,但我无法在我的应用程序中使其工作

到目前为止,我一直在设法在每次调用displayData功能时获取手机的最后一个已知位置,但我无法克服在尝试更改为RequestLocationUpdate时出现的所有错误。我在这里所做的就是调用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) 个答案

  1. # 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就会关闭

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

    • 如果displayData()在前一个请求解决之前被调用,则避免重复调用requestLocationUpdates()的一种方法
    • 处理onSuccess()方法中提到的UI元素不再可用的情况b/c活动在GPS请求“进行中”期间onDestroy()'d
    • 如果需要清理,取消正在进行的请求等
  2. # 2 楼答案

    我遵循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
        }