java - 在 googleMap (android) 中更新位置

标签 java android google-maps gps location

我正在尝试构建一个应用程序,它将在 googleMap 中显示我的位置并每隔几秒更新一次我的位置。

这是我的代码:

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

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

    /**
     * The desired interval for location updates. Inexact. Updates may be more or less frequent.
     */
    public static final long UPDATE_INTERVAL_IN_MILLISECONDS = 10000;

    /**
     * The fastest rate for active location updates. Exact. Updates will never be more frequent
     * than this value.
     */
    public static final long FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS =
            UPDATE_INTERVAL_IN_MILLISECONDS / 2;

    // 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";

    protected GoogleApiClient mGoogleApiClient;
    protected LocationRequest mLocationRequest;
    protected Location mCurrentLocation;


    /**
     * Tracks the status of the location updates request. Value changes when the user presses the
     * Start Updates and Stop Updates buttons.
     */
    protected Boolean mRequestingLocationUpdates;
    private GoogleMap mMap;
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_maps);
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);

        mRequestingLocationUpdates = false;
        updateValuesFromBundle(savedInstanceState);
        buildGoogleApiClient();
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        LatLng loc = new LatLng(-34,151);
        mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
        startUpdates();
    }

    private void updateValuesFromBundle(Bundle savedInstanceState) {
        Log.i(TAG, "Updating values from bundle");
        if (savedInstanceState != null) {
            if (savedInstanceState.keySet().contains(REQUESTING_LOCATION_UPDATES_KEY)) {
                mRequestingLocationUpdates = savedInstanceState.getBoolean(
                        REQUESTING_LOCATION_UPDATES_KEY);
            }

            // 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();
        }
    }


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

    protected void createLocationRequest() {
        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setFastestInterval(FASTEST_UPDATE_INTERVAL_IN_MILLISECONDS);
        mLocationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    }


    public void startUpdates() { // start updating location
        if (!mRequestingLocationUpdates) {
            mRequestingLocationUpdates = true;
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }

    public void stopUpdates() { // stop updating location
        if (mRequestingLocationUpdates) {
            mRequestingLocationUpdates = false;
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }
    /**
     * Updates the latitude, the longitude, and the last location time in the UI.
     */
    private void updateUI() {
        LatLng loc = new LatLng(mCurrentLocation.getLatitude(), mCurrentLocation.getLongitude());
        mMap.addMarker(new MarkerOptions().position(loc).title("my location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLng(loc));
    }

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

    @Override
    public void onResume() {
        super.onResume();
        if (mGoogleApiClient.isConnected() && mRequestingLocationUpdates) {
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }

    @Override
    protected void onPause() {
        super.onPause();
        // Stop location updates to save battery, but don't disconnect the GoogleApiClient object.
        if (mGoogleApiClient.isConnected()) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

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

    /**
     * Runs when a GoogleApiClient object successfully connects.
     */
    @Override
    public void onConnected(Bundle connectionHint) {
        Log.i(TAG, "Connected to GoogleApiClient");

        if (mCurrentLocation == null) {
            mCurrentLocation = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient);
            updateUI();
        }

        if (mRequestingLocationUpdates) {
            LocationServices.FusedLocationApi.requestLocationUpdates(
                    mGoogleApiClient, mLocationRequest, this);
        }
    }


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

    @Override
    public void onConnectionSuspended(int cause) {
        // 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 result) {
        // Refer to the javadoc for ConnectionResult to see what error codes might be returned in
        // onConnectionFailed.
        Log.i(TAG, "Connection failed: ConnectionResult.getErrorCode() = " + result.getErrorCode());
    }


    /**
     * 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);
    }
}

此代码是来自 google 的示例代码的一部分,但我更改了一些内容并添加了 googleMap,它只是在 onMapReady() 之后崩溃。

堆栈跟踪:

    java.lang.IllegalStateException: GoogleApiClient is not connected yet.
                                                                     at com.google.android.gms.common.api.internal.zzh.zzb(Unknown Source)
                                                                     at com.google.android.gms.common.api.internal.zzl.zzb(Unknown Source)
                                                                     at com.google.android.gms.common.api.internal.zzj.zzb(Unknown Source)
                                                                     at com.google.android.gms.location.internal.zzd.requestLocationUpdates(Unknown Source)
                                                                     at com.idanofek.photomap.MapsActivity.startUpdates(MapsActivity.java:135)
                                                                     at com.idanofek.photomap.MapsActivity.onMapReady(MapsActivity.java:91)
                                                                     at com.google.android.gms.maps.SupportMapFragment$zza$1.zza(Unknown Source)
                                                                     at com.google.android.gms.maps.internal.zzo$zza.onTransact(Unknown Source)
                                                                     at android.os.Binder.transact(Binder.java:387)
                                                                     at com.google.android.gms.maps.internal.be.a(SourceFile:82)
                                                                     at com.google.maps.api.android.lib6.e.fb.run(Unknown Source)
                                                                     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)

最佳答案

在执行任何操作之前,必须使用“connect()” 方法连接 GoogleApiClient。在调用 onConnected(Bundle) 回调之前,客户端不会被视为已连接。

您应该在 Activity 的 'onCreated(Bundle)' 中实例化一个客户端对象方法,然后在 onStart()

上调用 connect()

您可以从 onConnected() 回调中调用 startLocationUpdate()

@Override
public void onConnected(Bundle connectionHint) {
...
if (mRequestingLocationUpdates) {
startLocationUpdates();
}
}

protected void startLocationUpdates() {
LocationServices.FusedLocationApi.requestLocationUpdates(
mGoogleApiClient, mLocationRequest, this);
}

这是关于位置更新的 Google 文档:http://developer.android.com/training/location/receive-location-updates.html

关于java - 在 googleMap (android) 中更新位置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35670461/

相关文章:

javax.ejb.EJBException : java. lang.ClassCastException 抛出(HQL 查询)

java - 在android中将16位音频存储在8位字节数组上

javascript - 根据输入的地址和所选半径显示谷歌地图

android - 使用 fragment 更改为横向时 map 行为会发生变化

java - Kloudless:如何下载/上传文件

java - 在 Java 中使用 for-each 循环

java - instanceof 在现代 JVM 实现中是如何实现的?

android - 如何获得默认分隔符?

安卓 : Getting Clipboard Data Item List

google-maps - Google map API v3 中的 Javascript 错误 (RefererDeniedMapError)