How to get current Location in GoogleMap using FusedLocationProviderClient

前端 未结 4 1456
南方客
南方客 2020-11-28 04:33

I want to get periodic (say every 2 minutes) current location updates for this I\'m following official documentation, I wrote this code but its not giving current location u

相关标签:
4条回答
  • 2020-11-28 05:17

    For make it simple, try with this library https://github.com/mrmans0n/smart-location-lib. This will use the Fused Location Provider.

    You just put this code

    SmartLocation.with(context).location(new LocationBasedOnActivityProvider(callback))
        .start(new OnLocationUpdatedListener() { ... });
    
    0 讨论(0)
  • 2020-11-28 05:20
     mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                super.onLocationResult(locationResult);
                currentLocation = locationResult.getLastLocation();
    
            }
        };
    

    this work for me.

    0 讨论(0)
  • 2020-11-28 05:21

    This is similar to my other answer here, updated to use the recently introduced FusedLocationProviderClient class.

    In order to use a FusedLocationProviderClient in conjunction with a Google Map:

    1. Wait until the Google Map is ready

    2. Request the Location permission at runtime if needed

    3. Request location updates once the permission is granted

    4. Update the Google Map once the user's location is obtained

    First ensure that you're using at least version 11 of Google Play Services, as older versions don't have the FusedLocationProviderClient class (newer versions will work as well):

    dependencies {
          implementation 'com.google.android.gms:play-services-maps:17.0.0'
          implementation 'com.google.android.gms:play-services-location:17.0.0'
        //........
    }
    

    Note that the FusedLocationProviderClient is present in version 11.0.2, but due to bugs in the initial implementation, it's recommended that you only use this class on 11.6.0 and later. From the documentation:

    Note: It's recommended to use Google Play services version 11.6.0 or higher, which includes bug fixes for this class.

    Add the location permissions in the AndroidManifest.xml file, inside the manifest tag and outside of the application tag:

    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    

    Add the API key to the AndroidManifest.xml inside the application tag:

        <meta-data
                android:name="com.google.android.geo.API_KEY"
                android:value="AIza___YOUR_KEY_HERE______"/>
    

    Kotlin

    Here is the full Activity class in Kotlin:

    class MapsActivity : AppCompatActivity(), OnMapReadyCallback {
    
        lateinit var mGoogleMap: GoogleMap
        var mapFrag: SupportMapFragment? = null
        lateinit var mLocationRequest: LocationRequest
        var mLastLocation: Location? = null
        internal var mCurrLocationMarker: Marker? = null
        internal var mFusedLocationClient: FusedLocationProviderClient? = null
    
        internal var mLocationCallback: LocationCallback = object : LocationCallback() {
            override fun onLocationResult(locationResult: LocationResult) {
                val locationList = locationResult.locations
                if (locationList.isNotEmpty()) {
                    //The last location in the list is the newest
                    val location = locationList.last()
                    Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude())
                    mLastLocation = location
                    if (mCurrLocationMarker != null) {
                        mCurrLocationMarker?.remove()
                    }
    
                    //Place current location marker
                    val latLng = LatLng(location.latitude, location.longitude)
                    val markerOptions = 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.0F))
                }
            }
        }
    
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
            setContentView(R.layout.activity_maps)
    
            supportActionBar?.title = "Map Location Activity"
    
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this)
    
            mapFrag = supportFragmentManager.findFragmentById(R.id.map) as SupportMapFragment?
            mapFrag?.getMapAsync(this)
        }
    
        public override fun onPause() {
            super.onPause()
    
            //stop location updates when Activity is no longer active
            mFusedLocationClient?.removeLocationUpdates(mLocationCallback)
        }
    
        override fun onMapReady(googleMap: GoogleMap) {
            mGoogleMap = googleMap
            mGoogleMap.mapType = GoogleMap.MAP_TYPE_HYBRID
    
            mLocationRequest = LocationRequest()
            mLocationRequest.interval = 120000 // two minute interval
            mLocationRequest.fastestInterval = 120000
            mLocationRequest.priority = LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY
    
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                if (ContextCompat.checkSelfPermission(
                        this,
                        Manifest.permission.ACCESS_FINE_LOCATION
                    ) == PackageManager.PERMISSION_GRANTED
                ) {
                    //Location Permission already granted
                    mFusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
                    mGoogleMap.isMyLocationEnabled = true
                } else {
                    //Request Location Permission
                    checkLocationPermission()
                }
            } else {
                mFusedLocationClient?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper())
                mGoogleMap.isMyLocationEnabled = true
            }
        }
    
        private fun checkLocationPermission() {
            if (ActivityCompat.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.
                    AlertDialog.Builder(this)
                        .setTitle("Location Permission Needed")
                        .setMessage("This app needs the Location permission, please accept to use location functionality")
                        .setPositiveButton(
                            "OK"
                        ) { _, _ ->
                            //Prompt the user once explanation has been shown
                            ActivityCompat.requestPermissions(
                                this@MapsActivity,
                                arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                                MY_PERMISSIONS_REQUEST_LOCATION
                            )
                        }
                        .create()
                        .show()
    
    
                } else {
                    // No explanation needed, we can request the permission.
                    ActivityCompat.requestPermissions(
                        this,
                        arrayOf(Manifest.permission.ACCESS_FINE_LOCATION),
                        MY_PERMISSIONS_REQUEST_LOCATION
                    )
                }
            }
        }
    
        override fun onRequestPermissionsResult(
            requestCode: Int,
            permissions: Array<String>, grantResults: IntArray
        ) {
            when (requestCode) {
                MY_PERMISSIONS_REQUEST_LOCATION -> {
                    // If request is cancelled, the result arrays are empty.
                    if (grantResults.isNotEmpty() && 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
                        ) {
    
                            mFusedLocationClient?.requestLocationUpdates(
                                mLocationRequest,
                                mLocationCallback,
                                Looper.myLooper()
                            )
                            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
        }
    
        companion object {
            val MY_PERMISSIONS_REQUEST_LOCATION = 99
        }
    }
    

    Java

    Here is the full Activity class in Java:

    public class MapsActivity extends AppCompatActivity
            implements OnMapReadyCallback {
    
        GoogleMap mGoogleMap;
        SupportMapFragment mapFrag;
        LocationRequest mLocationRequest;
        Location mLastLocation;
        Marker mCurrLocationMarker;
        FusedLocationProviderClient mFusedLocationClient;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_maps);
    
            getSupportActionBar().setTitle("Map Location Activity");
    
            mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
    
            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 (mFusedLocationClient != null) {
                mFusedLocationClient.removeLocationUpdates(mLocationCallback);
            }
        }
    
        @Override
        public void onMapReady(GoogleMap googleMap) {
            mGoogleMap = googleMap;
            mGoogleMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
    
            mLocationRequest = new LocationRequest();
            mLocationRequest.setInterval(120000); // two minute interval
            mLocationRequest.setFastestInterval(120000);
            mLocationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);
    
            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
                    mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                    mGoogleMap.setMyLocationEnabled(true);
                } else {
                    //Request Location Permission
                    checkLocationPermission();
                }
            }
            else {
                mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                mGoogleMap.setMyLocationEnabled(true);
            }
        }
    
        LocationCallback mLocationCallback = new LocationCallback() {
            @Override
            public void onLocationResult(LocationResult locationResult) {
                List<Location> locationList = locationResult.getLocations();
                if (locationList.size() > 0) {
                    //The last location in the list is the newest
                    Location location = locationList.get(locationList.size() - 1);
                    Log.i("MapsActivity", "Location: " + location.getLatitude() + " " + location.getLongitude());
                    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(MapsActivity.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) {
    
                            mFusedLocationClient.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.myLooper());
                            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_maps.xml:

    <?xml version="1.0" encoding="utf-8"?>
    <androidx.constraintlayout.widget.ConstraintLayout
            xmlns:android="http://schemas.android.com/apk/res/android"
            xmlns:tools="http://schemas.android.com/tools"
            xmlns:app="http://schemas.android.com/apk/res-auto"
            android:layout_width="match_parent"
            android:layout_height="match_parent"
            tools:context=".map.MapsActivity">
    
        <fragment android:id="@+id/map"
                  xmlns:tools="http://schemas.android.com/tools"
                  android:layout_width="match_parent"
                  android:layout_height="match_parent"
                  tools:context=".map.MapsActivity"
                  app:layout_constraintTop_toTopOf="parent"
                  app:layout_constraintStart_toStartOf="parent"
                  app:layout_constraintBottom_toBottomOf="parent"
                  app:layout_constraintEnd_toEndOf="parent"
                  android:name="com.google.android.gms.maps.SupportMapFragment"/>
    
    </androidx.constraintlayout.widget.ConstraintLayout>
    

    The user will be prompted to accept the Location permission:

    The location will be updated on app launch, and every two minutes:

    Extra note regarding AndroidX

    If you are using AndroidX, you might need to add these lines to your gradle.properties file (see here for more info):

    android.useAndroidX=true
    android.enableJetifier=true
    
    0 讨论(0)
  • 2020-11-28 05:28
        private LocationRequest locationRequest;
    
        public class MapsActivity extends FragmentActivity implements LocationListener{
    
        locationRequest = new LocationRequest();
        locationRequest.setInterval(60 * 1000);
        locationRequest.setFastestInterval(15 * 1000);
        locationRequest.setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY);
    
    
    @Override
    public void onLocationChanged(Location location) {
    
        latitude = location.getLatitude();
        longitude = location.getLongitude();
    
    }
    

    Implement Location change listener and you will be able to override onlocation changed...

    0 讨论(0)
提交回复
热议问题