我需要每1分钟和每5米位移更新融合位置(我知道它的不良做法,但为了测试和显示在日志中)我开始服务按钮按下按钮我得到位置在logcat但只有一次。根据服务等级, onLocationChanged 应该每隔1分钟调用一次,但是即使我的GPS几乎每分钟开启一次也不会再次呼叫,然后在关机后关闭,但仍然没有位置在Logcat中更新。我需要服务类来保持更新位置而不影响UI或主线程
这是logcat,只显示一次位置更新
09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service onConnected Calling
09-16 03:13:37.125 10419-10419/com.example.com.pro_working1 D/===Location Service===: Start Location Update is Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Service OnLocationChanged Calling
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Here is Updated Locations: Latitude 28.5XXXXX Longitude 77.2XXXXX
09-16 03:13:38.315 10419-10419/com.example.com.pro_working1 D/===Location Service===: Sending Location Starting Accuracy is: 37.5
这是我的服务类
public class Location_Service_background extends Service implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener {
public static final String TAG = "===Location Service===";
GoogleApiClient apiClient;
Location mCurrentLocation;
LocationRequest locationRequest;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
GoogleApiSetup();
RequestLocationUpdates();
Log.d(TAG,"OnStartCommand Is Calling ");
return START_STICKY;
}
@Override
public IBinder onBind(Intent intent) {
// TODO: Return the communication channel to the service.
throw new UnsupportedOperationException("Not yet implemented");
}
@Override
public void onCreate() {
super.onCreate();
}
@Override
public void onDestroy() {
super.onDestroy();
if (apiClient.isConnected()){
Log.d(TAG,"Service On Destroy Calling and apiClient is Connected");
StopLocationUpdates();
apiClient.disconnect();
}
}
@Override
public void onLowMemory() {
super.onLowMemory();
}
@Override
public void onConnected(@Nullable Bundle bundle) {
Log.d(TAG,"Service onConnected Calling");
if (mCurrentLocation != null) {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(apiClient);
}
else {
Log.d(TAG,"Start Location Update is Calling");
StartLocationUpdate();
}
}
@Override
public void onConnectionSuspended(int i) {
Log.d(TAG,"Service OnConnectionSuspended Calling");
apiClient.connect();
}
@Override
public void onLocationChanged(Location location) {
Log.d(TAG,"Service OnLocationChanged Calling");
mCurrentLocation=location;
Log.d(TAG,"Here is Updated Locations: Latitude "+mCurrentLocation.getLatitude()+"Longitude "+mCurrentLocation.getLongitude());
String Latitude= String.valueOf(mCurrentLocation.getLatitude());
String Longitude=String.valueOf(mCurrentLocation.getLongitude());
String Accuracy=String.valueOf(mCurrentLocation.getAccuracy());
Log.d(TAG,"Sending Location Starting"+" "+" Accuracy is: "+mCurrentLocation.getAccuracy());
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.d(TAG,"Connection Failed Called "+connectionResult);
}
private synchronized void GoogleApiSetup() {
apiClient = new GoogleApiClient.Builder(this)
.addApi(LocationServices.API)
.addConnectionCallbacks(this)
.addOnConnectionFailedListener(this)
.build();
apiClient.connect();
}
private void RequestLocationUpdates() {
locationRequest = new LocationRequest();
//1 Min = 60 seconds AND 1000 milliseconds in 1 second
locationRequest.setInterval(60 * 1000);//5 Min 300 x 1000=300000
locationRequest.setFastestInterval(60 * 1000);//2 Min
locationRequest.setSmallestDisplacement(5);
locationRequest.setMaxWaitTime(60*1000);
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
}
private void StopLocationUpdates() {
LocationServices.FusedLocationApi.removeLocationUpdates(apiClient, this);
}
private void StartLocationUpdate() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return;
}
if (apiClient.isConnected()) {
LocationServices.FusedLocationApi.requestLocationUpdates(apiClient, locationRequest, this);
}
else {
Log.d(TAG,"GoogleApiClient is not connected yet.Please Try Again");
apiClient.connect();
}
}
}
答案 0 :(得分:3)
希望这有助于拯救某人在这个问题上遇到的挫败感。我正在使用FusedLocationAPI来请求位置更新和GoogleApiClient。我也是从服务中做到的。
您没有在您的定时间隔获得任何位置更新,因为setSmallestDisplacement()优先于其他参数。所以,即使你有
locationRequestTimeInterval = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(1)
.setFastestInterval(1)
.setMaxWaitTime(1)
.setSmallestDisplacement(5);
这将永远不会被触发,直到满足minimumDisplacement参数。
对此的解决方案是创建两个单独的LocationRequests ...一个仅关注距离,一个仅关注时间,并使用您的单个GoogleApiClient创建2个requestLocationUpdates命令,一个使用Time LocationRequest ,另一个使用距离位置请求。
所以你的2个LocationRequests看起来像这样:
locationRequestDistanceInterval = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setFastestInterval(0) // This MUST be set, otherwise no updates
.setSmallestDisplacement(LOCATION_REQUEST_MIN_DISTNACE);
locationRequestTimeInterval = LocationRequest.create()
.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
.setInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL)
.setFastestInterval(PROVIDER_GPS_UPDATE_TIME_INTERVAL);
然后在您的GoogleApiClients onConnected()中,您可以添加两个requestLocationUpdates()调用。
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestDistanceInterval, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// Handle your Distance based updates
});
LocationServices.FusedLocationApi.requestLocationUpdates(mLocationClient, locationRequestTimeInterval, new LocationListener() {
@Override
public void onLocationChanged(Location location) {
// Handle your Time based updates
}
});
您可以使用相同或单独的LocationListeners来处理每个请求的响应。 希望这会有所帮助。
答案 1 :(得分:0)
假设您实际上将设备移动到预期更新之间的距离超过5米,我认为LocationRequest类可能存在问题,其中setSmallestDisplacement()方法不是没有问题正常工作......或者至少它没有按预期工作。 (我在other posts)上看到了这些问题。
您可以通过删除setSmallestDisplacement()来自行检查距离,而不是:
onLocationChanged(){
double distance = // [ calculate distance between current lat/long and previous lat/long ]
if (distance > 5 meters) {
// do your normal onLocationChanged() code here
}
}
还有可能由于某种原因,FusedLocationProvider无法访问您的GPS而是使用wifi或手机信号塔......在这种情况下,5米距离太小而无法指定。你的日志说准确度是37.5米,因此看起来不够精确,无法测量5米。那么......也许你没有在你的清单中设置FINE访问权限?
也可能是运行时权限未正确完成的问题?您可以暂时将目标SDK设置为22以进行检查。
答案 2 :(得分:0)
小帮手谁知道可以用
int jarak = 10;
int interval = 5;
LocationRequest request = new LocationRequest();
request.setInterval(interval*1000); //update lokasi 10 detik
request.setFastestInterval(interval*1000); //dapat update dari aplikasi lain yg lebih cepat 10 detik
//request.setSmallestDisplacement(1); //diupdate jika berpindah 1 meter
request.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
FusedLocationProviderClient client = LocationServices.getFusedLocationProviderClient(this);
int permission = ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION);
if(permission == PackageManager.PERMISSION_GRANTED) {
client.requestLocationUpdates(request, new LocationCallback() {
@Override
public void onLocationResult(LocationResult locationResult) {
List<Location> locationList = locationResult.getLocations();
if (locationList.size() > 0) {
Location locationCurrent = locationList.get(locationList.size() - 1);
double latitude = locationCurrent.getLatitude();
double longitude = locationCurrent.getLongitude();
double lastlatitude = Double.parseDouble(prefs.getString("lastlatitude","0"));
double lastlongitude = Double.parseDouble(prefs.getString("lastlongitude","0"));
Location startPoint=new Location("LokasiA");
startPoint.setLatitude(latitude);
startPoint.setLongitude(longitude);
Location endPoint = new Location("LokasiB");
endPoint.setLatitude(lastlatitude);
endPoint.setLongitude(lastlongitude);
double distance = startPoint.distanceTo(endPoint);
Log.d(tag, "location update last " + endPoint);
if(distance > jarak) {
Log.d(tag, "location update new" + startPoint);
Log.d(tag, "location dest " + distance);
SharedPreferences.Editor editor = prefs.edit();
editor.putString("lastlatitude", String.valueOf(latitude));
editor.putString("lastlongitude", String.valueOf(longitude));
editor.apply();
Log.i("getLatitude:",String.valueOf(locationCurrent.getLatitude()) );
Log.i("getLongitude:",String.valueOf(locationCurrent.getLongitude()) );
}
}
}
},null);
}