简体   繁体   中英

How to move the camera on current position when I open my app?

I need your help.

How can I move the camera on my current position, immediately when I open the app?

I have a button which works (if I click it, it move the camera on my current position), but when I open the app, the camera is set on the middle of the ocean. I want to open the app and the camera is already set on my current position.

This is my code:

MapsActivity.java

    import android.Manifest;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.location.LocationManager;
    import android.os.Build;
    import android.support.annotation.NonNull;
    import android.support.annotation.Nullable;
    import android.support.v4.app.ActivityCompat;
    import android.support.v4.app.FragmentActivity;
    import android.os.Bundle;
    import android.support.v4.content.ContextCompat;
    import android.widget.Toast;

    import com.google.android.gms.common.ConnectionResult;
    import com.google.android.gms.common.GooglePlayServicesNotAvailableException;
    import com.google.android.gms.common.GooglePlayServicesRepairableException;
    import com.google.android.gms.location.LocationListener;
    import com.google.android.gms.common.api.GoogleApi;
    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.maps.CameraUpdate;
    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.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;

    public class MapsActivity extends FragmentActivity implements OnMapReadyCallback, GoogleApiClient.ConnectionCallbacks,
            GoogleApiClient.OnConnectionFailedListener, LocationListener {

        private GoogleMap mMap;
        private GoogleApiClient googleApiClient;
        private LocationRequest locationRequest;
        private Location lastLocation;
        private Marker currentUserLocationMarker;
        private static final int Request_User_Location_Code = 99;


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

            if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.M){
                checkUserLocationPermission();
            }

            // Obtain the SupportMapFragment and get notified when the map is ready to be used.
            SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                    .findFragmentById(R.id.map);
            mapFragment.getMapAsync(this);
        }

        /**
         * Manipulates the map once available.
         * This callback is triggered when the map is ready to be used.
         * This is where we can add markers or lines, add listeners or move the camera. In this case,
         * we just add a marker near Sydney, Australia.
         * If Google Play services is not installed on the device, the user will be prompted to install
         * it inside the SupportMapFragment. This method will only be triggered once the user has
         * installed Google Play services and returned to the app.
         */

        @Override
        public void onMapReady(GoogleMap googleMap) {
            mMap = googleMap;

            if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
                buildGoogleApiClient();
                mMap.setMyLocationEnabled(true);
            }
            /*disabling toolbar (it is used to continue using this app without having to
            use the official google maps app)*/

            mMap.getUiSettings().setMapToolbarEnabled(false);
        }

        public boolean checkUserLocationPermission(){
            if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) != PackageManager.PERMISSION_GRANTED){
                if(ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.ACCESS_FINE_LOCATION)){
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code );
                }
                else{
                    ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.ACCESS_FINE_LOCATION}, Request_User_Location_Code );
                }
                return false;
            }
            else{
                return true;
            }
        }

        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            switch (requestCode){
                case Request_User_Location_Code:
                    if(grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED){
                        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
                            if(googleApiClient == null){
                                buildGoogleApiClient();
                            }
                            mMap.setMyLocationEnabled(true);
                        }
                    }
                    else{
                        Toast.makeText(this, "Permesso vietato", Toast.LENGTH_SHORT).show();
                    }
                    return;
            }
        }

        protected synchronized void buildGoogleApiClient(){

            googleApiClient = new GoogleApiClient.Builder(this)
                    .addConnectionCallbacks(this)
                    .addOnConnectionFailedListener(this)
                    .addApi(LocationServices.API)
                    .build();

            googleApiClient.connect();


        }

        @Override
        public void onLocationChanged(Location location) {
            lastLocation = location;

            if(currentUserLocationMarker != null){
                currentUserLocationMarker.remove();
            }

            LatLng latLng = new LatLng(location.getLatitude(), location.getLongitude());

            MarkerOptions markerOptions = new MarkerOptions();

            markerOptions.position(latLng);
            markerOptions.title("Posizione corrente");
            markerOptions.icon(BitmapDescriptorFactory.defaultMarker(BitmapDescriptorFactory.HUE_BLUE));

            currentUserLocationMarker = mMap.addMarker(markerOptions);

            mMap.moveCamera(CameraUpdateFactory.newLatLng(latLng));
            mMap.animateCamera(CameraUpdateFactory.zoomBy(11));

            if (googleApiClient != null){
                LocationServices.FusedLocationApi.removeLocationUpdates(googleApiClient, this);
            }
        }

        @Override
        public void onConnected(@Nullable Bundle bundle) {

            locationRequest = new LocationRequest();
            locationRequest.setInterval(1100);
            locationRequest.setFastestInterval(1100);
            locationRequest.setPriority(LocationRequest.PRIORITY_BALANCED_POWER_ACCURACY);

            if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
                LocationServices.FusedLocationApi.requestLocationUpdates(googleApiClient, locationRequest, this);
            }
        }

        @Override
        public void onConnectionSuspended(int i) {

        }

        @Override
        public void onConnectionFailed(@NonNull ConnectionResult connectionResult) {

        }
}

activity_maps.xml :

<?xml version="1.0" encoding="utf-8"?>
<fragment xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:map="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/map"
    android:name="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MapsActivity"
    class="com.google.android.gms.maps.SupportMapFragment"/>

Already add this in my AndroidManifest.xml :

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

Thanks for your help.

So you have done almost all the work already. You just need to go one step further.

First to understand, setMyLocationEnabled when set to true adds that location compass button on the map. This is what you click to find your current location. Good start.

You also need to set the camera to your current location when you initialize the map.

if(locationPermissionGranted){
            Task<Location> locationResult = fusedLocationProviderClient.getLastLocation();
            locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() {
                @Override
                public void onComplete(@NonNull Task<Location> task) {
                    if(task.isSuccessful()){
                        // Set the maps camera to current location
                        lastKnownLocation = task.getResult();
                        map.moveCamera(CameraUpdateFactory.newLatLngZoom(
                                new LatLng(lastKnownLocation.getLatitude(), lastKnownLocation.getLongitude()), 12));
                    }
                    else{
                        Log.d(TAG, "Current location is null");
                        Log.e(TAG,"Exception: %s", task.getException());
                        map.moveCamera(CameraUpdateFactory.newLatLngZoom(defaultLocation, 12));
                        map.getUiSettings().setMyLocationButtonEnabled(false);
                    }
                }
            });
        }

Try this. First make sure you have location permissions granted. Then try and find the last known location. (If you are using an emulator try opening Google Maps before trying this code. The location services on an emulator have never been initiated). It will try and grab your current location. If success it moves the camera to that location, if failed I have set a default location for the map to move to instead of opening in the ocean.

private LatLng defaultLocation = new LatLng(41.651031, -83.541939);

Hope this helps.

I think, I solved in this way.

I have modified my onMapReady :

public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;

        if(ContextCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED){
            buildGoogleApiClient();
            mMap.setMyLocationEnabled(true);
            mMap.setOnMyLocationChangeListener(new GoogleMap.OnMyLocationChangeListener() {

                @Override
                public void onMyLocationChange(Location arg0) {
                    float zoomLevel = 15.0f;
                    LatLng latLng = new LatLng(arg0.getLatitude(), arg0.getLongitude());
                    mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latLng, zoomLevel));
                }
            });

        }
        /*disabling toolbar (it is used to continue using this app without having to
        use the official google maps app)*/
        mMap.getUiSettings().setMapToolbarEnabled(false);

Then, when I open my app, the camera is set on my current location. Thanks a lot.

[Prerequisite] - Make sure you have location permission granted and location services is turned on.

public void onMapReady(GoogleMap googleMap){
    mMap = googleMap;
    // You can register for Location Change Once the location is updated,
    // Fetch lat, lng from it. Once you have lat,lng convert it into `LatLng`
    LatLng currLatLng = fetchedFromAPI();
    CameraPosition newPos =
                new CameraPosition.Builder()
                        .target(currLatLng)
                        .build();
    if (showAnimation){
        mMap.animateCamera(CameraUpdateFactory.newCameraPosition(newPos));
    }else{
        mMap.moveCamera(CameraUpdateFactory.newCameraPosition(newPos));
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM