Compare commits

...

132 Commits

Author SHA1 Message Date
65a36707eb Removed Logger and Fragment2.java 2023-06-23 17:22:36 +02:00
35e2226787 Removed some unnecessary files 2023-06-23 17:01:22 +02:00
681a2f0230 Changed detection overtime from 10 seconds to 5 seconds 2023-06-23 16:27:22 +02:00
0c808f1daa chnaged start dely to 2 seconds 2023-06-23 16:21:04 +02:00
5b52dfc6e5 Version 5.2 working with Fragment 3 2023-06-22 14:59:05 +02:00
02cbb14f3c Merge remote-tracking branch 'origin/ms_master_copie'
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
2023-06-22 12:11:02 +02:00
2c9b2523a4 Changed some stuff on the videolist layout 2023-06-22 08:46:11 +02:00
741b46e713 Version 5.1 working with Fragment 3 2023-06-22 00:33:35 +02:00
bd8371d96d Recording working but only on camera detection 2023-06-22 00:29:16 +02:00
b900ec2e04 Version 5 working with Fragment 3 2023-06-21 23:56:25 +02:00
404091db15 Version 4.2 with num for counter Detections 2023-06-21 23:40:05 +02:00
b976e9ae32 Refactor 2023-06-21 23:04:35 +02:00
0082602bea VideoView Fragment and pop up working 2023-06-21 22:57:33 +02:00
4b720c3a33 Refactor 2023-06-21 22:02:10 +02:00
7e4e885fe0 - added fragment3 2023-06-21 20:18:32 +02:00
5df6b32fc3 Added Messages to fragment alarm 2023-06-21 20:00:25 +02:00
34076149df - added text to alarm fragment 2023-06-21 19:41:45 +02:00
0948d7f44f - added audio and motion detection again 2023-06-21 19:36:20 +02:00
c8b947bb57 - added video detection again 2023-06-21 19:30:34 +02:00
4a1c554a09 - 'removed' files added to project 2023-06-21 19:20:39 +02:00
eb1629a700 removed Fragment classes from MainActivity
- work in Progress
2023-06-21 19:01:48 +02:00
b97c494427 Merge branch 'master' into prepareMaster
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/Detection/DetectionReport.java
#	app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java
#	app/src/main/java/com/example/ueberwachungssystem/Detection/MicrophoneDetector.java
#	app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
#	app/src/main/java/com/example/ueberwachungssystem/WifiCommunication.java
#	app/src/main/res/layout/activity_main.xml
2023-06-21 18:43:55 +02:00
6a251fbb27 removed Fragment classes from MainActivity
- removed fragments
- removed unnecessary classes
- removed unnecessary code
2023-06-21 18:33:01 +02:00
076db89147 removed Fragment classes from MainActivity
- changed buttons, added fragments
2023-06-21 18:21:52 +02:00
5007623acc Version 4.1 with new PopUpClass 2023-06-21 18:11:14 +02:00
3d9e6b7a3e Merge branch 'ms_service_copie' 2023-06-21 17:57:01 +02:00
61cad34931 Version 4 working 2023-06-21 17:56:30 +02:00
e54322e3e2 Version 3 working 2023-06-21 16:41:20 +02:00
edcf555b5b Version 2.1 working 2023-06-21 16:34:17 +02:00
e571373fbb Version 2. working 2023-06-21 15:28:57 +02:00
8e002107b5 Version 1. working 2023-06-21 15:06:57 +02:00
1eba8e0f7c Merge branch 'bk_service' 2023-06-21 13:12:43 +02:00
d17f455ae1 Added toMessage() to DetectionReport 2023-06-21 13:05:56 +02:00
94970885cf Changed time to lay phone down to startDelay = 20000, threadSleeptime = 10 and Log.d Report in case of detection for readability ´reasons 2023-06-21 13:04:52 +02:00
3b88a140cc Removed DetectorService methods and added public classes 2023-06-21 10:49:18 +02:00
c730eec9f9 Working DetectorService with all Detectors and Recorders 2023-06-21 10:24:45 +02:00
1aea88d08f Fixed another bug with calculating pixels changed 2023-06-21 10:02:58 +02:00
43eac872ed Bug Fixes on VideoDetector 2023-06-21 09:50:14 +02:00
39295f9780 Changed Format in Detection Report 2023-06-21 09:49:45 +02:00
54ba3b4862 Sensors working together in main 2023-06-21 00:26:33 +02:00
2087edd3e6 Reset main 2023-06-20 23:29:43 +02:00
4222ebef83 Fixed error 2023-06-20 23:24:05 +02:00
061646a7d6 Merge remote-tracking branch 'origin/master'
# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
#	app/src/main/res/layout/activity_main.xml
2023-06-20 23:05:14 +02:00
6f78836c4d Merge remote-tracking branch 'origin/master' 2023-06-20 22:34:42 +02:00
b667e70fef Kommunikationcopie Version 1.8 UDP Socket 2023-06-20 22:30:30 +02:00
272daf9fae Adjustment to fit master 2023-06-20 22:25:20 +02:00
55ae95e661 Merge of MicrophoneDetector 2023-06-20 21:58:09 +02:00
8e47934beb Merge branch 'tw' into master
# Conflicts:
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
#	app/src/main/res/layout/activity_main.xml
#	gradle.properties
2023-06-20 21:42:25 +02:00
c60a14b6ac Clean project for merge 2023-06-20 21:37:17 +02:00
Leon Market
b9c66f7533 Updated detection report constructor in Accelerometer 2023-06-20 21:23:57 +02:00
Leon Market
7e1143880e Merge branch 'lm'
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/Detection/DetectionReport.java
#	app/src/main/java/com/example/ueberwachungssystem/Detection/Detector.java
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
#	app/src/main/res/layout/activity_main.xml
2023-06-20 21:20:04 +02:00
4381ae78f8 Commit before cleaning project for merge (minor changes) 2023-06-20 21:16:18 +02:00
c198292fbf Merge remote-tracking branch 'origin/master' into Kommunikationcopie
# Conflicts:
#	app/src/main/AndroidManifest.xml
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
#	app/src/main/java/com/example/ueberwachungssystem/WifiCommunication.java
#	app/src/main/res/layout/activity_main.xml
2023-06-20 21:13:26 +02:00
Leon Market
81c3542654 Removed unnecessary packages 2023-06-20 21:13:08 +02:00
35d52088aa merge Kommunikationcopie Version 1.7 UDP Socket 2023-06-20 21:06:51 +02:00
81e04e370a Commit before cleaning project for merge 2023-06-20 21:04:33 +02:00
Leon Market
d33ab299ab Added reportViolation() 2023-06-20 20:59:18 +02:00
ee61f7042b Kommunikation Version 1.6 UDP Socket 2023-06-20 20:50:18 +02:00
ab54b6d96a Kommunikation Version 1.5 UDP Socket 2023-06-20 20:47:53 +02:00
a85fb1f5ca Kommunikation Version 1.5 UDP Socket 2023-06-20 20:33:46 +02:00
f8f1fd23fb Merge branch 'bk_video'
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
2023-06-20 15:34:24 +02:00
e007ad1744 Kommunikation Version 1.4 UDP Socket 2023-06-20 15:22:27 +02:00
292c3457fa Kommunikation Version 1.4 UDP Socket 2023-06-20 15:22:10 +02:00
79c7c16d21 Kommunikation Version 1.4 UDP Socket 2023-06-20 15:19:29 +02:00
e01e23eccd Refactor 2023-06-20 14:29:10 +02:00
a493bafb79 Refactor 2023-06-20 11:16:26 +02:00
aed079377f Refactor 2023-06-20 11:07:57 +02:00
bff6abbd29 Removed Permission Handling from Video Detector, Added PermissionHandler.java class 2023-06-20 11:00:26 +02:00
5d31f0bb46 Adapted Parameters 2023-06-19 15:47:40 +02:00
ea0e88ed89 Refactor in DetectorService class 2023-06-19 14:51:04 +02:00
7dee124378 Refactor in DetectorService class 2023-06-19 14:41:41 +02:00
0ee1446cbc Merge branch 'bk_video_service' into bk_video
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
2023-06-19 14:40:06 +02:00
bc5227ba4f Refactor of DetectorService 2023-06-19 14:37:49 +02:00
4185cb5200 Proper display of Toasts in Audio Recorder 2023-06-19 14:34:07 +02:00
0a3600d0d6 Refactor 2023-06-19 14:27:04 +02:00
9b2d57ad37 Refactor 2023-06-19 13:35:02 +02:00
847e90f5ac Fixed Bug in VideoDetector 2023-06-19 13:17:17 +02:00
ab41217f0e Added DetectionService 2023-06-19 13:13:23 +02:00
0782bbdd04 merge Kommunikation Version 1.3 UDP Socket 2023-06-19 13:00:22 +02:00
e088b0afa3 Working Recorder and Video Detector 2023-06-18 20:17:19 +02:00
493fa8ca83 Fixed Grey Stripes and Rotation Problems 2023-06-18 18:12:03 +02:00
6954d38143 Moved OpenCV Helper to its own Java File 2023-06-18 13:43:10 +02:00
Leon Market
8a5d720685 Changed to a (hopefully) working version of the Accelerometer 2023-06-18 13:13:30 +02:00
057c7fc139 Added Audio Recorder 2023-06-18 13:03:38 +02:00
29c193b716 Removed Preview Use Case, Audio still not working 2023-06-18 10:55:21 +02:00
Leon Market
90aea5b1bc Added LinkedBlockingQueue to collect data, added Thread to evaluate data from queue 2023-06-17 23:58:34 +02:00
76442888f7 Working Video Detector + Recorder WIP: Use Case logic 2023-06-17 19:44:08 +02:00
Leon Market
8a357e0d26 Fixed errors after merge with origin:lm 2023-06-17 19:20:32 +02:00
Leon Market
83268c763b Merge remote-tracking branch 'origin/lm' into lm
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/Beschleunigungssensor.java
2023-06-17 19:17:11 +02:00
Leon Market
3d02d8d4c0 Added 2023-06-17 19:16:48 +02:00
Leon Market
cafe763c4a Removed unnecessary code parts 2023-06-17 19:14:34 +02:00
Leon Market
2cff334056 Added detection report 2023-06-17 19:00:44 +02:00
d32e0a11f5 Fixed bug in Detector and VideoDetector 2023-06-17 11:20:56 +02:00
b94a1d98b7 Working detection with calibration and dB signals. FFT also implemented, but does not work properly at the moment. (Added Complex class, FFT class and imported jjoe64 Graphview (in gradle and gradle.properties) for visualising FFT results) 2023-06-16 16:49:20 +02:00
746eec18ba removed Fragment classes from MainActivity 2023-06-15 17:19:35 +02:00
44e056b5fe Merge branch 'ko'
# Conflicts:
#	app/src/main/java/com/example/ueberwachungssystem/MainActivity.java
2023-06-15 17:06:56 +02:00
df1fefef5f added Toggle Button to start Cam Detection 2023-06-15 16:59:17 +02:00
df9b28c830 merge Kommunikation Version 1.2 UDP Socket 2023-06-15 16:56:59 +02:00
6ec0b175e4 merge Kommunikation Version 1.2 UDP Socket 2023-06-15 16:56:21 +02:00
e89a5d11a1 Kommunikation Version 1.2 UDP Socket 2023-06-15 16:38:49 +02:00
5bcd465ecc Merge branch 'master' into ko
# Conflicts:
#	app/build.gradle
#	app/src/main/AndroidManifest.xml
#	app/src/main/res/layout/activity_main.xml
#	gradle/wrapper/gradle-wrapper.properties
2023-06-15 16:20:40 +02:00
a6fdf3f774 added landscape xml file 2023-06-15 16:12:30 +02:00
b46db4cdfc reworked Button Positions 2023-06-15 16:04:50 +02:00
b246ad8624 Kommunikation Version 1.1 UDP Socket 2023-06-15 15:09:19 +02:00
Leon Market
6c4905d0e7 Added constructors for activity and textView in ThreadDemo 2023-06-15 14:27:25 +02:00
fb8bdcd895 Fixed up Video detector 2023-06-15 12:40:54 +02:00
Leon Market
402b73e4bd Removed calibration code and added method checkAlarm 2023-06-14 22:28:05 +02:00
Leon Market
9e5b669986 Added Accelerometer as Runnable Class and ThreadDemo as example 2023-06-14 22:25:54 +02:00
Leon Market
8275d8bd5a Added 2023-06-14 22:11:17 +02:00
7ef0df48dd Refactored Detector 2023-06-14 20:14:06 +02:00
50b579705e Detector based on OpenCV working 2023-06-14 19:43:18 +02:00
8551abfc5d Changde Detector class 2023-06-14 16:38:33 +02:00
bbd333426d unfinished changes in Detector 2023-06-13 20:55:30 +02:00
74eb3e0d98 Added Toggle Buttons for Detection Mode
Added Scrollview for alarm
2023-06-12 20:23:42 +02:00
5f7e2a43f2 added new Project ueberwachungssystem 2023-06-12 19:04:22 +02:00
e98ae10267 refactor 2023-06-12 19:03:52 +02:00
07f60f974b added new Project ueberwachungssystem 2023-06-12 14:15:39 +02:00
7d29ed1ca9 Rebuild to use openCV. Alarm not yet implemented 2023-06-09 20:56:14 +02:00
f98079d431 Readded main and main xml 2023-06-09 09:09:50 +02:00
192f88ede5 Kommunikation Version 1 UDP Socket 2023-06-08 18:10:39 +02:00
3c1366bd10 Kommunikation Version 1 UDP Socket 2023-06-08 17:59:47 +02:00
11dbcd0362 Merge branch 'bk_video' of siebenhaarmi76624/MDT5_1_Ueberwachungssystem_G1 into master 2023-06-02 15:51:55 +00:00
047d45f1cb Added comments to VideoDetector class 2023-06-02 17:48:41 +02:00
95919a6602 preparing branch for merge 2023-06-02 14:56:57 +02:00
7c8610facb Move from Mikrofon to MicrophoneDetector class and add of abstract Detector class 2023-05-25 16:58:08 +02:00
Leon Market
4999f1b998 added Detector, DetectorReport, Logger 2023-05-25 16:46:12 +02:00
Leon Market
620528302e added Beschleunigungssensor 2023-05-24 20:40:18 +02:00
unknown
90a2aad491 new class Mikrofon 2023-05-11 16:21:59 +02:00
35583a4cdd Merge branch 'test' of siebenhaarmi76624/MDT5_1_Ueberwachungssystem_G1 into ms 2023-05-11 13:39:00 +00:00
d22952d83b Initial commit Project Version 0 2023-05-11 15:38:14 +02:00
57bf2c2fb7 added new Project ueberwachungssystem 2023-05-11 15:31:47 +02:00
5c0263198c added new Project ueberwachungssystem 2023-05-11 15:25:28 +02:00
40 changed files with 2810 additions and 324 deletions

Binary file not shown.

View File

@ -26,6 +26,9 @@ android {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
buildFeatures {
viewBinding true
}
}
dependencies {
@ -33,10 +36,19 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.6.1'
implementation 'com.google.android.material:material:1.8.0'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
implementation 'com.google.android.gms:play-services-nearby:18.0.0'
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
// OpenCV (from: https://github.com/QuickBirdEng/opencv-android)
def opencv_version = "4.5.3.0"
implementation "com.quickbirdstudios:opencv:${opencv_version}"
implementation "androidx.lifecycle:lifecycle-extensions:2.0.0"
// Required for CameraX
def camerax_version = "1.2.2"
implementation "androidx.camera:camera-core:${camerax_version}"

View File

@ -4,6 +4,11 @@
<uses-feature android:name="android.hardware.camera"/>
<uses-permission android:name="android.permission.CAMERA"/>
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
@ -23,6 +28,7 @@
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<service android:name=".Detection.DetectorService"/>
</application>
</manifest>

View File

@ -0,0 +1,108 @@
package com.example.ueberwachungssystem.Detection;
import static java.lang.Math.sqrt;
import android.content.Context;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
/**
* Accelerometer inherits some methods from abstract Detector class (more info there)
*
*
* USE FROM MAIN ACTIVITY:
*
* Accelerometer beschleunigungssensor = new Accelerometer(this);
* onCreate:
* //Accelerometer Setup
* beschleunigungssensor = new Accelerometer(this, logger, textViewLog); //logger and textview only for debugging necessary
* beschleunigungssensor.getSensor();
*
* //Starting Detection:
* beschleunigungssensor.startDetection();
* //Stopping Detection: also recommended at onPause to avoid unnecessary battery consumption
* beschleunigungssensor.stopDetection();
*
* */
public class Accelerometer extends Detector implements SensorEventListener {
public SensorManager sensorManager;
private static final int sensorType = Sensor.TYPE_LINEAR_ACCELERATION;
private Sensor accelerometer;
private Context context;
boolean alarm = false;
//Preallocate memory for the data of each axis of the acceleration sensor
float x;
float y;
float z;
float betrag; //Betrag aller drei Achsen sqrt(x*x + y*y + z*z)
private DetectionReport detectionReport;
// In constructor pass Activity, Context and TextView from MainActivity in Accelerometer class
public Accelerometer(Context context){
super(); //von Detektor
this.context = context;
}
public void getSensor(){
sensorManager = (SensorManager)context.getSystemService(Context.SENSOR_SERVICE);
if(sensorManager.getSensorList(sensorType).size()==0) {
accelerometer = null;
}
else {
accelerometer = sensorManager.getSensorList(sensorType).get(0);
}
}
@Override
public void onSensorChanged(SensorEvent event) {
try {
checkAlarm(event);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
public void checkAlarm (SensorEvent event) throws InterruptedException {
x = event.values[0];
y = event.values[1];
z = event.values[2];
betrag = (float) sqrt(x*x + y*y + z*z);
float threshold = 1.5F;
if (!alarm) {
if (betrag > threshold) {
alarm = true;
reportViolation("Bewegung", betrag);
}
} else {
if (betrag < threshold) {
alarm = false;
} else {
}
}
}
@Override
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
@Override
public void startDetection() {
// entspricht void start()
//getSensor();
if (accelerometer != null) {
sensorManager.registerListener(this, accelerometer, SensorManager.SENSOR_DELAY_GAME);
}
}
@Override
public void stopDetection() {
// entspricht void stop()
sensorManager.unregisterListener(this, accelerometer);
}
}

View File

@ -0,0 +1,74 @@
package com.example.ueberwachungssystem.Detection;
import android.content.Context;
import android.media.MediaPlayer;
import android.media.MediaRecorder;
import android.widget.Toast;
import java.io.File;
import java.io.IOException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class AudioRecorder {
private final Context context;
private MediaRecorder mediaRecorder = null;
private boolean isRecording = false;
private File outputDir; // Default: in app files directory
public AudioRecorder (Context context) {
this.context = context;
this.outputDir = context.getFilesDir();
}
public void startRecording() {
// Handle logic
if (outputDir == null)
return;
if (isRecording)
return;
isRecording = true;
// Setup Audio Recorder for output Format: 3GP
mediaRecorder = new MediaRecorder();
mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
mediaRecorder.setOutputFile(outputDir + "/" + generateFileName() + ".3gp");
mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
try {
mediaRecorder.prepare();
} catch (IOException e) {
e.printStackTrace();
}
mediaRecorder.start();
}
public void stopRecording() {
if (mediaRecorder != null) {
mediaRecorder.stop();
mediaRecorder.reset();
mediaRecorder.release();
mediaRecorder = null;
isRecording = false;
Toast.makeText(context, "audio recording saved", Toast.LENGTH_SHORT).show();
}
}
public boolean isRecording(){
return isRecording;
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
private String generateFileName(){
// Get the current timestamp
LocalDateTime currentTime = LocalDateTime.now();
// Define the format for the timestamp
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
// Return the timestamp as a string
return currentTime.format(formatter);
}
}

View File

@ -0,0 +1,57 @@
package com.example.ueberwachungssystem.Detection;
import android.annotation.SuppressLint;
import android.util.Log;
import com.example.ueberwachungssystem.WifiCommunication;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
/** Detection Report Class */
public class DetectionReport {
public String timeStamp;
public String detectionType;
public float detectedValue;
public boolean detectionState;
public DetectionReport(boolean detectionState, String detectionType, float detectedAmplitude) {
// New Date Format
@SuppressLint("SimpleDateFormat") SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date curDate = new Date(System.currentTimeMillis());
this.timeStamp = formatter.format(curDate);
//Old Date Format: this.timeStamp = String.valueOf(Calendar.getInstance().getTime());
this.detectionType = detectionType;
this.detectedValue = detectedAmplitude;
this.detectionState = detectionState;
//this.detectorID = detectorID;
}
/** Get Detection Report in String format */
public String toString() {
String state = "State: " + "[" + this.detectionState + "]";
String time = "Time: " + "[" + this.timeStamp + "]";
String type = "Type: " + "[" + this.detectionType + "]";
String value = "Value: " + "[" + this.detectedValue + "]";
return String.join("\t", state, time, type, value);
}
public String toMessage() {
String state;
if(detectionState)
state = "An";
else
state = "Aus";
return String.join(",", "1", timeStamp, "Gruppe2", WifiCommunication.getLocalIpAddress(), state, detectionType, String.valueOf(detectedValue));
}
/** Debug Report */
public void log(String tag) {
Log.d(tag, this.toString());
}
}

View File

@ -0,0 +1,76 @@
package com.example.ueberwachungssystem.Detection;
import android.os.CountDownTimer;
import androidx.annotation.NonNull;
import androidx.camera.core.ExperimentalGetImage;
abstract public class Detector {
private OnDetectionListener listener;
private boolean isDetecting = false;
private boolean extendViolation = false;
// Countdown parameters
private final int COUNTDOWN_TIME = 5000; // milliseconds
private final int COUNTDOWN_POLLING_TIME = 100; // milliseconds
/** Constructor - takes context of current activity */
public Detector() {}
/** On Detection Listener - runs when violation is reported */
public interface OnDetectionListener {
void onDetection(@NonNull DetectionReport detectionReport);
}
public void setOnDetectionListener(@NonNull OnDetectionListener listener) {
this.listener = listener;
}
/** Triggers onDetectionListener - call this to trigger violation/alarm */
public void reportViolation(String detectionType, float amplitude) {
if (listener != null) {
if (!isDetecting) {
isDetecting = true;
DetectionReport detectionReport = new DetectionReport(true, detectionType, amplitude);
listener.onDetection(detectionReport);
startDetectionTimer(detectionType, amplitude);
} else {
extendViolation = true;
}
} else {
isDetecting = false;
extendViolation = false;
}
}
private void startDetectionTimer(String detectionType, float amplitude) {
isDetecting = true;
new CountDownTimer((long) COUNTDOWN_TIME, COUNTDOWN_POLLING_TIME) {
@Override
public void onTick(long millisUntilFinished) {
if (extendViolation) {
extendViolation = false;
startDetectionTimer(detectionType, amplitude);
this.cancel();
}
}
@Override
public void onFinish() {
isDetecting = false;
DetectionReport detectionReport = new DetectionReport(false, detectionType, amplitude);
listener.onDetection(detectionReport);
}
}.start();
}
public void extendViolation(){
this.extendViolation = true;
}
/** Starts Detection (abstract method: needs to be overridden in child class) */
public abstract void startDetection();
/** Stops Detection (abstract method: needs to be overridden in child class) */
public abstract void stopDetection();
}

View File

@ -0,0 +1,176 @@
package com.example.ueberwachungssystem.Detection;
import android.content.Intent;
import android.os.Binder;
import android.os.IBinder;
import android.util.Log;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.ExperimentalGetImage;
import androidx.lifecycle.LifecycleService;
import com.example.ueberwachungssystem.WifiCommunication;
import java.io.File;
@ExperimentalGetImage
public class DetectorService extends LifecycleService {
public ServiceBinder serviceBinder = new ServiceBinder();
private DetectorService.OnDetectionListener listener;
private boolean isServiceRunning = false;
// Used Objects:
public VideoDetector videoDetector = null;
public AudioRecorder audioRecorder = null;
public Accelerometer motionDetector = null;
public MicrophoneDetector audioDetector = null;
public WifiCommunication wifiCommunication;
String wifiData;
StringBuffer stringBufferWifi = new StringBuffer();
String typOfAlarm;
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
if (isServiceRunning)
return START_NOT_STICKY;
/** Wifi Instanz **/
wifiCommunication = new WifiCommunication(1234);
wifiCommunication.sendTrue("TEst");
wifiCommunication.setOnConnectionListener(new WifiCommunication.OnConnectionListener() {
@Override
public void onConnection(String data) {
Log.d("Listener", data);
wifiData = data;
stringToStringbuffer(data);
Log.d("buffer",stringBufferWifi.toString());
passToServiceListener(stringBufferWifi);
checkState(data);
checkTyp(data);
}
});
/** Video Detection/Recorder **/
videoDetector = new VideoDetector(this);
videoDetector.setOnDetectionListener(new Detector.OnDetectionListener() {
@Override
public void onDetection(@NonNull DetectionReport detectionReport) {
//passToServiceListener(detectionReport);
if(detectionReport.detectionState){
videoDetector.startRecording();
} else {
videoDetector.stopRecording();
}
wifiCommunication.sendTrue(detectionReport.toMessage());
}
});
/** Motion Detection**/
motionDetector = new Accelerometer(this);
motionDetector.getSensor();
motionDetector.setOnDetectionListener(new Detector.OnDetectionListener() {
@Override
public void onDetection(@NonNull DetectionReport detectionReport) {
//passToServiceListener(detectionReport);
wifiCommunication.sendTrue(detectionReport.toMessage());
}
});
/** Audio Detection **/
audioDetector = new MicrophoneDetector(this);
audioDetector.setOnDetectionListener(new Detector.OnDetectionListener() {
@Override
public void onDetection(@NonNull DetectionReport detectionReport) {
//passToServiceListener(detectionReport);
wifiCommunication.sendTrue(detectionReport.toMessage());
}
});
/** Audio Recorder**/
audioRecorder = new AudioRecorder(this);
isServiceRunning = true;
return super.onStartCommand(intent, flags, startId);
}
@Override
public void onDestroy() {
super.onDestroy();
isServiceRunning = false;
}
/** Service methods */
public class ServiceBinder extends Binder {
public DetectorService getBoundService() {
// Return an instance of the TestService
return DetectorService.this;
}
}
@Nullable
@Override
public IBinder onBind(Intent intent) {
super.onBind(intent);
return serviceBinder;
}
/** Pass Detection Report to Service Detection Listener and trigger it */
public void passToServiceListener(StringBuffer stringBuffer) {
if (listener != null) {
listener.onDetection(stringBuffer);
}
}
/** On Detection Listener - runs when violation is reported */
public interface OnDetectionListener {
void onDetection(@NonNull StringBuffer stringBuffer);
}
public void setOnDetectionListener(@NonNull DetectorService.OnDetectionListener listener) {
this.listener = listener;
}
public void stringToStringbuffer(String string){
if(string != null) {
stringBufferWifi.insert(0,string + "\n");
}
}
public String[] splitString(String string){
String[] splitrxString = string.split(",");
return splitrxString; //splitrxString[0] = "1",splitrxString[1] = "HH:MM:SS", splitrxString[0].equals("1")
}
public boolean checkState(String string){
Log.d("state", String.valueOf(splitString(string)[4].equals("An")));
return splitString(string)[4].equals("An");
}
public String checkTyp(String string){
if (splitString(string)[5] != null) {
typOfAlarm = splitString(string)[5];
Log.d("Type", typOfAlarm);
}
return typOfAlarm;
}
}

View File

@ -0,0 +1,365 @@
package com.example.ueberwachungssystem.Detection;
import static java.lang.Math.*;
import android.annotation.SuppressLint;
import android.content.Context;
import android.media.AudioFormat;
import android.media.AudioRecord;
import android.media.MediaRecorder;
import android.os.AsyncTask;
import android.util.Log;
import com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex;
import com.example.ueberwachungssystem.Detection.Signalverarbeitung.FFT;
public class MicrophoneDetector extends Detector {
/**
* Constructor - takes context of current activity
*
* @param context
*/
private AufnahmeTask aufnahmeTask;
public boolean armed = false;
public int schwellwertAlarm = 100;
private Context context;
public MicrophoneDetector(Context context) {
super();
this.context = context;
}
@Override
public void startDetection() {
aufnahmeTask = new AufnahmeTask();
aufnahmeTask.execute();
}
@Override
public void stopDetection() {
if (aufnahmeTask != null) {
aufnahmeTask.cancel(true);
}
}
class AufnahmeTask extends AsyncTask<Long, Verarbeitungsergebnis, Void> {
private AudioRecord recorder;
private final int sampleRateInHz = 44100;
private final int channelConfig = AudioFormat.CHANNEL_IN_MONO;
private final int audioFormat = AudioFormat.ENCODING_PCM_16BIT;
private final int startDelay = 2000;
private final int threadSleeptime = 10;
private int minPufferGroesseInBytes;
private int pufferGroesseInBytes;
private RingPuffer ringPuffer = new RingPuffer(10);
private float kalibierWert;
private com.example.ueberwachungssystem.Detection.DetectionReport detectionReport;
@SuppressLint("MissingPermission")
AufnahmeTask() {
minPufferGroesseInBytes = AudioRecord.getMinBufferSize(sampleRateInHz, channelConfig, audioFormat);
pufferGroesseInBytes = minPufferGroesseInBytes * 2;
try {
recorder = new AudioRecord(MediaRecorder.AudioSource.MIC, sampleRateInHz, channelConfig, audioFormat, pufferGroesseInBytes);
} catch (Exception e) {
e.printStackTrace();
}
Log.d("0","Puffergroeße: "+ minPufferGroesseInBytes + " " + pufferGroesseInBytes);
Log.d("0","Recorder (SR, CH): "+ recorder.getSampleRate() + " " + recorder.getChannelCount());
int anzahlBytesProAbtastwert;
String s;
switch (recorder.getAudioFormat()) {
case AudioFormat.ENCODING_PCM_8BIT:
s = "8 Bit PCM ";
anzahlBytesProAbtastwert = 1;
break;
case AudioFormat.ENCODING_PCM_16BIT:
s = "16 Bit PCM";
anzahlBytesProAbtastwert = 2;
break;
case AudioFormat.ENCODING_PCM_FLOAT:
s = "Float PCM";
anzahlBytesProAbtastwert = 4;
break;
default:
throw new IllegalArgumentException();
}
switch (recorder.getChannelConfiguration()) {
case AudioFormat.CHANNEL_IN_MONO:
s = "Mono";
break;
case AudioFormat.CHANNEL_IN_STEREO:
s = "Stereo";
anzahlBytesProAbtastwert *= 2;
break;
case AudioFormat.CHANNEL_INVALID:
s = "ungültig";
break;
default:
throw new IllegalArgumentException();
}
Log.d("0","Konfiguration: "+ s);
}
@Override
protected Void doInBackground(Long... params) {
recorder.startRecording();
short[] puffer = new short[pufferGroesseInBytes / 2];
long lastTime = System.currentTimeMillis();
float verarbeitungsrate = 0;
final int maxZaehlerZeitMessung = 10;
int zaehlerZeitMessung = 0;
int anzahlVerarbeitet = 0;
GleitenderMittelwert gleitenderMittelwert = new GleitenderMittelwert(0.3f);
//Kalibrierung
try {
Thread.sleep(startDelay); // Time to lay down the phone
} catch (InterruptedException e) {
e.printStackTrace();
}
int i = 0;
for (i = 0; i < 20; i++) {
int n = recorder.read(puffer, 0, puffer.length);
Verarbeitungsergebnis kalibrierErgebnis = verarbeiten(puffer, n);
kalibierWert += kalibrierErgebnis.maxAmp;
try {
Thread.sleep(threadSleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
kalibierWert = kalibierWert/i;
// __Part of FFT__
// Complex[] zeitSignal = new Complex[puffer.length];
// for (int j = 0; j < puffer.length; j++) {
// zeitSignal[j] = new Complex(puffer[j], 0);
// }
// Complex[] spektrum = FFT.fft(zeitSignal);
// double[] spektrum = calculateFFT(puffer);
// DataPoint AddPoint;
// LineGraphSeries<DataPoint> series = new LineGraphSeries<DataPoint>(new DataPoint[]{});
// for (i = 0; i < spektrum.length; i++) {
// AddPoint = new DataPoint(i, spektrum[i]);
// series.appendData(AddPoint, true, spektrum.length);
// }
// graph.addSeries(series);
for (; ; ) {
if (aufnahmeTask.isCancelled()) {
break;
} else {
int n = recorder.read(puffer, 0, puffer.length);
Verarbeitungsergebnis ergebnis = verarbeiten(puffer, n);
anzahlVerarbeitet += n;
// __Part of FFT__
// spektrum = calculateFFT(puffer);
// LineGraphSeries<DataPoint> newseries = new LineGraphSeries<DataPoint>(new DataPoint[]{});
// for (i = 0; i < spektrum.length; i++) {
// AddPoint = new DataPoint(i, spektrum[i]);
// newseries.appendData(AddPoint, true, spektrum.length);
// }
zaehlerZeitMessung++;
if (zaehlerZeitMessung == maxZaehlerZeitMessung) {
long time = System.currentTimeMillis();
long deltaTime = time - lastTime;
verarbeitungsrate = 1000.0f * anzahlVerarbeitet / deltaTime;
verarbeitungsrate = gleitenderMittelwert.mittel(verarbeitungsrate);
zaehlerZeitMessung = 0;
anzahlVerarbeitet = 0;
lastTime = time;
}
ergebnis.verarbeitungsrate = (int) verarbeitungsrate;
publishProgress(ergebnis);
try {
Thread.sleep(threadSleeptime);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
recorder.release();
return null;
}
private Verarbeitungsergebnis verarbeiten(short[] daten, int n) {
String status;
short maxAmp = -1;
if (n == AudioRecord.ERROR_INVALID_OPERATION) {
status = "ERROR_INVALID_OPERATION";
} else if (n == AudioRecord.ERROR_BAD_VALUE) {
status = "ERROR_BAD_VALUE";
} else {
status = "OK";
short max = 0;
for (int i = 0; i < n; i++) {
if (daten[i] > max) {
max = daten[i];
}
}
ringPuffer.hinzufuegen(max);
maxAmp = ringPuffer.maximum();
if (maxAmp <= schwellwertAlarm + kalibierWert) {
armed = true;
}
}
return new Verarbeitungsergebnis(status, maxAmp, 0);
}
@Override
protected void onProgressUpdate(Verarbeitungsergebnis... progress) {
super.onProgressUpdate(progress);
float maxAmpPrint = round(20*log10(abs(progress[0].maxAmp/1.0)));
float kalibierWertPrint = round(20*log10(abs(kalibierWert)));
Log.d("alarmAudio","VR: " + progress[0].verarbeitungsrate + ", Amp: " + maxAmpPrint
+ " dB, Kal: " + kalibierWertPrint + " dB");
if (progress[0].maxAmp >= schwellwertAlarm + kalibierWert && armed == true) {
armed = false;
detectionReport = new DetectionReport(true, "Audio", maxAmpPrint);
reportViolation("Audio", maxAmpPrint);
Log.d("1",detectionReport.toString());
}
}
}
private double[] calculateFFT(short[] zeitsignal)
{
byte signal[] = new byte[zeitsignal.length];
// loops through all the values of a Short
for (int i = 0; i < zeitsignal.length-1; i++) {
signal[i] = (byte) (zeitsignal[i]);
signal[i+1] = (byte) (zeitsignal[i] >> 8);
}
final int mNumberOfFFTPoints =1024;
double temp;
Complex[] y;
Complex[] complexSignal = new Complex[mNumberOfFFTPoints];
double[] absSignal = new double[mNumberOfFFTPoints/2];
for(int i = 0; i < mNumberOfFFTPoints; i++){
temp = (double)((signal[2*i] & 0xFF) | (signal[2*i+1] << 8)) / 32768.0F;
complexSignal[i] = new Complex(temp,0.0);
}
y = FFT.fft(complexSignal);
for(int i = 0; i < (mNumberOfFFTPoints/2); i++)
{
absSignal[i] = y[i].abs();
}
return absSignal;
}
class Verarbeitungsergebnis {
String status;
short maxAmp;
int verarbeitungsrate;
Verarbeitungsergebnis(String status, short maxAmp, int verarbeitungsrate) {
this.status = status;
this.maxAmp = maxAmp;
this.verarbeitungsrate = verarbeitungsrate;
}
}
class RingPuffer {
private short[] puffer;
private final int laenge;
private int anzahlEnthaltenerDaten;
private int position;
public RingPuffer(int n) {
laenge = n;
anzahlEnthaltenerDaten = 0;
position = 0;
puffer = new short[laenge];
}
public void hinzufuegen(short wert) {
puffer[position] = wert;
position++;
if (position >= laenge) {
position = 0;
}
if (anzahlEnthaltenerDaten < laenge) {
anzahlEnthaltenerDaten++;
}
}
public void hinzufuegen(short[] daten) {
for (short d : daten) {
puffer[position] = d;
position++;
if (position >= laenge) {
position = 0;
}
}
if (anzahlEnthaltenerDaten < laenge) {
anzahlEnthaltenerDaten += daten.length;
if (anzahlEnthaltenerDaten >= laenge) {
anzahlEnthaltenerDaten = laenge;
}
}
}
public short maximum() {
short max = 0;
for (int i = 0; i < anzahlEnthaltenerDaten; i++) {
if (puffer[i] > max) {
max = puffer[i];
}
}
return max;
}
public float mittelwert() {
float summe = 0;
for (int i = 0; i < anzahlEnthaltenerDaten; i++) {
summe += puffer[i];
}
return summe / anzahlEnthaltenerDaten;
}
}
class GleitenderMittelwert {
private final float wichtungNeuerWert;
private final float wichtungAlterWert;
private float mittelwert = 0;
private boolean istMittelwertGesetzt = false;
GleitenderMittelwert(float wichtungNeuerWert) {
this.wichtungNeuerWert = wichtungNeuerWert;
this.wichtungAlterWert = 1 - this.wichtungNeuerWert;
}
float mittel(float wert) {
if (istMittelwertGesetzt) {
mittelwert = wert * wichtungNeuerWert + mittelwert * wichtungAlterWert;
} else {
mittelwert = wert;
istMittelwertGesetzt = true;
}
return mittelwert;
}
}
}

View File

@ -0,0 +1,109 @@
package com.example.ueberwachungssystem.Detection;
import android.graphics.Bitmap;
import android.media.Image;
import android.widget.ImageView;
import androidx.annotation.NonNull;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageProxy;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@ExperimentalGetImage
public class OpenCVHelper {
/** OpenCV helper methods **/
public static Mat addGaussianBlur(Mat inputMat, Size kernelSize){
Mat outputMat = new Mat();
Imgproc.GaussianBlur(inputMat, outputMat, kernelSize, 0);
return outputMat;
}
public static Mat addBlur(Mat inputMat, Size kernelSize){
Mat outputMat = new Mat();
Imgproc.blur(inputMat, outputMat, kernelSize);
return outputMat;
}
public static Mat extractYChannel(@NonNull ImageProxy imgProxy) {
Image img = imgProxy.getImage();
assert img != null;
ByteBuffer yBuffer = img.getPlanes()[0].getBuffer();
byte[] yData = new byte[yBuffer.remaining()];
yBuffer.get(yData);
Mat yMat = new Mat(img.getHeight(), img.getWidth(), CvType.CV_8UC1);
yMat.put(0, 0, yData);
return yMat;
}
public static Mat thresholdPixels(Mat inputMat, Mat previousImage, int threshold){
Mat diffImage = new Mat();
Core.absdiff(inputMat, previousImage, diffImage);
Mat binaryMat = new Mat();
Imgproc.threshold(diffImage, binaryMat, threshold, 255, Imgproc.THRESH_BINARY);
return binaryMat;
}
public static Mat thresholdContourArea(Mat inputMat, float areaThreshold){
List<MatOfPoint> contours = new ArrayList<>();
Mat hierarchy = new Mat();
Imgproc.findContours(inputMat, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE);
Mat outputMat = new Mat(inputMat.size(), inputMat.type(), new Scalar(0));
// Iterate over the contours and draw only the larger contours on the outputMat
for (MatOfPoint contour : contours) {
double contourArea = Imgproc.contourArea(contour);
if (contourArea > areaThreshold) {
Imgproc.drawContours(outputMat, Collections.singletonList(contour), 0, new Scalar(255), -1);
}
}
// Apply the outputMat as a mask to the dilatedImage
Mat maskedImage = new Mat();
inputMat.copyTo(maskedImage, outputMat);
return outputMat;
}
public static Mat dilateBinaryMat(Mat inputMat, Size kernelSize){
Mat dilatedMat = new Mat();
Mat kernel = Imgproc.getStructuringElement(Imgproc.MORPH_ELLIPSE, kernelSize);
Imgproc.dilate(inputMat, dilatedMat, kernel);
return dilatedMat;
}
public static int countNonZeroPixels(Mat inputImage) {
if (inputImage != null)
return Core.countNonZero(inputImage);
else
return 0;
}
public static void debugMat(Mat mat, ImageView imageView) {
if (imageView == null || mat == null)
return;
Bitmap bitmap = Bitmap.createBitmap(mat.cols(), mat.rows(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(mat, bitmap);
// Display the bitmap in an ImageView
imageView.setImageBitmap(bitmap);
}
}

View File

@ -0,0 +1,148 @@
package com.example.ueberwachungssystem.Detection.Signalverarbeitung;
import java.util.Objects;
public class Complex {
private final double re; // the real part
private final double im; // the imaginary part
// create a new object with the given real and imaginary parts
public Complex(double real, double imag) {
re = real;
im = imag;
}
// return a string representation of the invoking com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object
public String toString() {
if (im == 0) return re + "";
if (re == 0) return im + "i";
if (im < 0) return re + " - " + (-im) + "i";
return re + " + " + im + "i";
}
// return abs/modulus/magnitude
public double abs() {
return Math.hypot(re, im);
}
// return angle/phase/argument, normalized to be between -pi and pi
public double phase() {
return Math.atan2(im, re);
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this + b)
public Complex plus(Complex b) {
Complex a = this; // invoking object
double real = a.re + b.re;
double imag = a.im + b.im;
return new Complex(real, imag);
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this - b)
public Complex minus(Complex b) {
Complex a = this;
double real = a.re - b.re;
double imag = a.im - b.im;
return new Complex(real, imag);
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is (this * b)
public Complex times(Complex b) {
Complex a = this;
double real = a.re * b.re - a.im * b.im;
double imag = a.re * b.im + a.im * b.re;
return new Complex(real, imag);
}
// return a new object whose value is (this * alpha)
public Complex scale(double alpha) {
return new Complex(alpha * re, alpha * im);
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the conjugate of this
public Complex conjugate() {
return new Complex(re, -im);
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the reciprocal of this
public Complex reciprocal() {
double scale = re * re + im * im;
return new Complex(re / scale, -im / scale);
}
// return the real or imaginary part
public double re() {
return re;
}
public double im() {
return im;
}
// return a / b
public Complex divides(Complex b) {
Complex a = this;
return a.times(b.reciprocal());
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex exponential of this
public Complex exp() {
return new Complex(Math.exp(re) * Math.cos(im), Math.exp(re) * Math.sin(im));
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex sine of this
public Complex sin() {
return new Complex(Math.sin(re) * Math.cosh(im), Math.cos(re) * Math.sinh(im));
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex cosine of this
public Complex cos() {
return new Complex(Math.cos(re) * Math.cosh(im), -Math.sin(re) * Math.sinh(im));
}
// return a new com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex object whose value is the complex tangent of this
public Complex tan() {
return sin().divides(cos());
}
// a static version of plus
public static Complex plus(Complex a, Complex b) {
double real = a.re + b.re;
double imag = a.im + b.im;
Complex sum = new Complex(real, imag);
return sum;
}
// See Section 3.3.
public boolean equals(Object x) {
if (x == null) return false;
if (this.getClass() != x.getClass()) return false;
Complex that = (Complex) x;
return (this.re == that.re) && (this.im == that.im);
}
// See Section 3.3.
public int hashCode() {
return Objects.hash(re, im);
}
// sample client for testing
public static void main(String[] args) {
Complex a = new Complex(5.0, 6.0);
Complex b = new Complex(-3.0, 4.0);
System.out.println("a = " + a);
System.out.println("b = " + b);
System.out.println("Re(a) = " + a.re());
System.out.println("Im(a) = " + a.im());
System.out.println("b + a = " + b.plus(a));
System.out.println("a - b = " + a.minus(b));
System.out.println("a * b = " + a.times(b));
System.out.println("b * a = " + b.times(a));
System.out.println("a / b = " + a.divides(b));
System.out.println("(a / b) * b = " + a.divides(b).times(b));
System.out.println("conj(a) = " + a.conjugate());
System.out.println("|a| = " + a.abs());
System.out.println("tan(a) = " + a.tan());
}
}

View File

@ -0,0 +1,246 @@
package com.example.ueberwachungssystem.Detection.Signalverarbeitung;
// Source: https://introcs.cs.princeton.edu/java/97data/FFT.java.html
/******************************************************************************
* Compilation: javac FFT.java
* Execution: java FFT n
* Dependencies: com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex.java
*
* Compute the FFT and inverse FFT of a length n complex sequence
* using the radix 2 Cooley-Tukey algorithm.
* Bare bones implementation that runs in O(n log n) time and O(n)
* space. Our goal is to optimize the clarity of the code, rather
* than performance.
*
* This implementation uses the primitive root of unity w = e^(-2 pi i / n).
* Some resources use w = e^(2 pi i / n).
*
* Reference: https://www.cs.princeton.edu/~wayne/kleinberg-tardos/pdf/05DivideAndConquerII.pdf
*
* Limitations
* -----------
* - assumes n is a power of 2
*
* - not the most memory efficient algorithm (because it uses
* an object type for representing complex numbers and because
* it re-allocates memory for the subarray, instead of doing
* in-place or reusing a single temporary array)
*
* For an in-place radix 2 Cooley-Tukey FFT, see
* https://introcs.cs.princeton.edu/java/97data/InplaceFFT.java.html
*
******************************************************************************/
public class FFT {
// compute the FFT of x[], assuming its length n is a power of 2
public static Complex[] fft(Complex[] x) {
int n = x.length;
// base case
if (n == 1) return new Complex[]{x[0]};
// radix 2 Cooley-Tukey FFT
if (n % 2 != 0) {
throw new IllegalArgumentException("n is not a power of 2");
}
// compute FFT of even terms
Complex[] even = new Complex[n / 2];
for (int k = 0; k < n / 2; k++) {
even[k] = x[2 * k];
}
Complex[] evenFFT = fft(even);
// compute FFT of odd terms
Complex[] odd = even; // reuse the array (to avoid n log n space)
for (int k = 0; k < n / 2; k++) {
odd[k] = x[2 * k + 1];
}
Complex[] oddFFT = fft(odd);
// combine
Complex[] y = new Complex[n];
for (int k = 0; k < n / 2; k++) {
double kth = -2 * k * Math.PI / n;
Complex wk = new Complex(Math.cos(kth), Math.sin(kth));
y[k] = evenFFT[k].plus(wk.times(oddFFT[k]));
y[k + n / 2] = evenFFT[k].minus(wk.times(oddFFT[k]));
}
return y;
}
// compute the inverse FFT of x[], assuming its length n is a power of 2
public static Complex[] ifft(Complex[] x) {
int n = x.length;
Complex[] y = new Complex[n];
// take conjugate
for (int i = 0; i < n; i++) {
y[i] = x[i].conjugate();
}
// compute forward FFT
y = fft(y);
// take conjugate again
for (int i = 0; i < n; i++) {
y[i] = y[i].conjugate();
}
// divide by n
for (int i = 0; i < n; i++) {
y[i] = y[i].scale(1.0 / n);
}
return y;
}
// compute the circular convolution of x and y
public static Complex[] cconvolve(Complex[] x, Complex[] y) {
// should probably pad x and y with 0s so that they have same length
// and are powers of 2
if (x.length != y.length) {
throw new IllegalArgumentException("Dimensions don't agree");
}
int n = x.length;
// compute FFT of each sequence
Complex[] a = fft(x);
Complex[] b = fft(y);
// point-wise multiply
Complex[] c = new Complex[n];
for (int i = 0; i < n; i++) {
c[i] = a[i].times(b[i]);
}
// compute inverse FFT
return ifft(c);
}
// compute the linear convolution of x and y
public static Complex[] convolve(Complex[] x, Complex[] y) {
Complex ZERO = new Complex(0, 0);
Complex[] a = new Complex[2 * x.length];
for (int i = 0; i < x.length; i++) a[i] = x[i];
for (int i = x.length; i < 2 * x.length; i++) a[i] = ZERO;
Complex[] b = new Complex[2 * y.length];
for (int i = 0; i < y.length; i++) b[i] = y[i];
for (int i = y.length; i < 2 * y.length; i++) b[i] = ZERO;
return cconvolve(a, b);
}
// compute the DFT of x[] via brute force (n^2 time)
public static Complex[] dft(Complex[] x) {
int n = x.length;
Complex ZERO = new Complex(0, 0);
Complex[] y = new Complex[n];
for (int k = 0; k < n; k++) {
y[k] = ZERO;
for (int j = 0; j < n; j++) {
int power = (k * j) % n;
double kth = -2 * power * Math.PI / n;
Complex wkj = new Complex(Math.cos(kth), Math.sin(kth));
y[k] = y[k].plus(x[j].times(wkj));
}
}
return y;
}
// display an array of com.example.ueberwachungssystem.Detection.Signalverarbeitung.Complex numbers to standard output
public static void show(Complex[] x, String title) {
System.out.println(title);
System.out.println("-------------------");
for (int i = 0; i < x.length; i++) {
System.out.println(x[i]);
}
System.out.println();
}
/***************************************************************************
* Test client and sample execution
*
* % java FFT 4
* x
* -------------------
* -0.03480425839330703
* 0.07910192950176387
* 0.7233322451735928
* 0.1659819820667019
*
* y = fft(x)
* -------------------
* 0.9336118983487516
* -0.7581365035668999 + 0.08688005256493803i
* 0.44344407521182005
* -0.7581365035668999 - 0.08688005256493803i
*
* z = ifft(y)
* -------------------
* -0.03480425839330703
* 0.07910192950176387 + 2.6599344570851287E-18i
* 0.7233322451735928
* 0.1659819820667019 - 2.6599344570851287E-18i
*
* c = cconvolve(x, x)
* -------------------
* 0.5506798633981853
* 0.23461407150576394 - 4.033186818023279E-18i
* -0.016542951108772352
* 0.10288019294318276 + 4.033186818023279E-18i
*
* d = convolve(x, x)
* -------------------
* 0.001211336402308083 - 3.122502256758253E-17i
* -0.005506167987577068 - 5.058885073636224E-17i
* -0.044092969479563274 + 2.1934338938072244E-18i
* 0.10288019294318276 - 3.6147323062478115E-17i
* 0.5494685269958772 + 3.122502256758253E-17i
* 0.240120239493341 + 4.655566391833896E-17i
* 0.02755001837079092 - 2.1934338938072244E-18i
* 4.01805098805014E-17i
*
***************************************************************************/
public static void main(String[] args) {
int n = Integer.parseInt(args[0]);
Complex[] x = new Complex[n];
// original data
for (int i = 0; i < n; i++) {
x[i] = new Complex(i, 0);
}
show(x, "x");
// FFT of original data
Complex[] y = fft(x);
show(y, "y = fft(x)");
// FFT of original data
Complex[] y2 = dft(x);
show(y2, "y2 = dft(x)");
// take inverse FFT
Complex[] z = ifft(y);
show(z, "z = ifft(y)");
// circular convolution of x with itself
Complex[] c = cconvolve(x, x);
show(c, "c = cconvolve(x, x)");
// linear convolution of x with itself
Complex[] d = convolve(x, x);
show(d, "d = convolve(x, x)");
}
}

View File

@ -0,0 +1,332 @@
package com.example.ueberwachungssystem.Detection;
import android.Manifest;
import android.annotation.SuppressLint;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.media.Image;
import android.os.CountDownTimer;
import android.util.Log;
import android.view.Display;
import android.view.Surface;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.core.Preview;
import androidx.camera.core.VideoCapture;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;
import com.google.common.util.concurrent.ListenableFuture;
import org.opencv.android.OpenCVLoader;
import org.opencv.core.Mat;
import org.opencv.core.Size;
import java.io.File;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.concurrent.ExecutionException;
/**
* Video Detector inherits some methods from abstract Detector class (more info there)
* */
@ExperimentalGetImage
public class VideoDetector extends Detector {
// Calling Activity
private final Context context;
// Camera Provider
private ProcessCameraProvider cameraProvider;
private ImageAnalysis imageAnalysis;
private VideoCapture videoCapture;
//private Preview preview;
// Logic
private boolean isDetecting = false;
private boolean isRecording = false;
private boolean allowReportViolation = false;
// Image Processing
private Mat previousImage = null;
// Debugging
private ImageView inputImageView = null;
private ImageView outputImageView = null;
// Recorder
private File outputDir; // Default: in app files directory
// Parameters
private static final float ALARM_THRESHOLD = 0f; // Percent of pixels changed
private static final float AREA_THRESHOLD = 10f;
private static final int DILATE_ITERATIONS = 2;
private static final float START_DELAY = 2000; // milliseconds
private static final android.util.Size IMAGE_RES = new android.util.Size(640, 480);
/** Constructor */
public VideoDetector(Context context) {
super();
this.context = context;
this.imageAnalysis = setupImageAnalysis();
this.videoCapture = setupVideoCapture();
this.outputDir = context.getFilesDir();
//this.preview = new Preview.Builder().build();
}
/** Get States */
public boolean isDetecting() {
return isDetecting;
}
public boolean isRecording(){
return isRecording;
}
/** Starts the Video Detection */
@Override
public void startDetection() {
// Check States
if (isDetecting)
return;
// Configure Image Analysis
imageAnalysis = setupImageAnalysis();
// Open CV startup check
if (!OpenCVLoader.initDebug()) {
Log.e("OpenCV", "Unable to load OpenCV!");
return;
} else
Log.d("OpenCV", "OpenCV loaded Successfully!");
// Get Process Camera Provider and start
final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(context);
cameraProviderFuture.addListener(() -> {
try {
cameraProvider = cameraProviderFuture.get();
isDetecting = true;
bindCameraProvider();
} catch (ExecutionException | InterruptedException e) {}
}, ContextCompat.getMainExecutor(context));
// Disable Violation Calling for Setup Time
startViolationTimer(START_DELAY);
}
/** Starts the Recorder */
@SuppressLint("RestrictedApi")
public void startRecording() {
// Check States
if (isRecording){
return;
}
Toast.makeText(context, "Aufnahme gestartet", Toast.LENGTH_SHORT).show();
videoCapture = setupVideoCapture();
final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(context);
cameraProviderFuture.addListener(() -> {
try {
cameraProvider = cameraProviderFuture.get();
isRecording = true;
bindCameraProvider();
File vidFile = new File(context.getFilesDir() + "/" + generateFileName() + ".mp4");
if (ActivityCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED) {
return;
}
videoCapture.startRecording(
new VideoCapture.OutputFileOptions.Builder(vidFile).build(),
context.getMainExecutor(),
new VideoCapture.OnVideoSavedCallback() {
@Override
public void onVideoSaved(@NonNull VideoCapture.OutputFileResults outputFileResults) {
isRecording = false;
Toast.makeText(context, "Aufnahme gespeichert", Toast.LENGTH_SHORT).show();
}
@Override
public void onError(int videoCaptureError, @NonNull String message, @Nullable Throwable cause) {
isRecording = false;
Toast.makeText(context, "Aufnahme fehlgeschlagen", Toast.LENGTH_SHORT).show();
}
}
);
} catch (ExecutionException | InterruptedException ignored) {}
}, ContextCompat.getMainExecutor(context));
}
/** Stops the Video Detection */
@Override
public void stopDetection() {
if (!isDetecting || imageAnalysis == null)
return;
if (!isRecording)
cameraProvider.unbindAll();
else
cameraProvider.unbind(imageAnalysis);
isDetecting = false;
allowReportViolation = false;
}
/** Stops the Recording */
@SuppressLint("RestrictedApi")
public void stopRecording(){
if(!isRecording)
return;
videoCapture.stopRecording();
if (!isDetecting())
cameraProvider.unbindAll();
else
cameraProvider.unbind(videoCapture);
isRecording = false;
}
/** Bind Camera Provider */
private void bindCameraProvider() {
// Specify which Camera to use
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
cameraProvider.unbindAll();
cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, imageAnalysis, videoCapture);
}
/** Setup Use Cases */
private ImageAnalysis setupImageAnalysis() {
// Configure and create Image Analysis
ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
builder.setTargetResolution(IMAGE_RES);
builder.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
builder.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888);
builder.setTargetRotation(Surface.ROTATION_90);
ImageAnalysis imageAnalysis = builder.build();
// Set Analyzer
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(context), imageProxy -> {
if (imageProxy.getFormat() == ImageFormat.YUV_420_888) {
Image image = imageProxy.getImage();
assert image != null;
// Violation Handling
Mat processed = processImage(imageProxy);
int n = OpenCVHelper.countNonZeroPixels(processed);
int pixelCount = image.getWidth() * image.getHeight();
float percentChanged = ((float) n / pixelCount) * 100;
// Violation Condition
if (percentChanged> ALARM_THRESHOLD) {
if (allowReportViolation)
reportViolation("Video", percentChanged);
}
}
imageProxy.close();
});
return imageAnalysis;
}
@SuppressLint("RestrictedApi")
private VideoCapture setupVideoCapture() {
int rotation = getDisplayRotation();
return new VideoCapture.Builder()
.setTargetRotation(rotation)
.build();
}
/** Process Image to be used for Motion Detection */
private Mat processImage(ImageProxy imageProxy){
if (imageProxy == null)
return null;
// Image Transformation
Mat imageMat = OpenCVHelper.extractYChannel(imageProxy);
// Show Input Image
if (inputImageView != null)
OpenCVHelper.debugMat(imageMat, inputImageView);
// Preprocess Image
Mat preprocessed = imageMat;
preprocessed = OpenCVHelper.addGaussianBlur(preprocessed, new Size(21, 21));
preprocessed = OpenCVHelper.addBlur(preprocessed, new Size(3, 3));
// Set Previous Image
if (previousImage == null) {
previousImage = preprocessed;
return null;
}
// Process Image
Mat processed = preprocessed.clone();
processed = OpenCVHelper.thresholdPixels(processed, previousImage, 25);
for(int i = 0; i < DILATE_ITERATIONS; i++)
processed = OpenCVHelper.dilateBinaryMat(processed, new Size(3,3));
processed = OpenCVHelper.thresholdContourArea(processed, AREA_THRESHOLD);
// Output
previousImage = preprocessed.clone();
// Show Output Image
if (outputImageView != null)
OpenCVHelper.debugMat(processed, outputImageView);
return processed;
}
/** Debug input and result of processing */
public void debugProcessing(@NonNull ImageView inputImageView, @NonNull ImageView outputImageView){
this.inputImageView = inputImageView;
this.outputImageView = outputImageView;
}
/**
private void setPreviewView(@NonNull PreviewView previewView) {
// Create Preview
if (this.preview != null)
this.preview.setSurfaceProvider(previewView.getSurfaceProvider());
}
*/
/** Generate File Name */
private String generateFileName(){
// Get the current timestamp
LocalDateTime currentTime = LocalDateTime.now();
// Define the format for the timestamp
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd_HHmmss");
// Return the timestamp as a string
return currentTime.format(formatter);
}
/** Get current Display Rotation */
private int getDisplayRotation() {
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = windowManager.getDefaultDisplay();
return display.getRotation();
}
/** Start delay until Violation Report is allowed */
private void startViolationTimer(float setupTime) {
new CountDownTimer((long) (setupTime), 100) {
@Override
public void onTick(long millisUntilFinished) {
}
@Override
public void onFinish() {
allowReportViolation = true;
}
}.start();
}
public void setOutputDir(File outputDir) {
this.outputDir = outputDir;
}
}

View File

@ -1,36 +0,0 @@
package com.example.ueberwachungssystem;
import android.util.Log;
import java.util.Calendar;
/** Detection Report Class */
public class DetectionReport {
public String timeStamp;
public String detectionType;
public float detectedValue;
public String detectorID;
public DetectionReport(String detectorID, String detectionType, float detectedAmplitude) {
this.timeStamp = String.valueOf(Calendar.getInstance().getTime());
this.detectionType = detectionType;
this.detectedValue = detectedAmplitude;
this.detectorID = detectorID;
}
/** Get Detection Report in String format */
public String toString() {
String time = "Time: " + "[" + this.timeStamp + "]";
String type = "Type: " + "[" + this.detectionType + "]";
String value = "Value: " + "[" + this.detectedValue + "]";
String id = "ID: " + "[" + this.detectorID + "]";
return String.join("\t", time, type, value, id);
}
/** Debug Report */
public void log(String tag) {
Log.d(tag, this.toString());
}
}

View File

@ -1,38 +0,0 @@
package com.example.ueberwachungssystem;
import androidx.annotation.NonNull;
abstract public class Detector {
private OnDetectionListener listener;
/** Constructor - takes context of current activity */
public Detector() {}
/** On Detection Listener - runs when violation is reported */
public interface OnDetectionListener {
void onDetection(@NonNull DetectionReport detectionReport);
}
public void setOnDetectionListener(@NonNull OnDetectionListener listener) {
this.listener = listener;
}
/** Triggers onDetectionListener - call this to trigger violation/alarm */
public void reportViolation(String detectorID, String detectionType, float amplitude) {
if (listener != null) {
DetectionReport detectionReport = new DetectionReport(detectorID, detectionType, amplitude);
listener.onDetection(detectionReport);
} else {
throw new IllegalStateException("No listener set for violation reporting");
}
}
/** Starts Detection (abstract method: needs to be overridden in child class) */
public abstract void startDetection();
/** Stops Detection (abstract method: needs to be overridden in child class) */
public abstract void stopDetection();
}

View File

@ -0,0 +1,61 @@
package com.example.ueberwachungssystem.Fragments;
import android.content.Context;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;
import android.widget.VideoView;
import androidx.fragment.app.Fragment;
import com.example.ueberwachungssystem.R;
import java.io.File;
public class Fragment1 extends Fragment {
private String text;
private final static String KEY_TEXT = "KEY_TEXT";
private void log(String nachricht) {
Log.d(this.getClass().getSimpleName(), nachricht);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
log("onCreateView");
View view = inflater.inflate(R.layout.fragment1, container, false);
TextView Sensor = (TextView) view.findViewById(R.id.Alarm);
Sensor.setText(text);
return view;
}
public static Fragment1 erstellen(String text) {
Fragment1 fragment = new Fragment1();
Bundle b = new Bundle();
b.putString(KEY_TEXT, text);
fragment.setArguments(b);
return fragment;
}
public static Fragment1 aktualisieren(String text){
Fragment1 fragment = new Fragment1();
Bundle b = new Bundle();
b.putString(KEY_TEXT, text);
fragment.setArguments(b);
return fragment;
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Bundle args = getArguments();
if (args != null ) {
text = args.getString(KEY_TEXT);
log("onCreate: text=" + text);
} else {
log("onCreate");
}
}
}

View File

@ -0,0 +1,62 @@
package com.example.ueberwachungssystem.Fragments;
import android.content.Context;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import androidx.fragment.app.Fragment;
import com.example.ueberwachungssystem.R;
public class Fragment3 extends Fragment {
private OnImageViewReadyListener onImageViewReadyListener;
private String text;
public static ImageView ivp;
private final static String KEY_TEXT = "KEY_TEXT";
private void log(String nachricht) {
Log.d(this.getClass().getSimpleName(), nachricht);
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle bundle) {
log("onCreateView");
View view = inflater.inflate(R.layout.fragment3, container, false);
if (onImageViewReadyListener != null) {
ImageView ivp = (ImageView) view.findViewById(R.id.Video);
ImageView ivp2 = (ImageView) view.findViewById(R.id.Video2);
onImageViewReadyListener.onImageViewReady(ivp, ivp2);
}
return view;
}
public static Fragment3 erstellen(View view) {
Fragment3 fragment = new Fragment3();
return fragment;
}
public interface OnImageViewReadyListener {
void onImageViewReady(ImageView imageView, ImageView imageView2);
}
public void onAttach(Context context) {
super.onAttach(context);
try {
onImageViewReadyListener = (OnImageViewReadyListener) context;
} catch (ClassCastException e) {
throw new ClassCastException(context.toString() + " must implement OnImageViewReadyListener");
}
}
@Override
public void onCreate(Bundle bundle) {
super.onCreate(bundle);
Bundle args = getArguments();
if (args != null ) {
text = args.getString(KEY_TEXT);
log("onCreate: text=" + text);
} else {
log("onCreate");
}
}
}

View File

@ -0,0 +1,104 @@
package com.example.ueberwachungssystem.Fragments;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;
import android.widget.PopupWindow;
import android.widget.Toast;
import android.widget.VideoView;
import androidx.fragment.app.Fragment;
import com.example.ueberwachungssystem.R;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
public class VideoListFragment extends Fragment {
private ListView listView;
private Button button;
private ArrayAdapter<String> adapter;
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
View rootView = inflater.inflate(R.layout.videolist_fragment, container, false);
button = rootView.findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
File dir = getContext().getFilesDir();
File[] files = dir.listFiles();
for (File file: files) {
file.delete();
}
}
});
listView = rootView.findViewById(R.id.listView);
adapter = new ArrayAdapter<>(requireContext(), android.R.layout.simple_list_item_1, getFileNames());
listView.setAdapter(adapter);
listView.setOnItemClickListener(new AdapterView.OnItemClickListener() {
@Override
public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
// Handle item click event here
String selectedItem = getContext().getFilesDir().toString() + "/" + adapter.getItem(position);
//Toast.makeText(requireContext(), selectedItem, Toast.LENGTH_SHORT).show();
openVideoPopup(selectedItem);
}
});
return rootView;
}
private List<String> getFileNames() {
// Add your data source here, e.g., an array or a list
File dir = getContext().getFilesDir();
File[] files = dir.listFiles();
Log.d("files", getContext().getFilesDir().toString());
List<String> fileNamesList = new ArrayList<>();
assert files != null;
for (File file : files) {
fileNamesList.add(file.getName());
}
return fileNamesList;
}
private void openVideoPopup(String videoPath) {
LayoutInflater inflater = LayoutInflater.from(requireContext());
View popupView = inflater.inflate(R.layout.videolist_popup, null);
VideoView videoView = popupView.findViewById(R.id.videoView);
videoView.setVideoPath(videoPath);
videoView.start();
PopupWindow popupWindow = new PopupWindow(popupView, ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT, true);
popupView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//Close the window when clicked
popupWindow.dismiss();
return true;
}
});
popupWindow.showAtLocation(listView, Gravity.CENTER, 0, 0);
}
}

View File

@ -1,86 +1,233 @@
package com.example.ueberwachungssystem;
import androidx.camera.core.ExperimentalGetImage;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.camera.view.PreviewView;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import androidx.camera.core.ExperimentalGetImage;
import android.Manifest;
import android.content.pm.PackageManager;
import android.annotation.SuppressLint;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.ServiceConnection;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.ToggleButton;
import com.example.ueberwachungssystem.VideoDetection.VideoDetector;
import com.example.ueberwachungssystem.Fragments.Fragment1;
import com.example.ueberwachungssystem.Detection.DetectorService;
import com.example.ueberwachungssystem.Fragments.Fragment3;
import com.example.ueberwachungssystem.Fragments.VideoListFragment;
import java.util.OptionalInt;
@ExperimentalGetImage
public class MainActivity extends AppCompatActivity {
public class MainActivity extends AppCompatActivity implements Fragment3.OnImageViewReadyListener{
//StringBuffer
private StringBuffer messageBuffer = new StringBuffer();
private static final int CAMERA_PERMISSION_REQUEST_CODE = 101;
//Fragmente
private Fragment aktuellesFragment;
private Fragment fragment1_;
private Fragment fragment2_;
private Fragment fragment3_;
private Fragment1 fragment1;
private Fragment3 fragment3;
private ImageView fragmentImage;
private ImageView fragmentImage2;
private VideoListFragment videoListFragment = new VideoListFragment();
private DetectorService detectorService = new DetectorService();
int num = 0;
//Textviews
private TextView Auswahl;
private TextView AoderA;
private String auswahltext = "Wahl des Detektionsmodus";
private String auswahlAoderA = "Wahl von Alarmmeldungen oder Auswahl von Alarmaufzeichnungen";
//Buttons
private ToggleButton toggleKamera;
private ToggleButton toggleAudio;
private ToggleButton toggleBewegung;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setTitle("Supervision");
setContentView(R.layout.activity_main);
TextView textView = findViewById(R.id.textView);
PreviewView previewView = findViewById(R.id.previewView);
VideoDetector vd = new VideoDetector(this);
vd.setPreviewView(previewView);
vd.setOnDetectionListener(new VideoDetector.OnDetectionListener() {
@Override
public void onDetection(@NonNull DetectionReport detectionReport) {
detectionReport.log("OnDetection");
textView.setText(detectionReport.toString());
}
});
//vd.startDetection();
ToggleButton toggleButton = findViewById(R.id.previewButton);
toggleButton.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
getCameraAccess();
if (isCameraAccessAllowed() && toggleButton.isChecked())
{
vd.startDetection();
}
else {
vd.stopDetection();
textView.setText("");
}
}
});
}
private boolean isCameraAccessAllowed() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
}
private void getCameraAccess() {
if (!isCameraAccessAllowed())
ActivityCompat.requestPermissions(this, new String[]{android.Manifest.permission.CAMERA}, CAMERA_PERMISSION_REQUEST_CODE);
Auswahl = findViewById(R.id.textAuswahl);
Auswahl.setText(auswahltext);
AoderA = findViewById(R.id.textAoderA);
AoderA.setText(auswahlAoderA);
toggleKamera = findViewById(R.id.toggleKamera);
toggleAudio = findViewById(R.id.toggleAudio);
toggleBewegung = findViewById(R.id.toggleBewegung);
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
protected void onResume() {
super.onResume();
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE && grantResults.length > 0) {
boolean cameraRights = grantResults[0] == PackageManager.PERMISSION_GRANTED;
if (cameraRights) {
Toast.makeText(this, "camera permission granted", Toast.LENGTH_LONG).show();
} else {
Toast.makeText(this, "camera permission denied", Toast.LENGTH_LONG).show();
}
PermissionHandler permissionHandler = new PermissionHandler(this);
//permissionHandler.getPermissions();
if (permissionHandler.hasPermissions()) {
Intent serviceIntent = new Intent(this, DetectorService.class);
bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE);
startService(serviceIntent);
toggleKamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (toggleKamera.isChecked()) {
if(detectorService != null) {
detectorService.videoDetector.startDetection();
}
} else {
if(detectorService != null) {
detectorService.videoDetector.stopDetection();
}
}
}
});
toggleAudio.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (toggleAudio.isChecked()) {
if(detectorService != null) {
detectorService.audioDetector.startDetection();
}
} else {
if(detectorService != null) {
detectorService.audioDetector.stopDetection();
}
}
}
});
toggleBewegung.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (toggleBewegung.isChecked()) {
if(detectorService != null) {
detectorService.motionDetector.startDetection();
}
} else {
if(detectorService != null) {
detectorService.motionDetector.stopDetection();
}
}
}
});
}else{
Toast.makeText(this,"Bitte Rechte geben", Toast.LENGTH_SHORT).show();
}
}
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.options_menu, menu);
return true;
}
public boolean onOptionsItemSelected(MenuItem item) {
Toast.makeText(this, "Selected Item: " + item.getTitle(), Toast.LENGTH_SHORT).show();
PopUpClass popUpClass;
switch (item.getItemId()) {
case R.id.Rechteverwaltung:
popUpClass = new PopUpClass(MainActivity.this);
popUpClass.showPopupWindow(toggleAudio);
popUpClass.RechtePrüfen();
return true;
case R.id.Sensoren:
popUpClass = new PopUpClass(MainActivity.this);
popUpClass.showPopupWindow(toggleAudio);
popUpClass.Sensoren();
return true;
case R.id.Impressum:
popUpClass = new PopUpClass(MainActivity.this);
popUpClass.showPopupWindow(toggleAudio);
popUpClass.Impressum();
return true;
case R.id.Detection:
popUpClass = new PopUpClass(MainActivity.this);
popUpClass.showPopupWindow(toggleAudio);
popUpClass.DetectionTotal(num);
return true;
default:
return super.onOptionsItemSelected(item);
}
}
private ServiceConnection serviceConnection = new ServiceConnection() {
@Override
public void onServiceConnected(ComponentName name, IBinder service) {
DetectorService.ServiceBinder binder = (DetectorService.ServiceBinder) service;
detectorService = binder.getBoundService();
detectorService.setOnDetectionListener(new DetectorService.OnDetectionListener() {
@Override
public void onDetection(@NonNull StringBuffer stringBuffer) {
Log.d("onDetection", stringBuffer.toString()); //Für oli hier Textview einbauen
num = stringBuffer.toString().split("\n").length;
messageBuffer = stringBuffer;
if ((aktuellesFragment == fragment1_) && (aktuellesFragment != null)) {
Log.d("Fragment", aktuellesFragment.toString() + " " + fragment1_.toString());
fragment1_ = zeigeFragment(fragment1.erstellen(messageBuffer.toString()));
}
}
});
}
@Override
public void onServiceDisconnected(ComponentName name) {
}
};
public void onClickZeigeFragment1(View view) {
Button button = (Button) view;
fragment1_ = zeigeFragment(fragment1.erstellen(messageBuffer.toString()));
}
public void onClickZeigeFragment2(View view) {
Button button = (Button) view;
//zeigeFragment(fragment2.erstellen("Hier stehen dann die Videos"));
fragment2_ = zeigeFragment(videoListFragment);
}
public void onClickZeigeFragment3(View view) {
Button button = (Button) view;
fragment3_ = zeigeFragment(fragment3.erstellen(view));
}
public void onImageViewReady(ImageView imageView, ImageView imageView2) {
fragmentImage = imageView;
fragmentImage2 = imageView2;
detectorService.videoDetector.debugProcessing(fragmentImage, fragmentImage2); //inputImageView
}
public void onClickEntferneFragment(View view) {
entferneFragment();
}
private Fragment zeigeFragment(Fragment fragment) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.replace(R.id.frame, fragment);
ft.commit();
aktuellesFragment = fragment;
return aktuellesFragment;
}
private void entferneFragment() {
if (aktuellesFragment != null) {
FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
ft.remove(aktuellesFragment);
ft.commit();
aktuellesFragment = null ;
}
}
}

View File

@ -0,0 +1,43 @@
package com.example.ueberwachungssystem;
import android.app.Activity;
import android.content.Context;
import android.content.pm.PackageManager;
import android.widget.Toast;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
public class PermissionHandler {
private final Context context;
private static final int PERMISSION_REQUEST_CODE = 23409;
private static final String[] permissions = new String[]{
android.Manifest.permission.CAMERA,
android.Manifest.permission.RECORD_AUDIO
};
public PermissionHandler(Context context) {
this.context = context;
}
public boolean hasPermissions() {
boolean permissionState = true;
for (String permission: permissions) {
permissionState = permissionState && ContextCompat.checkSelfPermission(context, permission) == PackageManager.PERMISSION_GRANTED;
}
return permissionState;
}
public void getPermissions() {
if (!hasPermissions())
ActivityCompat.requestPermissions((Activity) context, permissions, PERMISSION_REQUEST_CODE);
}
public void showPermissionToast() {
if (hasPermissions())
Toast.makeText(context, "permissions available", Toast.LENGTH_SHORT).show();
else
Toast.makeText(context, "permissions missing", Toast.LENGTH_SHORT).show();
}
}

View File

@ -0,0 +1,48 @@
package com.example.ueberwachungssystem;
import static android.Manifest.permission.INTERNET;
import static android.Manifest.permission.CAMERA;
import static android.Manifest.permission.RECORD_AUDIO;
import android.content.pm.PackageManager;
import android.os.Handler;
import android.widget.Toast;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.ContextCompat;
public class PermissionRequest extends AppCompatActivity{
private static final int PERMISSION_REQUEST_CODE = 123;
private final MainActivity mainActivity;
Handler handler = new Handler();
public PermissionRequest(MainActivity mainActivity) {
this.mainActivity = mainActivity;
}
public StringBuilder rechtePruefen() {
boolean rechtKamera = ContextCompat.checkSelfPermission(mainActivity, CAMERA) == PackageManager.PERMISSION_GRANTED;
boolean rechtMikrofon = ContextCompat.checkSelfPermission(mainActivity, RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED;
boolean rechtInternet = ContextCompat.checkSelfPermission(mainActivity, INTERNET) == PackageManager.PERMISSION_GRANTED;
StringBuilder sb = new StringBuilder();
sb.append("Rechte prüfen:")
.append("\nKamera: ").append(rechtKamera)
.append("\nMikrofon: ").append(rechtMikrofon)
.append("\nInternet: ").append(rechtInternet);
//mainActivity.runOnUiThread(() -> mainActivity.tvMessages.setText(sb));
if (!(rechtKamera && rechtMikrofon && rechtInternet)){
handler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(mainActivity.getApplicationContext(),"Es werden Rechte benötigt", Toast.LENGTH_SHORT).show();
}
});
}
return sb;
}
public void rechteAnfordern() {
mainActivity.requestPermissions(new String[]{CAMERA, RECORD_AUDIO, INTERNET}, PERMISSION_REQUEST_CODE);
}
}

View File

@ -0,0 +1,96 @@
package com.example.ueberwachungssystem;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
public class PopUpClass {
private final MainActivity mainActivity;
PermissionRequest permission;
TextView PopUpText;
Button buttonEdit;
public PopUpClass(MainActivity mainActivity) {
this.mainActivity = mainActivity;
permission = new PermissionRequest(mainActivity);
}
//PopupWindow display method
public void showPopupWindow(final View view) {
//Create a View object yourself through inflater
LayoutInflater inflater = (LayoutInflater) view.getContext().getSystemService(view.getContext().LAYOUT_INFLATER_SERVICE);
View popupView = inflater.inflate(R.layout.popup_window, null);
//Specify the length and width through constants
int width = LinearLayout.LayoutParams.WRAP_CONTENT;
int height = LinearLayout.LayoutParams.WRAP_CONTENT;
//Make Inactive Items Outside Of PopupWindow
boolean focusable = true;
//Create a window with our parameters
final PopupWindow popupWindow = new PopupWindow(popupView,width*1, height*1, focusable);
//Set the location of the window on the screen
popupWindow.showAtLocation(view, Gravity.CENTER, 0, 0);
//Initialize the elements of our window, install the handler
PopUpText = popupView.findViewById(R.id.titleText);
buttonEdit = popupView.findViewById(R.id.RechteAnfordern);
buttonEdit.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
RechteAnfordern();
}
});
//Handler for clicking on the inactive zone of the window
popupView.setOnTouchListener(new View.OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
//Close the window when clicked
popupWindow.dismiss();
return true;
}
});
}
public void RechtePrüfen(){
StringBuilder Text = permission.rechtePruefen();
PopUpText.setText(Text);
buttonEdit.setVisibility(View.VISIBLE);
}
public void RechteAnfordern(){
permission.rechteAnfordern();
StringBuilder Text = permission.rechtePruefen();
PopUpText.setText(Text);
}
public void Sensoren(){
PopUpText.setText("Es können 3 verschiedene Sensoren verwendet werden \n -1. Beschleunigungssensor\n -2. Mikrofon\n -3. Kamera\n Diese können sowohl einzeln als auch alle zusammen verwendet werden");
buttonEdit.setVisibility(View.GONE);
}
public void Impressum(){
PopUpText.setText("Die Ueberwachungsapp wurde im Rahmen eines Praktikums der TH-Nürnberg programmiert \n Von: \n -Kohler Bastian\n -Kleinecke Oliver\n -Market Leon\n -Siebenhaar Miguel\n -Wolz Tobias ");
buttonEdit.setVisibility(View.GONE);
}
public void DetectionTotal(int num) {
PopUpText.setText("Total Detektions:" +num);
buttonEdit.setVisibility(View.GONE);
}
}

View File

@ -1,165 +0,0 @@
package com.example.ueberwachungssystem.VideoDetection;
import android.content.Context;
import android.graphics.ImageFormat;
import android.media.Image;
import android.util.Size;
import androidx.annotation.NonNull;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ExperimentalGetImage;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.Preview;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.camera.view.PreviewView;
import androidx.core.content.ContextCompat;
import androidx.lifecycle.LifecycleOwner;
import com.example.ueberwachungssystem.Detector;
import com.google.common.util.concurrent.ListenableFuture;
import java.nio.ByteBuffer;
import java.util.concurrent.ExecutionException;
@ExperimentalGetImage
public class VideoDetector extends Detector {
// Calling Activity
private final Context context;
// Camera Provider
private ProcessCameraProvider cameraProvider;
private Boolean isDetectionRunning = false;
// Preview Camera Image
private PreviewView previewView = null;
// Detect Violation
private static final float PIXEL_THRESHOLD = 30f; // Luminosity (brightness channel of YUV_420_888)
private static final float ALARM_THRESHOLD = 1f; // Percent of pixels changed
private ByteBuffer previousBuffer = null;
/** Constructor */
public VideoDetector(Context context) {
super();
this.context = context;
}
/** Starts Video Detection */
@Override
public void startDetection() {
if (isDetectionRunning)
return;
// Request Camera Provider
final ListenableFuture<ProcessCameraProvider> cameraProviderFuture = ProcessCameraProvider.getInstance(context);
//Check for Camera availability
cameraProviderFuture.addListener(() -> {
try {
cameraProvider = cameraProviderFuture.get();
bindLuminosityAnalysis(cameraProvider);
isDetectionRunning = true;
previousBuffer = null;
} catch (ExecutionException | InterruptedException e) {
// No errors need to be handled for this Future. This should never be reached.
}
},ContextCompat.getMainExecutor(context));
}
/** Stops Video Detection */
@Override
public void stopDetection() {
if (!isDetectionRunning)
return;
cameraProvider.unbindAll();
isDetectionRunning = false;
}
/** Set PreviewView to show Image */
public void setPreviewView(PreviewView previewView) {
this.previewView = previewView;
}
/** Binds the Luminosity Analyzer (configure and run Analysis) */
private void bindLuminosityAnalysis(@NonNull ProcessCameraProvider cameraProvider) {
// Configure and create Image Analysis
ImageAnalysis.Builder builder = new ImageAnalysis.Builder();
builder.setTargetResolution(new Size(640, 480));
builder.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST);
builder.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_YUV_420_888);
ImageAnalysis imageAnalysis = builder.build();
// Set Analyzer
imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(context), imageProxy -> {
if (imageProxy.getFormat() == ImageFormat.YUV_420_888) {
Image image = imageProxy.getImage();
assert image != null;
// Changed Pixel Detection
int pixelChanged = getChangedPixelCount(image);
int width = image.getWidth();
int height = image.getHeight();
float percentPixelChanged = (float) 100f * pixelChanged / (width * height);
if (percentPixelChanged > ALARM_THRESHOLD)
reportViolation("0", "Video", percentPixelChanged);
}
imageProxy.close();
});
// Create Preview
Preview preview = new Preview.Builder().build();
// Specify which Camera to use
CameraSelector cameraSelector = new CameraSelector.Builder().requireLensFacing(CameraSelector.LENS_FACING_BACK).build();
// Update PreviewView if set
if (previewView != null)
preview.setSurfaceProvider(previewView.getSurfaceProvider());
cameraProvider.bindToLifecycle((LifecycleOwner) context, cameraSelector, imageAnalysis, preview);
}
/** Calculate Amount of Pixels changed */
private int getChangedPixelCount(Image image) {
Image.Plane[] planes = image.getPlanes();
ByteBuffer buffer = planes[0].getBuffer();
if (previousBuffer == null) {
previousBuffer = ByteBuffer.allocate(buffer.capacity());
buffer.rewind();
previousBuffer.put(buffer);
previousBuffer.rewind();
return 0;
}
int width = image.getWidth();
int height = image.getHeight();
int yRowStride = image.getPlanes()[0].getRowStride();
int yPixelStride = image.getPlanes()[0].getPixelStride();
int changedPixelCount = 0;
// Count changed pixels
for (int y = 0; y < height; ++y) {
for (int x = 0; x < width; x++) {
int index = (y * yRowStride) + (x * yPixelStride);
int luminosity = (buffer.get(index) & 0xff);
int previousLuminosity = (previousBuffer.get(index) & 0xff);
int diff = Math.abs(luminosity - previousLuminosity);
if (diff > PIXEL_THRESHOLD)
changedPixelCount++;
}
}
// Reset and copy Byte Buffer
buffer.rewind();
previousBuffer.rewind();
previousBuffer.put(buffer);
return changedPixelCount;
}
}

View File

@ -0,0 +1,176 @@
package com.example.ueberwachungssystem;
import android.annotation.SuppressLint;
import android.util.Log;
import android.widget.Toast;
import androidx.annotation.NonNull;
import com.example.ueberwachungssystem.Detection.DetectionReport;
import com.example.ueberwachungssystem.Detection.Detector;
import com.example.ueberwachungssystem.Detection.DetectorService;
import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.SocketException;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Enumeration;
public class WifiCommunication {
//private final MainActivity mainActivity;
private final InetAddress address;
private final int port;
private String messageToSend;
volatile private boolean send;
private final DatagramSocket socket;
volatile private boolean running;
private boolean Gruppe =true;
private boolean showMessage = true;
StringBuffer rxStringBuffer = new StringBuffer();
private OnConnectionListener listener;
@SuppressLint("SetTextI18n")
public WifiCommunication(int port) {
//this.mainActivity = mainActivity;
this.port = port;
try {
socket = new DatagramSocket(this.port);
socket.setBroadcast(true);
address = InetAddress.getByName("255.255.255.255"); //100.82.255.255
running = true;
send = false;
new ReceiveThread().start();
new SendThread().start();
} catch (SocketException | UnknownHostException e) {
throw new RuntimeException(e);
}
//Toast.makeText(mainActivity.getApplicationContext(),"Communication running", Toast.LENGTH_SHORT).show();
//mainActivity.runOnUiThread(() -> mainActivity.tvMessages.setText("Communication running"));
}
public interface OnConnectionListener {
void onConnection(String data);
}
public void setOnConnectionListener(@NonNull OnConnectionListener listener) {
this.listener = listener;
}
public void sendWifiData(String wifiMessage) {
if (listener != null) {
listener.onConnection(wifiMessage);
}
}
private class ReceiveThread extends Thread {
private String rxString="";
private String previousRxString = "";
@Override
public void run() {
try {
do {
byte[] receiveData = new byte[512];
DatagramPacket rxPacket = new DatagramPacket(receiveData, receiveData.length);
socket.receive(rxPacket);
rxString = new String(receiveData, 0, rxPacket.getLength());
String[] splitrxString = rxString.split(",");
String[] splitrxStringBuffer = splitBufferIntoStrings(rxStringBuffer);
for(String elem: splitrxStringBuffer){
if(elem.equals(rxString)){
showMessage = false;
}else{
showMessage = true;
}
}
if(Gruppe){
if(!previousRxString.equals(rxString) && splitrxString[0].equals("1") && splitrxString.length==7 && showMessage) {
rxStringBuffer.append(rxString).append("\n");
Log.d("empfangen", rxString);
sendWifiData(rxString);
//mainActivity.runOnUiThread(() -> mainActivity.tvMessages.setText(rxStringBuffer));
previousRxString = rxString;
}
}else{
if(!previousRxString.equals(rxString) && splitrxString[0].equals("1") && splitrxString.length==7 && showMessage) {
rxStringBuffer.append(rxString).append("\n");
Log.d("empfangen", rxString);
sendWifiData(rxString);
//mainActivity.runOnUiThread(() -> mainActivity.tvMessages.setText(rxStringBuffer));
previousRxString = rxString;
}
}
} while (running);
}
catch (IOException e) {
e.printStackTrace();
}
}
}
private class SendThread extends Thread {
private int tmpCnt = 0;
@Override
public void run() {
try {
do {
if(send)
{
send = false;
/*SimpleDateFormat formatter = new SimpleDateFormat("HH:mm:ss");
Date curDate = new Date(System.currentTimeMillis());
String str = formatter.format(curDate);*/
byte[] send_Data = new byte[512];
String txString = (messageToSend); //"1," +str+ ",Gruppe2," + getLocalIpAddress() + ",An,Video,"
Log.d("send", txString);
send_Data = txString.getBytes();
DatagramPacket txPacket = new DatagramPacket(send_Data, txString.length(), address, port);
for(int i = 0; i < 500; i++) {
socket.send(txPacket);
}
}
} while (running);
} catch (IOException e) {
e.printStackTrace();
}
}
}
public static String getLocalIpAddress() {
try {
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface networkInterface = (NetworkInterface) ((Enumeration<?>) en).nextElement();
for (Enumeration<InetAddress> addresses = networkInterface.getInetAddresses(); addresses.hasMoreElements();) {
InetAddress inetAddress = addresses.nextElement();
if (!inetAddress.isLoopbackAddress() && inetAddress instanceof Inet4Address) {
return inetAddress.getHostAddress();
}
}
}
} catch (SocketException ex) {
ex.printStackTrace();
}
return null;
}
public void sendTrue(String message){
send = true;
messageToSend = message;
}
public void stopCommunication() {
running = false;
socket.close();
}
public String[] splitBufferIntoStrings(StringBuffer string){
String[] splitrxString2 = string.toString().split("\n");
return splitrxString2;
}
}

View File

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_checked="false" android:drawable="@color/redbright" />
<item android:state_checked="true" android:drawable="@color/greenbright" />
</selector>

View File

@ -1,37 +1,133 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"
android:gravity="center"
android:orientation="vertical"
tools:context=".MainActivity">
android:background="#010C49"
android:visibility="visible"
tools:context="com.example.ueberwachungssystem.MainActivity"
tools:visibility="visible">
<TextView
android:id="@+id/textView"
android:layout_width="wrap_content"
android:id="@+id/textAuswahl"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text=""
android:textSize="20dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
android:textSize="20sp"
android:textColor="@color/white"/>
<TextView
android:id="@+id/textAoderA"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_below="@+id/toggleAudio"
android:layout_alignParentLeft="true"
android:layout_marginTop="15dp"
android:textSize="20sp"
android:textColor="@color/white"/>
<ToggleButton
android:id="@+id/previewButton"
android:layout_width="match_parent"
android:id="@+id/toggleKamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="ToggleButton" />
android:layout_alignBottom="@id/toggleAudio"
android:layout_marginRight="30dp"
android:layout_toLeftOf="@id/toggleAudio"
android:textColor="@color/yellow"
android:textOn="Kamera an"
android:textOff="Kamera aus"
android:background="@drawable/toggle_btn"/>
<ToggleButton
android:id="@+id/toggleAudio"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/textAuswahl"
android:layout_centerHorizontal="true"
android:layout_marginTop="5dp"
android:textColor="@color/yellow"
android:textOn="Audio an"
android:textOff="Audio aus"
android:background="@drawable/toggle_btn"/>
<androidx.camera.view.PreviewView
android:id="@+id/previewView"
<ToggleButton
android:id="@+id/toggleBewegung"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@id/toggleAudio"
android:layout_marginLeft="30dp"
android:layout_toEndOf="@+id/toggleAudio"
android:layout_toRightOf="@id/toggleAudio"
android:textColor="@color/yellow"
android:textOn="Bewegung an"
android:textOff="Bewegung aus"
android:background="@drawable/toggle_btn"/>
<Button
android:id="@+id/btnAlarme"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btnAufnahmen"
android:layout_toLeftOf="@id/btnAufnahmen"
android:layout_marginRight="15dp"
android:theme="@style/Button.Green"
android:onClick="onClickZeigeFragment1"
android:text="Alarme" />
<Button
android:id="@+id/btnAufnahmen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textAoderA"
android:layout_centerHorizontal="true"
android:layout_marginTop="15dp"
android:theme="@style/Button.Green"
android:onClick="onClickZeigeFragment2"
android:text="Aufnahmen" />
<Button
android:id="@+id/btnAnzeigeVerb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBottom="@+id/btnAufnahmen"
android:layout_toRightOf="@id/btnAufnahmen"
android:layout_marginLeft="15dp"
android:text="Live Video"
android:onClick="onClickZeigeFragment3"/>
<FrameLayout
android:id="@+id/frame"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:backgroundTint="@android:color/black"/>
android:layout_below="@+id/btnAufnahmen"
android:layout_marginTop="25dp"
android:layout_alignParentStart="true"
android:background="@color/white">
</FrameLayout>
</LinearLayout>
<!--
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_below="@id/btnAufnahmen"
android:layout_marginTop="25dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/Alarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@color/red"/>
</LinearLayout>
</ScrollView>
-->
<ListView
android:id = "@+id/listView"
android:layout_width = "wrap_content"
android:layout_height = "wrap_content"/>
</RelativeLayout>

View File

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:background="@color/bluedark">
<ScrollView
android:id="@+id/scrollView1"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="25dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/Alarm"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/yellow"/>
</LinearLayout>
</ScrollView>
</RelativeLayout>

View File

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:background="@android:color/holo_blue_light" >
<ScrollView
android:id="@+id/scrollView2"
android:layout_width="match_parent"
android:layout_height="250dp"
android:layout_marginTop="25dp">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >
<TextView
android:id="@+id/Aufzeichnungen"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@color/yellow"/>
</LinearLayout>
</ScrollView>
<VideoView
android:id="@+id/AusAuf"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@id/scrollView2"
android:textAppearance="?android:attr/textAppearanceLarge"/>
</LinearLayout>

View File

@ -0,0 +1,24 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:background="@color/bluedark">
<ImageView
android:id="@+id/Video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:rotation="90">
</ImageView>
<ImageView
android:id="@+id/Video2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:rotation="90">
</ImageView>
</LinearLayout>

View File

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:paddingLeft="10dp"
android:paddingRight="10dp"
android:gravity="center"
android:background="#010C49">
<TextView
android:id="@+id/titleText"
android:layout_gravity="center"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="20sp"
android:textStyle="italic"
android:textColor="@color/white"
android:padding="10dp"/>
<Button
android:id="@+id/RechteAnfordern"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_weight="1"
android:backgroundTint="@color/purple_500"
android:text="Rechte Anfordern" />
</LinearLayout>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<androidx.appcompat.widget.LinearLayoutCompat xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"
android:orientation="vertical"
android:background="@android:color/holo_blue_light">
<Button
android:id="@+id/button"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Aufnahmen Löschen"
android:backgroundTint="#010C49"
tools:ignore="MissingConstraints" />
<ListView
android:id="@+id/listView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
tools:ignore="MissingConstraints"
tools:layout_editor_absoluteX="0dp"
tools:layout_editor_absoluteY="0dp" />
</androidx.appcompat.widget.LinearLayoutCompat>

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<VideoView
android:id="@+id/videoView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_gravity="center"/>
</FrameLayout>

View File

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<menu xmlns:android="http://schemas.android.com/apk/res/android" >
<item android:id="@+id/Rechteverwaltung"
android:title="Rechteverwaltung" />
<item android:id="@+id/Sensoren"
android:title="Sensoren" />
<item android:id="@+id/Detection"
android:title="Detektionen" />
<item android:id="@+id/Impressum"
android:title="Impressum" />
</menu>

View File

@ -7,4 +7,9 @@
<color name="teal_700">#FF018786</color>
<color name="black">#FF000000</color>
<color name="white">#FFFFFFFF</color>
<color name="red">#5C0000</color>
<color name="redbright">#EF3434</color>
<color name="greenbright">#469733</color>
<color name="bluedark">#053C8E</color>
<color name="yellow">#FFEB3B</color>
</resources>

View File

@ -13,4 +13,9 @@
<item name="android:statusBarColor">?attr/colorPrimaryVariant</item>
<!-- Customize your theme here. -->
</style>
<style name="Button.Green" parent="ThemeOverlay.AppCompat">
<item name="colorAccent">#0F3E01</item>
</style>
</resources>

View File

@ -1,5 +1,5 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'com.android.application' version '8.0.0' apply false
id 'com.android.library' version '8.0.0' apply false
}

Binary file not shown.

View File

@ -18,4 +18,6 @@ android.useAndroidX=true
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonTransitiveRClass=true
android.defaults.buildfeatures.buildconfig=true
android.nonFinalResIds=false

View File

@ -1,6 +1,6 @@
#Thu May 11 15:04:30 CEST 2023
#Thu May 11 15:19:24 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.0-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME

View File

@ -14,3 +14,4 @@ dependencyResolutionManagement {
}
rootProject.name = "Ueberwachungssystem"
include ':app'
include ':app'