From ab41217f0e5d25c31766de981961fe3e024948bb Mon Sep 17 00:00:00 2001 From: Bastian Kohler Date: Mon, 19 Jun 2023 13:13:23 +0200 Subject: [PATCH 1/3] Added DetectionService --- app/build.gradle | 2 + app/src/main/AndroidManifest.xml | 1 + .../Detection/DetectorService.java | 134 ++++++++++++++++++ .../ueberwachungssystem/MainActivity.java | 65 +++++---- 4 files changed, 175 insertions(+), 27 deletions(-) create mode 100644 app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java diff --git a/app/build.gradle b/app/build.gradle index 02a2cc2..083ba82 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -42,6 +42,8 @@ dependencies { 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" diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 3ea0c3b..3fe9720 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -24,6 +24,7 @@ + \ No newline at end of file diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java new file mode 100644 index 0000000..8834374 --- /dev/null +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java @@ -0,0 +1,134 @@ +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; + +@ExperimentalGetImage +public class DetectorService extends LifecycleService { + + public TestBinder testBinder = new TestBinder(); + private DetectorService.OnDetectionListener listener; + + VideoDetector videoDetector = null; + AudioRecorder audioRecorder = null; + + + @Override + public int onStartCommand(Intent intent, int flags, int startId) { + videoDetector = new VideoDetector(this); + videoDetector.setOnDetectionListener(new Detector.OnDetectionListener() { + @Override + public void onDetection(@NonNull DetectionReport detectionReport) { + passToServiceListener(detectionReport); + } + }); + + audioRecorder = new AudioRecorder(this); + return super.onStartCommand(intent, flags, startId); + } + + /** Service methods */ + public class TestBinder 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 testBinder; + } + + + /** Video Detection */ + public void startVideoDetection() { + if(videoDetector != null) + videoDetector.startDetection(); + } + public void stopVideoDetection() { + if(videoDetector != null) + videoDetector.stopDetection(); + } + public boolean isVideoDetectionRunning() { + if(videoDetector != null) + return videoDetector.isDetecting(); + return false; + } + public void debugVideoProcessing(ImageView input, ImageView output) { + if(videoDetector != null) + videoDetector.debugProcessing(input, output); + } + + /** Audio Detection */ + public void startAudioDetection() { + + } + public void stopAudioDetection() { + + } + + /** Motion Detection */ + public void startMotionDetection() { + + } + public void stopMotionDetection() { + + } + + /** Video Recording */ + public void startVideoRecording() { + if(videoDetector != null) + videoDetector.startRecording(); + } + public void stopVideoRecording() { + if(videoDetector != null) + videoDetector.stopRecording(); + } + public boolean isVideoRecordingRunning() { + if(videoDetector != null) + return videoDetector.isRecording(); + return false; + } + + /** Audio Recording */ + public void startAudioRecording() { + if(audioRecorder != null) + audioRecorder.startRecording(); + } + public void stopAudioRecording() { + if(audioRecorder != null) + audioRecorder.stopRecording(); + } + public boolean isAudioRecordingRunning() { + if(videoDetector != null) + return audioRecorder.isRecording(); + return false; + } + + + /** pass Detection Report to Service Detection Listener and trigger it */ + public void passToServiceListener(DetectionReport detectionReport) { + if (listener != null) { + listener.onDetection(detectionReport); + } + } + + + /** On Detection Listener - runs when violation is reported */ + public interface OnDetectionListener { + void onDetection(@NonNull DetectionReport detectionReport); + } + public void setOnDetectionListener(@NonNull DetectorService.OnDetectionListener listener) { + this.listener = listener; + } +} diff --git a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java index a75571b..cdecc38 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java +++ b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java @@ -5,48 +5,43 @@ import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.ExperimentalGetImage; import androidx.camera.view.PreviewView; +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.View; import android.widget.ImageView; import android.widget.ToggleButton; -import com.example.ueberwachungssystem.Detection.AudioRecorder; import com.example.ueberwachungssystem.Detection.DetectionReport; -import com.example.ueberwachungssystem.Detection.Detector; -import com.example.ueberwachungssystem.Detection.VideoDetector; +import com.example.ueberwachungssystem.Detection.DetectorService; @ExperimentalGetImage public class MainActivity extends AppCompatActivity { + private DetectorService detectorService = new DetectorService(); + private ImageView inputImageView; + private ImageView outputImageView; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); - ImageView inputImageView = findViewById(R.id.inputImageView); - ImageView outputImageView = findViewById(R.id.outputImageView); + inputImageView = findViewById(R.id.inputImageView); + outputImageView = findViewById(R.id.outputImageView); PreviewView previewView = findViewById(R.id.previewView); - VideoDetector vd = new VideoDetector(this); - //vd.setPreviewView(previewView); - vd.debugProcessing(inputImageView, outputImageView); - vd.setOnDetectionListener(new Detector.OnDetectionListener() { - @Override - public void onDetection(@NonNull DetectionReport detectionReport) { - Log.d("onDetection", detectionReport.toString()); - if (detectionReport.detectionState) - vd.startRecording(); - else - vd.stopRecording(); - } - }); - vd.startDetection(); + Intent serviceIntent = new Intent(this, DetectorService.class); + bindService(serviceIntent, serviceConnection, Context.BIND_AUTO_CREATE); + startService(serviceIntent); - AudioRecorder audioRecorder = new AudioRecorder(this); @@ -56,17 +51,33 @@ public class MainActivity extends AppCompatActivity { public void onClick(View v) { if (toggleButton.isChecked()) { - //vd.startDetection(); - vd.stopDetection(); - //vd.startRecording(); - audioRecorder.startRecording(); + detectorService.startVideoRecording(); + //detectorService.startAudioRecording(); } else { - //vd.stopDetection(); - vd.stopRecording(); - audioRecorder.stopRecording(); + //detectorService.stopAudioRecording(); + detectorService.stopVideoRecording(); } } }); } + + private ServiceConnection serviceConnection = new ServiceConnection() { + @Override + public void onServiceConnected(ComponentName name, IBinder service) { + DetectorService.TestBinder binder = (DetectorService.TestBinder) service; + detectorService = binder.getBoundService(); + + detectorService.startVideoDetection(); + detectorService.debugVideoProcessing(inputImageView, outputImageView); + detectorService.setOnDetectionListener(new DetectorService.OnDetectionListener() { + @Override + public void onDetection(@NonNull DetectionReport detectionReport) { + Log.d("onDetection", detectionReport.toString()); + } + }); + } + @Override + public void onServiceDisconnected(ComponentName name) {} + }; } \ No newline at end of file From 0a3600d0d6f6a43335956570c616c3f75234dfa5 Mon Sep 17 00:00:00 2001 From: Bastian Kohler Date: Mon, 19 Jun 2023 14:27:04 +0200 Subject: [PATCH 2/3] Refactor --- .../Detection/DetectorService.java | 18 ++++++++++++++++++ .../Detection/VideoDetector.java | 3 +-- .../ueberwachungssystem/MainActivity.java | 15 +++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java index 8834374..8f1bb82 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java @@ -1,6 +1,9 @@ package com.example.ueberwachungssystem.Detection; +import android.Manifest; +import android.app.Activity; import android.content.Intent; +import android.content.pm.PackageManager; import android.os.Binder; import android.os.IBinder; import android.util.Log; @@ -9,6 +12,8 @@ import android.widget.ImageView; import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.camera.core.ExperimentalGetImage; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; import androidx.lifecycle.LifecycleService; @ExperimentalGetImage @@ -16,6 +21,7 @@ public class DetectorService extends LifecycleService { public TestBinder testBinder = new TestBinder(); private DetectorService.OnDetectionListener listener; + private boolean isServiceRunning = false; VideoDetector videoDetector = null; AudioRecorder audioRecorder = null; @@ -23,6 +29,8 @@ public class DetectorService extends LifecycleService { @Override public int onStartCommand(Intent intent, int flags, int startId) { + if (isServiceRunning) + return START_NOT_STICKY; videoDetector = new VideoDetector(this); videoDetector.setOnDetectionListener(new Detector.OnDetectionListener() { @Override @@ -32,9 +40,19 @@ public class DetectorService extends LifecycleService { }); audioRecorder = new AudioRecorder(this); + + + isServiceRunning = true; + return super.onStartCommand(intent, flags, startId); } + @Override + public void onDestroy() { + super.onDestroy(); + isServiceRunning = false; + } + /** Service methods */ public class TestBinder extends Binder { public DetectorService getBoundService() { diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java index 9c0ebda..5df58d6 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/VideoDetector.java @@ -76,13 +76,12 @@ public class VideoDetector extends Detector { // Recorder private File outputDir; // Default: in app files directory - private int rotation = 0; // Parameters private static final float ALARM_THRESHOLD = 0.5f; // Percent of pixels changed private static final float START_DELAY = 20000; // milliseconds - private static final android.util.Size IMAGE_RES = new android.util.Size(640, 480); + private static final android.util.Size IMAGE_RES = new android.util.Size(480, 360); diff --git a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java index cdecc38..c4ff843 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java +++ b/app/src/main/java/com/example/ueberwachungssystem/MainActivity.java @@ -4,11 +4,16 @@ import androidx.annotation.NonNull; import androidx.appcompat.app.AppCompatActivity; import androidx.camera.core.ExperimentalGetImage; import androidx.camera.view.PreviewView; +import androidx.core.app.ActivityCompat; +import androidx.core.content.ContextCompat; +import android.Manifest; +import android.app.Activity; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.ServiceConnection; +import android.content.pm.PackageManager; import android.os.Bundle; import android.os.IBinder; import android.util.Log; @@ -80,4 +85,14 @@ public class MainActivity extends AppCompatActivity { @Override public void onServiceDisconnected(ComponentName name) {} }; + + + private boolean hasPermissions() { + return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED && + ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; + } + private void getPermissions() { + if (!hasPermissions()) + ActivityCompat.requestPermissions((Activity) this, new String[]{android.Manifest.permission.CAMERA, Manifest.permission.RECORD_AUDIO}, 12345); + } } \ No newline at end of file From bc5227ba4f9770b384078d8614b962ca041a69d9 Mon Sep 17 00:00:00 2001 From: Bastian Kohler Date: Mon, 19 Jun 2023 14:37:49 +0200 Subject: [PATCH 3/3] Refactor of DetectorService --- .../Detection/DetectorService.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java index 8f1bb82..49b46c0 100644 --- a/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java +++ b/app/src/main/java/com/example/ueberwachungssystem/Detection/DetectorService.java @@ -16,6 +16,8 @@ import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; import androidx.lifecycle.LifecycleService; +import java.io.File; + @ExperimentalGetImage public class DetectorService extends LifecycleService { @@ -117,6 +119,10 @@ public class DetectorService extends LifecycleService { return videoDetector.isRecording(); return false; } + public void setVideoRecordingDir(File outputDir) { + if (videoDetector != null) + videoDetector.setOutputDir(outputDir); + } /** Audio Recording */ public void startAudioRecording() { @@ -132,6 +138,12 @@ public class DetectorService extends LifecycleService { return audioRecorder.isRecording(); return false; } + public void setAudioRecordingDir(File outputDir) { + if (audioRecorder != null) + audioRecorder.setOutputDir(outputDir); + } + + /** pass Detection Report to Service Detection Listener and trigger it */