mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
Lock screen shortcut
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:tools="http://schemas.android.com/tools">
|
||||
<permission android:name="com.bintianqi.owndroid.MyPermission"/>
|
||||
<uses-permission android:name="com.bintianqi.owndroid.MyPermission"/>
|
||||
<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
|
||||
<uses-permission android:name="android.permission.REQUEST_DELETE_PACKAGES"/>
|
||||
@@ -61,6 +63,11 @@
|
||||
android:label="@string/package_chooser"
|
||||
android:exported="false"
|
||||
android:launchMode="singleInstance"/>
|
||||
<activity
|
||||
android:name=".ShortcutsReceiverActivity"
|
||||
android:permission="com.bintianqi.owndroid.MyPermission"
|
||||
android:exported="true"
|
||||
android:theme="@android:style/Theme.NoDisplay" />
|
||||
<receiver
|
||||
android:name=".Receiver"
|
||||
android:description="@string/app_name"
|
||||
|
||||
@@ -6,12 +6,16 @@ import android.app.admin.DeviceAdminReceiver
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.content.pm.ShortcutInfo
|
||||
import android.content.pm.ShortcutManager
|
||||
import android.graphics.drawable.Icon
|
||||
import android.os.Build.VERSION
|
||||
import android.os.PersistableBundle
|
||||
import android.os.UserHandle
|
||||
import android.os.UserManager
|
||||
import android.widget.Toast
|
||||
import androidx.core.app.NotificationCompat
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import com.bintianqi.owndroid.dpm.handleNetworkLogs
|
||||
import com.bintianqi.owndroid.dpm.isDeviceOwner
|
||||
import com.bintianqi.owndroid.dpm.isProfileOwner
|
||||
@@ -42,6 +46,16 @@ class Receiver : DeviceAdminReceiver() {
|
||||
if(context.isProfileOwner || context.isDeviceOwner){
|
||||
setDefaultAffiliationID(context)
|
||||
Toast.makeText(context, context.getString(R.string.onEnabled), Toast.LENGTH_SHORT).show()
|
||||
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()))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,6 +63,10 @@ class Receiver : DeviceAdminReceiver() {
|
||||
super.onDisabled(context, intent)
|
||||
Toast.makeText(context, R.string.onDisabled, Toast.LENGTH_SHORT).show()
|
||||
SharedPrefs(context).isDefaultAffiliationIdSet = false
|
||||
if(VERSION.SDK_INT >= 25) {
|
||||
val sm = context.getSystemService(ShortcutManager::class.java)
|
||||
sm.removeDynamicShortcuts(listOf("LockScreen"))
|
||||
}
|
||||
}
|
||||
|
||||
override fun onProfileProvisioningComplete(context: Context, intent: Intent) {
|
||||
|
||||
@@ -20,7 +20,7 @@ class SharedPrefs(context: Context) {
|
||||
var blackTheme by BooleanSharedPref("theme.black")
|
||||
var lockPassword by StringSharedPref("lock.password")
|
||||
var biometricsUnlock by BooleanSharedPref("lock.biometrics")
|
||||
var applicationsListView by BooleanSharedPref("applications.list_view")
|
||||
var applicationsListView by BooleanSharedPref("applications.list_view", true)
|
||||
}
|
||||
|
||||
private class BooleanSharedPref(val key: String, val defValue: Boolean = false): ReadWriteProperty<SharedPrefs, Boolean> {
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
package com.bintianqi.owndroid
|
||||
|
||||
import android.app.Activity
|
||||
import android.os.Bundle
|
||||
import com.bintianqi.owndroid.dpm.getDPM
|
||||
|
||||
class ShortcutsReceiverActivity: Activity() {
|
||||
override fun onCreate(savedInstanceState: Bundle?) {
|
||||
super.onCreate(savedInstanceState)
|
||||
try {
|
||||
if(intent.action == "com.bintianqi.owndroid.action.LOCK") {
|
||||
getDPM().lockNow()
|
||||
}
|
||||
} catch(_: Exception) {}
|
||||
finish()
|
||||
}
|
||||
}
|
||||
@@ -88,7 +88,6 @@ import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.material3.MenuAnchorType
|
||||
import androidx.compose.material3.OutlinedTextField
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.SegmentedButton
|
||||
import androidx.compose.material3.SegmentedButtonDefaults
|
||||
import androidx.compose.material3.SingleChoiceSegmentedButtonRow
|
||||
@@ -133,7 +132,6 @@ import com.bintianqi.owndroid.SharedPrefs
|
||||
import com.bintianqi.owndroid.formatDate
|
||||
import com.bintianqi.owndroid.formatFileSize
|
||||
import com.bintianqi.owndroid.humanReadableDate
|
||||
import com.bintianqi.owndroid.humanReadableDateTime
|
||||
import com.bintianqi.owndroid.showOperationResultToast
|
||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||
import com.bintianqi.owndroid.ui.ErrorDialog
|
||||
|
||||
@@ -69,13 +69,13 @@ import com.bintianqi.owndroid.HorizontalPadding
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.SharedPrefs
|
||||
import com.bintianqi.owndroid.showOperationResultToast
|
||||
import com.bintianqi.owndroid.ui.CardItem
|
||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||
import com.bintianqi.owndroid.ui.FullWidthCheckBoxItem
|
||||
import com.bintianqi.owndroid.ui.FullWidthRadioButtonItem
|
||||
import com.bintianqi.owndroid.ui.FunctionItem
|
||||
import com.bintianqi.owndroid.ui.Notes
|
||||
import com.bintianqi.owndroid.ui.InfoItem
|
||||
import com.bintianqi.owndroid.ui.MyScaffold
|
||||
import com.bintianqi.owndroid.ui.Notes
|
||||
import com.bintianqi.owndroid.ui.RadioButtonItem
|
||||
import com.bintianqi.owndroid.yesOrNo
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -220,7 +220,7 @@ fun PasswordInfoScreen(onNavigateUp: () -> Unit) {
|
||||
val deviceOwner = context.isDeviceOwner
|
||||
val profileOwner = context.isProfileOwner
|
||||
var dialog by remember { mutableIntStateOf(0) } // 0:none, 1:password complexity
|
||||
MyScaffold(R.string.password_info, onNavigateUp) {
|
||||
MyScaffold(R.string.password_info, onNavigateUp, 0.dp) {
|
||||
if(VERSION.SDK_INT >= 29) {
|
||||
val text = when(dpm.passwordComplexity) {
|
||||
PASSWORD_COMPLEXITY_NONE -> R.string.none
|
||||
@@ -229,13 +229,13 @@ fun PasswordInfoScreen(onNavigateUp: () -> Unit) {
|
||||
PASSWORD_COMPLEXITY_HIGH -> R.string.high
|
||||
else -> R.string.unknown
|
||||
}
|
||||
CardItem(R.string.current_password_complexity, text) { dialog = 1 }
|
||||
InfoItem(R.string.current_password_complexity, text, true) { dialog = 1 }
|
||||
}
|
||||
if(deviceOwner || profileOwner) {
|
||||
CardItem(R.string.password_sufficient, dpm.isActivePasswordSufficient.yesOrNo)
|
||||
InfoItem(R.string.password_sufficient, dpm.isActivePasswordSufficient.yesOrNo)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 28 && profileOwner && dpm.isManagedProfile(receiver)) {
|
||||
CardItem(R.string.unified_password, dpm.isUsingUnifiedPassword(receiver).yesOrNo)
|
||||
InfoItem(R.string.unified_password, dpm.isUsingUnifiedPassword(receiver).yesOrNo)
|
||||
}
|
||||
}
|
||||
if(dialog != 0) AlertDialog(
|
||||
|
||||
@@ -646,13 +646,13 @@ fun DeviceInfoScreen(onNavigateUp: () -> Unit) {
|
||||
val dpm = context.getDPM()
|
||||
val receiver = context.getReceiver()
|
||||
var dialog by remember { mutableIntStateOf(0) }
|
||||
MyScaffold(R.string.device_info, onNavigateUp) {
|
||||
MyScaffold(R.string.device_info, onNavigateUp, 0.dp) {
|
||||
if(VERSION.SDK_INT>=34 && (context.isDeviceOwner || dpm.isOrgProfile(receiver))) {
|
||||
CardItem(R.string.financed_device, dpm.isDeviceFinanced.yesOrNo)
|
||||
InfoItem(R.string.financed_device, dpm.isDeviceFinanced.yesOrNo)
|
||||
}
|
||||
if(VERSION.SDK_INT >= 33) {
|
||||
val dpmRole = dpm.devicePolicyManagementRoleHolderPackage
|
||||
CardItem(R.string.dpmrh, if(dpmRole == null) stringResource(R.string.none) else dpmRole)
|
||||
InfoItem(R.string.dpmrh, if(dpmRole == null) stringResource(R.string.none) else dpmRole)
|
||||
}
|
||||
val encryptionStatus = mutableMapOf(
|
||||
DevicePolicyManager.ENCRYPTION_STATUS_INACTIVE to R.string.es_inactive,
|
||||
@@ -661,16 +661,16 @@ fun DeviceInfoScreen(onNavigateUp: () -> Unit) {
|
||||
)
|
||||
if(VERSION.SDK_INT >= 23) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_DEFAULT_KEY] = R.string.es_active_default_key }
|
||||
if(VERSION.SDK_INT >= 24) { encryptionStatus[DevicePolicyManager.ENCRYPTION_STATUS_ACTIVE_PER_USER] = R.string.es_active_per_user }
|
||||
CardItem(R.string.encryption_status, encryptionStatus[dpm.storageEncryptionStatus] ?: R.string.unknown)
|
||||
InfoItem(R.string.encryption_status, encryptionStatus[dpm.storageEncryptionStatus] ?: R.string.unknown)
|
||||
if(VERSION.SDK_INT >= 28) {
|
||||
CardItem(R.string.support_device_id_attestation, dpm.isDeviceIdAttestationSupported.yesOrNo) { dialog = 1 }
|
||||
InfoItem(R.string.support_device_id_attestation, dpm.isDeviceIdAttestationSupported.yesOrNo, true) { dialog = 1 }
|
||||
}
|
||||
if (VERSION.SDK_INT >= 30) {
|
||||
CardItem(R.string.support_unique_device_attestation, dpm.isUniqueDeviceAttestationSupported.yesOrNo) { dialog = 2 }
|
||||
InfoItem(R.string.support_unique_device_attestation, dpm.isUniqueDeviceAttestationSupported.yesOrNo, true) { dialog = 2 }
|
||||
}
|
||||
val adminList = dpm.activeAdmins
|
||||
if(adminList != null) {
|
||||
CardItem(R.string.activated_device_admin, adminList.map { it.flattenToShortString() }.joinToString("\n"))
|
||||
InfoItem(R.string.activated_device_admin, adminList.map { it.flattenToShortString() }.joinToString("\n"))
|
||||
}
|
||||
}
|
||||
if(dialog != 0) AlertDialog(
|
||||
|
||||
@@ -67,7 +67,7 @@ import androidx.compose.ui.window.DialogProperties
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.parseTimestamp
|
||||
import com.bintianqi.owndroid.showOperationResultToast
|
||||
import com.bintianqi.owndroid.ui.CardItem
|
||||
import com.bintianqi.owndroid.ui.InfoItem
|
||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||
import com.bintianqi.owndroid.ui.FunctionItem
|
||||
import com.bintianqi.owndroid.ui.Notes
|
||||
@@ -192,25 +192,25 @@ fun UserInfoScreen(onNavigateUp: () -> Unit) {
|
||||
val userManager = context.getSystemService(Context.USER_SERVICE) as UserManager
|
||||
val user = Process.myUserHandle()
|
||||
var infoDialog by remember { mutableIntStateOf(0) }
|
||||
MyScaffold(R.string.user_info, onNavigateUp) {
|
||||
if(VERSION.SDK_INT >= 24) CardItem(R.string.support_multiuser, UserManager.supportsMultipleUsers().yesOrNo)
|
||||
if(VERSION.SDK_INT >= 31) CardItem(R.string.headless_system_user_mode, UserManager.isHeadlessSystemUserMode().yesOrNo) { infoDialog = 1 }
|
||||
MyScaffold(R.string.user_info, onNavigateUp, 0.dp) {
|
||||
if(VERSION.SDK_INT >= 24) InfoItem(R.string.support_multiuser, UserManager.supportsMultipleUsers().yesOrNo)
|
||||
if(VERSION.SDK_INT >= 31) InfoItem(R.string.headless_system_user_mode, UserManager.isHeadlessSystemUserMode().yesOrNo, true) { infoDialog = 1 }
|
||||
Spacer(Modifier.padding(vertical = 8.dp))
|
||||
if(VERSION.SDK_INT >= 23) CardItem(R.string.system_user, userManager.isSystemUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 34) CardItem(R.string.admin_user, userManager.isAdminUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 25) CardItem(R.string.demo_user, userManager.isDemoUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 23) InfoItem(R.string.system_user, userManager.isSystemUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 34) InfoItem(R.string.admin_user, userManager.isAdminUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 25) InfoItem(R.string.demo_user, userManager.isDemoUser.yesOrNo)
|
||||
if(VERSION.SDK_INT >= 26) userManager.getUserCreationTime(user).let {
|
||||
if(it != 0L) CardItem(R.string.creation_time, parseTimestamp(it))
|
||||
if(it != 0L) InfoItem(R.string.creation_time, parseTimestamp(it))
|
||||
}
|
||||
if (VERSION.SDK_INT >= 28) {
|
||||
CardItem(R.string.logout_enabled, dpm.isLogoutEnabled.yesOrNo)
|
||||
InfoItem(R.string.logout_enabled, dpm.isLogoutEnabled.yesOrNo)
|
||||
if(context.isDeviceOwner || context.isProfileOwner) {
|
||||
CardItem(R.string.ephemeral_user, dpm.isEphemeralUser(receiver).yesOrNo)
|
||||
InfoItem(R.string.ephemeral_user, dpm.isEphemeralUser(receiver).yesOrNo)
|
||||
}
|
||||
CardItem(R.string.affiliated_user, dpm.isAffiliatedUser.yesOrNo)
|
||||
InfoItem(R.string.affiliated_user, dpm.isAffiliatedUser.yesOrNo)
|
||||
}
|
||||
CardItem(R.string.user_id, (Binder.getCallingUid() / 100000).toString())
|
||||
CardItem(R.string.user_serial_number, userManager.getSerialNumberForUser(Process.myUserHandle()).toString())
|
||||
InfoItem(R.string.user_id, (Binder.getCallingUid() / 100000).toString())
|
||||
InfoItem(R.string.user_serial_number, userManager.getSerialNumberForUser(Process.myUserHandle()).toString())
|
||||
}
|
||||
if(infoDialog != 0) AlertDialog(
|
||||
text = { Text(stringResource(R.string.info_headless_system_user_mode)) },
|
||||
|
||||
@@ -55,12 +55,12 @@ import androidx.compose.ui.text.input.KeyboardType
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.showOperationResultToast
|
||||
import com.bintianqi.owndroid.ui.CardItem
|
||||
import com.bintianqi.owndroid.ui.CheckBoxItem
|
||||
import com.bintianqi.owndroid.ui.CopyTextButton
|
||||
import com.bintianqi.owndroid.ui.FunctionItem
|
||||
import com.bintianqi.owndroid.ui.Notes
|
||||
import com.bintianqi.owndroid.ui.InfoItem
|
||||
import com.bintianqi.owndroid.ui.MyScaffold
|
||||
import com.bintianqi.owndroid.ui.Notes
|
||||
import com.bintianqi.owndroid.ui.SwitchItem
|
||||
import com.bintianqi.owndroid.yesOrNo
|
||||
import kotlinx.serialization.Serializable
|
||||
@@ -172,7 +172,7 @@ fun OrganizationOwnedProfileScreen(onNavigateUp: () -> Unit) {
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getDPM()
|
||||
MyScaffold(R.string.org_owned_work_profile, onNavigateUp) {
|
||||
CardItem(R.string.org_owned_work_profile, dpm.isOrganizationOwnedDeviceWithManagedProfile.yesOrNo)
|
||||
InfoItem(R.string.org_owned_work_profile, dpm.isOrganizationOwnedDeviceWithManagedProfile.yesOrNo)
|
||||
Spacer(Modifier.padding(vertical = 5.dp))
|
||||
if(!dpm.isOrganizationOwnedDeviceWithManagedProfile) {
|
||||
SelectionContainer {
|
||||
|
||||
@@ -13,7 +13,6 @@ import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.LazyListScope
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
@@ -25,6 +24,7 @@ import androidx.compose.material3.MaterialTheme.typography
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.alpha
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.draw.rotate
|
||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||
@@ -33,6 +33,7 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.bintianqi.owndroid.HorizontalPadding
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.writeClipBoard
|
||||
import com.bintianqi.owndroid.zhCN
|
||||
@@ -236,28 +237,20 @@ fun CopyTextButton(@StringRes label: Int, content: String) {
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun CardItem(@StringRes title: Int, @StringRes text: Int, onClickInfo: (() -> Unit)? = null) {
|
||||
CardItem(title, stringResource(text), onClickInfo)
|
||||
}
|
||||
fun InfoItem(title: Int, text: Int, withInfo: Boolean = false, onClick: () -> Unit = {}) =
|
||||
InfoItem(title, stringResource(text), withInfo, onClick)
|
||||
|
||||
@Composable
|
||||
fun CardItem(@StringRes title: Int, text: String, onClickInfo: (() -> Unit)? = null) {
|
||||
Card(modifier = Modifier.fillMaxWidth().padding(vertical = 6.dp)) {
|
||||
fun InfoItem(title: Int, text: String, withInfo: Boolean = false, onClick: () -> Unit = {}) {
|
||||
Row(
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
Modifier.fillMaxWidth().padding(vertical = 6.dp).padding(start = HorizontalPadding, end = 8.dp),
|
||||
Arrangement.SpaceBetween, Alignment.CenterVertically
|
||||
) {
|
||||
Column(modifier = Modifier.fillMaxWidth(0.85F)) {
|
||||
Text(text = stringResource(title), style = typography.titleLarge, modifier = Modifier.padding(start = 8.dp, top = 6.dp))
|
||||
SelectionContainer {
|
||||
Text(text = text, modifier = Modifier.padding(start = 8.dp, bottom = 6.dp))
|
||||
}
|
||||
}
|
||||
if(onClickInfo != null) IconButton(onClick = onClickInfo) {
|
||||
Icon(imageVector = Icons.Outlined.Info, contentDescription = null)
|
||||
}
|
||||
Column {
|
||||
Text(stringResource(title), style = typography.titleLarge)
|
||||
Text(text, Modifier.alpha(0.8F))
|
||||
}
|
||||
if(withInfo) IconButton(onClick) { Icon(Icons.Outlined.Info, null) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user