diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index e348435..654bfb5 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,7 +3,11 @@ package="com.example.greenwatch"> - + + + + + diff --git a/app/src/main/java/com/example/greenwatch/AccelerometerActivity.java b/app/src/main/java/com/example/greenwatch/AccelerometerActivity.java index ec863b2..1c84428 100644 --- a/app/src/main/java/com/example/greenwatch/AccelerometerActivity.java +++ b/app/src/main/java/com/example/greenwatch/AccelerometerActivity.java @@ -11,6 +11,7 @@ import android.hardware.SensorEvent; import android.hardware.SensorEventListener; import android.hardware.SensorManager; import android.os.Bundle; +import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.TextView; @@ -27,6 +28,7 @@ public class AccelerometerActivity extends AppCompatActivity implements SensorEv private SensorManager accelerometerManager; private Sensor accelerometerSensor; + private SurfaceView surfaceView; private TextView accelerometerStatusMessage; private TextView accelerometerDataTV; private TextView accelerometerWarningTV; @@ -38,6 +40,7 @@ public class AccelerometerActivity extends AppCompatActivity implements SensorEv super.onCreate(savedInstanceState); setContentView(R.layout.activity_accelerometer); + surfaceView = (SurfaceView) findViewById(R.id.surfaceViewAccelerometer); accelerometerStatusMessage = (TextView) findViewById(R.id.tvAccelerometerStatusmessage); accelerometerDataTV = (TextView) findViewById(R.id.tvAccelerometerData); accelerometerWarningTV = (TextView) findViewById(R.id.tvAccelerometerWarning); @@ -65,7 +68,7 @@ public class AccelerometerActivity extends AppCompatActivity implements SensorEv }); mAccelerometerViewModel = new ViewModelProvider(this).get(AccelerometerViewModel.class); - mAccelerometerViewModel.init(); + mAccelerometerViewModel.init(surfaceView.getHolder()); mAccelerometerViewModel.getConnectedDeviceList().observe(this, new Observer>() { @Override public void onChanged(List devices) { @@ -84,9 +87,11 @@ public class AccelerometerActivity extends AppCompatActivity implements SensorEv @Override public void onChanged(Boolean aBoolean) { if (aBoolean) { + mAccelerometerViewModel.startAlarmRecording(); Toast.makeText(AccelerometerActivity.this, "Start Alarm Recording", Toast.LENGTH_LONG).show(); } else { + mAccelerometerViewModel.stopAlarmRecording(AccelerometerActivity.this); Toast.makeText(AccelerometerActivity.this, "Stop Alarm Recording", Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/example/greenwatch/MainActivity.java b/app/src/main/java/com/example/greenwatch/MainActivity.java index 683f40c..a22091b 100644 --- a/app/src/main/java/com/example/greenwatch/MainActivity.java +++ b/app/src/main/java/com/example/greenwatch/MainActivity.java @@ -8,6 +8,7 @@ import androidx.recyclerview.widget.RecyclerView; import android.content.Intent; import android.os.Bundle; +import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.Toast; @@ -27,6 +28,7 @@ public class MainActivity extends AppCompatActivity { private Button audiodetectionAndAccelerometerButton; private Button videodetectionAndAccelerometerButton; private Button connectionButton; + private SurfaceView surfaceView; private MainActivityViewModel mMainActivityViewModel; @Override @@ -34,6 +36,7 @@ public class MainActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); + surfaceView = (SurfaceView) findViewById(R.id.surfaceViewMainActivity); audiodetectionButton = (Button) findViewById(R.id.audiodetectionButton); videodetectionButton = (Button) findViewById(R.id.videodetectionButton); accelerometerButton = (Button) findViewById(R.id.accelerometerButton); @@ -56,8 +59,10 @@ public class MainActivity extends AppCompatActivity { alarmHistoryListRecyclerView.setAdapter(alarmHistoryListAdapter); mMainActivityViewModel = new ViewModelProvider(this).get(MainActivityViewModel.class); - mMainActivityViewModel.init(); + mMainActivityViewModel.init(surfaceView.getHolder()); mMainActivityViewModel.accessRequestCamera(this); + mMainActivityViewModel.accessRequestAudioRecording(this); + mMainActivityViewModel.accessRequestWriteExternalStorage(this); mMainActivityViewModel.getConnectedDeviceList().observe(this, new Observer>() { @Override public void onChanged(List devices) { @@ -76,9 +81,11 @@ public class MainActivity extends AppCompatActivity { @Override public void onChanged(Boolean aBoolean) { if (aBoolean) { + mMainActivityViewModel.startAlarmRecording(); Toast.makeText(MainActivity.this, "Start Alarm Recording", Toast.LENGTH_LONG).show(); } else { + mMainActivityViewModel.stopAlarmRecording(MainActivity.this); Toast.makeText(MainActivity.this, "Stop Alarm Recording", Toast.LENGTH_LONG).show(); } } @@ -148,8 +155,8 @@ public class MainActivity extends AppCompatActivity { startActivity(intent); } public void openVideodetectionAndAccelerometerActivity(){ - Intent intent = new Intent(this, VideodetectionAndAccelerometerActivity.class); - startActivity(intent); + //Intent intent = new Intent(this, VideodetectionAndAccelerometerActivity.class); + //startActivity(intent); } public void openConnectionActivity(){ //Intent intent = new Intent(this, ConnectionActivity.class); diff --git a/app/src/main/java/com/example/greenwatch/VideodetectionActivity.java b/app/src/main/java/com/example/greenwatch/VideodetectionActivity.java index e6a7f95..5042fdd 100644 --- a/app/src/main/java/com/example/greenwatch/VideodetectionActivity.java +++ b/app/src/main/java/com/example/greenwatch/VideodetectionActivity.java @@ -9,6 +9,7 @@ import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import android.os.Bundle; +import android.view.SurfaceView; import android.view.View; import android.widget.Button; import android.widget.Toast; @@ -26,6 +27,7 @@ import java.util.concurrent.ExecutionException; public class VideodetectionActivity extends AppCompatActivity { private Button backToMainActivity; + private SurfaceView surfaceView; private VideodetectionViewModel mVideoDetectionViewModel; @Override @@ -33,6 +35,7 @@ public class VideodetectionActivity extends AppCompatActivity { super.onCreate(savedInstanceState); setContentView(R.layout.activity_videodetection); + surfaceView = (SurfaceView) findViewById(R.id.surfaceViewVideodetection); backToMainActivity = (Button) findViewById(R.id.videodetectorBackToMainActivity); RecyclerView recyclerView = findViewById(R.id.deviceListRecyclerView); @@ -57,7 +60,7 @@ public class VideodetectionActivity extends AppCompatActivity { }); mVideoDetectionViewModel = new ViewModelProvider(this).get(VideodetectionViewModel.class); - mVideoDetectionViewModel.init(); + mVideoDetectionViewModel.init(surfaceView.getHolder()); mVideoDetectionViewModel.getConnectedDeviceList().observe(this, new Observer>() { @Override public void onChanged(List devices) { @@ -76,9 +79,11 @@ public class VideodetectionActivity extends AppCompatActivity { @Override public void onChanged(Boolean aBoolean) { if (aBoolean) { + mVideoDetectionViewModel.startAlarmRecording(); Toast.makeText(VideodetectionActivity.this, "Start Alarm Recording", Toast.LENGTH_LONG).show(); } else { + mVideoDetectionViewModel.stopAlarmRecording(VideodetectionActivity.this); Toast.makeText(VideodetectionActivity.this, "Stop Alarm Recording", Toast.LENGTH_LONG).show(); } } diff --git a/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java b/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java index f6118dd..4e47879 100644 --- a/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java +++ b/app/src/main/java/com/example/greenwatch/VideodetectionAndAccelerometerActivity.java @@ -1,4 +1,4 @@ -package com.example.greenwatch; +/*package com.example.greenwatch; import androidx.appcompat.app.AppCompatActivity; import androidx.camera.lifecycle.ProcessCameraProvider; @@ -168,4 +168,4 @@ public class VideodetectionAndAccelerometerActivity extends AppCompatActivity im accelerometerManager.unregisterListener(this, accelerometerSensor); } } -} \ No newline at end of file +}*/ \ No newline at end of file diff --git a/app/src/main/java/com/example/greenwatch/alarmrecorder/AlarmRecorder.java b/app/src/main/java/com/example/greenwatch/alarmrecorder/AlarmRecorder.java new file mode 100644 index 0000000..8292d02 --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/alarmrecorder/AlarmRecorder.java @@ -0,0 +1,251 @@ +package com.example.greenwatch.alarmrecorder; + +import android.app.Activity; +import android.content.Context; +import android.media.MediaCodec; +import android.media.MediaExtractor; +import android.media.MediaFormat; +import android.media.MediaMuxer; +import android.media.MediaRecorder; +import android.os.Environment; +import android.view.SurfaceHolder; +import android.widget.Toast; + +import com.example.greenwatch.MainActivity; +import com.example.greenwatch.alarmrecorder.runnables.AudioRecorder; +import com.example.greenwatch.alarmrecorder.runnables.VideoRecorder; +import com.example.greenwatch.sensors.AccelerometerSensor; +import com.example.greenwatch.sensors.CameraSensor; + +import java.io.File; +import java.io.IOException; +import java.nio.ByteBuffer; + +public class AlarmRecorder { + private static AlarmRecorder alarmRecorderInstance; + private boolean isRecording; + private String videoPath; + private String audioPath; + private MediaFormat videoFormat; + private MediaFormat audioFormat; + private MediaExtractor videoExtractor; + private MediaExtractor audioExtractor; + private Runnable audioRecorderRunnable; + private Runnable videoRecorderRunnable; + private SurfaceHolder previewHolder; + private MediaRecorder videoRecorder; + private MediaRecorder audioRecorder; + private Thread videoThread; // Video-Thread als Instanzvariable + private Thread audioThread; // Audio-Thread als Instanzvariable + + private AlarmRecorder() { + audioRecorder = new MediaRecorder(); + videoRecorder = new MediaRecorder(); + videoExtractor = new MediaExtractor(); + audioExtractor = new MediaExtractor(); + } + + public static synchronized AlarmRecorder getInstance() { + if (alarmRecorderInstance == null){ + alarmRecorderInstance = new AlarmRecorder(); + } + return alarmRecorderInstance; + } + + public void setPreviewHolder(SurfaceHolder previewHolder) { + this.previewHolder = previewHolder; + } + + public void startRecording() { + createStoragePaths(); //Speicherort und -namen für Audio- und Video-Datei + + audioRecorderRunnable = new AudioRecorder(audioRecorder, audioPath); + videoRecorderRunnable = new VideoRecorder(videoRecorder, videoPath, previewHolder); + audioThread = new Thread(audioRecorderRunnable); + videoThread = new Thread(videoRecorderRunnable); + + //Threads starten + videoThread.start(); + audioThread.start(); + } + + public void stopRecording(Context context) { + isRecording = false; + try { + stopVideoRecording(); + stopAudioRecording(); + + Toast.makeText(context, "Video- und Audioaufzeichnung beendet", Toast.LENGTH_SHORT).show(); + + waitTillThreadsStopped(); + File videoFile = new File(videoPath); //Speichere das aufgenommene Video + File audioFile = new File(audioPath); //Speichere die aufgenommene Audio + + if (videoFile.exists() && audioFile.exists()) { + //Wenn Video- und Audioaufzeichnung gestoppt und abgespeichert sind, beginne mit dem Mergeprozess der beiden + mergeVideoWithAudio(); + Toast.makeText(context, "Video und Audio erfolgreich zusammengeführt", Toast.LENGTH_SHORT).show(); + } else { + Toast.makeText(context, "Dateien wurden nicht gefunden!", Toast.LENGTH_SHORT).show(); + } + } catch (RuntimeException stopException) { + stopException.printStackTrace(); + } + } + + private void createStoragePaths(){ + //Pfade zum Zwischenspeichern der aufgenommenen Audio und Video-Datei + isRecording = true; + String externalStorageDirectory = Environment.getExternalStorageDirectory().getAbsolutePath(); + String dcimDirectory = externalStorageDirectory + "/DCIM"; + videoPath = dcimDirectory + "/video.mp4"; + audioPath = dcimDirectory + "/audio.mp3"; + } + + private void stopVideoRecording(){ + if (videoRecorder != null) { + videoRecorder.stop(); + videoRecorder.release(); + videoRecorder = null; + } + } + + private void stopAudioRecording(){ + if (audioRecorder != null) { + audioRecorder.stop(); + audioRecorder.release(); + audioRecorder = null; + } + } + + private void waitTillThreadsStopped(){ + try { + videoThread.join(); + audioThread.join(); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } + + private void mergeVideoWithAudio() { + try { + setVideoExtractorDataSource(); //extrahieren der Video Datei, die zuvor zwischengespeichert wurde + setAudioExtractorDataSource(); //extrahieren der Audio Datei, die zuvor zwischengespeichert wurde + + //Speicherort der später zusammengeführten Datei + String outputFilePath = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES).getAbsolutePath() + "/merged_video.mp4"; + //MediaMuxer zum Zusammenführen einer Audio- und einer Videodatei + MediaMuxer muxer = new MediaMuxer(outputFilePath, MediaMuxer.OutputFormat.MUXER_OUTPUT_MPEG_4); + int videoTrack = muxer.addTrack(videoFormat); + int audioTrack = muxer.addTrack(audioFormat); + muxer.start(); + + ByteBuffer buffer = ByteBuffer.allocate(1024 * 1024); + MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); + + videoExtraction(buffer, videoTrack, bufferInfo, muxer); + audioExtraction(buffer, audioTrack, bufferInfo, muxer); + + muxer.stop(); + muxer.release(); + + // Löschen der separaten Video- und Audio-Dateien + deleteVideoFile(); + deleteAudioFile(); + } catch (IOException e) { + e.printStackTrace(); + } + } + + private void setVideoExtractorDataSource() { + try { + videoExtractor.setDataSource(videoPath); + int videoTrackIndex = getTrackIndex(videoExtractor, "video/"); + if (videoTrackIndex < 0) { + // Video-Track nicht gefunden + return; + } + videoExtractor.selectTrack(videoTrackIndex); + videoFormat = videoExtractor.getTrackFormat(videoTrackIndex); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private void setAudioExtractorDataSource() { + try { + audioExtractor.setDataSource(audioPath); + int audioTrackIndex = getTrackIndex(audioExtractor, "audio/"); + if (audioTrackIndex < 0) { + // Audio-Track nicht gefunden + return; + } + audioExtractor.selectTrack(audioTrackIndex); + audioFormat = audioExtractor.getTrackFormat(audioTrackIndex); + + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + private int getTrackIndex(MediaExtractor extractor, String mimeType) { + int trackCount = extractor.getTrackCount(); + for (int i = 0; i < trackCount; i++) { + MediaFormat format = extractor.getTrackFormat(i); + String trackMimeType = format.getString(MediaFormat.KEY_MIME); + if (trackMimeType.startsWith(mimeType)) { + return i; + } + } + return -1; + } + + private void videoExtraction(ByteBuffer buffer, int videoTrack, MediaCodec.BufferInfo bufferInfo, MediaMuxer muxer) { + videoExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); + while (true) { + int sampleSize = videoExtractor.readSampleData(buffer, 0); + if (sampleSize < 0) { + break; + } + long presentationTimeUs = videoExtractor.getSampleTime(); + bufferInfo.offset = 0; + bufferInfo.size = sampleSize; + bufferInfo.flags = MediaCodec.BUFFER_FLAG_KEY_FRAME; + bufferInfo.presentationTimeUs = presentationTimeUs; + muxer.writeSampleData(videoTrack, buffer, bufferInfo); + videoExtractor.advance(); + } + } + + private void audioExtraction(ByteBuffer buffer, int audioTrack, MediaCodec.BufferInfo bufferInfo, MediaMuxer muxer) { + audioExtractor.seekTo(0, MediaExtractor.SEEK_TO_CLOSEST_SYNC); + while (true) { + int sampleSize = audioExtractor.readSampleData(buffer, 0); + if (sampleSize < 0) { + break; + } + long presentationTimeUs = audioExtractor.getSampleTime(); + bufferInfo.offset = 0; + bufferInfo.size = sampleSize; + bufferInfo.flags = 0; // or MediaCodec.BUFFER_FLAG_KEY_FRAME + bufferInfo.presentationTimeUs = presentationTimeUs; + muxer.writeSampleData(audioTrack, buffer, bufferInfo); + audioExtractor.advance(); + } + } + + + private void deleteVideoFile(){ + File videoFile = new File(videoPath); + if (videoFile.exists()) { + videoFile.delete(); + } + } + + private void deleteAudioFile(){ + File audioFile = new File(audioPath); + if (audioFile.exists()) { + audioFile.delete(); + } + } +} diff --git a/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/AudioRecorder.java b/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/AudioRecorder.java new file mode 100644 index 0000000..a828942 --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/AudioRecorder.java @@ -0,0 +1,33 @@ +package com.example.greenwatch.alarmrecorder.runnables; + +import android.media.MediaRecorder; +import android.widget.Toast; + +import com.example.greenwatch.MainActivity; + +import java.io.IOException; + +public class AudioRecorder implements Runnable { + + private final MediaRecorder audioRecorder; + private final String audioPath; + public AudioRecorder(MediaRecorder audioRecorder, String audioPath) { + this.audioRecorder = audioRecorder; + this.audioPath = audioPath; + } + @Override + public void run() { + audioRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT); + audioRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + audioRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC); + audioRecorder.setOutputFile(audioPath); + + try { + audioRecorder.prepare(); + audioRecorder.start(); + } catch (IOException e) { + e.printStackTrace(); + } + } + +} diff --git a/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/VideoRecorder.java b/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/VideoRecorder.java new file mode 100644 index 0000000..6be4aa7 --- /dev/null +++ b/app/src/main/java/com/example/greenwatch/alarmrecorder/runnables/VideoRecorder.java @@ -0,0 +1,38 @@ +package com.example.greenwatch.alarmrecorder.runnables; + +import android.media.MediaRecorder; +import android.view.SurfaceHolder; + +import com.example.greenwatch.viewmodels.ViewModelInterface; + +import java.io.IOException; + +public class VideoRecorder implements Runnable{ + private final MediaRecorder videoRecorder; + private final String videoPath; + private SurfaceHolder previewHolder; + + public VideoRecorder(MediaRecorder videoRecorder, String videoPath, SurfaceHolder previewHolder) { + this.videoRecorder = videoRecorder; + this.videoPath = videoPath; + this.previewHolder = previewHolder; + } + @Override + public void run() { + videoRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); + videoRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4); + videoRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT); + videoRecorder.setOutputFile(videoPath); + videoRecorder.setOrientationHint(90); + //todo find solution for videoView + videoRecorder.setPreviewDisplay(previewHolder.getSurface()); + + try { + videoRecorder.prepare(); + videoRecorder.start(); + + } catch (IOException e) { + e.printStackTrace(); + } + } +} diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/AccelerometerViewModel.java b/app/src/main/java/com/example/greenwatch/viewmodels/AccelerometerViewModel.java index 344480f..5a497f1 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/AccelerometerViewModel.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/AccelerometerViewModel.java @@ -1,9 +1,13 @@ package com.example.greenwatch.viewmodels; +import android.content.Context; +import android.view.SurfaceHolder; + import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.example.greenwatch.alarmrecorder.AlarmRecorder; import com.example.greenwatch.models.Device; import com.example.greenwatch.repositories.DeviceRepository; import com.example.greenwatch.sensors.AccelerometerSensor; @@ -17,16 +21,20 @@ public class AccelerometerViewModel extends ViewModel implements ViewModelInterf private MutableLiveData> mAlarmHistoryList; private MutableLiveData mStartAlarmRecording; private AccelerometerSensor mAccelerometerSensor; + private AlarmRecorder mAlarmRecorder; private DeviceRepository mDeviceRepository; @Override - public void init() { + public void init(SurfaceHolder previewHolder) { if (mDeviceRepository == null) { mDeviceRepository = DeviceRepository.getInstance(); } if (mAccelerometerSensor == null) { mAccelerometerSensor = AccelerometerSensor.getInstance(); } + if (mAlarmRecorder == null) { + mAlarmRecorder = AlarmRecorder.getInstance(); + } if (mDeviceList == null) { mDeviceList = mDeviceRepository.getConnectedDeviceList(); } @@ -39,6 +47,7 @@ public class AccelerometerViewModel extends ViewModel implements ViewModelInterf if (mAccelerometerAlarmDetected == null) { mAccelerometerAlarmDetected = mAccelerometerSensor.getAccelerometerAlarmDetected(); } + setAlarmRecordingPreviewHolder(previewHolder); } public void addValueToGesamtBE(float newValue) { @@ -140,4 +149,19 @@ public class AccelerometerViewModel extends ViewModel implements ViewModelInterf public String getSystemTimeStamp() { return mDeviceRepository.getSystemTimeStamp(); } + + @Override + public void startAlarmRecording() { + mAlarmRecorder.startRecording(); + } + + @Override + public void stopAlarmRecording(Context context) { + mAlarmRecorder.stopRecording(context); + } + + @Override + public void setAlarmRecordingPreviewHolder(SurfaceHolder previewHolder) { + mAlarmRecorder.setPreviewHolder(previewHolder); + } } diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/MainActivityViewModel.java b/app/src/main/java/com/example/greenwatch/viewmodels/MainActivityViewModel.java index 8f74ef1..54a9526 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/MainActivityViewModel.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/MainActivityViewModel.java @@ -1,8 +1,10 @@ package com.example.greenwatch.viewmodels; +import android.Manifest; import android.app.Activity; import android.content.Context; import android.content.pm.PackageManager; +import android.view.SurfaceHolder; import androidx.core.app.ActivityCompat; import androidx.core.content.ContextCompat; @@ -10,6 +12,7 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.example.greenwatch.alarmrecorder.AlarmRecorder; import com.example.greenwatch.communication.WiFiCommunication; import com.example.greenwatch.models.Device; import com.example.greenwatch.repositories.DeviceRepository; @@ -22,23 +25,29 @@ public class MainActivityViewModel extends ViewModel implements ViewModelInterfa private MutableLiveData> mAlarmHistoryList; private MutableLiveData mStartAlarmRecording; private DeviceRepository mDeviceRepository; + private AlarmRecorder mAlarmRecorder; private static final int RIGHTS_REQUEST_CAMERA = 10; + private static final int REQUEST_PERMISSION = 200; @Override - public void init() { + public void init(SurfaceHolder previewHolder) { WiFiCommunication mWiFiCommunication; if(mDeviceList != null) { return; } + if (mAlarmRecorder == null) { + mAlarmRecorder = AlarmRecorder.getInstance(); + } //todo: check if WiFi instanz can be hold only by the repository mDeviceRepository = DeviceRepository.getInstance(); mWiFiCommunication = WiFiCommunication.getInstance(); mDeviceRepository.setWiFiCommunication(mWiFiCommunication); mWiFiCommunication.setDeviceRepository(mDeviceRepository); - mDeviceRepository.createNewDevice(mDeviceRepository.getSystemTimeStamp(), mDeviceRepository.getLocalDeviceUUID(), false, "No Sensor selected", 0); + //mDeviceRepository.createNewDevice(mDeviceRepository.getSystemTimeStamp(), mDeviceRepository.getLocalDeviceUUID(), false, "No Sensor selected", 0); mDeviceList = mDeviceRepository.getConnectedDeviceList(); mAlarmHistoryList = mDeviceRepository.getAlarmHistoryDeviceList(); mStartAlarmRecording = mDeviceRepository.getStartAlarmRecording(); + setAlarmRecordingPreviewHolder(previewHolder); } public boolean isCameraAccessAllowed(Context context) { @@ -49,6 +58,22 @@ public class MainActivityViewModel extends ViewModel implements ViewModelInterfa ActivityCompat.requestPermissions(activity, new String[]{android.Manifest.permission.CAMERA}, RIGHTS_REQUEST_CAMERA); } + public boolean isAudioRecordingAccessAllowed(Context context) { + return ContextCompat.checkSelfPermission(context, Manifest.permission.RECORD_AUDIO) == PackageManager.PERMISSION_GRANTED; + } + + public void accessRequestAudioRecording(Activity activity) { + ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.RECORD_AUDIO}, REQUEST_PERMISSION); + } + + public boolean isWriteExternalStorageAccessAllowed(Context context) { + return ContextCompat.checkSelfPermission(context, Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED; + } + + public void accessRequestWriteExternalStorage(Activity activity) { + ActivityCompat.requestPermissions(activity, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, REQUEST_PERMISSION); + } + @Override public LiveData> getConnectedDeviceList() { return mDeviceList; @@ -128,4 +153,19 @@ public class MainActivityViewModel extends ViewModel implements ViewModelInterfa public String getSystemTimeStamp() { return null; } + + @Override + public void startAlarmRecording() { + mAlarmRecorder.startRecording(); + } + + @Override + public void stopAlarmRecording(Context context) { + mAlarmRecorder.stopRecording(context); + } + + @Override + public void setAlarmRecordingPreviewHolder(SurfaceHolder previewHolder) { + mAlarmRecorder.setPreviewHolder(previewHolder); + } } diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java index 79d7500..f7f7793 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionAndAccelerometerViewModel.java @@ -16,7 +16,7 @@ import com.example.greenwatch.sensors.CameraSensor; import java.util.List; -public class VideodetectionAndAccelerometerViewModel extends ViewModel implements ViewModelInterface{ +/*public class VideodetectionAndAccelerometerViewModel extends ViewModel implements ViewModelInterface{ private MutableLiveData> mDeviceList; private MutableLiveData mAccelerometerAlarmDetected; private MutableLiveData mVideoAlarmDetected; @@ -193,4 +193,4 @@ public class VideodetectionAndAccelerometerViewModel extends ViewModel implement public String getSystemTimeStamp() { return mDeviceRepository.getSystemTimeStamp(); } -} +}*/ diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionViewModel.java b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionViewModel.java index 1a252c5..d65b1eb 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionViewModel.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/VideodetectionViewModel.java @@ -1,6 +1,7 @@ package com.example.greenwatch.viewmodels; import android.content.Context; +import android.view.SurfaceHolder; import androidx.camera.lifecycle.ProcessCameraProvider; import androidx.lifecycle.LifecycleOwner; @@ -8,6 +9,7 @@ import androidx.lifecycle.LiveData; import androidx.lifecycle.MutableLiveData; import androidx.lifecycle.ViewModel; +import com.example.greenwatch.alarmrecorder.AlarmRecorder; import com.example.greenwatch.models.Device; import com.example.greenwatch.repositories.DeviceRepository; import com.example.greenwatch.sensors.CameraSensor; @@ -21,6 +23,7 @@ public class VideodetectionViewModel extends ViewModel implements ViewModelInter private MutableLiveData> mAlarmHistoryList; private MutableLiveData mStartAlarmRecording; private DeviceRepository mDeviceRepository; + private AlarmRecorder mAlarmRecorder; private CameraSensor mCameraSensor; @@ -29,13 +32,16 @@ public class VideodetectionViewModel extends ViewModel implements ViewModelInter } @Override - public void init() { + public void init(SurfaceHolder previewHolder) { if (mDeviceRepository == null) { mDeviceRepository = DeviceRepository.getInstance(); } if (mCameraSensor == null) { mCameraSensor = CameraSensor.getInstance(); } + if (mAlarmRecorder == null) { + mAlarmRecorder = AlarmRecorder.getInstance(); + } if (mDeviceList == null) { mDeviceList = mDeviceRepository.getConnectedDeviceList(); } @@ -48,6 +54,7 @@ public class VideodetectionViewModel extends ViewModel implements ViewModelInter if (mVideoAlarmDetected == null) { mVideoAlarmDetected = mCameraSensor.getVideoAlarmDetectedValue(); } + setAlarmRecordingPreviewHolder(previewHolder); } public void bindImageAnalysis(ProcessCameraProvider cameraProvider, LifecycleOwner lifecycleOwner, Context context) { @@ -137,4 +144,19 @@ public class VideodetectionViewModel extends ViewModel implements ViewModelInter public String getSystemTimeStamp() { return mDeviceRepository.getSystemTimeStamp(); } + + @Override + public void startAlarmRecording() { + mAlarmRecorder.startRecording(); + } + + @Override + public void stopAlarmRecording(Context context) { + mAlarmRecorder.stopRecording(context); + } + + @Override + public void setAlarmRecordingPreviewHolder(SurfaceHolder previewHolder) { + mAlarmRecorder.setPreviewHolder(previewHolder); + } } diff --git a/app/src/main/java/com/example/greenwatch/viewmodels/ViewModelInterface.java b/app/src/main/java/com/example/greenwatch/viewmodels/ViewModelInterface.java index eb290b4..1a5a79e 100644 --- a/app/src/main/java/com/example/greenwatch/viewmodels/ViewModelInterface.java +++ b/app/src/main/java/com/example/greenwatch/viewmodels/ViewModelInterface.java @@ -1,5 +1,8 @@ package com.example.greenwatch.viewmodels; +import android.content.Context; +import android.view.SurfaceHolder; + import androidx.lifecycle.LiveData; import com.example.greenwatch.models.Device; @@ -7,7 +10,7 @@ import com.example.greenwatch.models.Device; import java.util.List; public interface ViewModelInterface { - void init(); + void init(SurfaceHolder previewHolder); LiveData> getConnectedDeviceList(); LiveData> getAlarmHistoryList(); LiveData getStartAlarmRecording(); @@ -24,4 +27,7 @@ public interface ViewModelInterface { int getSensorMassage(String deviceID); String getLocalDeviceUUID(); String getSystemTimeStamp(); + void startAlarmRecording(); + void stopAlarmRecording(Context context); + void setAlarmRecordingPreviewHolder(SurfaceHolder previewHolder); } diff --git a/app/src/main/res/layout/activity_accelerometer.xml b/app/src/main/res/layout/activity_accelerometer.xml index b90e124..884f8b6 100644 --- a/app/src/main/res/layout/activity_accelerometer.xml +++ b/app/src/main/res/layout/activity_accelerometer.xml @@ -8,6 +8,13 @@ android:padding="10dp" tools:context=".AccelerometerActivity"> + + + @@ -20,9 +20,15 @@ android:id="@+id/deviceListRecyclerView" android:layout_width="match_parent" android:layout_height="match_parent" - android:layout_weight="3" + android:layout_weight="4" tools:listitem="@layout/device_item"> + + + + + +