每次调用函数时如何获取当前 gps 位置?
How can I get the current gps location every time a function is called?
我想做的是每次调用函数时获取位置经纬度。据我所知,最好的方法是将位置更新保留几秒钟以获取正确的修复,然后将其禁用,但我无法在我的应用程序中使用它。
到目前为止,我一直设法在每次调用 displayData 函数时获取 phone 的最后已知位置,但我无法克服我在调用时出现的所有错误我正在尝试更改为 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
}
}
以下是我对您的问题的理解:
- 您想要按需获取 GPS 位置,但是:
- 您不希望 GPS 一直 运行,并且:
- 您接受 GPS 必须 运行 短时间
尽量不要考虑 "function that returns the phone's current location",因为这意味着它是一个简单的同步操作,可以提供无阻塞的答案。我们不能在这里这样做。
相反,我建议您将其更多地视为 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()
returns 立即)
- 状态机最终会收敛到一个答案(前提是 GPS 功能正常)
- 一旦我们获得了所需的信息,GPS 就会关闭
您可能要考虑对此方案进行一些改进:
- 一种避免重复调用
requestLocationUpdates()
的方法,如果 displayData()
在上一个请求已解决之前被调用
- 处理
onSuccess()
方法中引用的 UI 元素不再可用的情况 b/c Activity 在此期间有 onDestroy()'d
GPS 请求是 "in progress"
- 如果需要清理等,取消正在进行的请求
我遵循了 Markus Kauppinen 的方法,以适合我的应用程序的时间间隔请求位置更新,然后在有来自蓝牙的传入数据时使用获取最后已知位置。所以我刚刚在 activity 中添加了以下内容:
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
}
我想做的是每次调用函数时获取位置经纬度。据我所知,最好的方法是将位置更新保留几秒钟以获取正确的修复,然后将其禁用,但我无法在我的应用程序中使用它。
到目前为止,我一直设法在每次调用 displayData 函数时获取 phone 的最后已知位置,但我无法克服我在调用时出现的所有错误我正在尝试更改为 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
}
}
以下是我对您的问题的理解:
- 您想要按需获取 GPS 位置,但是:
- 您不希望 GPS 一直 运行,并且:
- 您接受 GPS 必须 运行 短时间
尽量不要考虑 "function that returns the phone's current location",因为这意味着它是一个简单的同步操作,可以提供无阻塞的答案。我们不能在这里这样做。
相反,我建议您将其更多地视为 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()
returns 立即) - 状态机最终会收敛到一个答案(前提是 GPS 功能正常)
- 一旦我们获得了所需的信息,GPS 就会关闭
您可能要考虑对此方案进行一些改进:
- 一种避免重复调用
requestLocationUpdates()
的方法,如果displayData()
在上一个请求已解决之前被调用 - 处理
onSuccess()
方法中引用的 UI 元素不再可用的情况 b/c Activity 在此期间有onDestroy()'d
GPS 请求是 "in progress" - 如果需要清理等,取消正在进行的请求
我遵循了 Markus Kauppinen 的方法,以适合我的应用程序的时间间隔请求位置更新,然后在有来自蓝牙的传入数据时使用获取最后已知位置。所以我刚刚在 activity 中添加了以下内容:
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
}