I am building an Android app in Kotlin and I need to perform background recording using the front camera. I have searched online but could not find a solution specific to Kotlin. Can someone please guide me on how to achieve this using Kotlin? Thank you in advance!
Here is my code but for some reason it doesn't work
class MainActivity : AppCompatActivity() {
private lateinit var startButton: Button
private lateinit var stopButton: Button
private val PERMISSION_REQUEST_CODE=1001
private val REQUEST_CAMERA_AND_AUDIO_PERMISSION = 1
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
startButton = findViewById(R.id.start_button)
stopButton = findViewById(R.id.stop_button)
// Request permissions for camera, record audio and write external storage
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.RECORD_AUDIO) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED
&& ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
arrayOf(Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE),
PERMISSION_REQUEST_CODE)
}
startButton.setOnClickListener {
val intent = Intent(this, VideoRecordService::class.java)
startForegroundService(intent)
}
stopButton.setOnClickListener {
val intent = Intent(this, VideoRecordService::class.java)
stopService(intent)
}
}
}
class VideoRecordService : Service() {
private var camera: Camera? = null
private var mediaRecorder: MediaRecorder? = null
private var outputFile: File? = null
private val permissions = arrayOf(
Manifest.permission.CAMERA,
Manifest.permission.RECORD_AUDIO,
Manifest.permission.WRITE_EXTERNAL_STORAGE
)
override fun onBind(intent: Intent): IBinder? {
return null
}
override fun onStartCommand(intent: Intent?, flags: Int, startId: Int): Int {
startForeground(1, createNotification())
startRecording()
return START_STICKY
}
private fun createNotification(): Notification {
val channelId = "VideoRecorder"
val channelName = "Video Recorder"
val importance = NotificationManager.IMPORTANCE_LOW
val notificationChannel = NotificationChannel(channelId, channelName, importance)
val notificationManager = getSystemService(NotificationManager::class.java)
notificationManager?.createNotificationChannel(notificationChannel)
val notificationIntent = Intent(this, MainActivity::class.java)
val pendingIntent = PendingIntent.getActivity(this, 0, notificationIntent, 0)
return NotificationCompat.Builder(this, channelId)
.setContentTitle("Recording video")
.setContentText("Touch to open app")
.setSmallIcon(R.drawable.ic_launcher_background)
.setContentIntent(pendingIntent)
.build()
}
private fun startRecording() {
camera = Camera.open(Camera.CameraInfo.CAMERA_FACING_FRONT)
outputFile = getOutputFile()
if (!outputFile!!.exists())
{
Log.e("VideoRecordService", "Output file does not exist")
return
}
mediaRecorder = MediaRecorder().apply {
setCamera(camera)
setAudioSource(MediaRecorder.AudioSource.DEFAULT)
setVideoSource(MediaRecorder.VideoSource.DEFAULT)
setOutputFormat(MediaRecorder.OutputFormat.DEFAULT)
setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT)
setVideoEncoder(MediaRecorder.VideoEncoder.DEFAULT)
setOutputFile(outputFile?.path)
setPreviewDisplay(null)
try {
prepare()
start()
} catch (e: IOException) {
e.printStackTrace()
}
}
}
private fun getOutputFile(): File? {
val dir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_MOVIES)
Log.d("VideoRecordService", "Movies directory: $dir")
if (!dir.exists()) {
val created = dir.mkdirs()
Log.d("VideoRecordService", "Movies directory created: $created")
}
val videoFile = "video_${System.currentTimeMillis()}.mp4"
val outputFile = File(dir, videoFile)
Log.d("VideoRecordService", "Output file: $outputFile")
return outputFile
}
private fun stopRecording() {
if (mediaRecorder == null) return
try {
mediaRecorder?.stop()
mediaRecorder?.reset()
} catch (e: IllegalStateException) {
e.printStackTrace()
}
mediaRecorder?.release()
camera?.lock()
saveVideoToGallery()
Toast.makeText(this, "Video saved to gallery", Toast.LENGTH_SHORT).show()
}
private fun saveVideoToGallery() {
if (outputFile == null) return
val values = ContentValues().apply {
put(MediaStore.Video.Media.DISPLAY_NAME, outputFile?.name)
put(MediaStore.Video.Media.MIME_TYPE, "video/mp4")
put(MediaStore.Video.Media.DATE_TAKEN, System.currentTimeMillis())
put(MediaStore.Video.Media.DATA, outputFile?.path)
}
val contentResolver = applicationContext.contentResolver
contentResolver.insert(MediaStore.Video.Media.EXTERNAL_CONTENT_URI, values)
}
override fun onDestroy() {
super.onDestroy()
if (mediaRecorder != null) {
stopRecording()
}
camera?.release()
camera = null
}
}