将getLatitude()分配给变量时出现问题

时间:2017-05-24 20:56:10

标签: java android

我正在编写跟踪地图。在getDeviceLocation方法中,我想分配:

prevLat = mLastKnownLocation.getLatitude();

prevLng = mLastKnownLocation.getLongitude();

但它崩溃了应用程序。我希望稍后在distanceBetween()中为它分配它,以便在每次更改位置后获得距离。当通过killApp()关闭活动时,它应该总结所有距离并给我一个总计。它也会崩溃应用程序,因此它已被评论。

整个活动:

package com.example.micha.aplikacjatreningowa;


import android.Manifest;
import android.app.Dialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.location.Location;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AlertDialog;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.support.v4.app.DialogFragment;

import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;


import static android.location.Location.distanceBetween;
import static java.lang.Math.pow;

public class MapActivity extends AppCompatActivity implements     OnMapReadyCallback, com.google.android.gms.location.LocationListener,
    GoogleApiClient.ConnectionCallbacks,
    GoogleApiClient.OnConnectionFailedListener {


private static final String TAG = MapActivity.class.getSimpleName();
private GoogleMap mMap;
private GoogleApiClient mGoogleApiClient;
private LocationRequest mLocationRequest;
private CameraPosition mCameraPosition;

private static final int DEFAULT_ZOOM = 20;
private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
private boolean mLocationPermissionGranted = false;

private Location mLastKnownLocation;

private static final String KEY_CAMERA_POSITION = "camera_position";
private static final String KEY_LOCATION = "location";

private static final int UPDATE_INTERVAL = 1000;
private static final int FASTEST_INTERVAL = 500;
private static final int DISPLACEMENT = 1;

public double prevLat;
public double prevLng;

float totalDistance;
float[] distance;
float[] cBurned;
Float totalCalories;

public Button End;

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    //Ustalanie mapy
    setContentView(R.layout.activity_map);

    //Budowanie klienta API do użytku w wyznaczaniu położenia
    mGoogleApiClient = new GoogleApiClient.Builder(this)
            .enableAutoManage(this, this)
            .addConnectionCallbacks(this)
            .addApi(LocationServices.API)
            .build();
    mGoogleApiClient.connect();

    createLocationRequest();
    endButton();
}

//Zapisuje stan aplikacji
protected void onSaveInstanceState(Bundle outState) {
    if (mMap != null) {
        outState.putParcelable(KEY_CAMERA_POSITION, mMap.getCameraPosition());
        outState.putParcelable(KEY_LOCATION, mLastKnownLocation);
        super.onSaveInstanceState(outState);
    }
}

@Override
public void onConnected(@Nullable Bundle bundle) {
    SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
    mapFragment.getMapAsync(this);
}

//Gdy połączenie się nie uda
public void onConnectionFailed(@NonNull ConnectionResult result) {
    Log.d(TAG, "Połączenie nieudane: ConnectionResult.getErrorCode() = " + result.getErrorCode());
}

//Gdy połączenie zostanie wstrzymane
public void onConnectionSuspended() {
    Log.d(TAG, "Połączenie wstrzymane");
}

//Pobieranie lokacji użytkownika
private void getDeviceLocation() {
    //Prośba o pozwolenie na zczytanie lokacji urządzenia
    if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
    } else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }

    //Pobranie lokacji urządzenia
    if (mLocationPermissionGranted) {
        mLastKnownLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
        if(mLastKnownLocation != null) {
            prevLat=mLastKnownLocation.getLatitude();
            prevLng=mLastKnownLocation.getLongitude();
        }
    }

    moveCamera();
}

//Po otrzymaniu pozwolenia
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String permissions[], @NonNull int[] grantResults) {
    mLocationPermissionGranted = false;
    switch (requestCode) {
        case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                mLocationPermissionGranted = true;
            }
        }
    }
    updateLocationUI();
}

//Gdy mapa jest już gotowa
@Override
public void onMapReady(GoogleMap map) {
    mMap=map;
    updateLocationUI();
    getDeviceLocation();
    startLocationUpdates();
}

private void updateLocationUI() {
    if (mMap == null) {
        return;
    }

    if (ContextCompat.checkSelfPermission(this.getApplicationContext(), Manifest.permission.ACCESS_FINE_LOCATION)
            == PackageManager.PERMISSION_GRANTED) {
        mLocationPermissionGranted = true;
    } else {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }

    if (mLocationPermissionGranted) {
        mMap.setMyLocationEnabled(true);
    } else {
        mMap.setMyLocationEnabled(false);
        mLastKnownLocation = null;
    }
}

protected void startLocationUpdates() {
    if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) !=
            PackageManager.PERMISSION_GRANTED && ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_COARSE_LOCATION)
            != PackageManager.PERMISSION_GRANTED) {
        ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION},
                PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
    }
    LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this);
}

@Override
public void onLocationChanged(Location location) {
    moveCamera();
    float velocity = location.getSpeed();
    float caloriesBurned;
    String extra = getIntent().getStringExtra("EXTRA_MODE_TYPE");
    switch (extra) {
        case"walk": {
            distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
            prevLat=location.getLatitude();
            prevLng=location.getLongitude();
            double dbcaloriesBurned =(0.0215*pow(velocity*3600/1000, 3)-0.1765*pow(velocity*3600/1000, 2)+0.8710* + 1.4577*velocity*3600/1000);
            caloriesBurned = (float)dbcaloriesBurned;
            int count = 0;
            cBurned[count] = caloriesBurned;
            count++;
            if (velocity > 2) {
                killApp();
            }
            break;
        }
        case "run": {
            distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
            prevLat = location.getLatitude();
            prevLng = location.getLongitude();
            double dbcaloriesBurned = (0.0215 * pow(velocity * 3600 / 1000, 3) - 0.1765 * pow(velocity * 3600 / 1000, 2) + 0.8710 * +1.4577 * velocity * 3600 / 1000);
            caloriesBurned = (float) dbcaloriesBurned;
            int count = 0;
            cBurned[count] = caloriesBurned;
            count++;
            if (velocity > 3) {
                killApp();
            }
            break;
        }
        case "ride": {
            distanceBetween(prevLat, prevLng, location.getLatitude(), location.getLongitude(), distance);
            prevLat = location.getLatitude();
            prevLng = location.getLongitude();
            double dbcaloriesBurned = (0.0215 * pow(velocity * 3600 / 1000, 3) - 0.1765 * pow(velocity * 3600 / 1000, 2) + 0.8710 * +1.4577 * velocity * 3600 / 1000);
            caloriesBurned = (float) dbcaloriesBurned;
            int count = 0;
            cBurned[count] = caloriesBurned;
            count++;
            if (velocity > 5) {
                killApp();
            }
            break;
        }
    }
}

protected void createLocationRequest() {
    mLocationRequest = new LocationRequest();
    mLocationRequest.setInterval(UPDATE_INTERVAL);
    mLocationRequest.setFastestInterval(FASTEST_INTERVAL);
    mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    mLocationRequest.setSmallestDisplacement(DISPLACEMENT);
}

public void endButton(){
    End = (Button)findViewById(R.id.End);
    End.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            killApp();
        }
    });
}

public void moveCamera() {
    if (mCameraPosition != null) {
        mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
    } else if (mLastKnownLocation != null) {
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(mLastKnownLocation.getLatitude(),
                mLastKnownLocation.getLongitude()), DEFAULT_ZOOM));
    }
}

public void killApp() {
    stopLocationUpdates();
    /*for(int i=0; i<=distance.length; i++) {
        totalDistance += distance[i];
    }
    for(int j=0; j<cBurned.length; j++) {
        totalCalories += cBurned[j];
    }*/
    AlertDialog.Builder builder = new AlertDialog.Builder(MapActivity.this);
    builder.setMessage("Koniec treningu!\nPrzebiegłeś: " + totalDistance +" metrów.\nSpaliłeś: " + totalCalories +" kalorii.")
            .setCancelable(false)
            .setPositiveButton("Zakończ", new DialogInterface.OnClickListener() {
                public void onClick(DialogInterface dialog, int id) {
                    finish();
                }
            })
            .create().show();
}

protected void stopLocationUpdates() {
    LocationServices.FusedLocationApi.removeLocationUpdates(
            mGoogleApiClient, this);
}

@Override
public void onConnectionSuspended(int i) {

}
}

编辑: 崩溃日志:

                                                                                 --------- beginning of crash
05-24 22:16:57.509 2930-2930/com.example.micha.aplikacjatreningowa E/AndroidRuntime: FATAL EXCEPTION: main
                                                                                 Process: com.example.micha.aplikacjatreningowa, PID: 2930
                                                                                 java.lang.SecurityException: Client must have ACCESS_FINE_LOCATION permission to request PRIORITY_HIGH_ACCURACY locations.
                                                                                     at android.os.Parcel.readException(Parcel.java:1599)
                                                                                     at android.os.Parcel.readException(Parcel.java:1552)
                                                                                     at com.google.android.gms.internal.zzase$zza$zza.zza(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzasg.zza(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzash.zza(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzary$1.zza(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzaad$zza.zzb(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzaaq.zze(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzaaq.zzb(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzaav.zzb(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzaat.zzb(Unknown Source)
                                                                                     at com.google.android.gms.internal.zzary.requestLocationUpdates(Unknown Source)
                                                                                     at com.example.micha.aplikacjatreningowa.MapActivity.startLocationUpdates(MapActivity.java:187)
                                                                                     at com.example.micha.aplikacjatreningowa.MapActivity.onMapReady(MapActivity.java:156)
                                                                                     at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
                                                                                     at com.google.android.gms.maps.internal.zzt$zza.onTransact(Unknown Source)
                                                                                     at android.os.Binder.transact(Binder.java:387)
                                                                                     at com.google.android.gms.maps.internal.bw.a(:com.google.android.gms.DynamiteModulesB:82)
                                                                                     at com.google.maps.api.android.lib6.impl.bf.run(:com.google.android.gms.DynamiteModulesB:1805)
                                                                                     at android.os.Handler.handleCallback(Handler.java:739)
                                                                                     at android.os.Handler.dispatchMessage(Handler.java:95)
                                                                                     at android.os.Looper.loop(Looper.java:148)
                                                                                     at android.app.ActivityThread.main(ActivityThread.java:5417)
                                                                                     at java.lang.reflect.Method.invoke(Native Method)
                                                                                     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:726)
                                                                                     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:616)

编辑2:由于startLocationUpdates()方法

,应用程序崩溃

1 个答案:

答案 0 :(得分:1)

您没有正确处理Android运行时权限,因为您在条件时请求权限 Manifest.permission.ACCESS_FINE_LOCATION == PackageManager.PERMISSION_GRANTED是真的。再次检查您的代码。

你应该这样做:

String permission = Manifest.permission.ACCESS_FINE_LOCATION;
if (!isPermissionGranted(permission)) {

  if (isRationaleExplanationNeeded(permission)) {
    //show dialog to explain why you need permission
  } else {
    ActivityCompat.requestPermissions(this, new String[]{permission},
            PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
  }
} else {
  //do what ever you need to do
}

我认为由于未获得许可,您将获得安全例外。

上面提到的函数:

private boolean isPermissionGranted(String permission) {
   int hasRequestedPermission = ContextCompat.checkSelfPermission(this, permission);

   return hasRequestedPermission == PackageManager.PERMISSION_GRANTED;
} 

private boolean isRationaleExplanationNeeded(String permission) {
   return ActivityCompat.shouldShowRequestPermissionRationale(activity, permission);
}