使用Android融合定位API时,我的位置上没有显示蓝色圆点和圆圈。

14

我之前使用LocationManager来追踪用户的当前位置,现在将位置管理器更改为FusedLocation API后,即使设置了map.setMyLocationEnabled(true),蓝点和圆圈也没有显示出来。我可以在地图碎片的右上角看到当前位置图标,但是点击它没有任何反应。我将代码还原回LocationManager后,能够看到指向我的当前位置的蓝点。使用Fused Location API可能出了什么问题。


关于“MyLocation”按钮,您使用什么并不重要。您无需添加任何代码即可使该按钮和蓝色标记正常工作。 - Daniel Nugent
1
这很奇怪。你能展示一下你的代码吗?你正在使用SupportMapFragment吗? - Daniel Nugent
2
是的,我正在使用 SupportMapFragment - flexdroid
1
我刚在Android Studio中开始了一个新的空白项目,我需要添加的唯一代码是这个:mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); map = mFragment.getMap(); map.setMyLocationEnabled(true); - Daniel Nugent
获取当前用户位置,您是否正在使用Android FusedLocation API? - flexdroid
显示剩余3条评论
3个回答

29

针对API 23或更高版本:

请参考这个答案...

针对API 22及以下版本:

以下代码适用于我,它具有MyLocation蓝色圆点/圆圈,并且还使用Fused Location Provider在当前位置放置Marker

这是我使用的所有Activity代码:

import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.SupportMapFragment;
import android.location.Location;
import android.widget.Toast;
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.location.LocationListener;
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;
import com.google.android.gms.maps.OnMapReadyCallback;

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

    LocationRequest mLocationRequest;
    GoogleApiClient mGoogleApiClient;

    LatLng latLng;
    GoogleMap mGoogleMap;
    SupportMapFragment mFragment;
    Marker mCurrLocation;

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

        mFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
        mFragment.getMapAsync(this);
    }

    @Override
    public void onMapReady(GoogleMap googleMap) {

        mGoogleMap = googleMap;

        mGoogleMap.setMyLocationEnabled(true);

        buildGoogleApiClient();

        mGoogleApiClient.connect();
    }

    @Override
    public void onPause() {
        super.onPause();
        //Unregister for location callbacks:
        if (mGoogleApiClient != null) {
            LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
        }
    }

    protected synchronized void buildGoogleApiClient() {
        Toast.makeText(this,"buildGoogleApiClient",Toast.LENGTH_SHORT).show();
        mGoogleApiClient = new GoogleApiClient.Builder(this)
                .addConnectionCallbacks(this)
                .addOnConnectionFailedListener(this)
                .addApi(LocationServices.API)
                .build();
    }

    @Override
    public void onConnected(Bundle bundle) {
        Toast.makeText(this,"onConnected",Toast.LENGTH_SHORT).show();
        Location mLastLocation = LocationServices.FusedLocationApi.getLastLocation(
                mGoogleApiClient);
        if (mLastLocation != null) {
            //place marker at current position
            mGoogleMap.clear();
            latLng = new LatLng(mLastLocation.getLatitude(), mLastLocation.getLongitude());
            MarkerOptions markerOptions = new MarkerOptions();
            markerOptions.position(latLng);
            markerOptions.title("Current Position");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
            mCurrLocation = mGoogleMap.addMarker(markerOptions);
        }

        mLocationRequest = new LocationRequest();
        mLocationRequest.setInterval(5000); //5 seconds
        mLocationRequest.setFastestInterval(3000); //3 seconds
        mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
        //mLocationRequest.setSmallestDisplacement(0.1F); //1/10 meter

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

    @Override
    public void onConnectionSuspended(int i) {
        Toast.makeText(this,"onConnectionSuspended",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onConnectionFailed(ConnectionResult connectionResult) {
        Toast.makeText(this,"onConnectionFailed",Toast.LENGTH_SHORT).show();
    }

    @Override
    public void onLocationChanged(Location location) {

        //remove previous current location marker and add new one at current position
        if (mCurrLocation != null) {
            mCurrLocation.remove();
        }
        latLng = new LatLng(location.getLatitude(), location.getLongitude());
        MarkerOptions markerOptions = new MarkerOptions();
        markerOptions.position(latLng);
        markerOptions.title("Current Position");
        markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_MAGENTA));
        mCurrLocation = mGoogleMap.addMarker(markerOptions);

        Toast.makeText(this,"Location Changed",Toast.LENGTH_SHORT).show();

        //If you only need one location, unregister the listener
        //LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this);
    }

}

主活动的布局文件:activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">

    <fragment
        class="com.google.android.gms.maps.SupportMapFragment"
        android:id="@+id/map"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>

</RelativeLayout>

结果:

MyLocationPlusFusedLocationProvider


我尝试将latLang设为全局变量,但仍然出现nullpointerException。我不理解你的方法。你能详细说明一下吗? - gabbar0x
1
@MuhammadShahzad 你是在测试Android M(Android 6)吗?如果是的话,你需要在运行时提示用户,请参见这里:https://dev59.com/NlwY5IYBdhLWcg3wD0PG - Daniel Nugent
@Daniel,你的解决方案存在问题。如果onStart在onMapready之前被调用,Google客户端将永远不会调用connect。 - Johny19
@johny,这个答案里没有onStart()函数...听起来你只需要把一些代码从onStart()移动到onMapReady()里面。你的onStart()代码里有什么? - Daniel Nugent
是的,忘记我说的话吧,我把“:/”和另一个例子混淆了。 - Johny19
显示剩余9条评论

6

您需要在清单文件中添加以下权限:

<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="android.permission.INTERNET"/>
<uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />

1
哇...谢谢@MuhammadMoosa!我花了很多时间试图弄清楚为什么我的应用程序中位置不准确,而我调试另一个应用程序时却是完美的...我无数次检查权限,唯一缺少的是<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>。 我甚至没有想到这个权限与地图有任何关系.. - chabislav
实际上,您只需要其中一个。根据您的实现,可以是ACCESS_COARSE_LOCATION或ACCESS_FINE_LOCATION。 - mayid

1
MarkerOptions().position(new LatLng(
                            location.getLatitude(), location.getLongitude()));

尝试一下这个,
   if (location!=null) {
                googleMap.clear();
                LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

                CameraPosition cameraPosition = new CameraPosition.Builder()
                        .target(new LatLng(location.getLatitude(), location.getLongitude())).zoom(14).build();
                googleMap.animateCamera(CameraUpdateFactory
                        .newCameraPosition(cameraPosition));

                // create markerOptions
                MarkerOptions markerOptions = new MarkerOptions().position(new LatLng(
                        location.getLatitude(), location.getLongitude()));
                // ROSE color icon
                markerOptions.icon(BitmapDescriptorFactory
                        .defaultMarker(BitmapDescriptorFactory.HUE_ROSE));
                markerOptions.position(latLng);
                // adding markerOptions
                Marker marker = googleMap.addMarker(markerOptions);
                dropPinEffect(marker);
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接