【问题标题】:Error with location service AndroidAndroid定位服务出错
【发布时间】:2016-05-26 07:30:04
【问题描述】:

我有一个使用GoogleMapsLocation Services 的路线跟踪应用程序。直到昨天,我的应用程序每次都使用NullPointerException 崩溃时一切正常,我不知道为什么,我没有更改代码中的任何内容。 代码如下:

package com.example.rocketron.mapa.Activities;


import android.location.Location;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.util.Log;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.Toast;

import com.example.rocketron.mapa.R;
import com.google.android.gms.common.ConnectionResult;
import com.google.android.gms.common.api.GoogleApiClient;
import com.google.android.gms.location.LocationListener;
import com.google.android.gms.location.LocationRequest;
import com.google.android.gms.location.LocationServices;
import com.google.android.gms.maps.CameraUpdate;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.MapView;
import com.google.android.gms.common.api.GoogleApiClient.ConnectionCallbacks;
import com.google.android.gms.common.api.GoogleApiClient.OnConnectionFailedListener;
import com.google.android.gms.maps.OnMapReadyCallback;
import com.google.android.gms.maps.model.BitmapDescriptorFactory;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class MainActivity extends AppCompatActivity implements ConnectionCallbacks,
        OnConnectionFailedListener, LocationListener, OnMapReadyCallback {

    protected static final String TAG = "location-updates-sample";

    // Keys for storing activity state in the Bundle.
    protected final static String REQUESTING_LOCATION_UPDATES_KEY = "requesting-location-updates-key";
    protected final static String LOCATION_KEY = "location-key";

    //UI Elements
    protected Toolbar toolbar;
    protected FloatingActionButton fab;
    protected GoogleMap googleMap;
    protected MapView mapView;

    //Provides the entry point to Google Play services.
    protected GoogleApiClient mGoogleApiClient;

    //Stores parameters for requests to the FusedLocationProviderApi.
    protected LocationRequest mLocationRequest;

    //Represents a geographical location.
    protected Location mCurrentLocation;

    //Tracks the status of the location updates request. Value changes when the user presses the
    //Start Updates and Stop Updates button.
    protected boolean mRequestingLocationUpdates;

    protected double latitude;
    protected double longitude;
    protected LatLng mLatLng;
    protected CameraUpdate cameraUpdate;
    Marker currentMarker;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        toolbar = (Toolbar) findViewById(R.id.appbar);
        setSupportActionBar(toolbar);

        fab = (FloatingActionButton) findViewById(R.id.fab);

        mapView = (MapView) findViewById(R.id.mi_mapa);
        mapView.getMapAsync(this);
        mapView.onCreate(savedInstanceState);

        mRequestingLocationUpdates = false;
        updateValuesFromBundle(savedInstanceState);

        buildGoogleApiClient();

        fab.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                togglePeriodicLocationUpdates();
            }
        });
    }

    @Override
    public void onMapReady(GoogleMap map) {
        googleMap = map;
        googleMap.getUiSettings().setMapToolbarEnabled(false); //Hide Map Toolbar when marker is clicked
    }

    @Override
    protected void onStart() {
        mGoogleApiClient.connect();
        super.onStart();
    }

    @Override
    protected void onResume() {
        super.onResume();
        mapView.onResume();
        if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        mapView.onPause();
        if (mGoogleApiClient.isConnected()) {
            stopLocationUpdates();
        }
    }

    @Override
    protected void onStop() {
        mGoogleApiClient.disconnect();
        super.onStop();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mapView.onDestroy();
    }

    /**
     * Updates fields based on data stored in the bundle.
     *
     * @param savedInstanceState The activity state saved in the Bundle.
     */
    private void updateValuesFromBundle(Bundle savedInstanceState) {
        Log.i(TAG, "Updating values from bundle");
        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);
                setFabEnabledState();
            }

            // 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 mCurrentLocation
                // is not null.
                mCurrentLocation = savedInstanceState.getParcelable(LOCATION_KEY);
            }

            updateUI();
        }
    }

    /*------------- Build Google API Client ----------------*/
    protected synchronized void buildGoogleApiClient() {
        Log.i(TAG, "Building GoogleApiClient");
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
        createLocationRequest();
    }

    /*------------- Set Up a Location Request -----------------*/
    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000);
        mLocationRequest.setFastestInterval(1000);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }

    protected void updateUI() {
        if (currentMarker != null)
            currentMarker.remove();
        latitude = mCurrentLocation.getLatitude();
        longitude = mCurrentLocation.getLongitude();
        mLatLng = new LatLng(latitude, longitude);
        cameraUpdate = CameraUpdateFactory.newLatLng(mLatLng);
        googleMap.moveCamera(cameraUpdate);
        currentMarker = googleMap.addMarker(new MarkerOptions()
                .position(mLatLng)
                .title(String.format("%f, %f", latitude, longitude))
                .icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_ORANGE)));
    }

    private void togglePeriodicLocationUpdates() {
        if (!mRequestingLocationUpdates) {
            // Changing the fab button
            mRequestingLocationUpdates = true;
            setFabEnabledState();
            getSupportActionBar().hide();
            // Starting the location updates
            startLocationUpdates();

        } else {
            // Changing the fab button
            mRequestingLocationUpdates = false;
            setFabEnabledState();
            getSupportActionBar().show();
            // Stopping the location updates
            stopLocationUpdates();

        }
    }

    private void setFabEnabledState() {
        if (mRequestingLocationUpdates) {
            fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_stop_white_24dp));
        } else {
            fab.setImageDrawable(ContextCompat.getDrawable(this, R.drawable.ic_play_arrow_white_24dp));
        }
    }

    protected void startLocationUpdates() {

        LocationServices.FusedLocationApi.requestLocationUpdates(
                mGoogleApiClient, mLocationRequest, this);

    }

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

    /*-------------Override Methods from ConnectionCallbacks, OnConnectionFailedListener-------------*/
    @Override
    public void onConnected(Bundle bundle) {
        Log.i(TAG, "Connected to GoogleApiClient");
        if (mCurrentLocation == null) {
            mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            updateUI();
        }

        if (mRequestingLocationUpdates) {
            startLocationUpdates();
        }
    }

    @Override
    public void onConnectionSuspended(int i) {
        // The connection to Google Play services was lost for some reason. We call connect() to
        // attempt to re-establish the connection.
        Log.i(TAG, "Connection suspended");
        mGoogleApiClient.connect();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
        // onConnectionFailed.
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + connectionResult.getErrorCode());
    }

    /*----------------Override Methods from LocationListener ----------------------*/
    @Override
    public void onLocationChanged(Location location) {
        mCurrentLocation = location;
        updateUI();
        Toast.makeText(this, getResources().getString(R.string.location_updated_message), Toast.LENGTH_SHORT).show();
    }


    /*------------------Stores activity data in the Bundle.--------------------*/
    public void onSaveInstanceState(Bundle savedInstanceState) {
        savedInstanceState.putBoolean(REQUESTING_LOCATION_UPDATES_KEY, mRequestingLocationUpdates);
        savedInstanceState.putParcelable(LOCATION_KEY, mCurrentLocation);
        super.onSaveInstanceState(savedInstanceState);
    }

    /*----------------Toolbar Methods---------------*/
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.menu_main, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        // Handle action bar item clicks here. The action bar will
        // automatically handle clicks on the Home/Up button, so long
        // as you specify a parent activity in AndroidManifest.xml.
        int id = item.getItemId();

        //noinspection SimplifiableIfStatement
        if (id == R.id.action_settings) {
            return true;
        }

        return super.onOptionsItemSelected(item);
    }
}

还有错误:

02-15 07:02:47.675 13898-13898/com.example.rocketron.mapa 

E/AndroidRuntime: FATAL EXCEPTION: main
java.lang.NullPointerException
at com.example.rocketron.mapa.Activities.MainActivity.updateUI(MainActivity.java:187)
at com.example.rocketron.mapa.Activities.MainActivity.onConnected(MainActivity.java:244)
at com.google.android.gms.common.internal.zzk.zzk(Unknown Source)
at com.google.android.gms.internal.zzmg.zzi(Unknown Source)
at com.google.android.gms.internal.zzme.zzpi(Unknown Source)
at com.google.android.gms.internal.zzme.onConnected(Unknown Source)
at com.google.android.gms.internal.zzmi.onConnected(Unknown Source)
at com.google.android.gms.internal.zzlz.onConnected(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzg.zzqv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzc(Unknown Source)
at com.google.android.gms.common.internal.zzj$zza.zzv(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzc.zzqx(Unknown Source)
at com.google.android.gms.common.internal.zzj$zzb.handleMessage(Unknown Source)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:4867)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1007)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:774)
at dalvik.system.NativeStart.main(Native Method)

【问题讨论】:

  • 你的 GPS 必须在那个时候关闭
  • 还是不行:(

标签: android google-maps service location


【解决方案1】:

您的mCurrentLocation 似乎为空。这一行是问题mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);。 getLastLocation 不获取最后一个已知位置。您可能想查看此thread 以获得可能的解决方案。

如果至少有一个客户端连接到融合位置提供程序,它将只维护后台位置。现在仅仅打开定位服务并不能保证存储最后一个已知的位置。

一旦第一个客户端连接,它将立即尝试获取位置。如果您的活动是第一个连接的客户端,并且在 onConnected() 中立即调用 getLastLocation(),则可能没有足够的时间让第一个位置到达..

然后你设置mLocationRequest.setFastestInterval(30000); 这基本上意味着 30 秒。所以至少 30 秒后,通常根据您的设置,首选时间是 120 秒,如果根本没有存储的最后一个已知位置,这不是很长的时间吗?加上你正在设置电池平衡优先级,这会让你等待更长的时间。

mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

我建议你先启动地图应用,这样至少有一些确认的位置,然后测试你的应用。

另外,请仔细检查您是否启用了 GPS。您可以检查您的 GPS 是否打开/关闭。看到这个thread

【讨论】:

  • 你认为我应该把 getLastLocation() 放在哪里?我测试了,看来你是对的,谢谢你的帮助
猜你喜欢
  • 2017-12-02
  • 2015-03-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-01-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多