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

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
  1. package de.edotzlaff.schockwelle;
  2. import android.Manifest;
  3. import android.app.ActionBar;
  4. import android.content.Context;
  5. import android.content.pm.PackageManager;
  6. import android.hardware.Sensor;
  7. import android.hardware.SensorEvent;
  8. import android.hardware.SensorEventListener;
  9. import android.hardware.SensorManager;
  10. import android.location.Location;
  11. import android.net.wifi.WifiManager;
  12. import android.os.Build;
  13. import android.os.Bundle;
  14. import android.os.CountDownTimer;
  15. import android.os.SystemClock;
  16. import android.provider.ContactsContract;
  17. import android.provider.Settings;
  18. import android.util.Log;
  19. import android.widget.TextView;
  20. import android.widget.Toast;
  21. import androidx.annotation.NonNull;
  22. import androidx.annotation.RequiresApi;
  23. import androidx.core.app.ActivityCompat;
  24. import androidx.core.content.ContextCompat;
  25. import androidx.fragment.app.FragmentActivity;
  26. import com.google.android.gms.location.FusedLocationProviderClient;
  27. import com.google.android.gms.location.LocationServices;
  28. import com.google.android.gms.maps.CameraUpdateFactory;
  29. import com.google.android.gms.maps.GoogleMap;
  30. import com.google.android.gms.maps.OnMapReadyCallback;
  31. import com.google.android.gms.maps.SupportMapFragment;
  32. import com.google.android.gms.maps.model.LatLng;
  33. import com.google.android.gms.maps.model.MarkerOptions;
  34. import com.google.android.gms.tasks.OnCompleteListener;
  35. import com.google.android.gms.tasks.Task;
  36. import com.google.firebase.database.DataSnapshot;
  37. import com.google.firebase.database.DatabaseError;
  38. import com.google.firebase.database.DatabaseReference;
  39. import com.google.firebase.database.FirebaseDatabase;
  40. import com.google.firebase.database.ValueEventListener;
  41. import java.time.LocalDateTime;
  42. import java.time.ZoneOffset;
  43. import java.util.Calendar;
  44. import java.util.Date;
  45. import java.util.Objects;
  46. public class EarthquakeMapsActivity extends FragmentActivity implements OnMapReadyCallback {
  47. private static final String TAG = "MainActivity";
  48. private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION;
  49. private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234;
  50. private Boolean mLocationPermissionsGranted = false;
  51. private GoogleMap mMap;
  52. private FusedLocationProviderClient mFusedLocationProviderClient;
  53. Long currentTime;
  54. Location currentLocation;
  55. private DatabaseReference mDatenbank;
  56. private double breitengrad;
  57. private double laengengrad;
  58. private boolean useOwnGPS;
  59. private int indexID = 1;
  60. //##########################################################################################################################################################################
  61. //################################################################## vvv ShakeParameter vvv ##############################################################################
  62. private SensorManager mSensorManager;
  63. private static final float mUpperThreshold = 10.5f; // für Emulator auf 1.5 setzen
  64. private static final float mLowerThreshold = 5.5f; // für Emulator auf 0.5 setzen
  65. private static final long mShakeDetectionLockTimeMicroSeconds = 10000;
  66. private float mAccel;
  67. private float mAccelCurrent;
  68. private float mAccelLast;
  69. private boolean mShakeDetectionIsActive = false;
  70. private boolean mShakeDetected = false;
  71. private boolean allowShakeEvent = true;
  72. //################################################################## ^^^^ ShakeParameter ^^^^ ############################################################################
  73. //##########################################################################################################################################################################
  74. @Override
  75. protected void onCreate(Bundle savedInstanceState) {
  76. super.onCreate(savedInstanceState);
  77. setContentView(R.layout.activity_earthquake_maps);
  78. getDataBaseValuesNoListener();
  79. sensorManagementInit();
  80. getLocationPermission();
  81. }
  82. //#####################################################################################################################################################################
  83. //################################################################## vvv ShakeCode vvv ##############################################################################
  84. private void sensorManagementInit()
  85. {
  86. TextView txtEarthquake = (TextView) findViewById(R.id.txtEarthquake);
  87. mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
  88. Objects.requireNonNull(mSensorManager).registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
  89. mAccel = 1f;
  90. mAccelCurrent = SensorManager.GRAVITY_EARTH;
  91. mAccelLast = SensorManager.GRAVITY_EARTH;
  92. mShakeDetectionIsActive = true;
  93. mShakeDetected = false;
  94. }
  95. private CountDownTimer mLockTimer = new CountDownTimer(mShakeDetectionLockTimeMicroSeconds, 1000)
  96. {
  97. public void onTick(long millisUntilFinished) {
  98. ((TextView) findViewById(R.id.txtEarthquake)).setText("Earthquake started! Detection locked for " + millisUntilFinished / 1000 + " s");
  99. }
  100. public void onFinish() {
  101. mShakeDetectionIsActive = true;
  102. mShakeDetected = false;
  103. Toast.makeText(getApplicationContext(), "Shake Detection unlocked", Toast.LENGTH_SHORT).show();
  104. ( (TextView) findViewById(R.id.txtEarthquake)).setText("Shake your Smartphone for an Earthquake");
  105. }
  106. };
  107. private final SensorEventListener mSensorListener = new SensorEventListener() {
  108. @Override
  109. public void onSensorChanged(SensorEvent event) {
  110. float x = event.values[0];
  111. float y = event.values[1];
  112. float z = event.values[2];
  113. mAccelLast = mAccelCurrent;
  114. mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z));
  115. float delta = mAccelCurrent - mAccelLast;
  116. mAccel = mAccel * 0.9f + delta;
  117. // Log.d(TAG,"mAccel: "+ mAccel);
  118. if (mShakeDetectionIsActive) {
  119. if(Math.abs(mAccel) > mUpperThreshold) {
  120. new CountDownTimer(50, 10) {
  121. public void onTick(long millisUntilFinished) {
  122. if (Math.abs(mAccel) > mUpperThreshold) {
  123. mShakeDetectionIsActive = false;
  124. } else if (Math.abs(mAccel) < mLowerThreshold) {
  125. mShakeDetectionIsActive = true;
  126. this.cancel();
  127. }
  128. }
  129. @RequiresApi(api = Build.VERSION_CODES.O)
  130. public void onFinish() {
  131. if (Math.abs(mAccel) > mUpperThreshold) {
  132. mShakeDetectionIsActive = false;
  133. mShakeDetected = true;
  134. Toast.makeText(getApplicationContext(), "Shake event detected", Toast.LENGTH_SHORT).show();
  135. writeEarthquakeToDatabase();
  136. mLockTimer.start();
  137. } else {
  138. mShakeDetectionIsActive = true;
  139. mShakeDetected = false;
  140. }
  141. }
  142. }.start();
  143. }
  144. }
  145. }
  146. @Override
  147. public void onAccuracyChanged(Sensor sensor, int accuracy) {
  148. }
  149. };
  150. @RequiresApi(api = Build.VERSION_CODES.O)
  151. private void writeEarthquakeToDatabase()
  152. {
  153. setDataBaseValues();
  154. }
  155. @Override
  156. protected void onResume() {
  157. mSensorManager.registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
  158. super.onResume();
  159. }
  160. @Override
  161. protected void onPause() {
  162. mSensorManager.unregisterListener(mSensorListener);
  163. super.onPause();
  164. }
  165. //################################################################## ^^^^ ShakeCode ^^^^ ############################################################################
  166. //#####################################################################################################################################################################
  167. //#####################################################################################################################################################################
  168. //################################################################## vvv GPS Code vvv ###############################################################################
  169. private void getLocationPermission() {
  170. String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION};
  171. if (ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) {
  172. mLocationPermissionsGranted = true;
  173. initMap();
  174. } else {
  175. ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE);
  176. }
  177. }
  178. @Override
  179. public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
  180. super.onRequestPermissionsResult(requestCode, permissions, grantResults);
  181. mLocationPermissionsGranted = false;
  182. switch (requestCode) {
  183. case LOCATION_PERMISSION_REQUEST_CODE: {
  184. if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
  185. mLocationPermissionsGranted = true;
  186. initMap(); //initalize or map
  187. }
  188. }
  189. }
  190. }
  191. private void initMap() {
  192. SupportMapFragment mapFragment = (SupportMapFragment) getSupportFragmentManager().findFragmentById(R.id.map);
  193. mapFragment.getMapAsync(this);
  194. }
  195. @Override
  196. public void onMapReady(GoogleMap googleMap) {
  197. Toast.makeText(this, "Map is ready", Toast.LENGTH_SHORT).show();
  198. mMap = googleMap;
  199. if (mLocationPermissionsGranted) {
  200. getDeviceLocation();
  201. if (ActivityCompat.checkSelfPermission(this, Manifest.permission.ACCESS_FINE_LOCATION)
  202. != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission(this,
  203. Manifest.permission.ACCESS_COARSE_LOCATION) != PackageManager.PERMISSION_GRANTED) {
  204. return;
  205. }
  206. mMap.setMyLocationEnabled(true);
  207. }
  208. //TODO @ Eddy: Ich denke diesen Code brauchst du auch, oder? :D
  209. //Add a marker in Sydney and move the camera
  210. //LatLng sydney = new LatLng(-34, 151);
  211. //mMap.addMarker(new MarkerOptions().position(sydney).title("Marker in Sydney"));
  212. //mMap.moveCamera(CameraUpdateFactory.newLatLng(sydney));
  213. }
  214. private void getDeviceLocation(){
  215. mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this);
  216. try {
  217. if (mLocationPermissionsGranted){
  218. final Task location = mFusedLocationProviderClient.getLastLocation();
  219. location.addOnCompleteListener(new OnCompleteListener() {
  220. @Override
  221. public void onComplete(@NonNull Task task) {
  222. if (task.isSuccessful()){
  223. currentLocation = (Location) task.getResult();
  224. if(useOwnGPS)
  225. {
  226. breitengrad = currentLocation.getLatitude();
  227. laengengrad = currentLocation.getLongitude();
  228. }
  229. currentLocation.setLatitude(breitengrad);
  230. currentLocation.setLongitude(laengengrad);
  231. moveCamera(new LatLng(currentLocation.getLatitude(), currentLocation.getLongitude()),15f);
  232. }
  233. else{
  234. Toast.makeText(EarthquakeMapsActivity.this, "Current Location unavailable", Toast.LENGTH_SHORT).show();
  235. }
  236. }
  237. });
  238. }
  239. }catch (SecurityException e){
  240. Log.e(TAG,"Device Location not found" + e.getMessage());
  241. }
  242. }
  243. private void moveCamera(LatLng latlng, float zoom){
  244. Log.d(TAG,"Latitude: "+latlng.latitude+"Longitude: "+latlng.longitude);
  245. mMap.moveCamera(CameraUpdateFactory.newLatLngZoom(latlng, zoom));
  246. }
  247. //################################################################## ^^^^ GPS Code ^^^^ #############################################################################
  248. //#####################################################################################################################################################################
  249. //#####################################################################################################################################################################
  250. //################################################################## vvv Datenbank Code vvv #########################################################################
  251. public void getDataBaseValuesNoListener()
  252. {
  253. mDatenbank = FirebaseDatabase.getInstance().getReference();
  254. mDatenbank.child("overviewnodes").get().addOnCompleteListener(new OnCompleteListener<DataSnapshot>() {
  255. @Override
  256. public void onComplete(@NonNull Task<DataSnapshot> task) {
  257. if (!task.isSuccessful()) {
  258. System.out.println("Datenbankfehler in getDataBaseValuesNoListener");
  259. System.out.println("Error getting data: " + task.getException());
  260. }
  261. else {
  262. processDataBaseValues(task.getResult());
  263. }
  264. }
  265. });
  266. }
  267. public void processDataBaseValues (DataSnapshot data)
  268. {
  269. processDeviceIndex(data);
  270. processLocation(data);
  271. //processMessageDisplay(data);
  272. }
  273. public void processDeviceIndex(DataSnapshot data) //Bestimmt freien IDG Index um Daten einschreiben zu können und legt diesen Index als indexID fest.
  274. {
  275. for (int i = 1; i<=5; i++)
  276. {
  277. String androidid = data.child("IDG" + i).child("a_androidid").getValue().toString();
  278. if(androidid.isEmpty())
  279. {
  280. indexID = i;
  281. break;
  282. }else
  283. {
  284. continue;
  285. }
  286. }
  287. }
  288. public void processLocation(DataSnapshot data) //Wenn in DB f_nativegps als true hinterlegt ist, werden infolge eigene GPS koordinaten verwendet. Andernfalls wird Breitengrad und Laegengrad mit IDG = indexID als eigene GPS Daten verwendet
  289. {
  290. String nativegpsString = data.child("IDG" + indexID).child("f_nativegps").getValue().toString();
  291. String breitengradString = data.child("IDG" + indexID).child("d_breitengrad").getValue().toString();
  292. String laengengradString = data.child("IDG" + indexID).child("e_laengengrad").getValue().toString();
  293. if(nativegpsString.equals("true"))
  294. {
  295. useOwnGPS = true;
  296. }else{
  297. useOwnGPS = false;
  298. breitengrad = Double.parseDouble(breitengradString);
  299. laengengrad = Double.parseDouble(laengengradString);
  300. }
  301. }
  302. public void processMessageDisplay(DataSnapshot data)
  303. {
  304. String vibrationString;
  305. String androidid;
  306. for (int i = 1; i<=5; i++)
  307. {
  308. androidid = data.child("overviewnodes").child("IDG" + i).child("a_androidid").getValue().toString();
  309. vibrationString = data.child("overviewnodes").child("IDG" + i).child("g_vibration").getValue().toString();
  310. if((!androidid.isEmpty()) && vibrationString.equals("true"))
  311. {
  312. allowShakeEvent = false;
  313. }
  314. }
  315. }
  316. public String getandroidid ()
  317. {
  318. return Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID);
  319. }
  320. public String getDeviceIpAdress ()
  321. {
  322. WifiManager wm = (WifiManager) getApplicationContext().getSystemService(WIFI_SERVICE);
  323. int ip = wm.getConnectionInfo().getIpAddress();
  324. String ipAddress = String.format("%d.%d.%d.%d",(ip & 0xff),(ip >> 8 & 0xff),(ip >> 16 & 0xff), (ip >> 24 & 0xff));
  325. return ipAddress;
  326. }
  327. @RequiresApi(api = Build.VERSION_CODES.O)
  328. public void setDataBaseValues()
  329. {
  330. mDatenbank = FirebaseDatabase.getInstance().getReference();
  331. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("a_androidid").setValue(getandroidid());
  332. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  333. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("b_localdatetime").setValue(LocalDateTime.now(ZoneOffset.UTC).toString());
  334. }
  335. //mDatenbank.child("overviewnodes").child("IDG" + indexID).child("b_localdatetime").setValue(LocalDateTime.now(ZoneOffset.UTC).toString());
  336. //mDatenbank.child("overviewnodes").child("IDG" + indexID).child("b_localdatetime").setValue(LocalDateTime.now(ZoneOffset.UTC).toString());
  337. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("c_ip").setValue(getDeviceIpAdress());
  338. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("d_breitengrad").setValue(breitengrad);
  339. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("e_laengengrad").setValue(laengengrad);
  340. //mDatenbank.child("overviewnodes").child("IDG" + indexID).child("f_nativegps").setValue(true);
  341. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("g_vibration").setValue(true);
  342. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("h_timestamp").setValue(Calendar.getInstance().getTimeInMillis());
  343. mDatenbank.child("overviewnodes").child("IDG" + indexID).child("i_amplitude").setValue(1000);
  344. }
  345. //################################################################## ^^^^ Datenbank Code ^^^^ #############################################################################
  346. //###########################################################################################################################################################################
  347. }
  348. //Evtl. Redundanter Code
  349. /*
  350. public void getDataBaseValues()
  351. {
  352. mDatenbank = FirebaseDatabase.getInstance().getReference();
  353. mDatenbank.addValueEventListener(new ValueEventListener() {
  354. @Override
  355. public void onDataChange(@NonNull DataSnapshot snapshot) {
  356. processDataBaseValues(snapshot); //Daten Snapshot, Übergabe an processDataBaseValues
  357. }
  358. @Override
  359. public void onCancelled(@NonNull DatabaseError error) {
  360. getDataBaseFailure(error);
  361. }
  362. });
  363. }
  364. public void getDataBaseFailure (DatabaseError error)
  365. {
  366. System.out.println("Datenbankfehler in gerDataBaseFailure");
  367. Log.w("Datenbankfehler", error.toException());
  368. }
  369. */