我的应用程序会显示一个导航图,如果当前的GPS位置可用,它也会显示出来。我在沿着已知路线行驶的船上测试了这个。有时会显示正确的位置。有时我会得到一个旧的GPS位置,即使是在要求重新阅读的情况下。有时,它似乎会卡在旧位置进行多次阅读。发生这种情况时,我运行了谷歌地图,它似乎清除了错误,我又开始得到一个新的位置。
// try to look at GPS....
status1 = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
if (status1 != PackageManager.PERMISSION_GRANTED)
{ requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION},10);
}
status2 = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
Object cancellationToken = null;
if (status2 == PackageManager.PERMISSION_GRANTED)
fusedLocationClient.getCurrentLocation(PRIORITY_HIGH_ACCURACY, (CancellationToken) cancellationToken)
.addOnSuccessListener(this, location -> // using lambda expression...
{ if (location != null)
{ GPSLatitude = location.getLatitude();
GPSLongitude = location.getLongitude();
gotGPS = true;
//if we have a location, and it is on chart, draw the blue dot....
谷歌地图比我更擅长阅读GPS。我应该考虑另一种方法吗?
我建议试着每隔一段时间更新一次
if (ActivityCompat.checkSelfPermission(mActivity, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(mActivity, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 1000, 0, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
log.w("Get locations:: "+ location.getLatitude());
newLocation(location);
// locationManager.removeUpdates(this);
}
@Override
public void onStatusChanged(String provider, int status, Bundle extras) {
}
@Override
public void onProviderEnabled(String provider) {
}
@Override
public void onProviderDisabled(String provider) {
}
});
问题在于,对于跟踪资产位置的应用程序,您没有使用推荐的方法。您已经尝试通过getCurrentLocation
方法手动更新位置。事实上,getCurrentLocation
方法是在不需要不断更新位置时使用的。例如,您只需要一个新的用户位置,用于注册、附近搜索等。
当您需要不断跟踪资产时,您应该通过Request estLocationUpdate
方法侦听位置更新。根据官方推荐
适当使用位置信息可能对您的应用程序的用户有益。例如,如果您的应用程序帮助用户在步行或开车时找到路,或者如果您的应用程序跟踪资产的位置,它需要定期获取设备的位置。
这里我实现了一个完整的示例
package com.example.locationtracker;
import android.Manifest;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.recyclerview.widget.LinearLayoutManager;
import com.example.locationtracker.databinding.ActivityMainBinding;
import com.google.android.gms.location.FusedLocationProviderClient;
import com.google.android.gms.location.LocationCallback;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationResult;
import com.google.android.gms.location.LocationServices;
import com.google.android.material.snackbar.Snackbar;
import java.util.ArrayList;
public class MainActivity extends AppCompatActivity {
private boolean isTracking = false;
private FusedLocationProviderClient fusedLocationClient;
private LocationCallback locationCallback;
private LocationRequest locationRequest;
private LocationRecycleViewAdapter locationRecycleViewAdapter;
private final ArrayList<String> locations = new ArrayList<>();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
com.example.locationtracker.databinding.ActivityMainBinding binding = ActivityMainBinding.inflate(getLayoutInflater());
setContentView(binding.getRoot());
binding.location.setLayoutManager(new LinearLayoutManager(getApplicationContext()));
locationRecycleViewAdapter = new LocationRecycleViewAdapter(getApplicationContext(), locations);
binding.location.setAdapter(locationRecycleViewAdapter);
fusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(12000);
locationRequest.setFastestInterval(2000);
locationRequest.setWaitForAccurateLocation(true);
locationRequest.setSmallestDisplacement(0);
locationCallback = new LocationCallback() {
@Override
public void onLocationResult(@NonNull LocationResult locationResult) {
for (Location location : locationResult.getLocations()) {
System.out.println("New Location Received");
String loc = String.format("lat: %s, lon: %s", location.getLatitude(), location.getLongitude());
locations.add(loc);
locationRecycleViewAdapter.notifyDataSetChanged();
/*locationRecycleViewAdapter = new LocationRecycleViewAdapter(getApplicationContext(), locations);
binding.location.setAdapter(locationRecycleViewAdapter);*/
}
}
};
binding.fab.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (!isTracking) {
Snackbar.make(view, "Starting Location Tracking", Snackbar.LENGTH_LONG)
.show();
startLocationUpdates();
} else {
Snackbar.make(view, "Stopping Location Tracking", Snackbar.LENGTH_LONG)
.show();
stopLocationUpdates();
}
}
});
}
@Override
protected void onResume() {
super.onResume();
if (isTracking) {
startLocationUpdates();
}
}
private static final int PERMISSION_REQUEST_CODE = 200;
private void startLocationUpdates() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED || ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
requestPermissions(new String[]{Manifest.permission.ACCESS_FINE_LOCATION, Manifest.permission.ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
return;
}
fusedLocationClient.requestLocationUpdates(locationRequest,
locationCallback,
Looper.getMainLooper());
isTracking = true;
}
private void stopLocationUpdates() {
fusedLocationClient.removeLocationUpdates(locationCallback);
isTracking = false;
}
}
AndroidManifest。xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.locationtracker">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<application
android:allowBackup="false"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.LocationTracker">
<activity
android:name=".MainActivity"
android:exported="true"
android:label="@string/app_name"
android:theme="@style/Theme.LocationTracker.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
输出
确保您同时拥有精细和粗略位置权限
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
如果您想在最快的时间间隔内检索资产的位置,粗略定位和优先级高精度非常重要。以下设置也非常重要。
locationRequest = LocationRequest.create();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(12000);
locationRequest.setFastestInterval(2000);
locationRequest.setWaitForAccurateLocation(true);
locationRequest.setSmallestDisplacement(0);
欢迎加入谷歌FusedLocationProvider的受害者俱乐部,我建议您与GPS提供商一起使用LocationManager。可用于请求活动中的位置
fun getLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
// do proper permissions handling
return
}
val locationManager = getSystemService(Context.LOCATION_SERVICE) as LocationManager
val gpsEnabled = locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
if (gpsEnabled) {
// Register for location updates
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 1000, 0.0f, locationListener)
// Or get last known location
val location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER)
}
}
private val locationListener = LocationListener {
// Do something with the location
}
在某些情况下,我发现
FusedLocationProvider
非常不准确,在最近的一次体验中,我无法在我的应用程序中使用FusedLocationProvider
获得GPS锁,当我打开谷歌地图时,GPS锁销立即出现。所以我做了一些研究,确信我发现了FusedLocationProvider
的缺点,最后我使用了LocationManager
,至于它为什么会这样,我遇到的一些问题是
它的融合了
,这意味着它使用多个来源(WiFi、网络、GPS等),它将选择一个它认为合适的来源,或者在决定位置时混合使用所有来源
FusedLocationProvider
的最大卖点是它针对电池使用进行了优化,因此只要它能为您提供一个位置(通常是准确的,但并不总是准确的),如果它确定通话会给电池带来不必要的负载,它就不会影响硬件 - 它似乎也在做位置缓存,这可能是过时的位置修复的一个原因,在这个问题的评论中,一个用户分享了他们对这个案例的体验
FusedLocationProvider
如何影响早期使用LocationManager的数据采集应用程序的定位精度
FusedLocationProvider
由于缓存而导致问题
为什么
LocationManager
提供了更准确的位置
在某些情况下,
FusedLocationProvider
的性能如何
FusedLocationProvider
如何提供不准确的结果,请参阅投票数第二高的答案
我试图隐藏Actionbar并改用工具栏,但如果我更改Theme.appcompat.light.NoActionBar,它确实会隐藏,但应用程序在行setContentView(r.layout.activity_main)处崩溃; 尽管它确实使用getSupportActionBar()隐藏。hide();但我不能用这个代码 Toolbar Toolbar=(Toolbar)findViewB
我正在尝试通过gradle构建我的应用程序,在运行: 知道吗?
我在Heroku上托管了这个java discordbot,升级到最新版本的JDA后,我不得不将更改为。当从intellij运行我的机器人时,它可以毫无问题地工作,但从Heroku执行它时,它会给我“java.lang.NoSuchmetodError:'net.dv8tion.jda.api.entities.AudioChannelnet.dv8tion.jda.api.entities.Gu
我有一个带有索引的ISODate()类型字段的数据库(我也用字符串字段尝试了这个实验——结果相同)。我使用的是MongoDB(4. x)的开源版本,当我进行查询/排序以查找最大_finish_time时,除非我指定提示,否则不会使用索引。 我的问题是: 这解释为: 扫描整个收藏。当我为可用索引指定提示时,如: 我得到了查询计划: 它使用索引。我不想在查询中添加hint(),我对它为什么拒绝使用索引
我想在RxJava中实现一个下载一些文件的处理队列。我想下载的文件数量可能高达100个左右。 一切都是在Android上使用RxJava 1.1.1开发的 我做错了什么?