Open map at current user position

Asked

Viewed 936 times

10

I’m trying to open Googlemaps in the current position of the user, I’ve done a lot of research and still can’t make it work in my project. I’m using Fragments to manage the layout. In the current project the map already opens without problems, however, not as mentioned above. I’ll put the codes here, if anyone can help I’ll be grateful!

  1. My Mainactivity

    public class MainActivity1 extends AppCompatActivity {
    
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main1);
    
    
    //Add os ícones na Tab
    TabLayout tabLayout = (TabLayout) findViewById(R.id.tabLayout);
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_place_selector));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_favorite_selector));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_place_selector));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_favorite_selector));
    tabLayout.addTab(tabLayout.newTab().setIcon(R.drawable.ic_place_selector));
    tabLayout.setTabGravity(TabLayout.GRAVITY_FILL);
    
    // Configura o ViewPager
    final CustomViewPager viewPager = (CustomViewPager) findViewById(R.id.view_pager);
    if (viewPager != null) {
        viewPager.setPagingEnabled(false); //Desativa a mudança de tela deslizando o dedo
    }
    final PagerAdapter adapter = new PagerAdapter
            (getSupportFragmentManager(), this);
    viewPager.setAdapter(adapter);
    viewPager.addOnPageChangeListener(new TabLayout.TabLayoutOnPageChangeListener(tabLayout));
    tabLayout.addOnTabSelectedListener(new TabLayout.OnTabSelectedListener() {
        @Override
        public void onTabSelected(TabLayout.Tab tab) {
            viewPager.setCurrentItem(tab.getPosition());
        }
    
        @Override
        public void onTabUnselected(TabLayout.Tab tab) {
    
        }
    
        @Override
        public void onTabReselected(TabLayout.Tab tab) {
    
        }
    });
       }
    
    }
    
  2. Class Mapaactivity

      public class MapaActivity extends MainActivity1 {
    
      @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_mapa);
    
    if (savedInstanceState == null) {
        //Adiciona o fragment no layout da activity
        MapaFragment mapaFragment = new MapaFragment();
        mapaFragment.setArguments(getIntent().getExtras());
        getSupportFragmentManager().beginTransaction().replace(R.id.fragLayout,
                mapaFragment).commit();
    }
    }
    
    }
    

    3.Layout of the class Mapaactivity

      <LinearLayout
      xmlns:map="http://schemas.android.com/apk/res-auto"
      android:orientation="vertical"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      xmlns:android="http://schemas.android.com/apk/res/android"
      xmlns:tools="http://schemas.android.com/tools"
      map:cameraZoom="13"
      map:mapType="normal">
    
    
      <FrameLayout
      android:id="@+id/fragLayout"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      tools:layout="@layout/fragment_mapa"
    
      ></FrameLayout>
      </LinearLayout>
    

    4.Class Mapafragment

     public class MapaFragment extends Fragment implements OnMapReadyCallback {
    
     //Objeto que controla o Google Maps
     private GoogleMap map;
    
     public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    View view = inflater.inflate(R.layout.fragment_mapa,container,false);
    //Recupera o fragment que está no layout
    //Utiliza o GetChildFragmentManager() pois é um fragmento dentro de 
    outro
       SupportMapFragment mapFragment = (SupportMapFragment)
            getChildFragmentManager().findFragmentById(R.id.mapFragment);
    //Inicia o Google Maps dentro do fragment
    mapFragment.getMapAsync(this);
    
    return view;
    }
    
    @Override
    public void onMapReady(GoogleMap map) {
    //O método onMapReady(map) é chamado quando a inicialização do mapa estiver OK.
    this.map = map;
    
    //Tipo de Mapa;
    map.setMapType(GoogleMap.MAP_TYPE_NORMAL);
    
    CameraUpdate update = CameraUpdateFactory.zoomTo(10);
    }
    }
    

    5.Layout class Mapafragment

    <FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="com.ruan.goapp.Fragments.MapaFragment">
    
    <fragment android:id="@+id/mapFragment"
    class="com.google.android.gms.maps.SupportMapFragment"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
    
    </FrameLayout>
    

    6.I am using a lower tab

    public class CustomViewPager extends ViewPager {
    private boolean enabled;
    
    public CustomViewPager(Context context, AttributeSet attrs) {
    super(context, attrs);
    this.enabled = true;
    }
    
    @Override
    public boolean onTouchEvent(MotionEvent event) {
    if (enabled)
        return super.onTouchEvent(event);
    else
        return false;
    }
    
    @Override
    public boolean onInterceptTouchEvent(MotionEvent event) {
    return enabled && super.onInterceptTouchEvent(event);
    }
    
    public void setPagingEnabled(boolean enabled) {
    this.enabled = enabled;
    }
    
    public boolean isPagingEnabled() {
    return enabled;
    }
    }
    

    7.Layout custom_tab

    <?xml version="1.0" encoding="utf-8"?>
    <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:background="?attr/selectableItemBackground"
    android:gravity="center"
    android:orientation="vertical"
    android:paddingBottom="10dp"
    android:paddingTop="12dp">
    
    <ImageView
    android:id="@+id/icon"
    android:layout_width="24dp"
    android:layout_height="24dp"
    android:scaleType="centerInside" />
    
    <TextView
    android:id="@+id/title"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:ellipsize="end"
    android:maxLines="1"
    android:textAllCaps="false"
    android:textColor="@color/white"
    android:textSize="12sp"
    tools:text="Recents" />
    </LinearLayout>
    

    8.Pageradapter is the logic for exchanging screens

    public class PagerAdapter extends FragmentStatePagerAdapter {
    
    private Context context;
    private String[] abas = new String[]{"MAPA", "F1", "F2","F3", "F4"};
    
    public PagerAdapter(FragmentManager fm, Context c) {
    super(fm);
    this.context= c;
    }
    
    @Override
    public Fragment getItem(int position) {
    
    Fragment fragment = null;
    
    switch (position) {
        case 0:
            fragment = new MapaFragment();
            break;
        case 1:
            fragment = new Fragment1();
            break;
        case 2:
            fragment = new Fragment2();
            break;
        case 3:
            fragment = new Fragment3();
            break;
        case 4:
            fragment = new Fragment4();
            break;
    }
    return fragment;
    }
    
    
    @Override
     public int getCount() {
    return abas.length;
    }
    }
    

    9.My Androidmanifest.

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.ruan.goapp">
    
    <uses-feature
    android:glEsVersion="0x00020000"
    android:required="true" />
    
    <uses-permission android:name="android.permission.INTERNET" />/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    
    <application
    android:allowBackup="true"
    android:icon="@mipmap/ic_launcher"
    android:label="@string/app_name"
    android:supportsRtl="true"
    android:theme="@style/AppTheme">
    <meta-data
        android:name="com.google.android.gms.version"
        android:value="@integer/google_play_services_version" />
    <meta-data
        android:name="com.google.android.maps.v2.API_KEY"
        android:value="@string/API_KEY" />
    
    <activity android:name=".Activity.MainActivity1">
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />
    
            <category android:name="android.intent.category.LAUNCHER" />
        </intent-filter>
    </activity>
    <activity android:name=".Activity.MapaActivity"></activity>
    </application>
    
    </manifest>
    

    Print da tela inicial no momento

Estrutura do projeto

2 answers

1

First you need to get the user’s location using Fusedlocationproviderclient. See how in this reply.

The second step is to use the method moveCamera(), normally in the method onMapReady(), to position the map at this location:

map.moveCamera(CameraUpdateFactory.newLatLngZoom(minhaLocalizacao, 3));

minhaLocalizacao is a Latlng object that represents the user’s location. The value 3 is the zoom value at which the map will be displayed, it can be another value.

Basic example of implementation in an Activity:

Mapsactivity.java

public class MapsActivity extends AppCompatActivity implements OnMapReadyCallback {

    private GoogleMap mMap;
    private FusedLocationProviderClient mFusedLocationClient;
    protected Location mLastKnowLocation;


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

        //Obtém o FusedLocationClient e tenta obter a última localização conhecida
        mFusedLocationClient = LocationServices.getFusedLocationProviderClient(this);
        obtainLastKnowLocation();

        //Obtém o SupportMapFragment e pede para ser notificado quando o mapa estiver disponível
        SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager()
                .findFragmentById(R.id.map);
        mapFragment.getMapAsync(this);
    }


    @Override
    public void onMapReady(GoogleMap googleMap) {
        mMap = googleMap;
        //Se a localização já foi calculada
        //coloca uma marca e faz zoom
        if(mLastKnowLocation != null){
            zoomMapToMyLocation();
        }
    }

    @SuppressWarnings("MissingPermission")
    private void obtainLastKnowLocation() {
        mFusedLocationClient.getLastLocation()
                .addOnCompleteListener(this, new OnCompleteListener<Location>() {
                    @Override
                    public void onComplete(@NonNull Task<Location> task) {
                        if (task.isSuccessful() && task.getResult() != null) {

                            //obtém a última localização conhecida
                            mLastKnowLocation = task.getResult();
                            //Se o mapa está disponível
                            //coloca uma marca e faz zoom
                            if(mMap != null){
                                zoomMapToMyLocation();
                            }

                        } else {

                            //Não há localização conhecida ou houve uma excepção
                            //A excepção pode ser obtida com task.getException()
                            Toast.makeText(MapsActivity.this, 
                                    "Não há localização conhecida ou houve uma excepção", 
                                    Toast.LENGTH_SHORT).show();
                        }
                    }
                });
    }

    //Adiciona uma marca na última localização conhecida
    //e move a camara para essa localização com nível 8 de zoom
    private void zoomMapToMyLocation() {
        LatLng lastLocation = new LatLng(mLastKnowLocation.getLatitude(), mLastKnowLocation.getLongitude());
        mMap.addMarker(new MarkerOptions().position(lastLocation)
                                          .title("My last location"));
        mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(lastLocation, 8));

    }
}

activity_maps.xml

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

Notes:

  • Needs <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> in the Androidmanifest.xml and possibly treat the permission at runtime.
  • It may be the case that there is no "last known location", mainly in the use of an emulator. In this situation, run an application first that uses your location, such as Google Maps.
    To avoid this situation you should use a Locationrequest in conjunction with Fusedlocationclient, using the method mFusedLocationClient.requestLocationUpdates()(Location monitoring).
  • I had already read this answer, but I couldn’t implement the codes in this project. In which class do I implement Fusedlocationproviderclient or do I have to create one just for that? In Location Monitoring(Location updates), I have to put in my Activitymain too or in Map Activity?

  • It depends on where you need this information. If it is only on the map put in Mapfragment. If you need it in Activity and on the map, put it in Ragment and inform Activity, calling a method from it, whenever the location changes. If you need it in more than one Activity the best, perhaps, is to use a service.

1

I’m taking the position this way.

private LocationManager locationManager;
private Location location;
locationManager.requestLocationUpdates(LocationManager.GPS_PROVIDER, 0, 0, locationListenerGPS);
location = locationManager.getLastKnownLocation(LocationManager.GPS_PROVIDER);

Remembering that you have to use the permissions to use the gps.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.