diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 93b4c89..479ce08 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -1,6 +1,7 @@ + @@ -86,9 +87,13 @@ + android:name=".PackageInstallerReceiver" + android:description="@string/app_name" + android:permission="android.permission.BIND_DEVICE_ADMIN"> + + fun registerActivityResult(context: ComponentActivity){ getFile = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { activityResult -> @@ -87,4 +91,20 @@ fun registerActivityResult(context: ComponentActivity){ backToHomeStateFlow.value = true } } + requestPermission = context.registerForActivityResult(ActivityResultContracts.RequestPermission()) { permissionGranted.value = it } +} + +val permissionGranted = MutableStateFlow(null) + +suspend fun prepareForNotification(context: Context, action: ()->Unit) { + if(VERSION.SDK_INT >= 33) { + if(context.checkSelfPermission(Manifest.permission.POST_NOTIFICATIONS) == PackageManager.PERMISSION_GRANTED) { + action() + } else { + requestPermission.launch(Manifest.permission.POST_NOTIFICATIONS) + permissionGranted.collect { if(it == true) action() } + } + } else { + action() + } } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt index 730ea96..d22562d 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/SystemManager.kt @@ -3,6 +3,9 @@ package com.bintianqi.owndroid.dpm import android.annotation.SuppressLint import android.app.ActivityOptions import android.app.AlertDialog +import android.app.NotificationChannel +import android.app.NotificationManager +import android.app.PendingIntent import android.app.admin.DevicePolicyManager import android.app.admin.DevicePolicyManager.FLAG_EVICT_CREDENTIAL_ENCRYPTION_KEY import android.app.admin.DevicePolicyManager.InstallSystemUpdateCallback @@ -78,6 +81,7 @@ import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateListOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -88,6 +92,7 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp +import androidx.core.app.NotificationCompat import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -95,8 +100,10 @@ import androidx.navigation.compose.currentBackStackEntryAsState import androidx.navigation.compose.rememberNavController import com.bintianqi.owndroid.R import com.bintianqi.owndroid.Receiver +import com.bintianqi.owndroid.StopLockTaskModeReceiver import com.bintianqi.owndroid.fileUriFlow import com.bintianqi.owndroid.getFile +import com.bintianqi.owndroid.prepareForNotification import com.bintianqi.owndroid.toText import com.bintianqi.owndroid.toggle import com.bintianqi.owndroid.ui.Animations @@ -107,6 +114,7 @@ import com.bintianqi.owndroid.ui.SubPageItem import com.bintianqi.owndroid.ui.SwitchItem import com.bintianqi.owndroid.ui.TopBar import com.bintianqi.owndroid.uriToStream +import kotlinx.coroutines.launch import java.util.Date import java.util.TimeZone import java.util.concurrent.Executors @@ -650,6 +658,7 @@ private fun LockTaskMode() { val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val receiver = ComponentName(context,Receiver::class.java) val focusMgr = LocalFocusManager.current + val coroutine = rememberCoroutineScope() Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) { val lockTaskFeatures = remember { mutableStateListOf() } var custom by remember { mutableStateOf(false) } @@ -763,18 +772,13 @@ private fun LockTaskMode() { ) Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween) { Button( - onClick = { - lockTaskPackages.add(inputLockTaskPkg) - Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() - }, + onClick = { lockTaskPackages.add(inputLockTaskPkg) }, modifier = Modifier.fillMaxWidth(0.49F) ) { Text(stringResource(R.string.add)) } Button( - onClick = { - Toast.makeText(context, if(lockTaskPackages.remove(inputLockTaskPkg)) R.string.success else R.string.not_exist, Toast.LENGTH_SHORT).show() - }, + onClick = { lockTaskPackages.remove(inputLockTaskPkg) }, modifier = Modifier.fillMaxWidth(0.96F) ) { Text(stringResource(R.string.remove)) @@ -812,8 +816,13 @@ private fun LockTaskMode() { val packageManager = context.packageManager val launchIntent = packageManager.getLaunchIntentForPackage(startLockTaskApp) if (launchIntent != null) { - context.startActivity(launchIntent, options.toBundle()) - Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() + coroutine.launch { + prepareForNotification(context) { + sendStopLockTaskNotification(context) + context.startActivity(launchIntent, options.toBundle()) + Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show() + } + } } else { Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show() } @@ -1303,3 +1312,23 @@ fun InstallSystemUpdate() { Spacer(Modifier.padding(vertical = 30.dp)) } } + +@SuppressLint("NewApi") +private fun sendStopLockTaskNotification(context: Context) { + val nm = context.getSystemService(ComponentActivity.NOTIFICATION_SERVICE) as NotificationManager + if (VERSION.SDK_INT >= 26) { + val channel = NotificationChannel("LockTaskMode", context.getString(R.string.lock_task_mode), NotificationManager.IMPORTANCE_HIGH).apply { + description = "Notification channel for stop lock task mode" + setShowBadge(false) + } + nm.createNotificationChannel(channel) + } + val intent = Intent(context, StopLockTaskModeReceiver::class.java) + val pendingIntent = PendingIntent.getBroadcast(context, 0, intent, PendingIntent.FLAG_IMMUTABLE) + val builder = NotificationCompat.Builder(context, "LockTaskMode") + .setContentTitle(context.getText(R.string.lock_task_mode)) + .setSmallIcon(R.drawable.lock_fill0) + .addAction(NotificationCompat.Action.Builder(R.drawable.lock_fill0, context.getText(R.string.stop), pendingIntent).build()) + .setPriority(NotificationCompat.PRIORITY_HIGH) + nm.notify(1, builder.build()) +} diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index a0c3e39..b7e0106 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -50,6 +50,7 @@ G/Ç Hatası Mevcut Durum: Başlat + Stop Bilinmeyen Hata Tümünü İzin Ver Politika Kullan diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index 9674f59..ac76577 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -47,6 +47,7 @@ IO异常 当前状态: 开始 + 停止 未知错误 允许全部 使用策略 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index c4651f5..d4e8a60 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -50,6 +50,7 @@ IO Exception Current status: Start + Stop Unknown error Allow all Use policy