Android: как показать текущее местоположение нескольких устройств?

#android #google-maps #google-api #location #position

#Android #google-карты #google-api #Расположение #местоположение

Вопрос:

Для моей магистерской диссертации я должен реализовать следующее:

Приложение с разными вкладками, где Карты Google должны отображаться на одной вкладке. Цель состоит в том, чтобы отобразить текущее местоположение устройства. Это должно быть реализовано до 5 устройств, где каждое устройство в приложении видит положение другого. За этим должно последовать измерение расстояния через Bluetooth.

Что у меня есть до сих пор:

  • Отображение Карт Google на одной вкладке
  • текущее местоположение с устройства, на котором приложение запущено прямо сейчас

введите описание изображения здесь

Мой вопрос: как мне добавить положение каждого из других устройств? Если все 5 устройств открывают приложение, то каждый должен иметь возможность видеть всех. Должен ли я создать базу данных, в которой хранятся позиции, а затем извлекать эти позиции и устанавливать маркер?

Нужен ли каждому устройству собственный аккаунт Google? Нужно ли разблокировать устройства с помощью идентификатора?

Я был бы благодарен за любую помощь.

AndroidManifest.xml

 <?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    package="com.example.thesis">

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        tools:ignore="GoogleAppIndexingWarning">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

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

        <uses-library android:name="org.apache.http.legacy" android:required="false"/>
    </application>

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

</manifest>
 

activity_main.xml

 <?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    tools:context=".MainActivity">

    <com.google.android.material.tabs.TabLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:id="@ id/tab_layout"
        app:tabTextColor="@android:color/white"
        app:tabIndicatorColor="@android:color/white"
        app:tabSelectedTextColor="@android:color/white"
        android:background="@color/colorPrimary"/>

    <androidx.viewpager.widget.ViewPager
        android:id="@ id/view_pager"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />

</LinearLayout>
 

fragment_tab_ansicht.xml

 <?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent">

    <com.google.android.gms.maps.MapView
        android:id="@ id/map"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        class="com.google.android.gms.maps.MapFragment"/>
</FrameLayout>
 

MainActivity.java

 
    package com.example.thesis;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import android.Manifest;
    import android.content.pm.PackageManager;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.appcompat.app.AppCompatActivity;
    import android.os.Bundle;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    import androidx.fragment.app.Fragment;
    import androidx.fragment.app.FragmentManager;
    import androidx.fragment.app.FragmentPagerAdapter;
    import androidx.viewpager.widget.ViewPager;
    import com.example.thesis.fragment.AllgemeinFragment;
    import com.example.thesis.fragment.AnsichtFragment;
    import com.example.thesis.fragment.PositionFragment;
    import com.google.android.gms.maps.GoogleMap;
    import com.google.android.material.tabs.TabLayout;
    
    public class MainActivity extends AppCompatActivity {
    
        private static final int TAG_CODE_PERMISSION_LOCATION = 255;
        TabLayout tabLayout;
        ViewPager viewPager;
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
    
            tabLayout = findViewById(R.id.tab_layout);
            viewPager = findViewById(R.id.view_pager);
    
            ArrayList<String> arrayList = new ArrayList<>();
    
            // Tab Überschriften
            arrayList.add("Ansicht");
            arrayList.add("Position");
            arrayList.add("Allgemein");
    
            //viewpager
            prepareViewPager(viewPager, arrayList);
    
            //setup mit viewpager
            tabLayout.setupWithViewPager(viewPager);
    
            if (ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_FINE_LOCATION) ==
                    PackageManager.PERMISSION_GRANTED amp;amp;
                    ContextCompat.checkSelfPermission(this, android.Manifest.permission.ACCESS_COARSE_LOCATION) ==
                            PackageManager.PERMISSION_GRANTED) {
            } else {
                ActivityCompat.requestPermissions(this, new String[] {
                                                          Manifest.permission.ACCESS_FINE_LOCATION,
                                                          Manifest.permission.ACCESS_COARSE_LOCATION },
                                                  TAG_CODE_PERMISSION_LOCATION);
            }
    
        }
    
        private void prepareViewPager(ViewPager viewPager, ArrayList<String> arrayList) {
            //main adapter initialisieren
            MainAdapter adapter = new MainAdapter(getSupportFragmentManager());
            //fragments initialisieren
            AnsichtFragment ansichtFragment = new AnsichtFragment();
            PositionFragment positionFragment = new PositionFragment();
            AllgemeinFragment allgemeinFragment = new AllgemeinFragment();
    
            for (int i = 0; i<arrayList.size(); i  )
            {
                //Bundle initialisieren
                Bundle bundle = new Bundle();
                //put String
                bundle.putString("title", arrayList.get(i));
                //argument setzen
                allgemeinFragment.setArguments(bundle);
                positionFragment.setArguments(bundle);
                ansichtFragment.setArguments(bundle);
    
                //add Fragments
                if (i ==0) {
                    //Fragment hinzufügen
                    adapter.addFragment(ansichtFragment, arrayList.get(i));
                    //neues fragment definieren
                    ansichtFragment = new AnsichtFragment();
                } else if (i==1) {
                    adapter.addFragment(positionFragment, arrayList.get(i));
                    //neues fragment definieren
                    positionFragment = new PositionFragment();
                } else if (i==2) {
    
                    adapter.addFragment(allgemeinFragment, arrayList.get(i));
                    //neues fragment definieren
                    allgemeinFragment = new AllgemeinFragment();
                }
            }
            //Adapter setzen
            viewPager.setAdapter(adapter);
    
        }
    
        private class MainAdapter extends FragmentPagerAdapter {
    
            //Arraylist initialisieren
            ArrayList<String> arrayList = new ArrayList<>();
            List<Fragment> fragmentList = new ArrayList<>();
    
            //Konstruktor
            public void addFragment (Fragment fragment, String title) {
                // Titel hinzufügen
                arrayList.add(title);
                // Fragment hinzufügen
                fragmentList.add(fragment);
            }
    
            public MainAdapter(@NonNull FragmentManager fm) {
                super(fm);
            }
    
            @NonNull
            @Override
            public Fragment getItem(int position) {
                //Fragment position hinzufügen
                return fragmentList.get(position);
            }
    
            @Override
            public int getCount() {
                //Rückgabe der FragmentList Größe
                return fragmentList.size();
            }
    
            @Nullable
            @Override
            public CharSequence getPageTitle(int position) {
                //Rückgabe ArrayList position
                return arrayList.get(position);
            }
        }
    }

 

AnsichtFragment.java

 
    package com.example.thesis.fragment;
    
    import android.Manifest;
    import android.annotation.SuppressLint;
    import android.content.Context;
    import android.content.Intent;
    import android.content.pm.PackageManager;
    import android.location.Location;
    import android.location.LocationManager;
    import android.net.Uri;
    import android.os.Bundle;
    import android.os.Looper;
    import android.provider.Settings;
    import android.widget.TextView;
    import android.widget.Toast;
    import androidx.annotation.NonNull;
    import androidx.annotation.Nullable;
    import androidx.core.app.ActivityCompat;
    import androidx.core.content.ContextCompat;
    import androidx.fragment.app.Fragment;
    import android.view.LayoutInflater;
    import android.view.View;
    import android.view.ViewGroup;
    import com.example.thesis.R;
    import com.google.android.gms.common.api.GoogleApiClient;
    import com.google.android.gms.location.FusedLocationProviderClient;
    import com.google.android.gms.location.LocationCallback;
    import com.google.android.gms.location.LocationRequest;
    import com.google.android.gms.location.LocationResu<
    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.MapView;
    import com.google.android.gms.maps.MapsInitializer;
    import com.google.android.gms.maps.OnMapReadyCallback;
    import com.google.android.gms.maps.model.CameraPosition;
    import com.google.android.gms.maps.model.LatLng;
    import com.google.android.gms.maps.model.MarkerOptions;
    import com.google.android.gms.tasks.OnCompleteListener;
    import com.google.android.gms.tasks.Task;
    
    /**
     * A simple {@link Fragment} subclass.
     * Activities that contain this fragment must implement the
     * {@link MainFragment.OnFragmentInteractionListener} interface
     * to handle interaction events.
     * Use the {@link MainFragment#newInstance} factory method to
     * create an instance of this fragment.
     */
    public class AnsichtFragment extends Fragment  {
        MapView mMapView;
        private GoogleMap googleMap;
        private FusedLocationProviderClient fusedLocationClient;
    
        @Override
        public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
            //View initialisieren
            View rootView = inflater.inflate(R.layout.fragment_tab_ansicht, container, false);
    
            mMapView = (MapView) rootView.findViewById(R.id.map);
            mMapView.onCreate(savedInstanceState);
            mMapView.onResume(); // needed to get the map to display immediately
    
            //location client initialisieren
            fusedLocationClient = LocationServices.getFusedLocationProviderClient(getActivity());
    
            if(ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.ACCESS_FINE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED amp;amp; ContextCompat.checkSelfPermission(getActivity()
                    , Manifest.permission.ACCESS_COARSE_LOCATION)
                    == PackageManager.PERMISSION_GRANTED) {
                //When permission is granted
                //call method
                getCurrentLocation();
            }else {
                //when permission is not granted
                //reguest permission
                requestPermissions(new String[] {
                                                          Manifest.permission.ACCESS_FINE_LOCATION,
                                                          Manifest.permission.ACCESS_COARSE_LOCATION },
                                                  100);
            }
    
            try {
                MapsInitializer.initialize(getActivity().getApplicationContext());
            } catch (Exception e) {
                e.printStackTrace();
            }
    
            mMapView.getMapAsync(new OnMapReadyCallback() {
                @Override
                public void onMapReady(GoogleMap mMap) {
                    googleMap = mMap;
                    // For showing a move to my location button
                    googleMap.setMyLocationEnabled(true);
    
                   getCurrentLocation();
    
                }
            });
            return rootView;
        }
    
        @Override
        public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
            super.onRequestPermissionsResult(requestCode, permissions, grantResults);
            //check condiition
            if(requestCode == 100 amp;amp; (grantResults.length > 0) amp;amp;
                    (grantResults[0]   grantResults[1] == PackageManager.PERMISSION_GRANTED)){
                //when permission are granted
                //call method
                getCurrentLocation();
            }else {
                //when permission denied, display toast
                Toast.makeText(getActivity(), "Permission denied", Toast.LENGTH_SHORT).show();
            }
        }
    
        @SuppressLint("MissingPermission")
        private void getCurrentLocation() {
            //location manager initialisieren
            LocationManager locationManager = (LocationManager) getActivity().getSystemService(Context.LOCATION_SERVICE);
            //check conditions
            if (locationManager.isProviderEnabled(LocationManager.GPS_PROVIDER)
                || locationManager.isProviderEnabled(LocationManager.NETWORK_PROVIDER)){
                //if location service is enabled
                //get last location
                fusedLocationClient.getLastLocation().addOnCompleteListener(new OnCompleteListener<Location>() {
                    @Override
                    public void onComplete(@NonNull Task<Location> task) {
                        //Location initialisieren
                        Location location = task.getResult();
                        LatLng currentPosition = new LatLng(location.getLatitude(), location.getLongitude());
                        //check condition
                        if (location != null) {
                            //when not null, set latitude 
                            googleMap.addMarker(new MarkerOptions().position(currentPosition).title("Standort").snippet("Aktuelle Position"));
                            CameraPosition cameraPosition = new CameraPosition.Builder().target(currentPosition).zoom(12).build();
                            googleMap.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
                        }else {
                            //when location is null
                            //initialize location result
                            LocationRequest locationRequest = new LocationRequest()
                                    .setPriority(LocationRequest.PRIORITY_HIGH_ACCURACY)
                                    .setInterval(10000)
                                    .setFastestInterval(1000)
                                    .setNumUpdates(1);
    
                            //Initialize location call back
                            LocationCallback locationCallback = new LocationCallback(){
                                @Override
                                public void onLocationResult(LocationResult locationResult) {
                                    //initialize location
                                    Location location1 = locationResult.getLastLocation();
                                    //Set latutude 
                                    location1.getLatitude();
                                    //set longitude
                                    location1.getLongitude();
                                }
                            };
                            // Request Location
                            fusedLocationClient.requestLocationUpdates(locationRequest
                                    , locationCallback, Looper.myLooper());
                        }
                    }
                });
            }else {
                // when location service is not enabled
                //open location settings
                startActivity(new Intent(Settings.ACTION_LOCATION_SOURCE_SETTINGS)
                                      .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
            }
        }
    
        @Override
        public void onResume() {
            mMapView.onResume();
            super.onResume();
        }
    
        @Override
        public void onDestroy() {
            super.onDestroy();
            mMapView.onDestroy();
        }
    
        @Override
        public void onLowMemory() {
            super.onLowMemory();
            mMapView.onLowMemory();
        }
    
    }

 

Комментарии:

1. Для совместного использования местоположений Google потребуется, чтобы у каждого устройства были учетные записи; для проверки базы данных Firebase, которая бесплатна для небольших приложений. При использовании внешней базы данных (например, firebase) убедитесь, что пользователь понимает, что ваше приложение делится своим местоположением; Google location sharing дает это понять в действиях, которые пользователь предпринимает, чтобы разрешить это.

Ответ №1:

В общем, если вы хотите обмениваться данными между устройствами, вам, вероятно, лучше использовать базу данных, как указано в комментариях, для быстрых проектов рекомендуется firebase, простая в установке и использовании. Вероятно, вам потребуется сохранить длинные и широтные местоположения каждого пользователя и извлекать их с каждого устройства, которое хочет видеть местоположения других людей.

Вы можете обратиться к этому: https://developers.google.com/maps/documentation/android-sdk/map-with-marker

Возможно, попробуйте использовать маркеры, если этого достаточно для вашего проекта:

     @Override
public void onMapReady(GoogleMap googleMap) {
    LatLng myLocation = new LatLng(<LAT_FROM_DB>, <LONG_FROM_DB>);
    googleMap.addMarker(new MarkerOptions()
        .position(myLocation )
        .title("My Other User"));
}
 

Удачи с магистерской диссертацией.