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 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650
  1. package com.example.meinwald.ui.map;
  2. import android.Manifest;
  3. import android.content.pm.PackageManager;
  4. import android.graphics.Bitmap;
  5. import android.graphics.BitmapFactory;
  6. import android.graphics.Color;
  7. import android.location.Location;
  8. import android.os.Bundle;
  9. import android.os.IBinder;
  10. import android.preference.PreferenceManager;
  11. import android.util.Log;
  12. import android.view.LayoutInflater;
  13. import android.view.View;
  14. import android.view.ViewGroup;
  15. import android.widget.ListView;
  16. import android.widget.Toast;
  17. import com.example.meinwald.BuildConfig;
  18. import com.example.meinwald.R;
  19. import com.example.meinwald.ui.area.AreaReference;
  20. import com.example.meinwald.ui.area.OwnArea;
  21. import com.example.meinwald.ui.task.OwnTask;
  22. import com.google.android.gms.common.util.Hex;
  23. import com.google.android.gms.dynamic.IObjectWrapper;
  24. import com.google.android.gms.location.FusedLocationProviderClient;
  25. import com.google.android.gms.location.LocationServices;
  26. import com.google.android.gms.maps.CameraUpdateFactory;
  27. import com.google.android.gms.maps.GoogleMap;
  28. import com.google.android.gms.maps.OnMapReadyCallback;
  29. import com.google.android.gms.maps.SupportMapFragment;
  30. import com.google.android.gms.maps.model.BitmapDescriptor;
  31. import com.google.android.gms.maps.model.CameraPosition;
  32. import com.google.android.gms.maps.model.LatLng;
  33. import com.google.android.gms.maps.model.Marker;
  34. import com.google.android.gms.maps.model.MarkerOptions;
  35. import com.google.android.gms.maps.model.Polygon;
  36. import com.google.android.gms.maps.model.PolygonOptions;
  37. import com.google.android.gms.maps.model.Polyline;
  38. import com.google.android.gms.maps.model.PolylineOptions;
  39. import com.google.android.gms.tasks.OnCompleteListener;
  40. import com.google.android.gms.tasks.Task;
  41. import com.google.maps.android.SphericalUtil;
  42. import org.json.JSONArray;
  43. import org.json.JSONException;
  44. import java.io.BufferedReader;
  45. import java.io.File;
  46. import java.io.FileReader;
  47. import java.io.IOException;
  48. import java.util.ArrayList;
  49. import java.util.Date;
  50. import java.util.List;
  51. import androidx.annotation.NonNull;
  52. import androidx.core.app.ActivityCompat;
  53. import androidx.core.content.ContextCompat;
  54. import androidx.fragment.app.Fragment;
  55. import androidx.fragment.app.FragmentTransaction;
  56. import static com.example.meinwald.R.layout.fragment_map;
  57. public class MapsFragment extends Fragment implements OnMapReadyCallback {
  58. /**
  59. * ______________________________________________________________________________________________
  60. * MAPS
  61. */
  62. // A default location and default zoom to use when location permission is not granted.
  63. private static final LatLng M_DEFAULT_LOCATION = new LatLng(49.5, 11.0); //Nuremberg
  64. private static final int DEFAULT_ZOOM = 1;
  65. private static final float MAX_ZOOM = (float) 20.0;
  66. private static final int PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION = 1;
  67. private static final String TAG = MapsFragment.class.getSimpleName();
  68. // Keys for storing activity state.
  69. private static final String KEY_CAMERA_POSITION = "camera_position";
  70. private static final String KEY_LOCATION = "location";
  71. private GoogleMap mMap;
  72. private CameraPosition mCameraPosition;
  73. /**
  74. * The entry point to the Fused Location Provider.
  75. */
  76. private FusedLocationProviderClient mFusedLocationProviderClient;
  77. private boolean mLocationPermissionGranted;
  78. /**
  79. * The geographical location where the device is currently located.
  80. * That is the last-known location retrieved by the Fused Location Provider.
  81. */
  82. private Location mLastKnownLocation;
  83. /**
  84. * ______________________________________________________________________________________________
  85. * TASKS
  86. */
  87. private List<OwnTask> allTasks;
  88. private static final String KEY_ALL_TASKS = "allTasks";
  89. /**
  90. * ______________________________________________________________________________________________
  91. * STORAGEE
  92. */
  93. private static final int READ_EXTERNAL_STORAGE_CODE = 200;
  94. private static final int WRITE_EXTERNAL_STORAGE_CODE = 201;
  95. private boolean mReadStorageGranted;
  96. private boolean mWriteStorageGranted;
  97. /**
  98. * ______________________________________________________________________________________________
  99. * AREA
  100. */
  101. private List<OwnArea> allAreas;
  102. private static final String KEY_AREA_REFERENCES = "areaReferences";
  103. private List<AreaReference> areaReferences;
  104. @Override
  105. public void onCreate (Bundle savedInstanceState)
  106. {
  107. super.onCreate(savedInstanceState);
  108. areaReferences = new ArrayList<>();
  109. areaReferences = readAreaReferencesFromPreferences();
  110. }
  111. /**
  112. * Is called when the MapsFragment view is created. Initializes all service connections, the location client and map itself.
  113. * @param inflater Calling LayoutInflater
  114. * @param container ViewGroup
  115. * @param savedInstanceState Applications savedInstanceState
  116. * @return
  117. */
  118. public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
  119. //get view to inflate
  120. View root = inflater.inflate(fragment_map, container, false);
  121. //get storage permission
  122. getReadStoragePermission();
  123. //get tasks
  124. allTasks = readTasksFromPreferences();
  125. //get areas
  126. //instantiate area lists
  127. allAreas = new ArrayList<>();
  128. //get saved areas
  129. allAreas = loadAreasFromPreferences();
  130. //display map fragment
  131. SupportMapFragment mapFragment = new SupportMapFragment();
  132. FragmentTransaction transaction = getChildFragmentManager().beginTransaction();
  133. transaction.add(R.id.map, mapFragment).commit();
  134. //construct a FusedLocationProviderClient.
  135. mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(getActivity());
  136. //wait for map is ready
  137. mapFragment.getMapAsync(new OnMapReadyCallback()
  138. {
  139. @Override
  140. public void onMapReady(GoogleMap googleMap) {
  141. //save map instance locally
  142. mMap = googleMap;
  143. //set max zoom level
  144. mMap.setMaxZoomPreference(MAX_ZOOM);
  145. mMap.setMapType(GoogleMap.MAP_TYPE_HYBRID);
  146. mMap.setOnMarkerClickListener(new GoogleMap.OnMarkerClickListener() {
  147. @Override
  148. public boolean onMarkerClick(Marker marker) {
  149. if (mMap.getCameraPosition().zoom < 17.5)
  150. {
  151. mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),(float)17.5));
  152. }
  153. else
  154. {
  155. mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(marker.getPosition().latitude, marker.getPosition().longitude),mMap.getCameraPosition().zoom));
  156. }
  157. return false;
  158. }
  159. });
  160. //retrieve saved instance state
  161. 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()));
  162. mLastKnownLocation = new Location(PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_LOCATION, new LatLng(45.0,11.0).toString()));
  163. 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()));
  164. //move camera to last position
  165. mMap.moveCamera(CameraUpdateFactory.newCameraPosition(mCameraPosition));
  166. //get permission
  167. getLocationPermission();
  168. //turn on the My Location layer and the related control on the map.
  169. updateLocationUI();
  170. // Get the current location of the device and set the position of the map.
  171. getDeviceLocation();
  172. }
  173. });
  174. return root;
  175. }
  176. @Override
  177. public void onPause() {
  178. //save current location and camera position to shared preferences
  179. if (mMap.getCameraPosition() != null && mLastKnownLocation != null) {
  180. PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_CAMERA_POSITION, mMap.getCameraPosition().toString()).commit();
  181. PreferenceManager.getDefaultSharedPreferences(getContext()).edit().putString(KEY_LOCATION, mLastKnownLocation.toString()).commit();
  182. }
  183. super.onPause();
  184. }
  185. private void drawAreas()
  186. {
  187. for (OwnArea area: allAreas)
  188. {
  189. if (area.getLocations() != null && area.getLocations().size()>0)
  190. {
  191. PolygonOptions options = new PolygonOptions().clickable(true);
  192. if (BuildConfig.DEBUG)
  193. {
  194. Log.d(TAG, "Color: " + getAreaColor(area.getLastChecked()));
  195. Log.d(TAG, "Color: " + String.valueOf(getAreaColor(area.getLastChecked() & 0x00FFFFFF) | 0x60000000));
  196. Log.d(TAG, "Area: " + SphericalUtil.computeArea(area.getLocations()));
  197. }
  198. options.strokeColor(getAreaColor(area.getLastChecked()));
  199. options.fillColor((options.getStrokeColor() & 0x00FFFFFF) | 0x60000000);
  200. for (LatLng location: area.getLocations())
  201. {
  202. options.add(location);
  203. if (BuildConfig.DEBUG)
  204. {
  205. Log.d(TAG, "Position: " + location.toString());
  206. }
  207. }
  208. options.add(area.getLocations().get(0));
  209. mMap.addPolygon(options);
  210. }
  211. }
  212. }
  213. /**
  214. * Reads areaReferences saved in preferences as jsonStrings
  215. *
  216. * @return list of AreaReferences
  217. */
  218. private List<AreaReference> readAreaReferencesFromPreferences() {
  219. if (BuildConfig.DEBUG)
  220. {
  221. Log.d(TAG, "readAreaReferencesFromPreferences()");
  222. }
  223. List<AreaReference> areas = new ArrayList<>();
  224. try {
  225. String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_AREA_REFERENCES, "error");
  226. if(!"error".equalsIgnoreCase(jsonString)) {
  227. JSONArray jsonObjects = new JSONArray(jsonString);
  228. for (int i = 0; i<jsonObjects.length();i++) {
  229. areas.add(new AreaReference(jsonObjects.getJSONObject(i)));
  230. }
  231. }
  232. else
  233. {
  234. if (BuildConfig.DEBUG)
  235. {
  236. Log.e(TAG, "read area reference error");
  237. }
  238. }
  239. } catch (JSONException e) {
  240. if (BuildConfig.DEBUG) {
  241. Log.e(TAG, "Error while parsing area references as jsonObjects from preferences");
  242. e.printStackTrace();
  243. }
  244. }
  245. for (AreaReference reference: areas)
  246. {
  247. if (BuildConfig.DEBUG)
  248. {
  249. Log.d(TAG, "read reference: " + reference.toString());
  250. }
  251. }
  252. return areas;
  253. }
  254. /**
  255. * Get OwnAreas from a JSONString.
  256. * @return
  257. */
  258. private List<OwnArea> loadAreasFromPreferences()
  259. {
  260. if (BuildConfig.DEBUG)
  261. {
  262. Log.d(TAG, "loadAreasFromPreferences() reference size: " + areaReferences.size());
  263. }
  264. List<OwnArea> areas = new ArrayList<>();
  265. Integer i = 0;
  266. for (AreaReference reference: areaReferences)
  267. {
  268. String jsonString = readAreaFromExternalStorage(reference.getPath());
  269. areas.add(new OwnArea(jsonString));
  270. if (BuildConfig.DEBUG)
  271. {
  272. Log.d(TAG, "load area from preferences: " + areas.get(i).toString());
  273. }
  274. i++;
  275. }
  276. return areas;
  277. }
  278. /**
  279. * Read OwnArea from file in external storage and return as a string.
  280. *
  281. * @param path File path where the OwnArea is saved.
  282. * @return
  283. */
  284. private String readAreaFromExternalStorage(String path)
  285. {
  286. if (BuildConfig.DEBUG)
  287. {
  288. Log.d(TAG, "readAreaFromExternalStorage()");
  289. }
  290. //Get the text file
  291. File file = new File(path);
  292. //Read text from file
  293. StringBuilder text = new StringBuilder();
  294. try {
  295. BufferedReader br = new BufferedReader(new FileReader(file));
  296. String line;
  297. while ((line = br.readLine()) != null) {
  298. text.append(line);
  299. }
  300. br.close();
  301. }
  302. catch (IOException e) {
  303. if (BuildConfig.DEBUG)
  304. {
  305. Log.e(TAG, "Failed read from external storage: " + e.toString());
  306. }
  307. }
  308. return text.toString();
  309. }
  310. @Override
  311. public void onResume() {
  312. super.onResume();
  313. }
  314. /**
  315. * Parses a string and creates a new CameraPosition from it.
  316. * Use CameraPosition.toString() to get corresponding string.
  317. * @param posString String which includes a camera position.
  318. * @return The parsed position of type CameraPosition.
  319. */
  320. private CameraPosition parseCameraPosition(String posString) {
  321. //parse string from shared preferences (CameraPosition.toString())
  322. String[] stringsplit = posString.split(" ");
  323. float lat = Float.parseFloat(stringsplit[1].split(",")[0].substring(1));
  324. float lng = Float.parseFloat(stringsplit[1].split(",")[1].substring(0,stringsplit[1].split(",")[1].length()-1));
  325. float zoom = Float.parseFloat(stringsplit[2].split("=")[1].substring(0,stringsplit[2].split("=")[1].length()-1));
  326. float tilt = Float.parseFloat(stringsplit[3].split("=")[1].substring(0,stringsplit[3].split("=")[1].length()-1));
  327. float bearing = Float.parseFloat(stringsplit[4].split("=")[1].substring(0,stringsplit[4].split("=")[1].length()-1));
  328. return new CameraPosition(new LatLng(lat,lng),zoom,tilt,bearing);
  329. }
  330. /**
  331. * Request location permission, so that we can get the location of the device.
  332. * The result of the permission request is handled by a callback,
  333. * onRequestPermissionsResult.
  334. *
  335. */
  336. private void getLocationPermission() {
  337. if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
  338. android.Manifest.permission.ACCESS_FINE_LOCATION)
  339. == PackageManager.PERMISSION_GRANTED) {
  340. mLocationPermissionGranted = true;
  341. } else {
  342. ActivityCompat.requestPermissions(getActivity(),
  343. new String[]{android.Manifest.permission.ACCESS_FINE_LOCATION},
  344. PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION);
  345. }
  346. }
  347. /**
  348. * DOCU ME!
  349. * TOOD: What are grant results etc for?
  350. * @param requestCode
  351. * @param permissions
  352. * @param grantResults
  353. */
  354. @Override
  355. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults)
  356. {
  357. mLocationPermissionGranted = false;
  358. switch (requestCode) {
  359. case PERMISSIONS_REQUEST_ACCESS_FINE_LOCATION: {
  360. // If request is cancelled, the result arrays are empty.
  361. if (grantResults.length > 0
  362. && grantResults[0] == PackageManager.PERMISSION_GRANTED)
  363. {
  364. updateLocationUI();
  365. mLocationPermissionGranted = true;
  366. }
  367. }
  368. case READ_EXTERNAL_STORAGE_CODE: {
  369. if (grantResults.length > 0
  370. && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  371. mReadStorageGranted = true;
  372. }
  373. }
  374. }
  375. }
  376. /**
  377. * Get the best and most recent location of the device, which may be null in rare
  378. * cases when a location is not available.
  379. *
  380. */
  381. private void getDeviceLocation() {
  382. try {
  383. if (mLocationPermissionGranted) {
  384. Task<Location> locationResult = mFusedLocationProviderClient.getLastLocation();
  385. locationResult.addOnCompleteListener(getActivity(), new OnCompleteListener<Location>() {
  386. @Override
  387. public void onComplete(@NonNull Task<Location> task) {
  388. if (task.isSuccessful()) {
  389. // Set the last known position to the current location of the device.
  390. mLastKnownLocation = task.getResult();
  391. if (BuildConfig.DEBUG) {
  392. if (task.getResult() != null)
  393. {
  394. Log.d(TAG, "getDeviceLocation " + task.getResult().toString());
  395. }
  396. }
  397. } else {
  398. if (BuildConfig.DEBUG) {
  399. Log.d(TAG, "Current location is null. Using defaults.");
  400. Log.e(TAG, "Exception: %s", task.getException());
  401. }
  402. mMap.moveCamera(CameraUpdateFactory
  403. .newLatLngZoom(M_DEFAULT_LOCATION, DEFAULT_ZOOM));
  404. //mMap.getUiSettings().setMyLocationButtonEnabled(false);
  405. if (BuildConfig.DEBUG) {
  406. Log.d(TAG, "getDeviceLocation: task not successful");
  407. }
  408. }
  409. }
  410. });
  411. }
  412. } catch (SecurityException e) {
  413. if (BuildConfig.DEBUG) {
  414. Log.e(TAG, "Exception occurred: ");
  415. e.printStackTrace();
  416. }
  417. }
  418. }
  419. private void updateLocationUI() {
  420. if (mMap == null) {
  421. if (BuildConfig.DEBUG) {
  422. Log.d(TAG, "Permission: Map not ready!");
  423. }
  424. return;
  425. }
  426. try {
  427. if (mLocationPermissionGranted) {
  428. mMap.setMyLocationEnabled(true);
  429. mMap.getUiSettings().setMapToolbarEnabled(true);
  430. mMap.getUiSettings().setMyLocationButtonEnabled(true);
  431. mMap.getUiSettings().setCompassEnabled(true);
  432. mMap.getUiSettings().setZoomControlsEnabled(true);
  433. if (BuildConfig.DEBUG) {
  434. Log.d(TAG, "Permission: Granted!");
  435. }
  436. } else {
  437. mMap.setMyLocationEnabled(false);
  438. mMap.getUiSettings().setMyLocationButtonEnabled(false);
  439. mMap.getUiSettings().setZoomControlsEnabled(false);
  440. mMap.getUiSettings().setCompassEnabled(false);
  441. mMap.getUiSettings().setMapToolbarEnabled(false);
  442. mLastKnownLocation = null;
  443. if (BuildConfig.DEBUG) {
  444. Log.d(TAG, "Permission: Denied!");
  445. }
  446. getLocationPermission();
  447. }
  448. } catch (SecurityException e) {
  449. if (BuildConfig.DEBUG) {
  450. Log.e(TAG, "Exception occurred: ");
  451. e.printStackTrace();
  452. }
  453. }
  454. for (OwnTask task: allTasks)
  455. {
  456. MarkerOptions marker = new MarkerOptions();
  457. //set options
  458. marker.position(new LatLng(task.getLocation().getLatitude(), task.getLocation().getLongitude()));
  459. marker.title(task.getTitle());
  460. mMap.addMarker(marker);
  461. }
  462. drawAreas();
  463. }
  464. /**
  465. * Decides color of area based on the time passed since last ckeck update.
  466. *
  467. * @param time difference in milliseconds between last check and now
  468. * @return color number
  469. */
  470. private int getAreaColor(long time) {
  471. //set transparency related to time difference
  472. if(time > -1)
  473. {
  474. long timeDiff = new Date().getTime() - time;
  475. //less than a week
  476. if (timeDiff < 7*24*60*60*1000L)
  477. {
  478. return Color.parseColor("#57a639");
  479. }
  480. //less than two weeks
  481. else if (timeDiff < 14*24*60*60*1000L)
  482. {
  483. return Color.parseColor("#819b45");
  484. }
  485. //less than three weeks
  486. else if (timeDiff < 21*24*60*60*1000L)
  487. {
  488. return Color.parseColor("#d3d30c");
  489. }
  490. //less than four weeks
  491. else if (timeDiff < 28*24*60*60*1000L)
  492. {
  493. return Color.parseColor("#df9600");
  494. }
  495. //less than 6 weeks
  496. else if (timeDiff < 42*24*60*60*1000L)
  497. {
  498. return Color.parseColor("#df3d00");
  499. }
  500. //longer than four weeks
  501. else
  502. {
  503. return Color.parseColor("#f70000");
  504. }
  505. }
  506. else
  507. {
  508. return Color.parseColor("#f70000");
  509. }
  510. }
  511. /**
  512. * Request read external storage permission, so that we can get saved images from external storage.
  513. * The result of the permission request is handled by a callback,
  514. * onRequestPermissionsResult.
  515. *
  516. */
  517. private void getReadStoragePermission() {
  518. if (ContextCompat.checkSelfPermission(getActivity().getApplicationContext(),
  519. Manifest.permission.READ_EXTERNAL_STORAGE)
  520. == PackageManager.PERMISSION_GRANTED) {
  521. mReadStorageGranted = true;
  522. } else {
  523. ActivityCompat.requestPermissions(getActivity(),
  524. new String[]{android.Manifest.permission.READ_EXTERNAL_STORAGE},
  525. READ_EXTERNAL_STORAGE_CODE);
  526. }
  527. }
  528. /**
  529. * Reads tasks saved in preferences as jsonStrings
  530. *
  531. * @return list of OwnTask
  532. */
  533. private List<OwnTask> readTasksFromPreferences() {
  534. List<OwnTask> tasks = new ArrayList<>();
  535. try {
  536. String jsonString = PreferenceManager.getDefaultSharedPreferences(getContext()).getString(KEY_ALL_TASKS, "error");
  537. if(!"error".equalsIgnoreCase(jsonString)) {
  538. JSONArray jsonObjects = new JSONArray(jsonString);
  539. for (int i = 0; i<jsonObjects.length();i++) {
  540. tasks.add(new OwnTask(jsonObjects.getJSONObject(i)));
  541. if (BuildConfig.DEBUG) {
  542. Log.d(TAG, "Task loaded from shared preferences: " + tasks.get(i).toString());
  543. }
  544. Bitmap image = BitmapFactory.decodeFile(tasks.get(i).getPathImage() + File.separator + tasks.get(i).getId() + ".jpeg");
  545. if (BuildConfig.DEBUG) {
  546. Log.d(TAG, "Image loaded from shared preferences: " + image.getByteCount());
  547. }
  548. tasks.get(i).setImage(image);
  549. }
  550. }
  551. } catch (JSONException e) {
  552. if (BuildConfig.DEBUG) {
  553. Log.e(TAG, "Error while parsing tasks as jsonObjects from preferences");
  554. e.printStackTrace();
  555. }
  556. }
  557. return tasks;
  558. }
  559. @Override
  560. public void onMapReady(GoogleMap googleMap) { }
  561. }