您好我正在创建一个能够获取用户位置的Android地图应用程序,但是当用户打开他们的地图时,有时位置不准确并且会慢慢找到您的位置。
我试过这个。但它仍然称处理程序和TOASTS不会停止。
default_
我添加了一个每5秒运行一次的处理程序来检查用户位置,当getAccuracy数据等于或小于100时,它将停止。我该怎么做?
答案 0 :(得分:3)
getCurrentLocation可以调用handler.removeCallbacks(runnable);
,但是runnable将始终调用handler.postDelayed(this, 3000);
。
要解决这个问题,必须要有一些条件让Runnable检查它是否应该再次发布。
解决方案是让getCurrentLocation返回一个布尔值,指示它是否成功(足够):
private boolean getCurrentLocation() {
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED &&
ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
return false;
}
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
longitude = location.getLongitude();
latitude = location.getLatitude();
moveMap();
Integer loc = Math.round(location.getAccuracy());
textings.setText(Integer.toString(loc));
if(loc <= 100) {
handler.removeCallbacks(runnable);
Toast.makeText(mapsPage.this, "HANDLER STOPPED", Toast.LENGTH_SHORT).show();
return true;
}
}
return false;
}
然后在Runnable检查中是否需要另一次运行:
@Override
public void run() {
if(!getCurrentLocation()) {
handler.postDelayed(this, 3000);
}
}
然而,所有这些,您应该只检查LocationListener的onLocationChanged中的位置,并在该位置足够准确时执行某些操作。那么你根本不需要Runnable。
答案 1 :(得分:2)
你绝对应该接受RobCo的答案作为正确的答案,因为它直接解决你的问题,并提供额外的关键洞察力(即你根本不需要Runnable)。
但是,我很好奇RobCo的方法是什么样的,所以我创建了一个可能的实现方法。
事实证明,如果我们避开Runnable并依赖Google的回调,我们就可以使用更新的位置提供程序API(LocatonServices.FusedLocationApi)。可以消除旧的LocationManager API。
因此,在此实现中,我让Google位置服务在位置发生变化时触发回调(而不是使用来自客户端的定期民意调查):
public class MainActivity extends AppCompatActivity implements
ActivityCompat.OnRequestPermissionsResultCallback, GoogleApiClient.OnConnectionFailedListener,
GoogleApiClient.ConnectionCallbacks,
com.google.android.gms.location.LocationListener {
private static final String TAG = MainActivity.class.getSimpleName();
private static final int PERMISSION_REQUEST_CODE = 10001;
public static final int LOCATION_UPDATE_INTERVAL = 5000; // milliseconds
private GoogleApiClient googleApiClient;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
googleApiClient = new GoogleApiClient.Builder(this, this, this)
.enableAutoManage(this, this)
.addApi(LocationServices.API)
.build();
googleApiClient.connect();
}
private void requestPermission() {
ActivityCompat.requestPermissions(this,
new String[]{ACCESS_FINE_LOCATION, ACCESS_COARSE_LOCATION}, PERMISSION_REQUEST_CODE);
}
private void initLocationServices() {
try {
// make initial, synchronous request for current location
Location location = LocationServices.FusedLocationApi.getLastLocation(googleApiClient);
if (location != null) {
moveMap(location);
}
// request future location updates which will come in as callbacks later, when available
LocationRequest locationRequest = new LocationRequest();
locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
locationRequest.setInterval(LOCATION_UPDATE_INTERVAL);
LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
} catch (SecurityException se) {
Log.w(TAG, "App does not have sufficient permission to request location. " +
"Requesting permission now...");
requestPermission();
}
}
private void moveMap(Location location) {
Log.v(TAG, "moveMap");
// TODO: actual map moving code goes here
}
@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {
Log.e(TAG, "Connection failed:" + connectionResult.getErrorMessage());
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == PERMISSION_REQUEST_CODE && grantResults[0] == PERMISSION_GRANTED && grantResults[1] == PERMISSION_GRANTED) {
Log.v(TAG, "User granted permission. Will request current location.");
initLocationServices();
} else {
Log.w(TAG, "User did not grant permission. Cannot request location. Cannot proceed.");
}
}
@Override
public void onLocationChanged(Location newLocation) {
Log.v(TAG, "onLocationChanged:" + newLocation.toString());
moveMap(newLocation);
}
@Override
public void onConnected(@Nullable Bundle bundle) {
if ((ActivityCompat.checkSelfPermission(this, ACCESS_FINE_LOCATION) == PERMISSION_GRANTED)
&& (ActivityCompat.checkSelfPermission(this, ACCESS_COARSE_LOCATION) == PERMISSION_GRANTED)) {
initLocationServices();
} else {
Log.w(TAG, "onCreate: requesting sufficient permission from user");
requestPermission();
}
}
@Override
public void onConnectionSuspended(int i) {
Log.v(TAG, "onConnectionSuspended");
}
}
这个特定实现的缺点是MainActivity实现了几个接口并且增加了一些混淆(这些方法在这里做了什么?等等)
说不上。也许它很有用。无论如何,祝你的应用好运。