diff --git a/.idea/deploymentTargetDropDown.xml b/.idea/deploymentTargetDropDown.xml index 3e360fbf2c8193221ac3e01daea590c08591f873..61990b2903a825467b5c97bb12986b794bad14c8 100644 --- a/.idea/deploymentTargetDropDown.xml +++ b/.idea/deploymentTargetDropDown.xml @@ -3,25 +3,9 @@ <component name="deploymentTargetDropDown"> <value> <entry key="MainActivity"> - <State> - <targetSelectedWithDropDown> - <Target> - <type value="QUICK_BOOT_TARGET" /> - <deviceKey> - <Key> - <type value="VIRTUAL_DEVICE_PATH" /> - <value value="C:\Users\Khaleeq\.android\avd\Copy_of_Pixel_8_API_32.avd" /> - </Key> - </deviceKey> - </Target> - </targetSelectedWithDropDown> - <timeTargetWasSelectedWithDropDown value="2024-09-03T12:10:14.750266800Z" /> - </State> - </entry> - <entry key="PermissionRequestScreen"> <State /> </entry> - <entry key="TimerScreenPreview"> + <entry key="PermissionRequestScreen"> <State /> </entry> <entry key="app"> diff --git a/.idea/misc.xml b/.idea/misc.xml index f697d5ea267156235ec1fd2a91916875c8fe2930..468a0b2018a36cf69f4928c41f2a68e74e480e99 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -1,4 +1,3 @@ -<?xml version="1.0" encoding="UTF-8"?> <project version="4"> <component name="EntryPointsManager"> <list size="1"> diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 2917e9f4d08050047ab1c18c91d16518b25a6e34..d4dee63a58eef56cf5b2e0707621b156419ccc58 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -3,11 +3,10 @@ <!-- Permissions --> <uses-permission android:name="android.permission.VIBRATE" android:required="false"/> - <uses-permission android:name="android.permission.WAKE_LOCK" android:required="false"/> + <uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.FOREGROUND_SERVICE" android:required="false"/> <uses-permission android:name="android.permission.POST_NOTIFICATIONS" android:required="false"/> <uses-permission android:name="android.permission.ACCESS_NOTIFICATION_POLICY" android:required="false"/> - <uses-permission android:name="android.permission.USE_FULL_SCREEN_INTENT" android:required="false"/> <uses-permission android:name="android.permission.USE_EXACT_ALARM" android:required="false"/> <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" android:required="false"/> <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" android:required="false"/> @@ -21,8 +20,7 @@ android:label="@string/app_name" android:roundIcon="@drawable/ic_launcher_foreground" android:supportsRtl="true" - android:theme="@style/Theme.MyApplication" - > + android:theme="@style/Theme.MyApplication"> <!-- Main Activity --> <activity @@ -35,11 +33,6 @@ </intent-filter> </activity> - - - - - </application> -</manifest> +</manifest> \ No newline at end of file diff --git a/app/src/main/java/com/pomo/myapplication/MainActivity.kt b/app/src/main/java/com/pomo/myapplication/MainActivity.kt index 94a993b425fa0efe92b4ff6104c29ad02a5c0dfa..b5e98968b52ae551552980de9687d6aac21bff87 100644 --- a/app/src/main/java/com/pomo/myapplication/MainActivity.kt +++ b/app/src/main/java/com/pomo/myapplication/MainActivity.kt @@ -1,19 +1,14 @@ package com.pomo.myapplication -import android.Manifest -import android.content.pm.PackageManager import android.os.Bundle -import android.widget.Toast import androidx.activity.ComponentActivity import androidx.activity.compose.setContent -import androidx.activity.result.ActivityResultLauncher import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Surface import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier -import androidx.core.content.ContextCompat import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -22,29 +17,22 @@ import com.pomo.myapplication.ui.theme.MyApplicationTheme class MainActivity : ComponentActivity() { - private lateinit var notificationHelper: NotificationHelper - private lateinit var permissionLaunchers: Map<String, ActivityResultLauncher<String>> - private lateinit var pendingPermissions: MutableList<String> - var timeLeftForNotification: String = "" + lateinit var notificationHelper: NotificationHelper + lateinit var permissionsHelper: PermissionsHelper override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) notificationHelper = NotificationHelper(this) + permissionsHelper = PermissionsHelper(this) - pendingPermissions = mutableListOf() - - permissionLaunchers = mapOf( - Manifest.permission.POST_NOTIFICATIONS to createPermissionLauncher(Manifest.permission.POST_NOTIFICATIONS), - Manifest.permission.VIBRATE to createPermissionLauncher(Manifest.permission.VIBRATE), - Manifest.permission.WAKE_LOCK to createPermissionLauncher(Manifest.permission.WAKE_LOCK), - Manifest.permission.FOREGROUND_SERVICE to createPermissionLauncher(Manifest.permission.FOREGROUND_SERVICE), - Manifest.permission.ACCESS_NOTIFICATION_POLICY to createPermissionLauncher(Manifest.permission.ACCESS_NOTIFICATION_POLICY), - Manifest.permission.USE_FULL_SCREEN_INTENT to createPermissionLauncher(Manifest.permission.USE_FULL_SCREEN_INTENT), - Manifest.permission.USE_EXACT_ALARM to createPermissionLauncher(Manifest.permission.USE_EXACT_ALARM) - ) + permissionsHelper.initializePermissionLaunchers { permission -> + registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> + permissionsHelper.handlePermissionResult(permission, isGranted) + } + } - checkAndRequestPermissions() + permissionsHelper.checkAndRequestPermissions() setContent { MyApplicationTheme { @@ -59,43 +47,6 @@ class MainActivity : ComponentActivity() { } } - private fun createPermissionLauncher(permission: String): ActivityResultLauncher<String> { - return registerForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> - if (isGranted) { - Toast.makeText(this, "$permission Permission Granted", Toast.LENGTH_SHORT).show() - pendingPermissions.remove(permission) // Remove the granted permission from pending list - } else { - Toast.makeText(this, "$permission Permission Denied", Toast.LENGTH_SHORT).show() - pendingPermissions.add(permission) // Add the denied permission back to pending list - } - } - } - - private fun checkAndRequestPermissions() { - val permissionsToRequest = listOf( - Manifest.permission.POST_NOTIFICATIONS, - Manifest.permission.VIBRATE, - Manifest.permission.WAKE_LOCK, - Manifest.permission.FOREGROUND_SERVICE, - Manifest.permission.ACCESS_NOTIFICATION_POLICY, - Manifest.permission.USE_FULL_SCREEN_INTENT, - Manifest.permission.USE_EXACT_ALARM - ) - - permissionsToRequest.forEach { permission -> - if (ContextCompat.checkSelfPermission(this, permission) != PackageManager.PERMISSION_GRANTED) { - pendingPermissions.add(permission) // Add to pending list if not granted - permissionLaunchers[permission]?.launch(permission) - } - } - } - - private fun requestPendingPermissions() { - pendingPermissions.forEach { permission -> - permissionLaunchers[permission]?.launch(permission) - } - } - @Composable private fun SetupNavGraph(navController: NavHostController) { NavHost( @@ -106,7 +57,7 @@ class MainActivity : ComponentActivity() { TimerScreen( onToDoListClick = { navController.navigate("todo_screen") - requestPendingPermissions() // Request pending permissions on start button press + permissionsHelper.requestPendingPermissions() }, notificationHelper = notificationHelper, activity = this@MainActivity @@ -121,5 +72,4 @@ class MainActivity : ComponentActivity() { companion object { const val PERMISSION_REQUEST_CODE = 1001 } - -} +} \ No newline at end of file diff --git a/app/src/main/java/com/pomo/myapplication/NotificationUtils.kt b/app/src/main/java/com/pomo/myapplication/NotificationUtils.kt index 68f2c525822b68ac52029674552d833921903a9c..432469715e019c7656d10741e2621dd4175f2846 100644 --- a/app/src/main/java/com/pomo/myapplication/NotificationUtils.kt +++ b/app/src/main/java/com/pomo/myapplication/NotificationUtils.kt @@ -20,10 +20,10 @@ import androidx.core.app.NotificationManagerCompat class NotificationHelper(private val context: Context) { companion object { - private const val PERMISSION_REQUEST_CODE = 1001 - private const val CHANNEL_ID = "timer_channel" - private const val NOTIFICATION_ID = 1 - private const val ACTION_STOP_TIMER = "com.pomo.myapplication.ACTION_STOP_TIMER" + const val PERMISSION_REQUEST_CODE = 1001 + const val CHANNEL_ID = "timer_channel" + const val NOTIFICATION_ID = 1 + const val ACTION_STOP_TIMER = "com.pomo.myapplication.ACTION_STOP_TIMER" } val handler = Handler(Looper.getMainLooper()) @@ -131,7 +131,7 @@ class NotificationHelper(private val context: Context) { } } - private fun buildNotification(title: String, contentText: String, priority: Int, playSound: Boolean): Notification { + fun buildNotification(title: String, contentText: String, priority: Int, playSound: Boolean): Notification { val intent = Intent(context, MainActivity::class.java).apply { flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK } @@ -161,7 +161,7 @@ class NotificationHelper(private val context: Context) { .build() } - private fun showNotification(notification: Notification) { + fun showNotification(notification: Notification) { try { with(NotificationManagerCompat.from(context)) { notify(NOTIFICATION_ID, notification) @@ -171,9 +171,9 @@ class NotificationHelper(private val context: Context) { } } - private fun registerStopReceiver() { + fun registerStopReceiver() { val filter = IntentFilter(ACTION_STOP_TIMER) - context.registerReceiver(TimerStopReceiver(), filter) + context.registerReceiver(TimerStopReceiver(), filter, Context.RECEIVER_EXPORTED) } class TimerStopReceiver : BroadcastReceiver() { diff --git a/app/src/main/java/com/pomo/myapplication/Permissions.kt b/app/src/main/java/com/pomo/myapplication/Permissions.kt index 7925f8258ed2d9c25981760f04f3e8c0d5fe23db..475030d24197581195c5e24607d0045da15aed0e 100644 --- a/app/src/main/java/com/pomo/myapplication/Permissions.kt +++ b/app/src/main/java/com/pomo/myapplication/Permissions.kt @@ -1,92 +1,55 @@ package com.pomo.myapplication import android.Manifest +import android.content.Context import android.content.pm.PackageManager -import android.os.Bundle import android.widget.Toast -import androidx.activity.ComponentActivity -import androidx.activity.compose.rememberLauncherForActivityResult -import androidx.activity.compose.setContent -import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.layout.Column -import androidx.compose.material3.Button -import androidx.compose.material3.Text -import androidx.compose.runtime.Composable -import androidx.compose.ui.platform.LocalContext -import androidx.core.app.ActivityCompat - -class PermissionRequestScreen : ComponentActivity() { +import androidx.activity.result.ActivityResultLauncher +import androidx.core.content.ContextCompat + +class PermissionsHelper(private val context: Context) { + + lateinit var permissionLaunchers: Map<String, ActivityResultLauncher<String>> + var pendingPermissions: MutableList<String> = mutableListOf() + + fun initializePermissionLaunchers( + launcherFactory: (String) -> ActivityResultLauncher<String> + ) { + permissionLaunchers = mapOf( + Manifest.permission.POST_NOTIFICATIONS to launcherFactory(Manifest.permission.POST_NOTIFICATIONS), + Manifest.permission.ACCESS_NOTIFICATION_POLICY to launcherFactory(Manifest.permission.ACCESS_NOTIFICATION_POLICY), + Manifest.permission.USE_EXACT_ALARM to launcherFactory(Manifest.permission.USE_EXACT_ALARM) + ) + } - override fun onCreate(savedInstanceState: Bundle?) { - super.onCreate(savedInstanceState) - setContent { - PermissionScreen() + fun checkAndRequestPermissions() { + val permissionsToRequest = listOf( + Manifest.permission.POST_NOTIFICATIONS, + Manifest.permission.ACCESS_NOTIFICATION_POLICY, + Manifest.permission.USE_EXACT_ALARM + ) + + permissionsToRequest.forEach { permission -> + if (ContextCompat.checkSelfPermission(context, permission) != PackageManager.PERMISSION_GRANTED) { + pendingPermissions.add(permission) + permissionLaunchers[permission]?.launch(permission) + } } } - @Composable - fun PermissionScreen() { - Column { - PermissionButton( - permission = Manifest.permission.VIBRATE, - text = "Request VIBRATE Permission" - ) - PermissionButton( - permission = Manifest.permission.WAKE_LOCK, - text = "Request WAKE_LOCK Permission" - ) - PermissionButton( - permission = Manifest.permission.FOREGROUND_SERVICE, - text = "Request FOREGROUND_SERVICE Permission" - ) - PermissionButton( - permission = Manifest.permission.POST_NOTIFICATIONS, - text = "Request POST_NOTIFICATIONS Permission" - ) - PermissionButton( - permission = Manifest.permission.ACCESS_NOTIFICATION_POLICY, - text = "Request ACCESS_NOTIFICATION_POLICY Permission" - ) - PermissionButton( - permission = Manifest.permission.USE_FULL_SCREEN_INTENT, - text = "Request USE_FULLSCREEN_INTENT Permission" - ) - PermissionButton( - permission = Manifest.permission.USE_EXACT_ALARM, - text = "Request USE_EXACT_ALARM Permission" - ) + fun requestPendingPermissions() { + pendingPermissions.forEach { permission -> + permissionLaunchers[permission]?.launch(permission) } } - - @Composable - fun PermissionButton(permission: String, text: String) { - val context = LocalContext.current - val permissionLauncher = - rememberLauncherForActivityResult(ActivityResultContracts.RequestPermission()) { isGranted -> - if (isGranted) { - // Berechtigung gewährt - Toast.makeText(context, "$text: Permission Granted", Toast.LENGTH_SHORT).show() - } else { - // Berechtigung verweigert - Toast.makeText(context, "$text: Permission Denied", Toast.LENGTH_SHORT).show() - } - } - - Button(onClick = { - if (ActivityCompat.checkSelfPermission( - context, - permission - ) == PackageManager.PERMISSION_GRANTED - ) { - Toast.makeText(context, "$text: Permission already granted", Toast.LENGTH_SHORT) - .show() - } else { - permissionLauncher.launch(permission) - } - }) { - Text(text) + fun handlePermissionResult(permission: String, isGranted: Boolean) { + if (isGranted) { + Toast.makeText(context, "$permission Permission Granted", Toast.LENGTH_SHORT).show() + pendingPermissions.remove(permission) + } else { + Toast.makeText(context, "$permission Permission Denied", Toast.LENGTH_SHORT).show() + pendingPermissions.add(permission) } } - -} \ No newline at end of file +}