【发布时间】:2021-03-29 20:39:17
【问题描述】:
对于我的硕士论文,我必须实现以下内容:
具有不同选项卡的应用程序应在一个选项卡中显示 Google 地图。目标是显示设备的当前位置。这将在最多 5 个设备上实现,应用程序中的每个设备都可以看到另一个设备的位置。然后通过蓝牙进行距离测量。
到目前为止我所拥有的:
- 在一个标签中显示 Google 地图
- 当前启动应用的设备的当前位置
我的问题是: 如何添加每个其他设备的位置?如果所有 5 台设备都打开了应用程序,那么每个人应该都能看到每个人。 我应该创建一个存储位置的数据库,然后获取这些位置并设置标记吗?
每台设备都需要自己的 Google 帐户吗?设备是否需要使用 ID 解锁?
如果有任何帮助,我将不胜感激。
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 &&
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.LocationResult;
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 && 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 && (grantResults.length > 0) &&
(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();
}
}
【问题讨论】:
-
谷歌位置分享会要求每台设备都有账号;用于数据库结帐 Firebase,它对小型应用程序是免费的。使用外部数据库(例如 firebase)时,请确保用户了解您的应用正在共享他们的位置;谷歌位置共享在用户允许它所采取的操作中清楚地表明了这一点。
标签: android google-maps google-api location position