如何显示Android棉花糖Google地图上的当前位置?
我想谷歌地图显示用户的位置。 我试过这个代码,但是它在Android 6上无法使用。
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)); }
这里是我设置的权限:
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> <uses-permission android:name="android.permission.INTERNET" />
现在最好使用FusedLocationProviderApi ,因为它比旧的开源LocationManager API提供更less的电池消耗。 另外,如果您已经在Google地图上使用Google Play服务,则没有理由不使用它。
这是一个完整的Activity类,它将Marker放置在当前位置,并将摄像机移动到当前位置。
它还检查Android 6及更高版本(Marshmallow,Nougat,Oreo)在运行时的Location权限。 为了正确处理Android M / Android 6及更高版本所需的位置权限运行时检查,您需要确保用户在调用mGoogleMap.setMyLocationEnabled(true)
之前以及在请求位置更新之前已经授予了您的应用“位置”权限。
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中:
<?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显示权限说明(如果用户拒绝权限请求,或者授予权限,然后在设置中撤销权限,则会发生这种情况:)
通过调用ActivityCompat.requestPermissions()
提示用户input位置权限:
将摄像头移到当前位置,并在授予位置权限时放置标记:
首先确保您的API密钥是有效的,并将其添加到您的清单<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
这是我的地图活动..可能有一些冗余的信息,因为它来自于我创build的一个更大的项目。
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); } }
这里有很多很难理解的方法,但基本上所有的方法都是在暂停的时候更新地图等等。还有连接超时等等。抱歉,只是发布这个,我试图修复你的代码,但我不知道什么是错误。
- IntelliJ的IDEA – 不能build立任何东西,总是得到“包R不存在”
- 我怎样才能从我的Android设备访问我的本地主机?
- adb服务器已过期
- 未findSDK位置。 使用sdk.dir在local.properties文件中定义位置,或者使用ANDROID_HOME环境variables定义位置
- 如何在不下载Android Studio的情况下下载Android SDK?
- Android新的底部导航栏
- Android Studio找不到与com.android.support:appcompat-v7:+相匹配的任何版本
- 在Android Studio中导入现有项目时如何设置gradle home
- Android Studio Gradle:错误:任务“:app:processDebugGoogleServices”的执行失败。 >找不到匹配的客户端软件包