You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

MapsFragment.java 12KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. package com.example.meinwald.ui.main.map;
  2. import android.content.pm.PackageManager;
  3. import android.location.Location;
  4. import android.os.Bundle;
  5. import android.preference.PreferenceManager;
  6. import android.util.Log;
  7. import android.view.LayoutInflater;
  8. import android.view.View;
  9. import android.view.ViewGroup;
  10. import com.example.meinwald.BuildConfig;
  11. import com.example.meinwald.R;
  12. import com.google.android.gms.location.FusedLocationProviderClient;
  13. import com.google.android.gms.location.LocationServices;
  14. import com.google.android.gms.maps.CameraUpdateFactory;
  15. import com.google.android.gms.maps.GoogleMap;
  16. import com.google.android.gms.maps.OnMapReadyCallback;
  17. import com.google.android.gms.maps.SupportMapFragment;
  18. import com.google.android.gms.maps.model.CameraPosition;
  19. import com.google.android.gms.maps.model.LatLng;
  20. import com.google.android.gms.tasks.OnCompleteListener;
  21. import com.google.android.gms.tasks.Task;
  22. import androidx.annotation.NonNull;
  23. import androidx.core.app.ActivityCompat;
  24. import androidx.core.content.ContextCompat;
  25. import androidx.fragment.app.Fragment;
  26. import androidx.fragment.app.FragmentTransaction;
  27. import static com.example.meinwald.R.layout.fragment_map;
  28. public class MapsFragment extends Fragment implements OnMapReadyCallback {
  29. /**
  30. * ______________________________________________________________________________________________
  31. * MAPS
  32. */
  33. // A default location and default zoom to use when location permission is not granted.
  34. private static final LatLng M_DEFAULT_LOCATION = new LatLng(49.5, 11.0); //Nuremberg
  35. private static final int DEFAULT_ZOOM = 1;
  36. private static final float MAX_ZOOM = (float) 20.0;
  37. private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
  38. private static final String TAG = MapsFragment.class.getSimpleName();
  39. // Keys for storing activity state.
  40. private static final String KEY_CAMERA_POSITION = "camera_position";
  41. private static final String KEY_LOCATION = "location";
  42. private GoogleMap mMap;
  43. private CameraPosition mCameraPosition;
  44. /**
  45. * The entry point to the Fused Location Provider.
  46. */
  47. private FusedLocationProviderClient mFusedLocationProviderClient;
  48. private boolean mLocationPermissionGranted;
  49. /**
  50. * The geographical location where the device is currently located.
  51. * That is the last-known location retrieved by the Fused Location Provider.
  52. */
  53. private Location mLastKnownLocation;
  54. /**
  55. * Is called when the MapsFragment view is created. Initializes all service connections, the location client and map itself.
  56. * @param inflater Calling LayoutInflater
  57. * @param container ViewGroup
  58. * @param savedInstanceState Applications savedInstanceState
  59. * @return
  60. */
  61. public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  62. //get view to inflate
  63. View root = inflater.inflate(fragment_map, container, false);
  64. //display map fragment
  65. SupportMapFragment mapFragment = new SupportMapFragment();
  66. FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
  67. transaction.add(R.id.map, mapFragment).commit();
  68. //construct a FusedLocationProviderClient.
  69. mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
  70. //wait for map is ready
  71. mapFragment.getMapAsync(new OnMapReadyCallback() {
  72. @Override
  73. public void onMapReady(GoogleMap googleMap) {
  74. //save map instance locally
  75. mMap = googleMap;
  76. //set max zoom level
  77. mMap.setMaxZoomPreference(MAX_ZOOM);
  78. //retrieve saved instance state
  79. mCameraPosition = parseCameraPosition(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_CAMERA_POSITION, new CameraPosition(new LatLng(45.0,11.0), (float) 1.0, (float) 0.0,(float) 0.0).toString()));
  80. mLastKnownLocation = new Location(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_LOCATION, new LatLng(45.0,11.0).toString()));
  81. mCameraPosition = parseCameraPosition(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_CAMERA_POSITION, new CameraPosition(new LatLng(45.0,11.0), (float) 1.0, (float) 0.0,(float) 0.0).toString()));
  82. //move camera to last position
  83. mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
  84. //get permission
  85. getLocationPermission();
  86. //turn on the My Location layer and the related control on the map.
  87. updateLocationUI();
  88. // Get the current location of the device and set the position of the map.
  89. getDeviceLocation();
  90. }
  91. });
  92. return root;
  93. }
  94. @Override
  95. public void onPause() {
  96. //save current location and camera position to shared preferences
  97. if (mMap.getCameraPosition() != null && mLastKnownLocation != null) {
  98. PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_CAMERA_POSITION, mMap.getCameraPosition().toString()).commit();
  99. PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_LOCATION, mLastKnownLocation.toString()).commit();
  100. }
  101. super.onPause();
  102. }
  103. @Override
  104. public void onResume() {
  105. super.onResume();
  106. }
  107. /**
  108. * Parses a string and creates a new CameraPosition from it.
  109. * Use CameraPosition.toString() to get corresponding string.
  110. * @param posString String which includes a camera position.
  111. * @return The parsed position of type CameraPosition.
  112. */
  113. private CameraPosition parseCameraPosition(String posString) {
  114. //parse string from shared preferences (CameraPosition.toString())
  115. String[] stringsplit = posString.split(" ");
  116. float lat = Float.parseFloat(stringsplit[1].split(",")[0].substring(1));
  117. float lng = Float.parseFloat(stringsplit[1].split(",")[1].substring(0,stringsplit[1].split(",")[1].length()-1));
  118. float zoom = Float.parseFloat(stringsplit[2].split("=")[1].substring(0,stringsplit[2].split("=")[1].length()-1));
  119. float tilt = Float.parseFloat(stringsplit[3].split("=")[1].substring(0,stringsplit[3].split("=")[1].length()-1));
  120. float bearing = Float.parseFloat(stringsplit[4].split("=")[1].substring(0,stringsplit[4].split("=")[1].length()-1));
  121. return new CameraPosition(new LatLng(lat,lng),zoom,tilt,bearing);
  122. }
  123. /**
  124. * Request location permission, so that we can get the location of the device.
  125. * The result of the permission request is handled by a callback,
  126. * onRequestPermissionsResult.
  127. *
  128. */
  129. private void getLocationPermission() {
  130. if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
  131. android.Manifest.permission.ACCESS_FINE_LOCATION)
  132. == PackageManager.PERMISSION_GRANTED) {
  133. mLocationPermissionGranted = true;
  134. } else {
  135. ActivityCompat.requestPermissions(getActivity(),
  136. new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
  137. PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
  138. }
  139. }
  140. /**
  141. * DOCU ME!
  142. * TOOD: What are grant results etc for?
  143. * @param requestCode
  144. * @param permissions
  145. * @param grantResults
  146. */
  147. @Override
  148. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
  149. {
  150. mLocationPermissionGranted = false;
  151. switch (requestCode) {
  152. case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
  153. // If request is cancelled, the result arrays are empty.
  154. if (grantResults.length > 0
  155. && grantResults[0] == PackageManager.PERMISSION_GRANTED)
  156. {
  157. updateLocationUI();
  158. mLocationPermissionGranted = true;
  159. }
  160. }
  161. }
  162. }
  163. /**
  164. * Get the best and most recent location of the device, which may be null in rare
  165. * cases when a location is not available.
  166. *
  167. */
  168. private void getDeviceLocation() {
  169. try {
  170. if (mLocationPermissionGranted) {
  171. Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
  172. locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() {
  173. @Override
  174. public void onComplete(@NonNull Task<Location> task) {
  175. if (task.isSuccessful()) {
  176. // Set the last known position to the current location of the device.
  177. mLastKnownLocation = task.getResult();
  178. if (BuildConfig.DEBUG) {
  179. if (task.getResult() != null)
  180. {
  181. Log.d(TAG, "getDeviceLocation " + task.getResult().toString());
  182. }
  183. }
  184. } else {
  185. if (BuildConfig.DEBUG) {
  186. Log.d(TAG, "Current location is null. Using defaults.");
  187. Log.e(TAG, "Exception: %s", task.getException());
  188. }
  189. mMap.moveCamera(CameraUpdateFactory
  190. .newLatLngZoom(M_DEFAULT_LOCATION, DEFAULT_ZOOM));
  191. //mMap.getUiSettings().setMyLocationButtonEnabled(false);
  192. if (BuildConfig.DEBUG) {
  193. Log.d(TAG, "getDeviceLocation: task not successful");
  194. }
  195. }
  196. }
  197. });
  198. }
  199. } catch (SecurityException e) {
  200. if (BuildConfig.DEBUG) {
  201. Log.e(TAG, "Exception occurred: ");
  202. e.printStackTrace();
  203. }
  204. }
  205. }
  206. private void updateLocationUI() {
  207. if (mMap == null) {
  208. if (BuildConfig.DEBUG) {
  209. Log.d(TAG, "Permission: Map not ready!");
  210. }
  211. return;
  212. }
  213. try {
  214. if (mLocationPermissionGranted) {
  215. mMap.setMyLocationEnabled(true);
  216. mMap.getUiSettings().setMapToolbarEnabled(true);
  217. mMap.getUiSettings().setMyLocationButtonEnabled(true);
  218. mMap.getUiSettings().setCompassEnabled(true);
  219. mMap.getUiSettings().setZoomControlsEnabled(true);
  220. if (BuildConfig.DEBUG) {
  221. Log.d(TAG, "Permission: Granted!");
  222. }
  223. } else {
  224. mMap.setMyLocationEnabled(false);
  225. mMap.getUiSettings().setMyLocationButtonEnabled(false);
  226. mMap.getUiSettings().setZoomControlsEnabled(false);
  227. mMap.getUiSettings().setCompassEnabled(false);
  228. mMap.getUiSettings().setMapToolbarEnabled(false);
  229. mLastKnownLocation = null;
  230. if (BuildConfig.DEBUG) {
  231. Log.d(TAG, "Permission: Denied!");
  232. }
  233. getLocationPermission();
  234. }
  235. } catch (SecurityException e) {
  236. if (BuildConfig.DEBUG) {
  237. Log.e(TAG, "Exception occurred: ");
  238. e.printStackTrace();
  239. }
  240. }
  241. }
  242. @Override
  243. public void onMapReady(GoogleMap googleMap) { }
  244. }