diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 5965fad..79fda6e 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -11,7 +11,7 @@
-
+
diff --git a/app/src/main/java/com/bnyro/recorder/canvas_overlay/CanvasOverlay.kt b/app/src/main/java/com/bnyro/recorder/canvas_overlay/CanvasOverlay.kt
index ea49467..7791ed0 100644
--- a/app/src/main/java/com/bnyro/recorder/canvas_overlay/CanvasOverlay.kt
+++ b/app/src/main/java/com/bnyro/recorder/canvas_overlay/CanvasOverlay.kt
@@ -94,7 +94,7 @@ class CanvasOverlay(context: Context) {
y = 0
}
- init {
+ fun show() {
hideCanvas()
try {
if (canvasView.windowToken == null && canvasView.parent == null) {
diff --git a/app/src/main/java/com/bnyro/recorder/services/AudioRecorderTile.kt b/app/src/main/java/com/bnyro/recorder/services/AudioRecorderTile.kt
index 36c3c65..ca0b90f 100644
--- a/app/src/main/java/com/bnyro/recorder/services/AudioRecorderTile.kt
+++ b/app/src/main/java/com/bnyro/recorder/services/AudioRecorderTile.kt
@@ -1,6 +1,8 @@
package com.bnyro.recorder.services
+import android.app.PendingIntent
import android.content.Intent
+import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.os.Build
import android.service.quicksettings.TileService
import androidx.annotation.RequiresApi
@@ -11,12 +13,23 @@ import com.bnyro.recorder.ui.MainActivity
class AudioRecorderTile : TileService() {
override fun onClick() {
super.onClick()
-
val intent = Intent(this, MainActivity::class.java)
.putExtra(MainActivity.EXTRA_ACTION_KEY, RecorderType.AUDIO.name)
.apply {
- flags = Intent.FLAG_ACTIVITY_NEW_TASK
+ flags = FLAG_ACTIVITY_NEW_TASK
}
- startActivityAndCollapse(intent)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ startActivityAndCollapse(
+ PendingIntent.getActivity(
+ this, PENDING_INTENT_REQUEST_CODE, intent, PendingIntent.FLAG_IMMUTABLE
+ )
+ )
+ } else {
+ startActivityAndCollapse(intent)
+ }
+ }
+
+ companion object {
+ const val PENDING_INTENT_REQUEST_CODE = 20
}
}
diff --git a/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderTile.kt b/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderTile.kt
index cfce5e5..bc44759 100644
--- a/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderTile.kt
+++ b/app/src/main/java/com/bnyro/recorder/services/ScreenRecorderTile.kt
@@ -1,5 +1,6 @@
package com.bnyro.recorder.services
+import android.app.PendingIntent
import android.content.Intent
import android.os.Build
import android.service.quicksettings.TileService
@@ -11,12 +12,24 @@ import com.bnyro.recorder.ui.MainActivity
class ScreenRecorderTile : TileService() {
override fun onClick() {
super.onClick()
-
val intent = Intent(this, MainActivity::class.java)
.putExtra(MainActivity.EXTRA_ACTION_KEY, RecorderType.VIDEO.name)
.apply {
flags = Intent.FLAG_ACTIVITY_NEW_TASK
}
- startActivityAndCollapse(intent)
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.UPSIDE_DOWN_CAKE) {
+ startActivityAndCollapse(
+ PendingIntent.getActivity(
+ this, PENDING_INTENT_REQUEST_CODE, intent, PendingIntent.FLAG_IMMUTABLE
+ )
+ )
+ } else {
+ startActivityAndCollapse(intent)
+ }
+ }
+
+ companion object {
+ const val PENDING_INTENT_REQUEST_CODE = 21
}
}
diff --git a/app/src/main/java/com/bnyro/recorder/ui/MainActivity.kt b/app/src/main/java/com/bnyro/recorder/ui/MainActivity.kt
index 736098f..bdbfaa2 100644
--- a/app/src/main/java/com/bnyro/recorder/ui/MainActivity.kt
+++ b/app/src/main/java/com/bnyro/recorder/ui/MainActivity.kt
@@ -1,8 +1,14 @@
package com.bnyro.recorder.ui
+import android.app.Activity
+import android.content.Context
+import android.content.Intent
+import android.media.projection.MediaProjectionManager
import android.os.Bundle
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
+import androidx.activity.result.ActivityResultLauncher
+import androidx.activity.result.contract.ActivityResultContracts
import androidx.activity.viewModels
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.fillMaxSize
@@ -12,21 +18,30 @@ import androidx.compose.ui.Modifier
import androidx.navigation.compose.rememberNavController
import com.bnyro.recorder.enums.RecorderType
import com.bnyro.recorder.enums.ThemeMode
+import com.bnyro.recorder.ui.models.RecorderModel
import com.bnyro.recorder.ui.models.ThemeModel
import com.bnyro.recorder.ui.theme.RecordYouTheme
class MainActivity : ComponentActivity() {
private var initialRecorder = RecorderType.NONE
private var exitAfterRecordingStart = false
+ private lateinit var mProjectionManager: MediaProjectionManager
+ private val recorderModel: RecorderModel by viewModels()
+ private lateinit var launcher: ActivityResultLauncher
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
val themeModel: ThemeModel by viewModels()
+ launcher =
+ registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { result ->
+ if (result.resultCode == Activity.RESULT_OK) {
+ recorderModel.startVideoRecorder(this, result)
+ }
+ }
+ mProjectionManager =
+ getSystemService(Context.MEDIA_PROJECTION_SERVICE) as MediaProjectionManager
- initialRecorder = intent?.getStringExtra(EXTRA_ACTION_KEY)?.let {
- RecorderType.valueOf(it)
- } ?: RecorderType.NONE
- intent?.putExtra(EXTRA_ACTION_KEY, "")
+ processIntent(intent)
setContent {
RecordYouTheme(
@@ -53,9 +68,29 @@ class MainActivity : ComponentActivity() {
}
}
+ override fun onNewIntent(intent: Intent) {
+ processIntent(intent)
+ super.onNewIntent(intent)
+ }
+
+ private fun processIntent(intent: Intent) {
+ val initialRecorderType = intent.getStringExtra(EXTRA_ACTION_KEY)?.let {
+ RecorderType.valueOf(it)
+ } ?: RecorderType.NONE
+ initialRecorder = initialRecorderType
+ if (initialRecorderType == RecorderType.AUDIO) {
+ recorderModel.startAudioRecorder(this)
+ } else if (initialRecorderType == RecorderType.VIDEO) {
+ if (recorderModel.hasScreenRecordingPermissions(this)) {
+ launcher.launch(mProjectionManager.createScreenCaptureIntent())
+ }
+ }
+ intent.removeExtra(EXTRA_ACTION_KEY)
+ }
+
override fun onPause() {
super.onPause()
- if (initialRecorder != RecorderType.NONE) {
+ if (initialRecorder == RecorderType.VIDEO) {
exitAfterRecordingStart = true
initialRecorder = RecorderType.NONE
}
@@ -65,7 +100,7 @@ class MainActivity : ComponentActivity() {
super.onResume()
if (exitAfterRecordingStart) {
exitAfterRecordingStart = false
- finish()
+ moveTaskToBack(true)
}
}
diff --git a/app/src/main/java/com/bnyro/recorder/ui/components/RecorderController.kt b/app/src/main/java/com/bnyro/recorder/ui/components/RecorderController.kt
index 8db9724..f99bdc1 100644
--- a/app/src/main/java/com/bnyro/recorder/ui/components/RecorderController.kt
+++ b/app/src/main/java/com/bnyro/recorder/ui/components/RecorderController.kt
@@ -31,7 +31,6 @@ import androidx.compose.material3.IconButton
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
-import androidx.compose.runtime.LaunchedEffect
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -44,14 +43,12 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bnyro.recorder.R
import com.bnyro.recorder.enums.RecorderState
-import com.bnyro.recorder.enums.RecorderType
import com.bnyro.recorder.ui.common.ClickableIcon
import com.bnyro.recorder.ui.models.RecorderModel
@Composable
fun RecorderController(
- recordScreenMode: Boolean,
- initialRecorder: RecorderType
+ recordScreenMode: Boolean
) {
val recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
val context = LocalContext.current
@@ -71,19 +68,6 @@ fun RecorderController(
mProjectionManager.createScreenCaptureIntent()
)
}
- LaunchedEffect(Unit) {
- when (initialRecorder) {
- RecorderType.AUDIO -> {
- recorderModel.startAudioRecorder(context)
- }
-
- RecorderType.VIDEO -> {
- requestScreenRecording()
- }
-
- RecorderType.NONE -> {}
- }
- }
Column(
modifier = Modifier.wrapContentSize(),
horizontalAlignment = Alignment.CenterHorizontally
diff --git a/app/src/main/java/com/bnyro/recorder/ui/models/RecorderModel.kt b/app/src/main/java/com/bnyro/recorder/ui/models/RecorderModel.kt
index b713b11..23183f8 100644
--- a/app/src/main/java/com/bnyro/recorder/ui/models/RecorderModel.kt
+++ b/app/src/main/java/com/bnyro/recorder/ui/models/RecorderModel.kt
@@ -6,12 +6,10 @@ import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.content.ServiceConnection
-import android.net.Uri
import android.os.Build
import android.os.Handler
import android.os.IBinder
import android.os.Looper
-import android.provider.Settings
import androidx.activity.result.ActivityResult
import androidx.annotation.RequiresApi
import androidx.compose.runtime.getValue
@@ -31,7 +29,6 @@ import com.bnyro.recorder.util.PermissionHelper
import com.bnyro.recorder.util.Preferences
class RecorderModel : ViewModel() {
- private val audioPermission = arrayOf(Manifest.permission.RECORD_AUDIO)
private val supportsOverlay = Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
var recorderState by mutableStateOf(RecorderState.IDLE)
@@ -52,6 +49,7 @@ class RecorderModel : ViewModel() {
recorderState = it
}
(recorderService as? ScreenRecorderService)?.prepare(activityResult!!)
+ if (supportsOverlay) canvasOverlay?.show()
recorderService?.start()
}
@@ -73,7 +71,12 @@ class RecorderModel : ViewModel() {
@SuppressLint("NewApi")
fun startAudioRecorder(context: Context) {
- if (!PermissionHelper.checkPermissions(context, audioPermission)) return
+ val audioPermission = mutableListOf(Manifest.permission.RECORD_AUDIO)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
+ audioPermission.add(Manifest.permission.POST_NOTIFICATIONS)
+ }
+
+ if (!PermissionHelper.checkPermissions(context, audioPermission.toTypedArray())) return
val serviceIntent =
if (Preferences.prefs.getBoolean(Preferences.losslessRecorderKey, false)) {
@@ -152,19 +155,6 @@ class RecorderModel : ViewModel() {
@SuppressLint("NewApi")
fun hasScreenRecordingPermissions(context: Context): Boolean {
- val overlayEnabled = Preferences.prefs.getBoolean(
- Preferences.showOverlayAnnotationToolKey,
- false
- )
- if (supportsOverlay && overlayEnabled && !Settings.canDrawOverlays(context)) {
- val intent = Intent(
- Settings.ACTION_MANAGE_OVERLAY_PERMISSION,
- Uri.parse("package:" + context.packageName)
- )
- context.startActivity(intent)
- return false
- }
-
val requiredPermissions = arrayListOf()
val recordAudio =
diff --git a/app/src/main/java/com/bnyro/recorder/ui/screens/HomeScreen.kt b/app/src/main/java/com/bnyro/recorder/ui/screens/HomeScreen.kt
index 95496ba..742e447 100644
--- a/app/src/main/java/com/bnyro/recorder/ui/screens/HomeScreen.kt
+++ b/app/src/main/java/com/bnyro/recorder/ui/screens/HomeScreen.kt
@@ -43,7 +43,8 @@ fun HomeScreen(
onNavigate: (Destination) -> Unit,
recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
) {
- val pagerState = rememberPagerState { 2 }
+ val pagerState =
+ rememberPagerState(initialPage = if (initialRecorder == RecorderType.VIDEO) 1 else 0) { 2 }
val scope = rememberCoroutineScope()
val view = LocalView.current
Scaffold(modifier = Modifier.fillMaxSize(), topBar = {
@@ -114,7 +115,7 @@ fun HomeScreen(
state = pagerState,
modifier = Modifier.fillMaxSize()
) { index ->
- RecorderView(initialRecorder = initialRecorder, recordScreenMode = (index == 1))
+ RecorderView(recordScreenMode = (index == 1))
}
}
}
diff --git a/app/src/main/java/com/bnyro/recorder/ui/screens/RecorderScreen.kt b/app/src/main/java/com/bnyro/recorder/ui/screens/RecorderScreen.kt
index 64f0aae..8f92ab6 100644
--- a/app/src/main/java/com/bnyro/recorder/ui/screens/RecorderScreen.kt
+++ b/app/src/main/java/com/bnyro/recorder/ui/screens/RecorderScreen.kt
@@ -10,7 +10,6 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalContext
import androidx.lifecycle.viewmodel.compose.viewModel
import com.bnyro.recorder.enums.RecorderState
-import com.bnyro.recorder.enums.RecorderType
import com.bnyro.recorder.ui.common.ResponsiveRecordScreenLayout
import com.bnyro.recorder.ui.components.RecorderController
import com.bnyro.recorder.ui.components.RecorderPreview
@@ -18,7 +17,6 @@ import com.bnyro.recorder.ui.models.RecorderModel
@Composable
fun RecorderView(
- initialRecorder: RecorderType,
recordScreenMode: Boolean
) {
val recorderModel: RecorderModel = viewModel(LocalContext.current as ComponentActivity)
@@ -39,7 +37,7 @@ fun RecorderView(
RecorderPreview(recordScreenMode)
},
PaneTwo = {
- RecorderController(recordScreenMode, initialRecorder)
+ RecorderController(recordScreenMode)
}
)
}