2016-01-03 66 views
32

我想要谷歌地图显示用户的位置。我想这个代码,但它并没有在Android 6.如何显示Android棉花糖Google地图上的当前位置?

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" /> 
+0

它以什么方式不起作用?崩溃?错误的位置?同时检查你的logcat是否有错误,并在这里发布。 – Buddy

回答

126

对于使用新FusedLocationProviderClient:

看这里: How to get current Location in GoogleMap using FusedLocationProviderClient

对于使用(现在不推荐使用)Fus edLocationProviderApi:

FusedLocationProviderApi与旧的开源LocationManager API相比,电池消耗更少。 另外,如果您已经在Google地图上使用Google Play服务,则没有理由不使用它。

这是一个完整的Activity类,它将标记放置在当前位置,并将摄像机移动到当前位置。

它还检查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(需要发生这种情况,如果用户拒绝许可请求,或授予权限和然后在设置中将其撤销):

enter image description here

提示用户位置的权限调用ActivityCompat.requestPermissions()

enter image description here

移动相机的当前位置和地点标记在Location权限被授予:

enter image description here

+7

真棒答案,在片段上完美无缺地工作。 – Waclock

+3

LocationServices.FusedLocationApi.requestLocationUpdates(mGoogleApiClient,mLocationRequest,this); - 我尝试了你的解决方案,我被这行代码说“无法解决requestLocationUpdates” – RoCk

+5

@RoCk请确保你的导入是'import com.google.android.gms.location.LocationListener;',在这里看到的导入: http://stackoverflow.com/a/31448567/4409409 –

0

首先确保您的API密钥有效并将其添加到您的清单中<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />

这是我的地图活动..它可能有一些冗余信息,因为它来自我创建的更大的项目。

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

} 

有很多的方法,在这里是很难理解,但基本上也有连接超时等全部更新地图时,它的暂停等。抱歉只发布这个,我试图修复你的代码,但我无法弄清楚什么是错的。

相关问题