mirror of
https://github.com/Myzel394/Alibi.git
synced 2025-06-19 07:15:25 +02:00
feat: Add poc
This commit is contained in:
parent
82116bc089
commit
63198c316e
@ -79,6 +79,7 @@ android {
|
|||||||
buildFeatures {
|
buildFeatures {
|
||||||
compose true
|
compose true
|
||||||
buildConfig = true
|
buildConfig = true
|
||||||
|
viewBinding = true
|
||||||
}
|
}
|
||||||
composeOptions {
|
composeOptions {
|
||||||
kotlinCompilerExtensionVersion '1.5.1'
|
kotlinCompilerExtensionVersion '1.5.1'
|
||||||
@ -103,6 +104,7 @@ dependencies {
|
|||||||
implementation "androidx.compose.material:material-icons-extended:1.5.4"
|
implementation "androidx.compose.material:material-icons-extended:1.5.4"
|
||||||
implementation 'androidx.appcompat:appcompat:1.6.1'
|
implementation 'androidx.appcompat:appcompat:1.6.1'
|
||||||
implementation 'androidx.documentfile:documentfile:1.0.1'
|
implementation 'androidx.documentfile:documentfile:1.0.1'
|
||||||
|
implementation 'androidx.lifecycle:lifecycle-service:2.6.2'
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
|
||||||
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
|
||||||
@ -131,4 +133,13 @@ dependencies {
|
|||||||
implementation 'com.maxkeppeler.sheets-compose-dialogs:input:1.2.0'
|
implementation 'com.maxkeppeler.sheets-compose-dialogs:input:1.2.0'
|
||||||
|
|
||||||
implementation 'androidx.activity:activity-ktx:1.8.1'
|
implementation 'androidx.activity:activity-ktx:1.8.1'
|
||||||
|
|
||||||
|
def camerax_version = "1.3.0"
|
||||||
|
implementation "androidx.camera:camera-core:${camerax_version}"
|
||||||
|
implementation "androidx.camera:camera-camera2:${camerax_version}"
|
||||||
|
implementation "androidx.camera:camera-lifecycle:${camerax_version}"
|
||||||
|
implementation "androidx.camera:camera-video:${camerax_version}"
|
||||||
|
|
||||||
|
implementation "androidx.camera:camera-view:${camerax_version}"
|
||||||
|
implementation "androidx.camera:camera-extensions:${camerax_version}"
|
||||||
}
|
}
|
@ -13,6 +13,9 @@
|
|||||||
|
|
||||||
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_MICROPHONE" />
|
||||||
|
|
||||||
|
<uses-permission android:name="android.permission.CAMERA" />
|
||||||
|
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_CAMERA" />
|
||||||
|
|
||||||
<application
|
<application
|
||||||
android:name=".UpdateSettingsApp"
|
android:name=".UpdateSettingsApp"
|
||||||
android:allowBackup="true"
|
android:allowBackup="true"
|
||||||
@ -23,6 +26,7 @@
|
|||||||
android:roundIcon="@mipmap/ic_launcher_round"
|
android:roundIcon="@mipmap/ic_launcher_round"
|
||||||
android:supportsRtl="true"
|
android:supportsRtl="true"
|
||||||
android:theme="@style/Theme.Alibi"
|
android:theme="@style/Theme.Alibi"
|
||||||
|
android:hardwareAccelerated="true"
|
||||||
tools:targetApi="31">
|
tools:targetApi="31">
|
||||||
<activity
|
<activity
|
||||||
android:name=".MainActivity"
|
android:name=".MainActivity"
|
||||||
@ -43,9 +47,13 @@
|
|||||||
<category android:name="android.intent.category.DEFAULT" />
|
<category android:name="android.intent.category.DEFAULT" />
|
||||||
</intent-filter>
|
</intent-filter>
|
||||||
</receiver>
|
</receiver>
|
||||||
|
|
||||||
<service
|
<service
|
||||||
android:name=".services.AudioRecorderService"
|
android:name=".services.AudioRecorderService"
|
||||||
android:foregroundServiceType="microphone" />
|
android:foregroundServiceType="microphone" />
|
||||||
|
<service
|
||||||
|
android:name=".services.VideoService"
|
||||||
|
android:foregroundServiceType="camera" />
|
||||||
|
|
||||||
<!-- Change locale for Android <= 12 -->
|
<!-- Change locale for Android <= 12 -->
|
||||||
<service
|
<service
|
||||||
|
111
app/src/main/java/app/myzel394/alibi/services/VideoService.kt
Normal file
111
app/src/main/java/app/myzel394/alibi/services/VideoService.kt
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
package app.myzel394.alibi.services
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint
|
||||||
|
import android.content.ContentValues
|
||||||
|
import android.content.pm.ServiceInfo
|
||||||
|
import android.graphics.SurfaceTexture
|
||||||
|
import android.hardware.Camera
|
||||||
|
import android.os.Build
|
||||||
|
import android.provider.MediaStore
|
||||||
|
import android.view.Surface
|
||||||
|
import android.view.TextureView
|
||||||
|
import android.view.ViewGroup
|
||||||
|
import androidx.camera.core.CameraProvider
|
||||||
|
import androidx.camera.core.CameraSelector
|
||||||
|
import androidx.camera.core.Preview
|
||||||
|
import androidx.camera.core.Preview.SurfaceProvider
|
||||||
|
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||||
|
import androidx.camera.video.MediaStoreOutputOptions
|
||||||
|
import androidx.camera.video.Quality
|
||||||
|
import androidx.camera.video.QualitySelector
|
||||||
|
import androidx.camera.video.Recorder
|
||||||
|
import androidx.camera.video.VideoCapture.withOutput
|
||||||
|
import androidx.camera.video.VideoRecordEvent
|
||||||
|
import androidx.core.app.NotificationCompat
|
||||||
|
import androidx.core.app.ServiceCompat
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import androidx.lifecycle.LifecycleService
|
||||||
|
import app.myzel394.alibi.NotificationHelper
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.SupervisorJob
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
|
class VideoService : LifecycleService() {
|
||||||
|
private var job = SupervisorJob()
|
||||||
|
private var scope = CoroutineScope(Dispatchers.IO + job)
|
||||||
|
|
||||||
|
private fun createMediaStoreOutputOptions(): MediaStoreOutputOptions {
|
||||||
|
val name = "CameraX-recording.mp4"
|
||||||
|
val contentValues = ContentValues().apply {
|
||||||
|
put(MediaStore.Video.Media.DISPLAY_NAME, name)
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
|
||||||
|
put(MediaStore.MediaColumns.RELATIVE_PATH, "DCIM/Recorded Videos")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return MediaStoreOutputOptions.Builder(
|
||||||
|
contentResolver,
|
||||||
|
MediaStore.Video.Media.EXTERNAL_CONTENT_URI
|
||||||
|
)
|
||||||
|
.setContentValues(contentValues)
|
||||||
|
.build()
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressLint("MissingPermission")
|
||||||
|
override fun onCreate() {
|
||||||
|
super.onCreate()
|
||||||
|
|
||||||
|
val notification = NotificationCompat.Builder(
|
||||||
|
this,
|
||||||
|
NotificationHelper.RECORDER_CHANNEL_ID
|
||||||
|
).setContentTitle("Video Recorder")
|
||||||
|
.setContentText("Recording video")
|
||||||
|
.setSmallIcon(android.R.drawable.ic_media_play)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
ServiceCompat.startForeground(
|
||||||
|
this,
|
||||||
|
NotificationHelper.RECORDER_CHANNEL_NOTIFICATION_ID,
|
||||||
|
notification,
|
||||||
|
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
|
||||||
|
ServiceInfo.FOREGROUND_SERVICE_TYPE_CAMERA
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
val cameraProviderFuture = ProcessCameraProvider.getInstance(this)
|
||||||
|
cameraProviderFuture.addListener({
|
||||||
|
// Used to bind the lifecycle of cameras to the lifecycle owner
|
||||||
|
val cameraProvider = cameraProviderFuture.get()
|
||||||
|
val recorder = Recorder.Builder()
|
||||||
|
.setQualitySelector(QualitySelector.from(Quality.HIGHEST))
|
||||||
|
.build()
|
||||||
|
val videoCapture = withOutput(recorder)
|
||||||
|
// Select back camera as a default
|
||||||
|
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||||
|
|
||||||
|
// Unbind use cases before rebinding
|
||||||
|
cameraProvider?.unbindAll()
|
||||||
|
// Bind use cases to camera
|
||||||
|
cameraProvider?.bindToLifecycle(this@VideoService, cameraSelector, videoCapture)
|
||||||
|
|
||||||
|
val options = createMediaStoreOutputOptions()
|
||||||
|
|
||||||
|
val recording = videoCapture.output.prepareRecording(this@VideoService, options)
|
||||||
|
.withAudioEnabled()
|
||||||
|
|
||||||
|
val result = recording.start(ContextCompat.getMainExecutor(this@VideoService), {})
|
||||||
|
|
||||||
|
scope.launch {
|
||||||
|
delay(15000)
|
||||||
|
|
||||||
|
result.stop()
|
||||||
|
|
||||||
|
cameraProvider.unbindAll()
|
||||||
|
stopSelf()
|
||||||
|
}
|
||||||
|
}, ContextCompat.getMainExecutor(this))
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@ import app.myzel394.alibi.ui.models.AudioRecorderModel
|
|||||||
import app.myzel394.alibi.ui.screens.AboutScreen
|
import app.myzel394.alibi.ui.screens.AboutScreen
|
||||||
import app.myzel394.alibi.ui.screens.AudioRecorderScreen
|
import app.myzel394.alibi.ui.screens.AudioRecorderScreen
|
||||||
import app.myzel394.alibi.ui.screens.CustomRecordingNotificationsScreen
|
import app.myzel394.alibi.ui.screens.CustomRecordingNotificationsScreen
|
||||||
|
import app.myzel394.alibi.ui.screens.POCVideo
|
||||||
import app.myzel394.alibi.ui.screens.SettingsScreen
|
import app.myzel394.alibi.ui.screens.SettingsScreen
|
||||||
import app.myzel394.alibi.ui.screens.WelcomeScreen
|
import app.myzel394.alibi.ui.screens.WelcomeScreen
|
||||||
|
|
||||||
@ -70,10 +71,7 @@ fun Navigation(
|
|||||||
scaleOut(targetScale = SCALE_IN) + fadeOut(tween(durationMillis = 150))
|
scaleOut(targetScale = SCALE_IN) + fadeOut(tween(durationMillis = 150))
|
||||||
}
|
}
|
||||||
) {
|
) {
|
||||||
AudioRecorderScreen(
|
POCVideo()
|
||||||
navController = navController,
|
|
||||||
audioRecorder = audioRecorder,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
composable(
|
composable(
|
||||||
Screen.Settings.route,
|
Screen.Settings.route,
|
||||||
|
21
app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt
Normal file
21
app/src/main/java/app/myzel394/alibi/ui/screens/POCVideo.kt
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package app.myzel394.alibi.ui.screens
|
||||||
|
|
||||||
|
import android.content.Intent
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.LaunchedEffect
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import app.myzel394.alibi.services.VideoService
|
||||||
|
|
||||||
|
@Composable
|
||||||
|
fun POCVideo() {
|
||||||
|
val context = LocalContext.current
|
||||||
|
|
||||||
|
LaunchedEffect(Unit) {
|
||||||
|
val intent = Intent(context, VideoService::class.java)
|
||||||
|
ContextCompat.startForegroundService(context, intent)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text(text = "POCVideo")
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user