Advertisement
Guest User

Untitled

a guest
Aug 24th, 2019
190
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 15.99 KB | None | 0 0
  1. package com.wind.app.screens.tabs.outside;
  2.  
  3. import android.Manifest;
  4. import android.annotation.SuppressLint;
  5. import android.content.Context;
  6. import android.content.Intent;
  7. import android.graphics.Color;
  8. import android.graphics.drawable.ColorDrawable;
  9. import android.graphics.drawable.Drawable;
  10. import android.location.Location;
  11. import android.location.LocationManager;
  12. import android.net.Uri;
  13. import android.os.Bundle;
  14. import android.os.Handler;
  15. import android.os.Looper;
  16. import android.text.Spannable;
  17. import android.text.SpannableString;
  18. import android.util.Log;
  19. import android.view.View;
  20. import android.view.inputmethod.EditorInfo;
  21. import android.widget.TextView;
  22.  
  23. import com.google.android.gms.maps.CameraUpdate;
  24. import com.google.android.gms.maps.CameraUpdateFactory;
  25. import com.google.android.gms.maps.GoogleMap;
  26. import com.google.android.gms.maps.OnMapReadyCallback;
  27. import com.google.android.gms.maps.SupportMapFragment;
  28. import com.google.android.gms.maps.model.BitmapDescriptorFactory;
  29. import com.google.android.gms.maps.model.CameraPosition;
  30. import com.google.android.gms.maps.model.LatLng;
  31. import com.google.android.gms.maps.model.Marker;
  32. import com.google.android.gms.maps.model.MarkerOptions;
  33. import com.google.android.gms.maps.model.VisibleRegion;
  34. import com.google.maps.android.ui.IconGenerator;
  35. import com.opencsv.CSVWriter;
  36. import com.sothree.slidinguppanel.SlidingUpPanelLayout;
  37. import com.wind.app.R;
  38. import com.wind.app.base.fragment.BaseViewModelFragment;
  39. import com.wind.app.base.interfaces.OnPermissionRequestListener;
  40. import com.wind.app.base.viewmodel.GenericViewModelFactory;
  41. import com.wind.app.databinding.FragmentAirBubblesBinding;
  42. import com.wind.app.model.OutsideAQI;
  43. import com.wind.app.screens.devices.fragment.AirQualityActivity;
  44. import com.wind.app.utils.Conversion;
  45. import com.wind.app.utils.CustomTypefaceSpan;
  46. import com.wind.app.utils.GeocoderUtils;
  47. import com.wind.app.utils.TextUtils;
  48. import com.wind.app.utils.ViewUtils;
  49.  
  50. import java.io.File;
  51. import java.io.FileWriter;
  52. import java.io.IOException;
  53. import java.util.ArrayList;
  54. import java.util.List;
  55.  
  56. import androidx.annotation.NonNull;
  57. import androidx.annotation.Nullable;
  58. import androidx.core.content.res.ResourcesCompat;
  59. import androidx.lifecycle.ViewModelProviders;
  60. import de.hdodenhof.circleimageview.CircleImageView;
  61.  
  62. public class AirBubblesFragment
  63. extends BaseViewModelFragment<AirBubblesViewModel.AirBubblesViewAction,
  64. AirBubblesViewModel,
  65. FragmentAirBubblesBinding>
  66. implements AirBubblesViewModel.AirBubblesViewAction,
  67. OnMapReadyCallback,
  68. GoogleMap.OnMarkerClickListener {
  69.  
  70. private static final int REQUEST_DELAY = 200;
  71. private static final Drawable TRANSPARENT_DRAWABLE = new ColorDrawable(Color.TRANSPARENT);
  72. private Handler handler = new Handler(Looper.getMainLooper());
  73. private GoogleMap map;
  74. private boolean searchVisible = false;
  75.  
  76. public static AirBubblesFragment build() {
  77. return new AirBubblesFragment();
  78. }
  79.  
  80. @Override
  81. protected AirBubblesViewModel createViewModel() {
  82. return ViewModelProviders.of(this, new GenericViewModelFactory<AirBubblesViewModel>() {
  83.  
  84. @Override
  85. protected AirBubblesViewModel createInstance() {
  86. return new AirBubblesViewModel(getArguments());
  87. }
  88. }).get(AirBubblesViewModel.class);
  89. }
  90.  
  91. @Override
  92. protected AirBubblesViewModel.AirBubblesViewAction createViewActionHandler() {
  93. return this;
  94. }
  95.  
  96. @Override
  97. public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
  98. super.onViewCreated(view, savedInstanceState);
  99. SupportMapFragment mapFragment = (SupportMapFragment) getChildFragmentManager()
  100. .findFragmentById(R.id.map);
  101. mapFragment.getMapAsync(this);
  102.  
  103. setupListeners();
  104. setupObservers();
  105. //initPlaces();
  106. }
  107.  
  108. // private void initPlaces() {
  109. // Places.initialize(getContext(), getString(R.string.google_maps_key));
  110. //
  111. // AutocompleteSupportFragment autocompleteFragment = (AutocompleteSupportFragment)
  112. // getChildFragmentManager().findFragmentById(R.id.autocomplete_fragment);
  113. //
  114. // autocompleteFragment.setPlaceFields(Arrays.asList(Place.Field.ID, Place.Field.NAME));
  115. //
  116. // autocompleteFragment.setOnPlaceSelectedListener(new PlaceSelectionListener() {
  117. // @Override
  118. // public void onPlaceSelected(@NonNull Place place) {
  119. // // TODO: 09.08.2019 close fragment and check camera logic
  120. // Log.d("PLACES_API", "onPlaceSelected: " + place.getLatLng());
  121. // LatLng location = place.getLatLng();
  122. // float zoom = map.getCameraPosition().zoom;
  123. // CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
  124. // location, zoom);
  125. // map.animateCamera(cameraUpdate);
  126. // }
  127. //
  128. // @Override
  129. // public void onError(@NonNull Status status) {
  130. // Log.d("PLACES_API", "onError: " + status);
  131. // }
  132. // });
  133. // }
  134.  
  135. private void setupListeners() {
  136. getBinding().slidingLayout.setFadeOnClickListener(v -> {
  137. getBinding().slidingLayout.setPanelState(SlidingUpPanelLayout.PanelState.COLLAPSED);
  138. });
  139.  
  140. // TODO: 12.08.2019 remove after connecting to google places API
  141. getBinding().locationEt.setOnEditorActionListener((v, actionId, event) -> {
  142. if (actionId == EditorInfo.IME_ACTION_DONE) {
  143. LatLng location = GeocoderUtils.getLocationByAddress(getContext(), v.getText().toString());
  144. if (location != null) {
  145. float zoom = map.getCameraPosition().zoom;
  146. CameraUpdate cameraUpdate = CameraUpdateFactory.newLatLngZoom(
  147. location, zoom);
  148. map.animateCamera(cameraUpdate);
  149. // map.moveCamera(CameraUpdateFactory.newLatLng(location));
  150. // map.animateCamera(CameraUpdateFactory.zoomTo(10), 2000, null);
  151. } else {
  152. showMessage("Given address was not found");
  153. }
  154. return true;
  155. }
  156. return false;
  157. });
  158.  
  159. getBinding().searchBtn.setOnClickListener(v -> {
  160. if (searchVisible) {
  161. getBinding().locationEt.setVisibility(View.GONE);
  162. getBinding().airBubblesTv.setVisibility(View.VISIBLE);
  163. } else {
  164. getBinding().locationEt.setVisibility(View.VISIBLE);
  165. getBinding().airBubblesTv.setVisibility(View.GONE);
  166. }
  167. searchVisible = !searchVisible;
  168. });
  169.  
  170. getBinding().locationBtn.setOnClickListener(new View.OnClickListener() {
  171. @Override
  172. public void onClick(View v) {
  173. Log.d(TAG, "onClick: ");
  174. }
  175. });
  176.  
  177. getBinding().shareBtn.setOnClickListener(new View.OnClickListener() {
  178. @Override
  179. public void onClick(View v) {
  180. Log.d(TAG, "onClick: ");
  181. }
  182. });
  183. }
  184.  
  185. private void setupObservers() {
  186. getViewModel().getMarkerData().observe(this, this::onMarkerDataChanged);
  187. }
  188.  
  189. private void onMarkerDataChanged(ArrayList<OutsideAQI> outsideAQIS) {
  190. map.clear();
  191.  
  192. View markerView = getLayoutInflater().inflate(R.layout.view_map_marker, null);
  193. TextView markerText = markerView.findViewById(R.id.marker_text);
  194. CircleImageView markerBackground = markerView.findViewById(R.id.marker_bg);
  195. IconGenerator iconGenerator = new IconGenerator(getContext());
  196. iconGenerator.setContentView(markerView);
  197. iconGenerator.setBackground(TRANSPARENT_DRAWABLE);
  198.  
  199. boolean isCurrentPointOnScreen = false;
  200.  
  201. for (OutsideAQI data : outsideAQIS) {
  202. boolean shouldUseAQI = false;
  203. int aqiValue = 0;
  204.  
  205. if (data.getAqi() != 0) {
  206. aqiValue = data.getAqi();
  207. shouldUseAQI = true;
  208. } else if (data.getPm25() != 0) {
  209. aqiValue = Conversion.pm2_5_to_aqi((int) data.getPm25());
  210. }
  211.  
  212. //setup and add marker
  213. markerText.setText(String.valueOf(aqiValue));
  214. markerBackground.setImageResource(ViewUtils.getColorBySensorReading(aqiValue, shouldUseAQI));
  215. Marker marker = map.addMarker(new MarkerOptions().
  216. icon(BitmapDescriptorFactory.fromBitmap(iconGenerator.makeIcon())).
  217. position(new LatLng(data.getLatitude(), data.getLongitude()))
  218. );
  219.  
  220. marker.setTag(data);
  221.  
  222. if (isTheSamePoint(getViewModel().getCurrentPointAQI(), data)) {
  223. onMarkerClick(marker);
  224. isCurrentPointOnScreen = true;
  225. }
  226. }
  227.  
  228. //check if point is not on the screen anymore
  229. if (!isCurrentPointOnScreen) {
  230. getViewModel().setCurrentPointAQI(null);
  231. }
  232. }
  233.  
  234. private boolean isTheSamePoint(OutsideAQI p1, OutsideAQI p2) {
  235. if (p1 == null || p2 == null) {
  236. return false;
  237. }
  238. return p1.getLatitude() == p2.getLatitude()
  239. && p1.getLongitude() == p2.getLongitude();
  240. }
  241.  
  242. @Override
  243. protected int getLayoutResId() {
  244. return R.layout.fragment_air_bubbles;
  245. }
  246.  
  247. @Override
  248. public void onMapReady(GoogleMap googleMap) {
  249. this.map = googleMap;
  250. googleMap.setOnMarkerClickListener(this);
  251. googleMap.setOnCameraIdleListener(() -> {
  252. handler.postDelayed(() -> {
  253. VisibleRegion region = map.getProjection().getVisibleRegion();
  254. getViewModel().onCameraIdle(region);
  255. }, REQUEST_DELAY);
  256. });
  257.  
  258. googleMap.setOnCameraMoveStartedListener(i -> {
  259. handler.removeCallbacksAndMessages(null);
  260. });
  261.  
  262. AQIInfoWindowAdapter adapter = new AQIInfoWindowAdapter(getContext());
  263. this.map.setInfoWindowAdapter(adapter);
  264. }
  265.  
  266. @Override
  267. public boolean onMarkerClick(Marker marker) {
  268. OutsideAQI data = (OutsideAQI) marker.getTag();
  269. setupSlidingPanelData(data);
  270. getViewModel().setCurrentPointAQI(data);
  271. int height = getResources().getDimensionPixelSize(R.dimen.sliding_panel_activated_height);
  272. getBinding().slidingLayout.setPanelHeight(height);
  273. marker.showInfoWindow();
  274. return true; // handled by code, no default behaviour
  275. }
  276.  
  277. private void setupSlidingPanelData(OutsideAQI data) {
  278. hideAllSlidingPanelData();
  279. String countryName = TextUtils.getLocationNameByLatLng(getContext(), data.getLatitude(), data.getLongitude());
  280. getBinding().countryTv.setText(countryName);
  281.  
  282. if (data.getAqi() != 0) {
  283. String text = String.valueOf(data.getAqi());
  284. getBinding().aqiLayout.setVisibility(View.VISIBLE);
  285. getBinding().aqiTv.setText(text);
  286. }
  287. if (data.getPm10() != 0) {
  288. Spannable text = getUmgText(data.getPm10());
  289. //String text = String.format(getString(R.string.outside_screen_ugm_format), data.getPm10());
  290. getBinding().pm10Layout.setVisibility(View.VISIBLE);
  291. getBinding().pm10Tv.setText(text);
  292. }
  293. if (data.getPm25() != 0) {
  294. Spannable text = getUmgText(data.getPm25());
  295. getBinding().pm25Layout.setVisibility(View.VISIBLE);
  296. getBinding().pm25Tv.setText(text);
  297. }
  298. if (data.getCo() != 0) {
  299. String text = String.format(getString(R.string.outside_screen_co_format), data.getCo());
  300. getBinding().coLayout.setVisibility(View.VISIBLE);
  301. getBinding().coTv.setText(text);
  302. }
  303. if (data.getNo2() != 0) {
  304. String text = String.format(getString(R.string.outside_screen_ppb_format), data.getNo2());
  305. getBinding().no2Layout.setVisibility(View.VISIBLE);
  306. getBinding().no2Tv.setText(text);
  307. }
  308. if (data.getO3() != 0) {
  309. String text = String.format(getString(R.string.outside_screen_ppm_format), data.getO3());
  310. getBinding().o3Layout.setVisibility(View.VISIBLE);
  311. getBinding().o3Tv.setText(text);
  312. }
  313. if (data.getSo2() != 0) {
  314. String text = String.format(getString(R.string.outside_screen_so2_format), data.getSo2());
  315. getBinding().so2Layout.setVisibility(View.VISIBLE);
  316. getBinding().so2Tv.setText(text);
  317. }
  318.  
  319. }
  320.  
  321. private Spannable getUmgText(float value) {
  322. String numberAndSpace = String.format(getString(R.string.outside_screen_number_space_format), value);
  323. String mu = "\u03BC";
  324. String end = "g/m\u00B3";
  325. Spannable spannable = new SpannableString(numberAndSpace + mu + end);
  326. spannable.setSpan(new CustomTypefaceSpan("", ResourcesCompat.getFont(getContext(), R.font.avenir_bold)),
  327. numberAndSpace.length(),
  328. numberAndSpace.length() + 1,
  329. Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
  330.  
  331. return spannable;
  332. }
  333.  
  334. private void hideAllSlidingPanelData() {
  335. getBinding().aqiLayout.setVisibility(View.GONE);
  336. getBinding().pm10Layout.setVisibility(View.GONE);
  337. getBinding().pm25Layout.setVisibility(View.GONE);
  338. getBinding().coLayout.setVisibility(View.GONE);
  339. getBinding().no2Layout.setVisibility(View.GONE);
  340. getBinding().o3Layout.setVisibility(View.GONE);
  341. getBinding().so2Layout.setVisibility(View.GONE);
  342.  
  343. }
  344.  
  345. @Override
  346. public void showInfoScreen() {
  347. AirQualityActivity.launch(getActivity());
  348. }
  349.  
  350. @Override
  351. public void shareInfo() {
  352. OutsideAQI data = new OutsideAQI();
  353. String fileName = "aqi_data";
  354. File file = new File(getContext().getFilesDir(), fileName);
  355.  
  356. try {
  357. CSVWriter writer = new CSVWriter(new FileWriter(file));
  358. List<String[]> csvFields = new ArrayList<>();
  359. csvFields.add(new String[]{"aqi", String.valueOf(data.getAqi())});
  360. csvFields.add(new String[]{"pm25", String.valueOf(data.getPm25())});
  361. csvFields.add(new String[]{"pm10", String.valueOf(data.getPm10())});
  362. csvFields.add(new String[]{"so2", String.valueOf(data.getSo2())});
  363. csvFields.add(new String[]{"co", String.valueOf(data.getCo())});
  364. csvFields.add(new String[]{"o3", String.valueOf(data.getO3())});
  365. csvFields.add(new String[]{"no2", String.valueOf(data.getNo2())});
  366. writer.writeAll(csvFields);
  367. writer.close();
  368.  
  369. Intent sendIntent = new Intent();
  370. sendIntent.setAction(Intent.ACTION_SEND);
  371. sendIntent.putExtra(Intent.EXTRA_TEXT, "This is my text to send.");
  372. sendIntent.setDataAndType(Uri.fromFile(file), "text/csv");
  373. sendIntent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
  374. startActivity(sendIntent);
  375.  
  376. } catch (IOException e) {
  377.  
  378. }
  379. }
  380.  
  381. private void shareCSV() {
  382.  
  383. }
  384.  
  385. @Override
  386. public void showCurrentLocation() {
  387.  
  388. checkPermission(new OnPermissionRequestListener() {
  389. @Override
  390. public void onPermissionGranted() {
  391. moveMapCameraToCurrentLocation();
  392. }
  393.  
  394. @Override
  395. public void onPermissionDenied() {
  396. Log.d(TAG, "onPermissionDenied: ");
  397. }
  398. }, Manifest.permission.ACCESS_FINE_LOCATION);
  399.  
  400. }
  401.  
  402. @SuppressLint("MissingPermission")
  403. private void moveMapCameraToCurrentLocation() {
  404. LocationManager lm = (LocationManager) getContext().getSystemService(Context.LOCATION_SERVICE);
  405. Location lastKnownLocation = lm.getLastKnownLocation(LocationManager.GPS_PROVIDER);
  406. double lastLat = lastKnownLocation.getLatitude();
  407. double lastLng = lastKnownLocation.getLongitude();
  408.  
  409. float zoom = map.getCameraPosition().zoom;
  410. CameraPosition cameraPosition = new CameraPosition.Builder()
  411. .target(new LatLng(lastLat, lastLng))
  412. .zoom(zoom)
  413. .build();
  414. map.animateCamera(CameraUpdateFactory.newCameraPosition(cameraPosition));
  415. }
  416. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement