package de.edotzlaff.detection; import androidx.annotation.NonNull; import androidx.annotation.RequiresApi; import androidx.appcompat.app.AppCompatActivity; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import android.Manifest; import android.app.Dialog; import android.content.Context; import android.content.Intent; import android.content.pm.PackageManager; import android.hardware.Sensor; import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.location.Location; import android.os.Build; import android.os.Bundle; import android.os.CountDownTimer; import android.provider.Settings; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.TextView; import android.widget.Toast; import com.google.android.gms.common.ConnectionResult; import com.google.android.gms.common.GoogleApiAvailability; import com.google.android.gms.location.FusedLocationProviderClient; import com.google.android.gms.location.LocationServices; import com.google.android.gms.maps.GoogleMap; import com.google.android.gms.tasks.OnCompleteListener; import com.google.android.gms.tasks.Task; import com.google.firebase.database.DataSnapshot; import com.google.firebase.database.DatabaseError; import com.google.firebase.database.DatabaseReference; import com.google.firebase.database.FirebaseDatabase; import com.google.firebase.database.ValueEventListener; import java.time.LocalDateTime; import java.time.ZoneOffset; import java.util.Calendar; import java.util.Objects; public class MainActivity extends AppCompatActivity { private static final String TAG = "MainActivity"; private static final int ERROR_DIALOG_REQUEST = 9001; private static final String FINE_LOCATION = Manifest.permission.ACCESS_FINE_LOCATION; private static final int LOCATION_PERMISSION_REQUEST_CODE = 1234; private Boolean mLocationPermissionsGranted = false; private GoogleMap mMap; private FusedLocationProviderClient mFusedLocationProviderClient; Long currentTime; Location currentLocation; private DatabaseReference mDatenbank; private double breitengrad; private double laengengrad; private boolean useOwnGPS = true; private int indexID = 1; private int writtenDevices = 1; private boolean allowCalculation = true; //########################################################################################################################################################################## //################################################################## vvv SensorParameter vvv ############################################################################## private SensorManager mSensorManager; private static final float mUpperThreshold = 1.0f; // für Emulator auf 1.5 setzen private static final float mLowerThreshold = 0.5f; // für Emulator auf 0.5 setzen private static final long mShakeDetectionLockTimeMicroSeconds = 3500; private float mAccel; private float mAccelCurrent; private float mAccelLast; private boolean mShakeDetectionIsActive = false; private boolean mShakeDetected = false; private boolean allowShakeEvent = true; //################################################################## ^^^^ SensorParameter ^^^^ ############################################################################ //########################################################################################################################################################################## @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); if (isServiceOK()){ init(); } sensorManagementInit(); initDataBase(); getLocationPermission(); getDataBaseValuesWithListener(); } //################################################################## vvv Detection Code vvv ################################################################################### //########################################################################################################################################################################## private void sensorManagementInit() { //TextView txtEarthquake = (TextView) findViewById(R.id.txtEarthquake); mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE); Objects.requireNonNull(mSensorManager).registerListener(mSensorListener, mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL); mAccel = 1f; mAccelCurrent = SensorManager.GRAVITY_EARTH; mAccelLast = SensorManager.GRAVITY_EARTH; mShakeDetectionIsActive = false; mShakeDetected = false; } private final SensorEventListener mSensorListener = new SensorEventListener() { @Override public void onSensorChanged(SensorEvent event) { float x = event.values[0]; float y = event.values[1]; float z = event.values[2]; mAccelLast = mAccelCurrent; mAccelCurrent = (float) Math.sqrt((double) (x * x + y * y + z * z)); float delta = mAccelCurrent - mAccelLast; mAccel = mAccel * 0.9f + delta; // Log.d(TAG,"mAccel: "+ mAccel); if (mShakeDetectionIsActive && !mShakeDetected) { if(Math.abs(mAccel) > mUpperThreshold) { new CountDownTimer(1000, 10) { public void onTick(long millisUntilFinished) { mShakeDetectionIsActive = false; /* if (Math.abs(mAccel) > mUpperThreshold) { mShakeDetectionIsActive = false; } else if (Math.abs(mAccel) < mLowerThreshold) { mShakeDetectionIsActive = true; this.cancel(); } */ } public void onFinish() { if (Math.abs(mAccel) > mUpperThreshold) { mShakeDetectionIsActive = false; mShakeDetected = true; earthquakeDetected(); } else { mShakeDetectionIsActive = true; mShakeDetected = false; } } }.start(); } } } @Override public void onAccuracyChanged(Sensor sensor, int accuracy) { } }; private void earthquakeDetected() { Toast.makeText(getApplicationContext(), "!Earthquake detected!", Toast.LENGTH_SHORT).show(); Log.d(TAG,"!Earthquake detected!"); //Hier wird bei Vibration in Db geschrieben getDataBaseValuesNoListenerForVibration(); Button buttonReadyToDetect = (Button) findViewById(R.id.buttonReadyToDetect); buttonReadyToDetect.setEnabled(true); } //################################################################## ^^^^ Detection Code ^^^^ ################################################################################### //########################################################################################################################################################################## //########################################################################################################################################################################## //################################################################## vvv Get Location from Device vvv #################################################################### private void getLocationPermission() { String[] permissions = {Manifest.permission.ACCESS_FINE_LOCATION}; if (ContextCompat.checkSelfPermission(this.getApplicationContext(), FINE_LOCATION) == PackageManager.PERMISSION_GRANTED) { mLocationPermissionsGranted = true; getDeviceLocation(); } else { ActivityCompat.requestPermissions(this, permissions, LOCATION_PERMISSION_REQUEST_CODE); } } private void getDeviceLocation(){ mFusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this); try { if (mLocationPermissionsGranted){ final Task location = mFusedLocationProviderClient.getLastLocation(); location.addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (task.isSuccessful()){ currentLocation = (Location) task.getResult(); if(useOwnGPS) { breitengrad = currentLocation.getLatitude(); laengengrad = currentLocation.getLongitude(); } currentLocation.setLatitude(breitengrad); currentLocation.setLongitude(laengengrad); //setText(); } else{ Toast.makeText(MainActivity.this, "Current Location unavailable", Toast.LENGTH_SHORT).show(); } } }); } }catch (SecurityException e){ Log.e(TAG,"Device Location not found" + e.getMessage()); } } //################################################################## ^^^^ Get Location from Device ^^^^ ################################################################## //########################################################################################################################################################################## //########################################################################################################################################################################## //################################################################## vvv DB Code vvv ##################################################################################### //TODO Aron //###### Für Start der APP #### public void initDataBase() { getDataBaseValuesNoListener(); } public void getDataBaseValuesNoListener() { mDatenbank = FirebaseDatabase.getInstance().getReference().child("overviewdetection"); mDatenbank.get().addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (!task.isSuccessful()) { System.out.println("Datenbank Fehler in getDataBaseValuesNoListener"); } else { analyzeForEmptyDB(task.getResult()); } } }); } //Methode bestimmt, ob DB mit leer IDGn Felder überhaupt vorhanden ist public void analyzeForEmptyDB(DataSnapshot data) { String androidid; String localedatetime; String breitengrad; String laengengrad; String timestamp; String ampltiude; int emptyIDG =0; for (int i=1; i<=data.getChildrenCount(); i++) { androidid = data.child("IDG" + i).child("a_androidid").getValue().toString(); localedatetime = data.child("IDG" + i).child("b_localdatetime").getValue().toString(); breitengrad = data.child("IDG" + i).child("d_breitengrad").getValue().toString(); laengengrad = data.child("IDG" + i).child("e_laengengrad").getValue().toString(); timestamp = data.child("IDG" + i).child("h_timestamp").getValue().toString(); ampltiude = data.child("IDG" + i).child("i_amplitude").getValue().toString(); if(androidid.isEmpty() && localedatetime.isEmpty() && breitengrad.isEmpty() && laengengrad.isEmpty() && timestamp.isEmpty() && ampltiude.isEmpty()) { emptyIDG++; }else{ emptyIDG--; } } //Wenn DB nicht vorhanden ODER leer ist, erstelle diese DB mit IDG 1-5 if(emptyIDG == data.getChildrenCount()) { for (int i=1; i<=5; i++) { if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { writeEmptyToSecondDataBase(i); } } } } @RequiresApi(api = Build.VERSION_CODES.O) public void writeEmptyToSecondDataBase(int k) { mDatenbank = FirebaseDatabase.getInstance().getReference().child("overviewdetection"); mDatenbank.child("IDG" + k).child("a_androidid").setValue(""); mDatenbank.child("IDG" + k).child("b_localdatetime").setValue(""); mDatenbank.child("IDG" + k).child("d_breitengrad").setValue(""); mDatenbank.child("IDG" + k).child("e_laengengrad").setValue(""); mDatenbank.child("IDG" + k).child("h_timestamp").setValue(""); mDatenbank.child("IDG" + k).child("i_amplitude").setValue(""); /* k=1; mDatenbank.child("IDG" + k).child("a_androidid").setValue(getandroidid()); mDatenbank.child("IDG" + k).child("b_localdatetime").setValue(LocalDateTime.now(ZoneOffset.UTC).toString()); mDatenbank.child("IDG" + k).child("d_breitengrad").setValue(123); mDatenbank.child("IDG" + k).child("e_laengengrad").setValue(456); mDatenbank.child("IDG" + k).child("h_timestamp").setValue(Calendar.getInstance().getTimeInMillis()); */ } //###### Bei Vibration der APP #### public void getDataBaseValuesNoListenerForVibration() { mDatenbank = FirebaseDatabase.getInstance().getReference().child("overviewdetection"); mDatenbank.get().addOnCompleteListener(new OnCompleteListener() { @Override public void onComplete(@NonNull Task task) { if (!task.isSuccessful()) { System.out.println("Datenbank Fehler in getDataBaseValuesNoListener"); } else { checkForEmptyIDG(task.getResult()); } } }); } public void checkForEmptyIDG(DataSnapshot data) { for (int i=1; i<=data.getChildrenCount(); i++) { System.out.println("Schaue ob in DB IDG leer ist bei: " + i ); if(analyzeForEmptyIDG(data,i)) { System.out.println("Schreibe in DB mit IDG " + i ); writeDeviceToDB(i); break; } } } public boolean analyzeForEmptyIDG(DataSnapshot data, int i) { String androidid; String localedatetime; String breitengrad; String laengengrad; String timestamp; String ampltiude; androidid = data.child("IDG" + i).child("a_androidid").getValue().toString(); localedatetime = data.child("IDG" + i).child("b_localdatetime").getValue().toString(); breitengrad = data.child("IDG" + i).child("d_breitengrad").getValue().toString(); laengengrad = data.child("IDG" + i).child("e_laengengrad").getValue().toString(); timestamp = data.child("IDG" + i).child("h_timestamp").getValue().toString(); ampltiude = data.child("IDG" + i).child("i_amplitude").getValue().toString(); if(androidid.isEmpty() && localedatetime.isEmpty() && breitengrad.isEmpty() && laengengrad.isEmpty() && timestamp.isEmpty() && ampltiude.isEmpty()) { return true; }else { return false; } } public void writeDeviceToDB (int k) { mDatenbank = FirebaseDatabase.getInstance().getReference().child("overviewdetection"); mDatenbank.child("IDG" + k).child("a_androidid").setValue(getandroidid()); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { mDatenbank.child("IDG" + k).child("b_localdatetime").setValue(LocalDateTime.now(ZoneOffset.UTC).toString()); } mDatenbank.child("IDG" + k).child("d_breitengrad").setValue(currentLocation.getLatitude()); mDatenbank.child("IDG" + k).child("e_laengengrad").setValue(currentLocation.getLongitude()); mDatenbank.child("IDG" + k).child("h_timestamp").setValue(Calendar.getInstance().getTimeInMillis()); mDatenbank.child("IDG" + k).child("i_amplitude").setValue(1000); } //###### Bei Eintragungen in der DB #### public void getDataBaseValuesWithListener() { mDatenbank = FirebaseDatabase.getInstance().getReference().child("overviewdetection"); mDatenbank.addValueEventListener(new ValueEventListener() { @Override public void onDataChange(@NonNull DataSnapshot snapshot) { analyzeDBchanges(snapshot); } @Override public void onCancelled(@NonNull DatabaseError error) { getDataBaseFailure(error); } }); } public void analyzeDBchanges(DataSnapshot data) { System.out.println("########################Höre auf Veränderungen...."); int takenIDG = 0; for (int i=1; i<=data.getChildrenCount(); i++) { if(analyzeForFullIDG(data,i)) { takenIDG++; } } if(takenIDG>=1 && takenIDG <=5) { //Schreibt bei einer neuen vollen IDG ins Display for(writtenDevices = writtenDevices; writtenDevices <= takenIDG; writtenDevices++) { setDisplayText(data,writtenDevices); } } //TODO @Aron hier Jans Code anschließen //Bei genau 3 Einträgen: if(takenIDG >= 3 && allowCalculation) { Toast.makeText(MainActivity.this, "Es wurden 3 Geräteeinträge registriert!", Toast.LENGTH_SHORT).show(); allowCalculation = false; System.out.println("Gebe an Berechnung raus"); //An Jans Code anknüpfen } } public boolean analyzeForFullIDG(DataSnapshot data, int i) { String androidid = data.child("IDG" + i).child("a_androidid").getValue().toString(); String localedatetime = data.child("IDG" + i).child("b_localdatetime").getValue().toString(); String breitengrad = data.child("IDG" + i).child("d_breitengrad").getValue().toString(); String laengengrad = data.child("IDG" + i).child("e_laengengrad").getValue().toString(); String timestamp = data.child("IDG" + i).child("h_timestamp").getValue().toString(); String ampltiude = data.child("IDG" + i).child("i_amplitude").getValue().toString(); if(!androidid.isEmpty() && !localedatetime.isEmpty() && !breitengrad.isEmpty() && !laengengrad.isEmpty() && !timestamp.isEmpty() && !ampltiude.isEmpty()) { return true; }else { return false; } } public void setDisplayText(DataSnapshot data, int i) { String androidid = data.child("IDG" + i).child("a_androidid").getValue().toString(); String localedatetime = data.child("IDG" + i).child("b_localdatetime").getValue().toString(); String breitengrad = data.child("IDG" + i).child("d_breitengrad").getValue().toString(); String laengengrad = data.child("IDG" + i).child("e_laengengrad").getValue().toString(); String timestamp = data.child("IDG" + i).child("h_timestamp").getValue().toString(); String ampltiude = data.child("IDG" + i).child("i_amplitude").getValue().toString(); TextView txtDevice1 = (TextView) findViewById(R.id.txtdevice1); TextView txtDevice2 = (TextView) findViewById(R.id.txtdevice2); TextView txtDevice3 = (TextView) findViewById(R.id.txtdevice3); TextView txtDevice4 = (TextView) findViewById(R.id.txtdevice4); switch (i){ case 1: txtDevice1.setText("Device ID 1: "+ androidid + "\n" + "Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad +"\n" + "Time Stamp: "+ timestamp + "\n" + "LocalDateTime: " + localedatetime +"\n"+ "Amplitude: "+ ampltiude+"\n"); break; case 2: txtDevice2.setText("Device ID 2: "+ androidid + "\n" + "Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad +"\n" + "Time Stamp: "+ timestamp + "\n" + "LocalDateTime: " + localedatetime +"\n"+ "Amplitude: "+ ampltiude+"\n"); break; case 3: txtDevice3.setText("Device ID 3: "+ androidid + "\n" + "Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad +"\n" + "Time Stamp: "+ timestamp + "\n" + "LocalDateTime: " + localedatetime +"\n"+ "Amplitude: "+ ampltiude+"\n"); break; case 4: txtDevice4.setText("Device ID 4: "+ androidid + "\n" + "Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad +"\n" + "Time Stamp: "+ timestamp + "\n" + "LocalDateTime: " + localedatetime +"\n"+ "Amplitude: "+ ampltiude+"\n"); break; default: System.out.println("Default Case trifft zu"); break; } } public String getandroidid () { return Settings.Secure.getString(this.getContentResolver(), Settings.Secure.ANDROID_ID); } public void getDataBaseFailure (DatabaseError error) { System.out.println("Fehler"); Log.w("Datenbankfehler", error.toException()); } //################################################################## ^^^^ DB Code ^^^^ ################################################################################### //########################################################################################################################################################################## //########################################################################################################################################################################## //################################################################## vvv Set Text of Device 1/2/3 on MainActivity vvv #################################################### private void setText(){ TextView txtDevice1 = (TextView) findViewById(R.id.txtdevice1); TextView txtDevice2 = (TextView) findViewById(R.id.txtdevice2); TextView txtDevice3 = (TextView) findViewById(R.id.txtdevice3); TextView txtDevice4 = (TextView) findViewById(R.id.txtdevice4); txtDevice1.setText("Device 1"+"\n"+"Time Stamp: "+ Calendar.getInstance().getTimeInMillis()+"\n"+"Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad+"\n"); txtDevice2.setText("Device 2"+"\n"+"Time Stamp: "+ Calendar.getInstance().getTimeInMillis()+"\n"+"Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad+"\n"); txtDevice3.setText("Device 3"+"\n"+"Time Stamp: "+ Calendar.getInstance().getTimeInMillis()+"\n"+"Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad+"\n"); txtDevice4.setText("Device 4"+"\n"+"Time Stamp: "+ Calendar.getInstance().getTimeInMillis()+"\n"+"Latitude: "+breitengrad+"\n"+ "Longitude: "+ laengengrad+"\n"); } //################################################################## ^^^^ Set Text of Device 1/2/3 on MainActivity ^^^^ ################################################## //########################################################################################################################################################################## //########################################################################################################################################################################## //################################################################## vvv Maps Code vvv ################################################################################### public boolean isServiceOK(){ Log.d(TAG, "isServicesOK(): checking google services version"); int available = GoogleApiAvailability.getInstance().isGooglePlayServicesAvailable(MainActivity.this); if (available== ConnectionResult.SUCCESS){ Log.d(TAG,"isServicesOK: Google Play Services is working"); return true; } else if (GoogleApiAvailability.getInstance().isUserResolvableError(available)){ Log.d(TAG, "isServicesOK(): an error occured but we can fix it"); Dialog dialog = GoogleApiAvailability.getInstance().getErrorDialog(MainActivity.this, available, ERROR_DIALOG_REQUEST); dialog.show(); } else { Toast.makeText(this, "You can`t make map request", Toast.LENGTH_SHORT).show(); } return false; } private void init() { Button btnEarthquake = (Button) findViewById(R.id.btnEarthquakeLocation); btnEarthquake.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(MainActivity.this, EarthquakeLocation.class); startActivity(intent); } }); Button btnResetDB = (Button) findViewById(R.id.btnResetDB); btnResetDB.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.O) @Override public void onClick(View v) { for (int i=1; i<=5; i++) { writeEmptyToSecondDataBase(i); } } }); Button btnReadyToDetect = (Button) findViewById(R.id.buttonReadyToDetect); btnReadyToDetect.setOnClickListener(new View.OnClickListener() { @RequiresApi(api = Build.VERSION_CODES.O) @Override public void onClick(View v) { for (int i=1; i<=5; i++) { System.out.println("Ready to Detect"); mShakeDetectionIsActive = true; mShakeDetected = false; btnReadyToDetect.setEnabled(false); } } }); } //################################################################## ^^^^ Maps Code ^^^^ ################################################################## //########################################################################################################################################################### }