【问题标题】:Android: LocationServices.FusedLocationApi.requestLocationUpdates keep running and doesn't returnAndroid:LocationServices.FusedLocationApi.requestLocationUpdates 继续运行且不返回
【发布时间】:2016-08-25 06:56:32
【问题描述】:

我正在尝试检索当前用户位置以在地图上精确定位用户,因为这是模拟器第一次获取用户位置,LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient) 返回空位置。然后我尝试使用此 LocationServices.FusedLocationApi.requestLocationUpdates 获取位置,但是当我调试应用程序时,应用程序在调试窗口中说应用程序正在运行,所以我猜它无法将位置返回到 onLocationChanged(Location location) 函数。

当我运行应用程序而不是调试它时,它会给出这样的错误

08-25 02:44:06.988 2976-2985/com.example.bkoseoglu.findlocation D/dalvikvm: GC_FOR_ALLOC 释放

08-25 02:44:07.128 2976-3013/com.example.bkoseoglu.findlocation D/dalvikvm:GC_FOR_ALLOC 释放 4228K,37% 释放 9469K/14988K,暂停 5ms,总共5ms

08-25 02:44:07.128 2976-3013/com.example.bkoseoglu.findlocation I/dalvikvm-heap:将堆(碎片情况)增加到 13.397MB 以获得 4194316 字节 分配

08-25 02:44:07.148 2976-3013/com.example.bkoseoglu.findlocation D/dalvikvm: GC_FOR_ALLOC 释放

您知道可能是什么原因以及如何将位置检索到 onLocationChanged 吗?我还复制并粘贴了下面的代码,因为更新设置、间隔或其他内容可能有问题。

public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
        GoogleApiClient.OnConnectionFailedListener,LocationListener {

@Override
public void onLocationChanged(Location location) {
    handleNewLocation(location);
}

private GoogleApiClient mGoogleApiClient;
public static final String TAG = MapsActivity.class.getSimpleName();
private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000;
private LocationRequest mLocationRequest;
private GoogleMap mMap;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //updateValuesFromBundle(savedInstanceState)
    setContentView(R.layout.activity_maps);
    // Obtain the SupportMapFragment and get notified when the map is ready to be used.
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
            .findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);

    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .addConnectionCallbacks(this)
            .addOnConnectionFailedListener(this)
            .addApi(LocationServices.API)
            .build();
    // Create the LocationRequest object
    mLocationRequest = LocationRequest.create()
            .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
            .setInterval(10 * 1000)        // 10 seconds, in milliseconds
            .setFastestInterval(1 * 1000); // 1 second, in milliseconds
}

/*private void updateValuesFromBundle(Bundle savedInstanceState) {
    if (savedInstanceState != null) {
        // Update the value of mRequestingLocationUpdates from the Bundle, and
        // make sure that the Start Updates and Stop Updates buttons are
        // correctly enabled or disabled.
        if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
            mRequestingLocationUpdates = savedInstanceState.getBoolean(
                    REQUESTING_LOCATION_UPDATES_KEY);
            setButtonsEnabledState();
        }

        // Update the value of mCurrentLocation from the Bundle and update the
        // UI to show the correct latitude and longitude.
        if (savedInstanceState.keySet().contains(LOCATION_KEY)) {
            // Since LOCATION_KEY was found in the Bundle, we can be sure that
            // mCurrentLocationis not null.
            mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
        }

        // Update the value of mLastUpdateTime from the Bundle and update the UI.
        if (savedInstanceState.keySet().contains(LAST_UPDATED_TIME_STRING_KEY)) {
            mLastUpdateTime = savedInstanceState.getString(
                    LAST_UPDATED_TIME_STRING_KEY);
        }
        updateUI();
    }
}*/
/*public void onSaveInstanceState(Bundle savedInstanceState) {
    savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY,
            mRequestingLocationUpdates);
    savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
    savedInstanceState.putString(LAST_UPDATED_TIME_STRING_KEY, mLastUpdateTime);
    super.onSaveInstanceState(savedInstanceState);
}*/
protected void startLocationUpdates() {
    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    if(CheckGps()) {
        LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
    }
    else{
        Log.d("GPS NOT ENABLED ", "GPS NOT ENABLED ");
    }
}
/**
 * Manipulates the map once available.
 * This callback is triggered when the map is ready to be used.
 * This is where we can add markers or lines, add listeners or move the camera. In this case,
 * we just add a marker near Sydney, Australia.
 * If Google Play services is not installed on the device, the user will be prompted to install
 * it inside the SupportMapFragment. This method will only be triggered once the user has
 * installed Google Play services and returned to the app.
 */
@Override
public void onMapReady(GoogleMap googleMap) {
    mMap = googleMap;

    // Add a marker in Sydney and move the camera
    LatLng sydney = new LatLng(-34, 151);
    mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
    mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
}



@Override
public void onConnected(@Nullable Bundle bundle) {

    if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
        // TODO: Consider calling
        //    ActivityCompat#requestPermissions
        // here to request the missing permissions, and then overriding
        //   public void onRequestPermissionsResult(int requestCode, String[] permissions,
        //                                          int[] grantResults)
        // to handle the case where the user grants the permission. See the documentation
        // for ActivityCompat#requestPermissions for more details.
        return;
    }
    Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
    LocationSettingsRequest.Builder builder = new LocationSettingsRequest.Builder()
            .addLocationRequest(mLocationRequest);

    PendingResult<LocationSettingsResult> result =
            LocationServices.SettingsApi.checkLocationSettings(mGoogleApiClient,
                    builder.build());
    result.setResultCallback(new ResultCallback<LocationSettingsResult>() {
        @Override
        public void onResult(LocationSettingsResult result) {
            final Status status = result.getStatus();
            final LocationSettingsStates locationSettingsStates = result.getLocationSettingsStates();
            switch (status.getStatusCode()) {
                case LocationSettingsStatusCodes.SUCCESS:
                    // All location settings are satisfied. The client can
                    // initialize location requests here.
                    break;
                case LocationSettingsStatusCodes.RESOLUTION_REQUIRED:
                    // Location settings are not satisfied, but this can be fixed
                    // by showing the user a dialog.
                    try {
                        // Show the dialog by calling startResolutionForResult(),
                        // and check the result in onActivityResult().
                        status.startResolutionForResult(
                                MapsActivity.this,
                                6);
                    } catch (IntentSender.SendIntentException e) {
                        // Ignore the error.
                    }
                    break;
                case LocationSettingsStatusCodes.SETTINGS_CHANGE_UNAVAILABLE:
                    // Location settings are not satisfied. However, we have no way
                    // to fix the settings so we won't show the dialog.
                    break;
            }
        }
    });

    if (location == null) {
        startLocationUpdates();
    }
    else {
        handleNewLocation(location);
    };
}
public void handleNewLocation(Location location){
    Log.d(TAG, location.toString());

    double currentLatitude = location.getLatitude();
    double currentLongitude = location.getLongitude();
    LatLng latLng = new LatLng(currentLatitude, currentLongitude);

    MarkerOptions options = new MarkerOptions()
            .position(latLng)
            .title("I am here!");
    mMap.addMarker(options);
    mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
}

@Override
public void onConnectionSuspended(int i) {
}

@Override
public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

    if (connectionResult.hasResolution()) {
        try {
            // Start an Activity that tries to resolve the error
            connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST);
        } catch (IntentSender.SendIntentException e) {
            e.printStackTrace();
        }
    } else {
        Log.i(TAG, "Location services connection failed with code " + connectionResult.getErrorCode());
    }
}
@Override
protected void onResume() {
    super.onResume();
    //setUpMapIfNeeded();
    mGoogleApiClient.connect();
}
@Override
protected void onPause() {
    super.onPause();
    if (mGoogleApiClient.isConnected()) {
        LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        mGoogleApiClient.disconnect();
    }
}
boolean CheckGps(){
    LocationManager lm = (LocationManager)MapsActivity.this.getSystemService(MapsActivity.this.LOCATION_SERVICE);
    boolean gps_enabled = false;
    boolean network_enabled = false;

    try {
        gps_enabled = lm.isProviderEnabled(LocationManager.GPS_PROVIDER);
    } catch(Exception ex) {}

    try {
        network_enabled = lm.isProviderEnabled(LocationManager.NETWORK_PROVIDER);
    } catch(Exception ex) {}

    if(!gps_enabled && !network_enabled) {
        return false;
    }
    else{
        return true;
    }
}
}

谢谢。

【问题讨论】:

  • 导入android.content.IntentSender;导入android.content.pm.PackageManager;导入android.location.Location;导入 android.location.LocationManager;导入android.support.annotation.NonNull;导入 android.support.annotation.Nullable;导入android.support.v4.app.ActivityCompat;导入android.support.v4.app.FragmentActivity;导入android.os.Bundle;导入android.util.Log;
  • 导入 com.google.android.gms.common.ConnectionResult;导入 com.google.android.gms.common.api.GoogleApiClient;导入 com.google.android.gms.common.api.PendingResult;导入 com.google.android.gms.common.api.ResultCallback;导入 com.google.android.gms.common.api.Status;导入 com.google.android.gms.location.LocationListener;
  • 这些是导入 com.google.android.gms.location.LocationRequest 的包;导入 com.google.android.gms.location.LocationServices;导入 com.google.android.gms.location.LocationSettingsRequest;导入 com.google.android.gms.location.LocationSettingsResult;导入 com.google.android.gms.location.LocationSettingsStates;导入 com.google.android.gms.location.LocationSettingsStatusCodes;导入 com.google.android.gms.maps.CameraUpdateFactory;导入 com.google.android.gms.maps.GoogleMap;
  • 导入 com.google.android.gms.maps.OnMapReadyCallback;导入 com.google.android.gms.maps.SupportMapFragment;导入 com.google.android.gms.maps.model.LatLng;导入 com.google.android.gms.maps.model.MarkerOptions;

标签: android google-maps locationlistener location-services fusedlocationproviderapi


【解决方案1】:

首先,如果可能,我会建议在真实设备中尝试。如果没有,请确保您已为模拟器设置了纬度/经度。这是一个很好的指导如何做到这一点How to emulate GPS location in the Android Emulator?

【讨论】:

  • 我已经修复了模拟器的纬度和经度,但通过将 telnet 与模拟器连接使用命令行但 Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);仍然返回一个空值位置。
  • @B.Koseoglu 是否可以在设备中试用该应用程序?
猜你喜欢
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多