How can I show current location on a Google Map on Android Marshmallow?
我希望Google地图显示用户的位置。 我尝试了这段代码,但在Android 6上无法正常工作。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | private GoogleMap map; LocationManager lm; LocationListener ll; Location l; LatLng pos; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.start_layout); lm = (LocationManager) this.getSystemService(Context.LOCATION_SERVICE); ll = new LocationListener() { @Override public void onLocationChanged(Location location) { l = (Location) location; } @Override public void onStatusChanged(String provider, int status, Bundle extras) {} @Override public void onProviderEnabled(String provider) {} @Override public void onProviderDisabled(String provider) {} }; SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager() .findFragmentById(R.id.nMap); mapFragment.getMapAsync(this); } @Override public void onMapReady(GoogleMap googleMap) { map = googleMap; if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { lm.requestLocationUpdates(lm.NETWORK_PROVIDER, 0, 0, ll); } pos = new LatLng(l.getLatitude(), l.getLongitude()); // Add a marker in Sydney and move the camera map.setMyLocationEnabled(true); map.addMarker(new MarkerOptions().position(pos).title("Marker in Sydney")); map.moveCamera(CameraUpdateFactory.newLatLng(pos)); } |
这是我设置的权限:
1 2 | <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" /> |
要将FusedLocationProviderClient与Google Play服务11及更高版本配合使用:
看这里:
如何使用FusedLocationProviderClient在GoogleMap中获取当前位置
对于使用(现已弃用)FusedLocationProviderApi:
如果您的项目使用的是Google Play服务10或更低版本,则使用FusedLocationProviderApi是最佳选择。
与旧的开源LocationManager API相比,FusedLocationProviderApi提供的电池消耗更少。
另外,如果您已经在使用Google Play的Google Maps服务,则没有理由不使用它。
这是一个完整的Activity类,该类将Marker放置在当前位置,并将摄像机移动到当前位置。
它还会在运行时检查Android 6及更高版本(棉花糖,牛轧糖,奥利奥)的"位置"权限。
为了正确处理Android M / Android 6及更高版本上必要的位置许可运行时检查,您需要确保用户在调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 | public class MapLocationActivity extends AppCompatActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { GoogleMap mGoogleMap; SupportMapFragment mapFrag; LocationRequest mLocationRequest; GoogleApiClient mGoogleApiClient; Location mLastLocation; Marker mCurrLocationMarker; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); getSupportActionBar().setTitle("Map Location Activity"); mapFrag = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map); mapFrag.getMapAsync(this); } @Override public void onPause() { super.onPause(); //stop location updates when Activity is no longer active if (mGoogleApiClient != null) { LocationServices.FusedLocationApi.removeLocationUpdates(mGoogleApiClient, this); } } @Override public void onMapReady(GoogleMap googleMap) { mGoogleMap=googleMap; mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID); //Initialize Google Play Services if (android.os.Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { //Location Permission already granted buildGoogleApiClient(); mGoogleMap.setMyLocationEnabled(true); } else { //Request Location Permission checkLocationPermission(); } } else { buildGoogleApiClient(); mGoogleMap.setMyLocationEnabled(true); } } protected synchronized void buildGoogleApiClient() { mGoogleApiClient = new GoogleApiClient.Builder(this) .addConnectionCallbacks(this) .addOnConnectionFailedListener(this) .addApi(LocationServices.API) .build(); mGoogleApiClient.connect(); } @Override public void onConnected(Bundle bundle) { mLocationRequest = new LocationRequest(); mLocationRequest.setInterval(1000); mLocationRequest.setFastestInterval(1000); mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY); if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } } @Override public void onConnectionSuspended(int i) {} @Override public void onConnectionFailed(ConnectionResult connectionResult) {} @Override public void onLocationChanged(Location location) { mLastLocation = location; if (mCurrLocationMarker != null) { mCurrLocationMarker.remove(); } //Place current location marker LatLng 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)); mCurrLocationMarker = mGoogleMap.addMarker(markerOptions); //move map camera mGoogleMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng,11)); } public static final int MY_PERMISSIONS_REQUEST_LOCATION = 99; private void checkLocationPermission() { if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED) { // Should we show an explanation? if (ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)) { // Show an explanation to the user *asynchronously* -- don't block // this thread waiting for the user's response! After the user // sees the explanation, try again to request the permission. new AlertDialog.Builder(this) .setTitle("Location Permission Needed") .setMessage("This app needs the Location permission, please accept to use location functionality") .setPositiveButton("OK", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialogInterface, int i) { //Prompt the user once explanation has been shown ActivityCompat.requestPermissions(MapLocationActivity.this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } }) .create() .show(); } else { // No explanation needed, we can request the permission. ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, MY_PERMISSIONS_REQUEST_LOCATION ); } } } @Override public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) { switch (requestCode) { case MY_PERMISSIONS_REQUEST_LOCATION: { // If request is cancelled, the result arrays are empty. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { // permission was granted, yay! Do the // location-related task you need to do. if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { if (mGoogleApiClient == null) { buildGoogleApiClient(); } mGoogleMap.setMyLocationEnabled(true); } } else { // permission denied, boo! Disable the // functionality that depends on this permission. Toast.makeText(this,"permission denied", Toast.LENGTH_LONG).show(); } return; } // other 'case' lines to check for other // permissions this app might request } } } |
activity_main.xml:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="match_parent" android:layout_height="match_parent"> <fragment xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" xmlns:map="http://schemas.android.com/apk/res-auto" android:layout_width="match_parent" android:layout_height="match_parent" android:id="@+id/map" tools:context=".MapLocationActivity" android:name="com.google.android.gms.maps.SupportMapFragment"/> </LinearLayout> |
结果:
如果需要,使用AlertDialog显示权限说明(如果用户拒绝权限请求或授予权限,然后在设置中将其撤销,则会发生这种情况):
通过调用
授予"位置"权限后,将摄像机移至当前位置并放置"标记":
抱歉,这太短了,太快了(上面),如果您有MapFragment,还必须进行映射,只需执行以下操作即可:
1 2 3 4 5 | if (ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { googleMap.setMyLocationEnabled(true) } else { // Show rationale and request permission. } |
代码在Kotlin中,希望您不要介意。
玩得开心
顺便说一句,我认为这是重复的:在Google Map Fragment中显示当前位置
首先,请确保您的API密钥有效,并将其添加到清单
这是我的地图活动。其中可能有一些多余的信息,因为它来自我创建的较大项目。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | import android.content.Intent; import android.content.IntentSender; import android.location.Location; import android.support.v4.app.FragmentActivity; import android.os.Bundle; import android.util.Log; import android.view.View; import android.widget.Button; 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.LocationListener; 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.LatLng; import com.google.android.gms.maps.model.Marker; import com.google.android.gms.maps.model.MarkerOptions; public class MapsActivity extends FragmentActivity implements GoogleApiClient.ConnectionCallbacks, GoogleApiClient.OnConnectionFailedListener, LocationListener { //These variable are initalized here as they need to be used in more than one methid private double currentLatitude; //lat of user private double currentLongitude; //long of user private double latitudeVillageApartmets= 53.385952001750184; private double longitudeVillageApartments= -6.599087119102478; public static final String TAG = MapsActivity.class.getSimpleName(); private final static int CONNECTION_FAILURE_RESOLUTION_REQUEST = 9000; private GoogleMap mMap; // Might be null if Google Play services APK is not available. private GoogleApiClient mGoogleApiClient; private LocationRequest mLocationRequest; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_maps); setUpMapIfNeeded(); 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 } /*These methods all have to do with the map and wht happens if the activity is paused etc*/ //contains lat and lon of another marker private void setUpMap() { MarkerOptions marker = new MarkerOptions().position(new LatLng(latitudeVillageApartmets, longitudeVillageApartments)).title("1"); //create marker mMap.addMarker(marker); // adding marker } //contains your lat and lon private void handleNewLocation(Location location) { Log.d(TAG, location.toString()); currentLatitude = location.getLatitude(); currentLongitude = location.getLongitude(); LatLng latLng = new LatLng(currentLatitude, currentLongitude); MarkerOptions options = new MarkerOptions() .position(latLng) .title("You are here"); mMap.addMarker(options); mMap.moveCamera(CameraUpdateFactory.newLatLngZoom((latLng), 11.0F)); } @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(); } } private void setUpMapIfNeeded() { // Do a null check to confirm that we have not already instantiated the map. if (mMap == null) { // Try to obtain the map from the SupportMapFragment. mMap = ((SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map)) .getMap(); // Check if we were successful in obtaining the map. if (mMap != null) { setUpMap(); } } } @Override public void onConnected(Bundle bundle) { Location location = LocationServices.FusedLocationApi.getLastLocation(mGoogleApiClient); if (location == null) { LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient, mLocationRequest, this); } else { handleNewLocation(location); } } @Override public void onConnectionSuspended(int i) { } @Override public void onConnectionFailed(ConnectionResult connectionResult) { if (connectionResult.hasResolution()) { try { // Start an Activity that tries to resolve the error connectionResult.startResolutionForResult(this, CONNECTION_FAILURE_RESOLUTION_REQUEST); /* * Thrown if Google Play services canceled the original * PendingIntent */ } catch (IntentSender.SendIntentException e) { // Log the error e.printStackTrace(); } } else { /* * If no resolution is available, display a dialog to the * user with the error. */ Log.i(TAG,"Location services connection failed with code" + connectionResult.getErrorCode()); } } @Override public void onLocationChanged(Location location) { handleNewLocation(location); } } |
这里有很多方法很难理解,但是基本上所有的方法都是在地图暂停时更新地图等。还有连接超时等。很抱歉,我刚刚发布了这篇文章,我试图修复您的代码,但我不知道是什么原因。错误。