Projektarbeit
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.

EarthquakeMapsActivity.java 13KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304
  1. package de.edotzlaff.schockwelle;
  2. import android.Manifest;
  3. import android.content.Context;
  4. import android.content.pm.PackageManager;
  5. import android.location.Location;
  6. import android.os.Bundle;
  7. import android.os.CountDownTimer;
  8. import android.os.SystemClock;
  9. import android.util.Log;
  10. import android.widget.Button;
  11. import android.widget.TextView;
  12. import android.widget.Toast;
  13. import android.hardware.Sensor;
  14. import android.hardware.SensorEvent;
  15. import android.hardware.SensorEventListener;
  16. import android.hardware.SensorManager;
  17. import androidx.annotation.NonNull;
  18. import androidx.core.app.ActivityCompat;
  19. import androidx.core.content.ContextCompat;
  20. import androidx.fragment.app.FragmentActivity;
  21. import com.google.android.gms.location.FusedLocationProviderClient;
  22. import com.google.android.gms.location.LocationServices;
  23. import com.google.android.gms.maps.CameraUpdateFactory;
  24. import com.google.android.gms.maps.GoogleMap;
  25. import com.google.android.gms.maps.OnMapReadyCallback;
  26. import com.google.android.gms.maps.SupportMapFragment;
  27. import com.google.android.gms.maps.model.LatLng;
  28. import com.google.android.gms.maps.model.MarkerOptions;
  29. import com.google.android.gms.tasks.OnCompleteListener;
  30. import com.google.android.gms.tasks.Task;
  31. import com.google.firebase.database.DataSnapshot;
  32. import com.google.firebase.database.DatabaseError;
  33. import com.google.firebase.database.DatabaseReference;
  34. import com.google.firebase.database.FirebaseDatabase;
  35. import com.google.firebase.database.ValueEventListener;
  36. import java.util.Calendar;
  37. import java.util.Date;
  38. import java.util.Objects;
  39. public class EarthquakeMapsActivity extends FragmentActivity implements OnMapReadyCallback {
  40. private static final String TAG = "MainActivity";
  41. private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
  42. private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
  43. //vars
  44. private Boolean mLocationPermissionsGranted = false;
  45. private GoogleMap mMap;
  46. private FusedLocationProviderClient mFusedLocationProviderClient;
  47. private DatabaseReference mDatenbank;
  48. //Date currentTime; //Workaround für Crash: currentTime nicht als Datum sondern als Long zeitstempel
  49. Long currentTime;
  50. Location currentLocation;
  51. private double breitengrad;
  52. private double laengengrad;
  53. //Shake Sensor
  54. private SensorManager mSensorManager;
  55. private static final float mUpperThreshold = 10.5f; // für Emulator auf 1.5 setzen
  56. private static final float mLowerThreshold = 5.5f; // für Emulator auf 0.5 setzen
  57. private static final long mShakeDetectionLockTimeMicroSeconds = 10000;
  58. private float mAccel;
  59. private float mAccelCurrent;
  60. private float mAccelLast;
  61. private boolean mShakeDetectionIsActive = false;
  62. private boolean mShakeDetected = false;
  63. private CountDownTimer mLockTimer = new CountDownTimer(mShakeDetectionLockTimeMicroSeconds, 1000) {
  64. public void onTick(long millisUntilFinished) {
  65. ((TextView) findViewById(R.id.txtEarthquake)).setText("Earthquake started! Detection locked for " + millisUntilFinished / 1000 + " s");
  66. }
  67. public void onFinish() {
  68. mShakeDetectionIsActive = true;
  69. mShakeDetected = false;
  70. Toast.makeText(getApplicationContext(), "Shake Detection unlocked", Toast.LENGTH_SHORT).show();
  71. ( (TextView) findViewById(R.id.txtEarthquake)).setText("Shake your Smartphone for an Earthquake");
  72. }
  73. };
  74. @Override
  75. protected void onCreate(Bundle savedInstanceState) {
  76. super.onCreate(savedInstanceState);
  77. setContentView(R.layout.activity_earthquake_maps);
  78. TextView txtEarthquake = (TextView) findViewById(R.id.txtEarthquake);
  79. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
  80. Objects.requireNonNull(mSensorManager).registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
  81. mAccel = 1f;
  82. mAccelCurrent = SensorManager.GRAVITY_EARTH;
  83. mAccelLast = SensorManager.GRAVITY_EARTH;
  84. mShakeDetectionIsActive = true;
  85. mShakeDetected = false;
  86. getDataBaseValues(); //TODO Edward: Nur als Anmerkung, diese Methode erfolgt damit deine Methode getDeviceLocation rechtzeitig Koordinaten aus der DB bekommt
  87. //TODO Hast schon echt viel erledigt :D Ich habe gedacht das die Class EarthquakeMapsActivity Daten an die DB schickt und die SensorMapsActivity die Daten bekommt, ich glaub die Funktion muss in die andere Class
  88. getLocationPermission();
  89. }
  90. private final SensorEventListener mSensorListener = new SensorEventListener() {
  91. @Override
  92. public void onSensorChanged(SensorEvent event) {
  93. float x = event.values[0];
  94. float y = event.values[1];
  95. float z = event.values[2];
  96. mAccelLast = mAccelCurrent;
  97. mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
  98. float delta = mAccelCurrent - mAccelLast;
  99. mAccel = mAccel * 0.9f + delta;
  100. // Log.d(TAG,"mAccel: "+ mAccel);
  101. if (mShakeDetectionIsActive) {
  102. if(Math.abs(mAccel) > mUpperThreshold) {
  103. new CountDownTimer(50, 10) {
  104. public void onTick(long millisUntilFinished) {
  105. if (Math.abs(mAccel) > mUpperThreshold) {
  106. mShakeDetectionIsActive = false;
  107. } else if (Math.abs(mAccel) < mLowerThreshold) {
  108. mShakeDetectionIsActive = true;
  109. this.cancel();
  110. }
  111. }
  112. public void onFinish() {
  113. if (Math.abs(mAccel) > mUpperThreshold) {
  114. mShakeDetectionIsActive = false;
  115. mShakeDetected = true;
  116. Toast.makeText(getApplicationContext(), "Shake event detected", Toast.LENGTH_SHORT).show();
  117. writeEarthquakeToDatabase();
  118. mLockTimer.start();
  119. } else {
  120. mShakeDetectionIsActive = true;
  121. mShakeDetected = false;
  122. }
  123. }
  124. }.start();
  125. }
  126. }
  127. }
  128. @Override
  129. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  130. }
  131. };
  132. private void writeEarthquakeToDatabase()
  133. {
  134. //TODO Erdbeben + Erzeugerparameter in Datenbank schreiben
  135. }
  136. @Override
  137. protected void onResume() {
  138. mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER),
  139. SensorManager.SENSOR_DELAY_NORMAL);
  140. super.onResume();
  141. }
  142. @Override
  143. protected void onPause() {
  144. mSensorManager.unregisterListener(mSensorListener);
  145. super.onPause();
  146. }
  147. private void getLocationPermission() {
  148. String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
  149. if (ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
  150. mLocationPermissionsGranted = true;
  151. initMap();
  152. } else {
  153. ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
  154. }
  155. }
  156. @Override
  157. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  158. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  159. mLocationPermissionsGranted = false;
  160. switch (requestCode) {
  161. case LOCATION_PERMISSION_REQUEST_CODE: {
  162. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  163. mLocationPermissionsGranted = true;
  164. //initalize or map
  165. initMap();
  166. }
  167. }
  168. }
  169. }
  170. private void initMap() {
  171. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
  172. mapFragment.getMapAsync(this);
  173. }
  174. @Override
  175. public void onMapReady(GoogleMap googleMap) {
  176. Toast.makeText(this, "Map is ready", Toast.LENGTH_SHORT).show();
  177. mMap = googleMap;
  178. if (mLocationPermissionsGranted) {
  179. getDeviceLocation();
  180. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
  181. != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
  182. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  183. return;
  184. }
  185. mMap.setMyLocationEnabled(true);
  186. }
  187. // Add a marker in Sydney and move the camera
  188. //LatLng sydney = new LatLng(-34, 151);
  189. //mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
  190. //mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
  191. }
  192. private void getDeviceLocation(){
  193. mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
  194. try {
  195. if (mLocationPermissionsGranted){
  196. final Task location = mFusedLocationProviderClient.getLastLocation();
  197. location.addOnCompleteListener(new OnCompleteListener() {
  198. @Override
  199. public void onComplete(@NonNull Task task) {
  200. if (task.isSuccessful()){
  201. currentLocation = (Location) task.getResult();
  202. //currentTime = Calendar.getInstance().getTime(); //Workaround für Crash: currentTime nicht als Datum sondern als Long zeitstempel
  203. currentTime = Calendar.getInstance().getTimeInMillis();
  204. Toast.makeText(EarthquakeMapsActivity.this, currentTime.toString(), Toast.LENGTH_SHORT).show();
  205. currentLocation.setLatitude(breitengrad);
  206. currentLocation.setLongitude(laengengrad);
  207. setDataBaseValues(); //TODO Edward: Die Funktion geht jetzt. Statt Datum wird Unix Zeitstempel als Long Typ verwendet
  208. moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),15f);
  209. }
  210. else{
  211. Toast.makeText(EarthquakeMapsActivity.this, "Current Location unavailable", Toast.LENGTH_SHORT).show();
  212. }
  213. }
  214. });
  215. }
  216. }catch (SecurityException e){
  217. Log.e(TAG,"Device Location not found" + e.getMessage());
  218. }
  219. }
  220. private void moveCamera(LatLng latlng, float zoom){
  221. Log.d(TAG,"Latitude: "+latlng.latitude+"Longitude: "+latlng.longitude);
  222. mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, zoom));
  223. }
  224. public void getDataBaseValues()
  225. {
  226. mDatenbank = FirebaseDatabase.getInstance().getReference();
  227. mDatenbank.addValueEventListener(new ValueEventListener() {
  228. @Override
  229. public void onDataChange(@NonNull DataSnapshot snapshot) {
  230. processDataBaseValues(snapshot); //Daten Snapshot, Übergabe an processDataBaseValues
  231. }
  232. @Override
  233. public void onCancelled(@NonNull DatabaseError error) {
  234. getDataBaseFailure(error);
  235. }
  236. });
  237. }
  238. public void processDataBaseValues (DataSnapshot data)
  239. {
  240. //####### Hier wird beispielweise mit IDG1 gearbeitet, sollte aber klüger ausgearbeitet werden #######:
  241. String breitengradString = data.child("overview").child("IDG1").child("breitengrad").getValue().toString(); //TODO Aron/Team: Idee für passende ID je nach zugreifendem Gerät ==> Hardcoded oder flexibel?
  242. String laengengradString = data.child("overview").child("IDG1").child("laengengrad").getValue().toString();
  243. breitengrad = Double.parseDouble(breitengradString);
  244. laengengrad = Double.parseDouble(laengengradString);
  245. }
  246. public void getDataBaseFailure (DatabaseError error)
  247. {
  248. System.out.println("Fehler");
  249. Log.w("Datenbankfehler", error.toException());
  250. }
  251. //TODO Edward: Hier ist eine beispielhafte Methode mit der du Werte in der Datenbank setzen kannst
  252. public void setDataBaseValues()
  253. {
  254. mDatenbank = FirebaseDatabase.getInstance().getReference();
  255. mDatenbank.child("overview").child("IDG1").child("ip").setValue("10.00.00.001");
  256. mDatenbank.child("overview").child("IDG1").child("vibration").setValue(true);
  257. mDatenbank.child("overview").child("IDG1").child("timestamp").setValue(currentTime); //aktueller Zeitstempel wird in Datenbank eingetragen
  258. mDatenbank.child("overview").child("IDG1").child("breitengrad").setValue(currentLocation.getLatitude()); //aktueller Breitengrad
  259. mDatenbank.child("overview").child("IDG1").child("laengengrad").setValue(currentLocation.getLongitude()); //aktueller Längergrad
  260. mDatenbank.child("overview").child("IDG1").child("amplitude").setValue(1001);
  261. }
  262. }