diff --git a/app/src/main/java/com/bintianqi/owndroid/Settings.kt b/app/src/main/java/com/bintianqi/owndroid/Settings.kt index 30a293f..c1b2128 100644 --- a/app/src/main/java/com/bintianqi/owndroid/Settings.kt +++ b/app/src/main/java/com/bintianqi/owndroid/Settings.kt @@ -44,6 +44,7 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.DpOffset import androidx.compose.ui.unit.dp import androidx.core.content.edit +import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.net.toUri import androidx.lifecycle.compose.collectAsStateWithLifecycle import com.bintianqi.owndroid.ui.FunctionItem @@ -85,13 +86,22 @@ fun SettingsScreen(onNavigateUp: () -> Unit, onNavigate: (Any) -> Unit) { @Composable fun SettingsOptionsScreen(onNavigateUp: () -> Unit) { - val sp = SharedPrefs(LocalContext.current) + val context = LocalContext.current + val sp = SharedPrefs(context) MyScaffold(R.string.options, onNavigateUp, 0.dp) { SwitchItem( R.string.show_dangerous_features, icon = R.drawable.warning_fill0, getState = { sp.displayDangerousFeatures }, onCheckedChange = { sp.displayDangerousFeatures = it } ) + SwitchItem( + R.string.shortcuts, icon = R.drawable.open_in_new, + getState = { sp.shortcuts }, onCheckedChange = { + sp.shortcuts = it + ShortcutManagerCompat.removeAllDynamicShortcuts(context) + createShortcuts(context) + } + ) } } diff --git a/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt b/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt index 2cf2856..efafd32 100644 --- a/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt +++ b/app/src/main/java/com/bintianqi/owndroid/SharedPrefs.kt @@ -22,6 +22,7 @@ class SharedPrefs(context: Context) { var lockPasswordHash by StringSharedPref("lock.password.sha256") var biometricsUnlock by BooleanSharedPref("lock.biometrics") var applicationsListView by BooleanSharedPref("applications.list_view", true) + var shortcuts by BooleanSharedPref("shortcuts", true) } private class BooleanSharedPref(val key: String, val defValue: Boolean = false): ReadWriteProperty { diff --git a/app/src/main/java/com/bintianqi/owndroid/ShortcutsReceiverActivity.kt b/app/src/main/java/com/bintianqi/owndroid/ShortcutsReceiverActivity.kt index 807b2ac..e234201 100644 --- a/app/src/main/java/com/bintianqi/owndroid/ShortcutsReceiverActivity.kt +++ b/app/src/main/java/com/bintianqi/owndroid/ShortcutsReceiverActivity.kt @@ -1,17 +1,72 @@ package com.bintianqi.owndroid import android.app.Activity +import android.content.Context +import android.content.Intent import android.os.Bundle +import androidx.core.content.pm.ShortcutInfoCompat +import androidx.core.content.pm.ShortcutManagerCompat +import androidx.core.graphics.drawable.IconCompat import com.bintianqi.owndroid.dpm.getDPM +import com.bintianqi.owndroid.dpm.getReceiver -class ShortcutsReceiverActivity: Activity() { +class ShortcutsReceiverActivity : Activity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) try { - if(intent.action == "com.bintianqi.owndroid.action.LOCK") { - getDPM().lockNow() + val action = intent.action?.removePrefix("com.bintianqi.owndroid.action.") + if (action != null && SharedPrefs(this).shortcuts) { + val dpm = getDPM() + val receiver = getReceiver() + when (action) { + "LOCK" -> dpm.lockNow() + "DISABLE_CAMERA" -> { + dpm.setCameraDisabled(receiver, !dpm.getCameraDisabled(receiver)) + createShortcuts(this) + } + "MUTE" -> { + dpm.setMasterVolumeMuted(receiver, !dpm.isMasterVolumeMuted(receiver)) + createShortcuts(this) + } + } } - } catch(_: Exception) {} - finish() + } finally { + finish() + } } -} \ No newline at end of file +} + +fun createShortcuts(context: Context) { + if (!SharedPrefs(context).shortcuts) return + val action = "com.bintianqi.owndroid.action" + val baseIntent = Intent(context, ShortcutsReceiverActivity::class.java) + val dpm = context.getDPM() + val receiver = context.getReceiver() + val cameraDisabled = dpm.getCameraDisabled(receiver) + val muted = dpm.isMasterVolumeMuted(receiver) + val list = listOf( + ShortcutInfoCompat.Builder(context, "LOCK") + .setIcon(IconCompat.createWithResource(context, R.drawable.screen_lock_portrait_fill0)) + .setShortLabel(context.getString(R.string.lock_screen)) + .setIntent(Intent(baseIntent).setAction("$action.LOCK")), + ShortcutInfoCompat.Builder(context, "DISABLE_CAMERA") + .setIcon( + IconCompat.createWithResource( + context, + if (cameraDisabled) R.drawable.photo_camera_fill0 else R.drawable.no_photography_fill0 + ) + ) + .setShortLabel(context.getString(if (cameraDisabled) R.string.enable_camera else R.string.disable_cam)) + .setIntent(Intent(baseIntent).setAction("$action.DISABLE_CAMERA")), + ShortcutInfoCompat.Builder(context, "MUTE") + .setIcon( + IconCompat.createWithResource( + context, + if (muted) R.drawable.volume_up_fill0 else R.drawable.volume_off_fill0 + ) + ) + .setShortLabel(context.getString(if (muted) R.string.unmute else R.string.mute)) + .setIntent(Intent(baseIntent).setAction("$action.MUTE")) + ) + ShortcutManagerCompat.setDynamicShortcuts(context, list.map { it.build() }) +} diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt index 5ca1902..a0dd6c2 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/DPM.kt @@ -22,12 +22,14 @@ import android.util.Log import androidx.annotation.DrawableRes import androidx.annotation.RequiresApi import androidx.annotation.StringRes +import androidx.core.content.pm.ShortcutManagerCompat import androidx.core.graphics.drawable.toBitmap import com.bintianqi.owndroid.R import com.bintianqi.owndroid.Receiver import com.bintianqi.owndroid.SharedPrefs import com.bintianqi.owndroid.ShortcutsReceiverActivity import com.bintianqi.owndroid.backToHomeStateFlow +import com.bintianqi.owndroid.createShortcuts import com.bintianqi.owndroid.myPrivilege import com.rosan.dhizuku.api.Dhizuku import com.rosan.dhizuku.api.Dhizuku.binderWrapper @@ -520,26 +522,17 @@ fun parsePackageInstallerMessage(context: Context, result: Intent): String { fun handlePrivilegeChange(context: Context) { val privilege = myPrivilege.value val activated = privilege.device || privilege.profile + val sp = SharedPrefs(context) if(activated) { + createShortcuts(context) if(!privilege.dhizuku) { setDefaultAffiliationID(context) - if(VERSION.SDK_INT >= 25) { - val sm = context.getSystemService(ShortcutManager::class.java) - val lockIntent = Intent("com.bintianqi.owndroid.action.LOCK") - .setComponent(ComponentName(context, ShortcutsReceiverActivity::class.java)) - val shortcut = ShortcutInfo.Builder(context, "LockScreen") - .setShortLabel(context.getString(R.string.lock_now)) - .setIcon(Icon.createWithBitmap(context.getDrawable(R.drawable.screen_lock_portrait_fill0)?.toBitmap())) - .setIntent(lockIntent) - sm.addDynamicShortcuts(listOf(shortcut.build())) - } } } else { - SharedPrefs(context).isDefaultAffiliationIdSet = false + sp.isDefaultAffiliationIdSet = false if(VERSION.SDK_INT >= 25) { - val sm = context.getSystemService(ShortcutManager::class.java) - sm.removeDynamicShortcuts(listOf("LockScreen")) + ShortcutManagerCompat.removeAllDynamicShortcuts(context) } - SharedPrefs(context).isApiEnabled = false + sp.isApiEnabled = false } } diff --git a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt index e4fd9f9..2a8ad44 100644 --- a/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt +++ b/app/src/main/java/com/bintianqi/owndroid/dpm/System.kt @@ -122,6 +122,7 @@ import com.bintianqi.owndroid.HorizontalPadding import com.bintianqi.owndroid.NotificationUtils import com.bintianqi.owndroid.R import com.bintianqi.owndroid.SharedPrefs +import com.bintianqi.owndroid.createShortcuts import com.bintianqi.owndroid.formatFileSize import com.bintianqi.owndroid.humanReadableDate import com.bintianqi.owndroid.myPrivilege @@ -250,8 +251,11 @@ fun SystemOptionsScreen(onNavigateUp: () -> Unit) { val privilege by myPrivilege.collectAsStateWithLifecycle() var dialog by remember { mutableIntStateOf(0) } MyScaffold(R.string.options, onNavigateUp, 0.dp) { - SwitchItem(R.string.disable_cam, icon = R.drawable.photo_camera_fill0, - getState = { dpm.getCameraDisabled(null) }, onCheckedChange = { dpm.setCameraDisabled(receiver,it) } + SwitchItem(R.string.disable_cam, icon = R.drawable.no_photography_fill0, + getState = { dpm.getCameraDisabled(null) }, onCheckedChange = { + dpm.setCameraDisabled(receiver, it) + createShortcuts(context) + } ) SwitchItem(R.string.disable_screen_capture, icon = R.drawable.screenshot_fill0, getState = { dpm.getScreenCaptureDisabled(null) }, onCheckedChange = { dpm.setScreenCaptureDisabled(receiver,it) } @@ -275,7 +279,10 @@ fun SystemOptionsScreen(onNavigateUp: () -> Unit) { } } SwitchItem(R.string.master_mute, icon = R.drawable.volume_off_fill0, - getState = { dpm.isMasterVolumeMuted(receiver) }, onCheckedChange = { dpm.setMasterVolumeMuted(receiver,it) } + getState = { dpm.isMasterVolumeMuted(receiver) }, onCheckedChange = { + dpm.setMasterVolumeMuted(receiver,it) + createShortcuts(context) + } ) if(VERSION.SDK_INT >= 26) { SwitchItem(R.string.backup_service, icon = R.drawable.backup_fill0, diff --git a/app/src/main/res/drawable/no_photography_fill0.xml b/app/src/main/res/drawable/no_photography_fill0.xml new file mode 100644 index 0000000..07add32 --- /dev/null +++ b/app/src/main/res/drawable/no_photography_fill0.xml @@ -0,0 +1,9 @@ + + + diff --git a/app/src/main/res/values-zh-rCN/strings.xml b/app/src/main/res/values-zh-rCN/strings.xml index d30e27f..2d0a1d0 100644 --- a/app/src/main/res/values-zh-rCN/strings.xml +++ b/app/src/main/res/values-zh-rCN/strings.xml @@ -117,18 +117,22 @@ 系统 禁用相机 + 启用相机 禁止屏幕捕获 禁用状态栏 自动设置时间 自动设置时区 要求自动时间 全局静音 + 静音 + 取消静音 备份服务 禁止蓝牙分享联系人 通用标准模式 禁用USB信号 锁屏 立即锁屏 + 锁屏 移除凭证加密密钥 硬件监视器 刷新间隔 @@ -551,6 +555,7 @@ 项目主页 外观 + 快捷方式 应用锁 长度不得小于4 留空以保持未更改 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 96a1231..93bc3c1 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -126,18 +126,22 @@ System Disable camera + Enable camera Disable screen capture Disable status bar Auto time Require auto time Auto timezone Master volume mute + Mute + Unmute Backup service Disable bluetooth contact sharing Common criteria mode Disable USB signal Keyguard Lock screen now + Lock screen Evict credential encryption key Hardware monitor Refresh interval @@ -584,6 +588,7 @@ Project homepage Appearance + Shortcuts App lock The length must not be less than 4 Leave empty to remain unchanged