delete old file
This commit is contained in:
parent
4b2eb8def9
commit
e0b84683d0
|
@ -123,7 +123,6 @@ class MainActivity : AppCompatActivity() {
|
|||
putExtra("useFrontCamera", useFrontCamera)
|
||||
}
|
||||
startForegroundService(serviceIntent)
|
||||
// startService(serviceIntent)
|
||||
}
|
||||
|
||||
private fun stopRecordingService() {
|
||||
|
@ -131,7 +130,6 @@ class MainActivity : AppCompatActivity() {
|
|||
val serviceIntent = Intent(this, RecordingService::class.java).apply {
|
||||
action = RecordingService.ACTION_STOP_RECORDING
|
||||
}
|
||||
stopForeground(STOP_FOREGROUND_DETACH)
|
||||
stopService(serviceIntent)
|
||||
}
|
||||
|
||||
|
|
|
@ -1,236 +0,0 @@
|
|||
package com.urkob.wittrail_android
|
||||
|
||||
import android.app.Notification
|
||||
import android.app.NotificationChannel
|
||||
import android.app.NotificationManager
|
||||
import android.app.PendingIntent
|
||||
import android.app.Service
|
||||
import android.content.Intent
|
||||
import android.media.MediaScannerConnection
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.IBinder
|
||||
import android.provider.MediaStore
|
||||
import android.util.Log
|
||||
import android.widget.Toast
|
||||
import androidx.camera.core.CameraSelector
|
||||
import androidx.camera.core.Preview
|
||||
import androidx.camera.lifecycle.ProcessCameraProvider
|
||||
import androidx.camera.video.MediaStoreOutputOptions
|
||||
import androidx.camera.video.Recorder
|
||||
import androidx.camera.video.Recording
|
||||
import androidx.camera.video.VideoCapture
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.content.ContextCompat
|
||||
import com.google.common.util.concurrent.ListenableFuture
|
||||
import java.io.File
|
||||
import java.text.SimpleDateFormat
|
||||
import java.util.Locale
|
||||
import java.util.concurrent.ExecutorService
|
||||
import java.util.concurrent.Executors
|
||||
|
||||
|
||||
class RecordingServices : Service() {
|
||||
private lateinit var cameraExecutor: ExecutorService
|
||||
private lateinit var cameraProviderFuture: ListenableFuture<ProcessCameraProvider>
|
||||
private var recording: Recording? = null
|
||||
private lateinit var videoCapture: VideoCapture<Recorder>
|
||||
|
||||
private val notificationChannelId = "RECORDING_CHANNEL"
|
||||
private val notificationId = 1
|
||||
private var videoFile: File? = null
|
||||
|
||||
override fun onCreate() {
|
||||
super.onCreate()
|
||||
cameraExecutor = Executors.newSingleThreadExecutor()
|
||||
}
|
||||
|
||||
override fun onBind(intent: Intent): IBinder? {
|
||||
return null
|
||||
}
|
||||
|
||||
private fun bindCamera() {
|
||||
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
|
||||
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||
|
||||
// You need to build the use cases. For example:
|
||||
val previewUseCase = Preview.Builder().build()
|
||||
val videoCaptureUseCase = VideoCapture.withOutput(Recorder.Builder().build())
|
||||
|
||||
try {
|
||||
cameraProvider.unbindAll()
|
||||
cameraProvider.bindToLifecycle(this, cameraSelector, previewUseCase, videoCaptureUseCase)
|
||||
} catch (exc: Exception) {
|
||||
Log.e(TAG, "Use case binding failed", exc)
|
||||
}
|
||||
}
|
||||
|
||||
private fun startRecording() {
|
||||
val mediaStoreOutputOptions = MediaStoreOutputOptions.Builder(contentResolver, MediaStore.Video.Media.EXTERNAL_CONTENT_URI)
|
||||
.build()
|
||||
|
||||
val outputOptions = VideoCapture.OutputFileOptions.Builder(videoFile).build()
|
||||
// Start recording
|
||||
videoCapture.startRecording(outputOptions, cameraExecutor, object : VideoCapture.OnVideoSavedCallback {
|
||||
fun onVideoSaved(outputFileResults: VideoCapture.OutputFileResults) {
|
||||
val savedUri = outputFileResults.savedUri ?: Uri.fromFile(videoFile)
|
||||
Log.d(TAG, "Video File Saved at $savedUri")
|
||||
// Here you can handle the saved video file
|
||||
}
|
||||
|
||||
fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
|
||||
Log.e(TAG, "Video capture error: $message", cause)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
private val captureListener = object : VideoCapture.OnVideoSavedCallback {
|
||||
fun onVideoSaved(file: File) {
|
||||
Log.d(TAG, "Video File: $file")
|
||||
// Here you can handle the saved video file
|
||||
}
|
||||
fun onError(videoCaptureError: Int, message: String, cause: Throwable?) {
|
||||
Log.e(TAG, "Video capture error: $message", cause)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onDestroy() {
|
||||
super.onDestroy()
|
||||
cameraExecutor.shutdown()
|
||||
recording?.stop() // Stop the recording
|
||||
}
|
||||
|
||||
// Helper function to create a file
|
||||
private fun createFile(baseFolder: File, format: String, extension: String) =
|
||||
File(baseFolder, SimpleDateFormat(format, Locale.US)
|
||||
.format(System.currentTimeMillis()) + extension)
|
||||
|
||||
companion object {
|
||||
private const val TAG = "RecordingService"
|
||||
private const val FILENAME = "yyyy-MM-dd-HH-mm-ss-SSS"
|
||||
private const val VIDEO_EXTENSION = ".mp4"
|
||||
private val outputDirectory: File by lazy {
|
||||
getOutputDirectory()
|
||||
}
|
||||
}
|
||||
|
||||
// Method to get the output directory
|
||||
private fun getOutputDirectory(): File {
|
||||
val mediaDir = externalMediaDirs.firstOrNull()?.let {
|
||||
File(it, resources.getString(R.string.app_name)).apply { mkdirs() }
|
||||
}
|
||||
return if (mediaDir != null && mediaDir.exists())
|
||||
mediaDir else filesDir
|
||||
}
|
||||
|
||||
override fun onStartCommand(intent: Intent, flags: Int, startId: Int): Int {
|
||||
createNotificationChannel()
|
||||
startForeground(notificationId, createNotification())
|
||||
|
||||
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
|
||||
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||
|
||||
val previewUseCase = Preview.Builder().build()
|
||||
val videoCaptureUseCase = VideoCapture.withOutput(Recorder.Builder().build())
|
||||
|
||||
try {
|
||||
cameraProvider.unbindAll()
|
||||
cameraProvider.bindToLifecycle(this, cameraSelector, previewUseCase, videoCaptureUseCase)
|
||||
} catch (exc: Exception) {
|
||||
Log.e(TAG, "Use case binding failed", exc)
|
||||
}
|
||||
|
||||
cameraProviderFuture = ProcessCameraProvider.getInstance(this)
|
||||
cameraProviderFuture.addListener(Runnable {
|
||||
val cameraProvider = cameraProviderFuture.get()
|
||||
bindCamera()
|
||||
}, ContextCompat.getMainExecutor(this))
|
||||
|
||||
return START_STICKY
|
||||
}
|
||||
|
||||
private fun startCamera() {
|
||||
val cameraProvider: ProcessCameraProvider = cameraProviderFuture.get()
|
||||
|
||||
val preview = Preview.Builder()
|
||||
.build()
|
||||
.also {
|
||||
it.setSurfaceProvider(viewBinding.viewFinder.surfaceProvider)
|
||||
}
|
||||
|
||||
val cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA
|
||||
|
||||
val videoCapture = VideoCapture.withOutput(Recorder.Builder().build())
|
||||
|
||||
|
||||
try {
|
||||
cameraProvider.unbindAll()
|
||||
cameraProvider.bindToLifecycle(
|
||||
this, cameraSelector, preview)
|
||||
|
||||
cameraProvider.bindToLifecycle(
|
||||
this, cameraSelector, preview, imageCapture, videoCapture)
|
||||
} catch (exc: Exception) {
|
||||
Log.e(TAG, "Use case binding failed", exc)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun stopRecording() {
|
||||
try {
|
||||
Log.d("RecordingService", "Recording stopped. File saved at: ${videoFile?.absolutePath}")
|
||||
// Now scan the file
|
||||
videoFile?.let { file ->
|
||||
Log.d("RecordingService", "Recording stopped. File saved at: ${file.absolutePath}")
|
||||
scanFile(file) // Use 'let' to ensure videoFile is not null when calling scanFile
|
||||
}
|
||||
} catch (e: RuntimeException) {
|
||||
e.printStackTrace()
|
||||
Toast.makeText(this, "Recording stop failed: ${e.message}", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun scanFile(file: File) {
|
||||
MediaScannerConnection.scanFile(
|
||||
this@`RecordingService.txt`,
|
||||
arrayOf(file.absolutePath),
|
||||
null
|
||||
) { path: String?, uri: Uri? ->
|
||||
Log.d("RecordingService", "Scanned $path:")
|
||||
Log.d("RecordingService", "-> Uri = $uri")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private fun createNotification(): Notification {
|
||||
val notificationIntent = Intent(this, MainActivity::class.java)
|
||||
// val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0)
|
||||
|
||||
val pendingIntent = PendingIntent.getActivity(
|
||||
this, 0, notificationIntent,
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) PendingIntent.FLAG_IMMUTABLE else 0
|
||||
)
|
||||
|
||||
return NotificationCompat.Builder(this, notificationChannelId)
|
||||
.setContentTitle("Recording Service")
|
||||
.setContentText("Recording in progress...")
|
||||
.setSmallIcon(android.R.drawable.ic_dialog_info)
|
||||
.setContentIntent(pendingIntent)
|
||||
.build()
|
||||
}
|
||||
|
||||
private fun createNotificationChannel() {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
|
||||
val serviceChannel = NotificationChannel(
|
||||
notificationChannelId,
|
||||
"Foreground Service Channel",
|
||||
NotificationManager.IMPORTANCE_DEFAULT
|
||||
)
|
||||
|
||||
val manager = getSystemService(NotificationManager::class.java)
|
||||
manager.createNotificationChannel(serviceChannel)
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue