Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package se.malmo.lighthouse.siberianhusky;
- import android.Manifest;
- import android.annotation.TargetApi;
- import android.app.AlertDialog;
- import android.app.NotificationManager;
- import android.app.PendingIntent;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.DialogInterface;
- import android.content.Intent;
- import android.content.IntentFilter;
- import android.content.pm.PackageManager;
- import android.location.Location;
- import android.os.Bundle;
- import android.support.annotation.NonNull;
- import android.support.v4.app.ActivityCompat;
- import android.support.v4.app.NotificationCompat;
- import android.support.v4.content.ContextCompat;
- import android.util.Log;
- import android.view.View;
- import android.widget.Button;
- import android.widget.SeekBar;
- import android.widget.TextView;
- import android.widget.Toast;
- import com.google.android.gms.maps.CameraUpdateFactory;
- import com.google.android.gms.maps.GoogleMap;
- import com.google.android.gms.maps.OnMapReadyCallback;
- import com.google.android.gms.maps.SupportMapFragment;
- import com.google.android.gms.maps.model.LatLng;
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import se.malmo.lighthouse.siberianhusky.Services.SavedRouteService;
- import se.malmo.lighthouse.siberianhusky.models.Contact;
- import se.malmo.lighthouse.siberianhusky.models.MapLocationDrawer;
- import se.malmo.lighthouse.siberianhusky.models.Route;
- import se.malmo.lighthouse.siberianhusky.models.RouteCoordinate;
- import se.malmo.lighthouse.siberianhusky.models.SMSClass;
- import se.malmo.lighthouse.siberianhusky.repositories.DataBaseFetcher;
- import se.malmo.lighthouse.siberianhusky.utils.Constants;
- import se.malmo.lighthouse.siberianhusky.utils.DistanceConverter;
- import se.malmo.lighthouse.siberianhusky.utils.NotificationWrapper;
- public class RunSelectedRouteActivity extends ToolbarMenu implements OnMapReadyCallback, SeekBar.OnSeekBarChangeListener, GoogleMap.OnMapLoadedCallback {
- public static final int MY_PERMISSIONS_REQUEST_CODE = 100;
- private List<Contact> emergencyList;
- private DataBaseFetcher dataBaseFetcher;
- private Route route;
- private GoogleMap map;
- private MapLocationDrawer mapLocationDrawer;
- private List<LatLng> polyList;
- private boolean paused;
- private boolean isWithin;
- private boolean hasReceievedBroadcast;
- private int routeIDHolder;
- private AlertDialog dialog;
- private AlertDialog.Builder builder;
- private TextView sliderText;
- private SeekBar slideBar;
- private Button emergencyButton;
- private Button pauseOrResumeButton;
- private boolean minimized = false;
- private boolean serviceIsRunning;
- private Location lastLocation;
- private Location currentLocation;
- private BroadcastReceiver broadcastReceiver;
- @Override
- protected void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- setContentView(R.layout.tracking_activity);
- SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
- mapFragment.getMapAsync(this);
- dataBaseFetcher = new DataBaseFetcher(this);
- route = dataBaseFetcher.getRouteByID(getIntent().getExtras().getInt("routeID"));
- emergencyList = dataBaseFetcher.getAllContacts(); // Get contacts
- mapLocationDrawer = new MapLocationDrawer(this);
- polyList = new ArrayList<>();
- routeIDHolder = route.getRouteID();
- for (RouteCoordinate rc : route.getRouteCoordinates()) {
- LatLng latLng = new LatLng(rc.getLatitude(), rc.getLongtitude());
- polyList.add(latLng);
- }
- /**
- * Init the last location
- */
- lastLocation = new Location("Destination");
- lastLocation.setLatitude(polyList.get(polyList.size() - 1).latitude);
- lastLocation.setLongitude(polyList.get(polyList.size() - 1).longitude);
- /**
- * Get everything necessary from View
- */
- pauseOrResumeButton = (Button) findViewById(R.id.tracking_activity_pause_resume);
- Button finishButton = (Button) findViewById(R.id.tracking_activity_finish);
- emergencyButton = (Button) findViewById(R.id.tracking_activity_Emergency);
- slideBar = (SeekBar) findViewById(R.id.seekbar);
- sliderText = (TextView) findViewById(R.id.slider_text);
- sliderText.setText(R.string.slide_to_send);
- slideBar.setOnSeekBarChangeListener(this);
- paused = false;
- /**
- * Either pause or resume
- */
- pauseOrResumeButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- if (!paused) {
- paused = true;
- pauseOrResumeButton.setText("Resume");
- Intent intent = new Intent(RunSelectedRouteActivity.this, SavedRouteService.class);
- stopService(intent);
- serviceIsRunning = false;
- } else {
- paused = false;
- pauseOrResumeButton.setText("Pause");
- Intent intent = new Intent(RunSelectedRouteActivity.this, SavedRouteService.class);
- Bundle bundle = new Bundle();
- bundle.putInt("routeID", route.getRouteID());
- intent.putExtras(bundle);
- startService(intent);
- serviceIsRunning = true;
- }
- }
- });
- /**
- * User clicked on finish, code below is pretty self explanatory.
- */
- finishButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- String distanceType = dataBaseFetcher.getSettings().getDistanceType();
- double distanceToLast = 0;
- if (currentLocation != null && lastLocation != null) {
- distanceToLast = currentLocation.distanceTo(lastLocation);
- if (DistanceConverter.isKilometers(distanceType) && distanceToLast < 1000) { // meter is displayed
- distanceType = "m";
- } else { // km or miles is displayed
- distanceToLast = DistanceConverter.convertDistance(distanceToLast, distanceType);
- }
- }
- builder = new AlertDialog.Builder(RunSelectedRouteActivity.this);
- builder.setMessage(getString(R.string.finish_dialog, distanceToLast, distanceType));
- builder.setPositiveButton("Finish", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- if (broadcastReceiver != null) {
- unregisterReceiver(broadcastReceiver);
- }
- /**
- * Kill the service and send the user back to the start menu
- */
- Intent intent = new Intent(RunSelectedRouteActivity.this, SavedRouteService.class);
- stopService(intent);
- intent = new Intent(RunSelectedRouteActivity.this, StartMenuActivity.class);
- startActivity(intent);
- dialog.dismiss();
- }
- });
- /**
- * Just do nothing
- */
- builder.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- dialog.dismiss();
- }
- });
- builder.create();
- builder.show();
- }
- });
- /**
- * Send emergency SMS
- */
- emergencyButton.setOnClickListener(new View.OnClickListener() {
- @Override
- public void onClick(View v) {
- emergencyButtonHandler(); // Run send emergency.
- resetSlider();
- }
- });
- }
- /**
- * Seekbar methods
- *
- */
- @Override
- public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
- if (progress > Constants.P_95) {
- seekBar.setThumb(ContextCompat.getDrawable(this, R.drawable.slider_icon));
- }
- }
- /**
- * Displaying a double with very many decimals isn't very useful for the user, so I wrote a method to simply convert a double to something more appropriate to show the user.
- * Converts a double, if it's below 1k, only pull the meters from the double, if it's above 1k, convert it do display something like: x.yy
- *
- * @param convertFrom the double you want to convert
- * @return the converted double
- */
- private Double convertDouble(double convertFrom) {
- double converted = 0;
- String value = String.valueOf(convertFrom);
- if (convertFrom < 1000) {
- String s = value.substring(0, 3);
- converted = Double.parseDouble(s);
- } else if (convertFrom > 1000) {
- char[] parts = new char[]{
- value.charAt(0),
- '.',
- value.charAt(1),
- value.charAt(2)
- };
- String s = String.valueOf(parts);
- converted = Double.parseDouble(s);
- }
- return converted;
- }
- @Override
- public void onStartTrackingTouch(SeekBar seekBar) {
- sliderText.setVisibility(View.INVISIBLE);
- }
- @Override
- public void onStopTrackingTouch(SeekBar seekBar) {
- Log.d("onStopTrackingTouch", "onStopTrackingTouch");
- if (seekBar.getProgress() < Constants.P_80) {
- seekBar.setProgress(Constants.ZERO);
- slideBar.setBackgroundResource(R.drawable.slider_bg_red);
- sliderText.setVisibility(View.VISIBLE);
- sliderText.setText(R.string.slide_to_send);
- } else {
- seekBar.setProgress(Constants.P_100);
- sliderText.setVisibility(View.VISIBLE);
- sliderText.setText(R.string.click_to_send);
- slideBar.setVisibility(View.INVISIBLE);
- emergencyButton.setVisibility(View.VISIBLE);
- }
- }
- private void resetSlider() {
- slideBar.setVisibility(View.VISIBLE);
- slideBar.setProgress(Constants.ZERO);
- emergencyButton.setVisibility(View.INVISIBLE);
- slideBar.setBackgroundResource(R.drawable.slider_bg_red);
- sliderText.setVisibility(View.VISIBLE);
- sliderText.setText(R.string.slide_to_send);
- }
- /**
- * Check SEND_SMS and ACCESS_FINE_LOCATION permissions
- */
- @TargetApi(23)
- private boolean checkAndRequestPermissions() {
- int sendSMSPermission = checkSelfPermission(android.Manifest.permission.SEND_SMS);
- int accessFineLocationPermission = checkSelfPermission(Manifest.permission.ACCESS_FINE_LOCATION);
- List<String> listPermissionsNeeded = new ArrayList<>();
- if (sendSMSPermission != PackageManager.PERMISSION_GRANTED) {
- listPermissionsNeeded.add(Manifest.permission.SEND_SMS);
- }
- if (accessFineLocationPermission != PackageManager.PERMISSION_GRANTED) {
- listPermissionsNeeded.add(Manifest.permission.ACCESS_FINE_LOCATION);
- }
- if (!listPermissionsNeeded.isEmpty()) {
- requestPermissions(listPermissionsNeeded.toArray(new String[listPermissionsNeeded.size()]), MY_PERMISSIONS_REQUEST_CODE);
- return false;
- }
- return true;
- }
- @TargetApi(23)
- @Override
- public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
- switch (requestCode) {
- case MY_PERMISSIONS_REQUEST_CODE: {
- Map<String, Integer> permissionsMap = new HashMap<>();
- // Initialize the map with both permissions
- permissionsMap.put(Manifest.permission.SEND_SMS, PackageManager.PERMISSION_GRANTED);
- permissionsMap.put(Manifest.permission.ACCESS_FINE_LOCATION, PackageManager.PERMISSION_GRANTED);
- // Fill with actual results from user
- if (grantResults.length > Constants.ZERO) {
- for (int i = Constants.ZERO; i < permissions.length; i++) {
- permissionsMap.put(permissions[i], grantResults[i]);
- }
- // Check for both permissions
- if (permissionsMap.get(Manifest.permission.SEND_SMS) == PackageManager.PERMISSION_GRANTED && permissionsMap.get(Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
- Toast.makeText(RunSelectedRouteActivity.this, "Both Permissions Granted", Toast.LENGTH_SHORT)
- .show();
- } else {
- // Permission is denied (this is the first time, when "never ask again" is not checked) so ask again explaining the usage of permission
- // shouldShowRequestPermissionRationale will return true
- // Show the dialog or snackbar saying its necessary and try again otherwise proceed with setup.
- if (shouldShowRequestPermissionRationale(Manifest.permission.SEND_SMS) || shouldShowRequestPermissionRationale(Manifest.permission.ACCESS_FINE_LOCATION)) {
- showDialogOK("SMS and Location Services Permission required for this app", new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialog, int which) {
- switch (which) {
- case DialogInterface.BUTTON_POSITIVE:
- checkAndRequestPermissions();
- break;
- case DialogInterface.BUTTON_NEGATIVE:
- // proceed with logic by disabling the related features or quit the app.
- break;
- }
- }
- });
- } else {
- Toast.makeText(this, "Go to settings and enable permissions", Toast.LENGTH_LONG)
- .show();
- //proceed with logic by disabling the related features or quit the app. }
- }
- }
- }
- }
- default:
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- }
- }
- /**
- * Called when user clicks Emergency button
- */
- public void emergencyButtonHandler() {
- //if permissions are ok
- if (checkAndRequestPermissions()) {
- SMSClass smsClass = new SMSClass(this);
- if (emergencyList.size() > Constants.ZERO) {
- smsClass.sendSMS(emergencyList, currentLocation.getLatitude(), currentLocation.getLongitude(), dataBaseFetcher.getSettings().getUserTextMessage());
- Toast.makeText(this, "Emergency SMS sent!", Toast.LENGTH_SHORT).show();
- } else {
- // else - show alert - OK: go to add contact, Cancel: go to start menu.
- builder = new AlertDialog.Builder(this);
- builder.setTitle(R.string.no_ICE_title)
- .setMessage(R.string.no_ICE_msg)
- .setPositiveButton(R.string.add_edit_contact, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int id) {
- // Go to contacts
- Intent intent = new Intent(getBaseContext(), ContactActivity.class);
- startActivity(intent);
- }
- })
- .setNegativeButton(R.string.cancel, new DialogInterface.OnClickListener() {
- @Override
- public void onClick(DialogInterface dialogInterface, int id) {
- }
- }
- );
- dialog = builder.create();
- dialog.setCanceledOnTouchOutside(false);
- dialog.setCancelable(false);
- dialog.show();
- }
- }
- resetSlider();
- }
- // Show dialog.
- private void showDialogOK(String message, DialogInterface.OnClickListener okListener) {
- new AlertDialog.Builder(this)
- .setMessage(message)
- .setPositiveButton("OK", okListener)
- .setNegativeButton("Cancel", okListener)
- .create()
- .show();
- }
- @Override
- public void onMapReady(GoogleMap googleMap) {
- map = googleMap;
- map.setOnMapLoadedCallback(this);
- googleMap.setMapType(dataBaseFetcher.getSettings().getMapType());
- /**
- * To avoid NullPointerException we check if the list is empty or not before we perform any logic including it. Get the first coordinate and place a marker from our own class
- * Why not just place the marker without it? Because if we have a method inside it zoom within all the marker positions we "draw" with our drawer.
- * Simply get the first and last index, place markers and zoom within is, kids stuff.
- */
- if (!polyList.isEmpty()) {
- googleMap.addMarker(mapLocationDrawer.addStartLocationMarkerToMap(polyList.get(0)));
- googleMap.addMarker(mapLocationDrawer.addEndLocationMarkerToMap(polyList.get(polyList.size() - 1)));
- mapLocationDrawer.drawRoute(googleMap, polyList);
- map.moveCamera(CameraUpdateFactory.zoomTo(dataBaseFetcher.getSettings().getZoomMap()));
- }
- if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
- googleMap.setMyLocationEnabled(true);
- }
- }
- @Override
- public void onMapLoaded(){
- }
- /**
- * Disable the back button
- */
- @Override
- public void onBackPressed() {
- if(!paused){
- Toast.makeText(RunSelectedRouteActivity.this, "You must pause before you can go back", Toast.LENGTH_SHORT).show();
- }
- else{
- Intent stopServiceIntent = new Intent(this, SavedRouteService.class);
- stopService(stopServiceIntent);
- Intent switchActivityIntent = new Intent(this, SelectRouteActivity.class);
- startActivity(switchActivityIntent);
- }
- }
- @Override
- public void onDestroy() {
- if( dialog != null && dialog.isShowing()) {
- dialog.dismiss();
- }
- super.onDestroy();
- Intent intent = new Intent(RunSelectedRouteActivity.this, SavedRouteService.class);
- stopService(intent);
- if(paused){
- NotificationWrapper.NotificationCancelAll(this);
- }
- resetSlider();
- broadcastReceiver = null;
- }
- @Override
- public void onStop() {
- super.onStop();
- Intent intent = new Intent(RunSelectedRouteActivity.this, SavedRouteService.class);
- stopService(intent);
- if(paused){
- NotificationWrapper.NotificationCancelAll(this);
- }
- resetSlider();
- }
- @Override
- public void onPause(){
- super.onPause();
- resetSlider();
- Intent pauseIntent = new Intent();
- pauseIntent.setAction("PAUSE_ACTION");
- Bundle pauseBundle = new Bundle();
- pauseBundle.putInt("id", routeIDHolder);
- pauseIntent.putExtras(pauseBundle);
- PendingIntent pausePending = PendingIntent.getBroadcast(getBaseContext(), 0, pauseIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- Intent terminateIntent = new Intent();
- pauseIntent.setAction("FINISH_ACTION");
- Bundle terminateBundle = new Bundle();
- terminateBundle.putInt("id", routeIDHolder);
- terminateIntent.putExtras(terminateBundle);
- PendingIntent terminatePending = PendingIntent.getBroadcast(getBaseContext(), 0, terminateIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- if(Constants.serviceStatus.equals("running")){
- NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext())
- .setSmallIcon(R.mipmap.iconsafepassage)
- .setContentTitle("Tracking")
- .addAction(R.drawable.pause_icon, "", pausePending)
- .addAction(R.drawable.stop_icon, "", terminatePending);
- NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- nManager.notify(Constants.SMALL_NOTI_ID, builder.build());
- }
- else{
- Intent resumeIntent = new Intent();
- resumeIntent.setAction("RESUME_ACTION");
- Bundle resumeBundle = new Bundle();
- resumeBundle.putInt("id", routeIDHolder);
- resumeBundle.putString("Flag", "RunSelectedRoute");
- resumeIntent.putExtras(resumeBundle);
- PendingIntent resumePending = PendingIntent.getBroadcast(getBaseContext(), 0, resumeIntent, PendingIntent.FLAG_UPDATE_CURRENT);
- NotificationCompat.Builder builder = new NotificationCompat.Builder(getBaseContext())
- .setSmallIcon(R.mipmap.iconsafepassage)
- .setContentTitle("Tracking")
- .addAction(R.drawable.resume_icon, "", resumePending)
- .addAction(R.drawable.stop_icon, "", terminatePending);
- NotificationManager nManager = (NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
- nManager.notify(Constants.SMALL_NOTI_ID, builder.build());
- }
- minimized = true;
- unregisterReceiver(broadcastReceiver);
- }
- @TargetApi(16)
- @Override
- public void onResume() {
- super.onResume();
- dataBaseFetcher = new DataBaseFetcher(this);
- emergencyList = dataBaseFetcher.getAllContacts();
- broadcastReceiver = new BroadcastReceiver() {
- @Override
- public void onReceive(Context context, Intent intent) {
- currentLocation = intent.getExtras().getParcelable("currentLocation");
- if (currentLocation.getLatitude() > 0 && currentLocation.getLatitude() > 0) {
- map.animateCamera(CameraUpdateFactory.newLatLngZoom(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()), dataBaseFetcher.getSettings().getZoomMap()));
- Log.d("Pos: ", "" + currentLocation.getLatitude());
- }
- /**
- * DON'T NEED THIS AT THE MOMENT, LEAVE IT HERE THOUGH. This is connected to the onLocationChanged method in the SavedRouteService.
- */
- /*
- if(!isWithin && hasReceievedBroadcast){
- TaskStackBuilder stackBuilder = TaskStackBuilder.create(getBaseContext());
- stackBuilder.addParentStack(RunSelectedRouteActivity.class);
- stackBuilder.addNextIntent(new Intent(RunSelectedRouteActivity.this, RunSelectedRouteActivity.class));
- NotificationCompat.Builder simpleNoti = new NotificationCompat.Builder(getBaseContext())
- .setSmallIcon(R.mipmap.ic_launcher)
- .setContentTitle("Deviated from Route!")
- .setContentText("You have deviated from your route, please go back or pause the app")
- .setVibrate(new long[] {0, 1000, 500, 1000});
- }
- */
- }
- };
- Log.d("FROM SERVICE, STATUS: ", Constants.serviceStatus);
- if(Constants.serviceStatus.equals("notRunning")){
- pauseOrResumeButton.setText("Resume");
- }
- else{
- pauseOrResumeButton.setText("Pause");
- }
- registerReceiver(broadcastReceiver, new IntentFilter("locationUpdates"));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement