mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 11:05:59 +00:00
Store App lock password hash in shared prefs
Add workflow release.yml Fix R8 error
This commit is contained in:
5
.github/workflows/build.yml
vendored
5
.github/workflows/build.yml
vendored
@@ -1,4 +1,4 @@
|
|||||||
name: Build APK
|
name: CI build
|
||||||
|
|
||||||
on:
|
on:
|
||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
@@ -62,9 +62,6 @@ jobs:
|
|||||||
name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed
|
name: OwnDroid-CI-${{ env.SHORT_SHA }}-release-signed
|
||||||
path: app/build/outputs/apk/release/app-release.apk
|
path: app/build/outputs/apk/release/app-release.apk
|
||||||
|
|
||||||
- name: Generate and submit dependency graph
|
|
||||||
uses: gradle/actions/dependency-submission@v4
|
|
||||||
|
|
||||||
upload-telegram:
|
upload-telegram:
|
||||||
name: Upload Builds
|
name: Upload Builds
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
|
|||||||
42
.github/workflows/release.yml
vendored
Normal file
42
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
name: Release
|
||||||
|
|
||||||
|
on:
|
||||||
|
workflow_dispatch:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
build:
|
||||||
|
name: Build
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Check out repository
|
||||||
|
uses: actions/checkout@v4
|
||||||
|
|
||||||
|
- name: Set up JDK 21
|
||||||
|
uses: actions/setup-java@v4
|
||||||
|
with:
|
||||||
|
distribution: 'temurin'
|
||||||
|
java-version: '21'
|
||||||
|
|
||||||
|
- name: Build APK
|
||||||
|
run: |
|
||||||
|
echo "${{ secrets.KEY_BASE64 }}" | base64 --decode - > app/release.jks
|
||||||
|
./gradlew clean assembleRelease --no-build-cache --no-configuration-cache --no-daemon -PStoreFile="$(pwd)/app/release.jks" -PStorePassword="${{ secrets.KEYSTORE_PASSWORD }}" -PKeyPassword="${{ secrets.KEY_PASSWORD }}" -PKeyAlias="${{ secrets.KEY_ALIAS }}"
|
||||||
|
|
||||||
|
- name: Create release
|
||||||
|
run: gh release create ${{ github.ref_name }} app/build/outputs/apk/release/app-release.apk#OwnDroid-${{ github.ref_name }}.apk -d --notes-from-tag
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Build APK (testkey)
|
||||||
|
run: ./gradlew build
|
||||||
|
|
||||||
|
- name: Upload testkey APK
|
||||||
|
run: gh release upload ${{ github.ref_name }} app/build/outputs/apk/release/app-release.apk#OwnDroid-${{ github.ref_name }}-testkey.apk
|
||||||
|
env:
|
||||||
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
|
|
||||||
|
- name: Generate and submit dependency graph
|
||||||
|
uses: gradle/actions/dependency-submission@v4
|
||||||
@@ -143,7 +143,7 @@ private fun AppInstaller(
|
|||||||
else Icon(Icons.Default.PlayArrow, null)
|
else Icon(Icons.Default.PlayArrow, null)
|
||||||
},
|
},
|
||||||
onClick = {
|
onClick = {
|
||||||
if(SharedPrefs(context).lockPassword.isNullOrEmpty()) onStartInstall() else appLockDialog = true
|
if(SharedPrefs(context).lockPasswordHash.isNullOrEmpty()) onStartInstall() else appLockDialog = true
|
||||||
},
|
},
|
||||||
expanded = !installing
|
expanded = !installing
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ fun AppLockDialog(onSucceed: () -> Unit, onDismiss: () -> Unit) {
|
|||||||
var input by remember { mutableStateOf("") }
|
var input by remember { mutableStateOf("") }
|
||||||
var isError by remember { mutableStateOf(false) }
|
var isError by remember { mutableStateOf(false) }
|
||||||
fun unlock() {
|
fun unlock() {
|
||||||
if(input == sp.lockPassword) {
|
if(input.hash() == sp.lockPasswordHash) {
|
||||||
fm.clearFocus()
|
fm.clearFocus()
|
||||||
onSucceed()
|
onSucceed()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -489,7 +489,7 @@ fun Home(vm: MyViewModel) {
|
|||||||
}
|
}
|
||||||
DisposableEffect(lifecycleOwner) {
|
DisposableEffect(lifecycleOwner) {
|
||||||
val observer = LifecycleEventObserver { _, event ->
|
val observer = LifecycleEventObserver { _, event ->
|
||||||
if(event == Lifecycle.Event.ON_CREATE && !SharedPrefs(context).lockPassword.isNullOrEmpty()) {
|
if(event == Lifecycle.Event.ON_CREATE && !SharedPrefs(context).lockPasswordHash.isNullOrEmpty()) {
|
||||||
navController.navigate(AppLock)
|
navController.navigate(AppLock)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ class ManageSpaceActivity: FragmentActivity() {
|
|||||||
setContent {
|
setContent {
|
||||||
val theme by vm.theme.collectAsStateWithLifecycle()
|
val theme by vm.theme.collectAsStateWithLifecycle()
|
||||||
OwnDroidTheme(theme) {
|
OwnDroidTheme(theme) {
|
||||||
var appLockDialog by remember { mutableStateOf(!SharedPrefs(this).lockPassword.isNullOrEmpty()) }
|
var appLockDialog by remember { mutableStateOf(!SharedPrefs(this).lockPasswordHash.isNullOrEmpty()) }
|
||||||
if(appLockDialog) {
|
if(appLockDialog) {
|
||||||
Dialog(::finish) {
|
Dialog(::finish) {
|
||||||
AppLockDialog({ appLockDialog = false }, ::finish)
|
AppLockDialog({ appLockDialog = false }, ::finish)
|
||||||
|
|||||||
@@ -164,7 +164,7 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
|||||||
var confirmPassword by remember { mutableStateOf("") }
|
var confirmPassword by remember { mutableStateOf("") }
|
||||||
var allowBiometrics by remember { mutableStateOf(sp.biometricsUnlock) }
|
var allowBiometrics by remember { mutableStateOf(sp.biometricsUnlock) }
|
||||||
val fr = FocusRequester()
|
val fr = FocusRequester()
|
||||||
val alreadySet = !sp.lockPassword.isNullOrEmpty()
|
val alreadySet = !sp.lockPasswordHash.isNullOrEmpty()
|
||||||
val isInputLegal = password.length !in 1..3 && (alreadySet || (password.isNotEmpty() && password.isNotBlank()))
|
val isInputLegal = password.length !in 1..3 && (alreadySet || (password.isNotEmpty() && password.isNotBlank()))
|
||||||
Column(Modifier.widthIn(max = 300.dp).align(Alignment.CenterHorizontally)) {
|
Column(Modifier.widthIn(max = 300.dp).align(Alignment.CenterHorizontally)) {
|
||||||
OutlinedTextField(
|
OutlinedTextField(
|
||||||
@@ -187,7 +187,7 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
|||||||
Button(
|
Button(
|
||||||
onClick = {
|
onClick = {
|
||||||
fm.clearFocus()
|
fm.clearFocus()
|
||||||
if(password.isNotEmpty()) sp.lockPassword = password
|
if(password.isNotEmpty()) sp.lockPasswordHash = password.hash()
|
||||||
sp.biometricsUnlock = allowBiometrics
|
sp.biometricsUnlock = allowBiometrics
|
||||||
onNavigateUp()
|
onNavigateUp()
|
||||||
},
|
},
|
||||||
@@ -199,7 +199,7 @@ fun AppLockSettingsScreen(onNavigateUp: () -> Unit) = MyScaffold(R.string.app_lo
|
|||||||
if(alreadySet) FilledTonalButton(
|
if(alreadySet) FilledTonalButton(
|
||||||
onClick = {
|
onClick = {
|
||||||
fm.clearFocus()
|
fm.clearFocus()
|
||||||
sp.lockPassword = ""
|
sp.lockPasswordHash = ""
|
||||||
sp.biometricsUnlock = false
|
sp.biometricsUnlock = false
|
||||||
onNavigateUp()
|
onNavigateUp()
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ class SharedPrefs(context: Context) {
|
|||||||
/** -1: follow system, 0: off, 1: on */
|
/** -1: follow system, 0: off, 1: on */
|
||||||
var darkTheme by IntSharedPref("theme.dark", -1)
|
var darkTheme by IntSharedPref("theme.dark", -1)
|
||||||
var blackTheme by BooleanSharedPref("theme.black")
|
var blackTheme by BooleanSharedPref("theme.black")
|
||||||
var lockPassword by StringSharedPref("lock.password")
|
var lockPasswordHash by StringSharedPref("lock.password.sha256")
|
||||||
var biometricsUnlock by BooleanSharedPref("lock.biometrics")
|
var biometricsUnlock by BooleanSharedPref("lock.biometrics")
|
||||||
var applicationsListView by BooleanSharedPref("applications.list_view", true)
|
var applicationsListView by BooleanSharedPref("applications.list_view", true)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ import kotlinx.serialization.json.Json
|
|||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.security.MessageDigest
|
||||||
import java.text.SimpleDateFormat
|
import java.text.SimpleDateFormat
|
||||||
import java.time.Instant
|
import java.time.Instant
|
||||||
import java.time.ZoneId
|
import java.time.ZoneId
|
||||||
@@ -89,11 +90,6 @@ fun Context.showOperationResultToast(success: Boolean) {
|
|||||||
Toast.makeText(this, if(success) R.string.success else R.string.failed, Toast.LENGTH_SHORT).show()
|
Toast.makeText(this, if(success) R.string.success else R.string.failed, Toast.LENGTH_SHORT).show()
|
||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("PrivateApi")
|
|
||||||
fun getContext(): Context {
|
|
||||||
return Class.forName("android.app.ActivityThread").getMethod("currentApplication").invoke(null) as Context
|
|
||||||
}
|
|
||||||
|
|
||||||
const val APK_MIME = "application/vnd.android.package-archive"
|
const val APK_MIME = "application/vnd.android.package-archive"
|
||||||
|
|
||||||
inline fun <reified T> serializableNavTypePair() =
|
inline fun <reified T> serializableNavTypePair() =
|
||||||
@@ -130,3 +126,9 @@ fun <T> NavHostController.navigate(route: T, args: Bundle) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val HorizontalPadding = 16.dp
|
val HorizontalPadding = 16.dp
|
||||||
|
|
||||||
|
@OptIn(ExperimentalStdlibApi::class)
|
||||||
|
fun String.hash(): String {
|
||||||
|
val md = MessageDigest.getInstance("SHA-256")
|
||||||
|
return md.digest(this.encodeToByteArray()).toHexString()
|
||||||
|
}
|
||||||
|
|||||||
@@ -137,71 +137,6 @@ fun Context.getReceiver(): ComponentName {
|
|||||||
|
|
||||||
val dhizukuErrorStatus = MutableStateFlow(0)
|
val dhizukuErrorStatus = MutableStateFlow(0)
|
||||||
|
|
||||||
fun Context.resetDevicePolicy() {
|
|
||||||
val dpm = getDPM()
|
|
||||||
val receiver = getReceiver()
|
|
||||||
RestrictionData.getAllRestrictions().forEach {
|
|
||||||
dpm.clearUserRestriction(receiver, it.id)
|
|
||||||
}
|
|
||||||
dpm.accountTypesWithManagementDisabled?.forEach {
|
|
||||||
dpm.setAccountManagementDisabled(receiver, it, false)
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 30) {
|
|
||||||
dpm.setConfiguredNetworksLockdownState(receiver, false)
|
|
||||||
dpm.setAutoTimeZoneEnabled(receiver, true)
|
|
||||||
dpm.setAutoTimeEnabled(receiver, true)
|
|
||||||
dpm.setCommonCriteriaModeEnabled(receiver, false)
|
|
||||||
try {
|
|
||||||
val frp = FactoryResetProtectionPolicy.Builder().setFactoryResetProtectionEnabled(false).setFactoryResetProtectionAccounts(listOf())
|
|
||||||
dpm.setFactoryResetProtectionPolicy(receiver, frp.build())
|
|
||||||
} catch(_: Exception) {}
|
|
||||||
dpm.setUserControlDisabledPackages(receiver, listOf())
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 33) {
|
|
||||||
dpm.minimumRequiredWifiSecurityLevel = DevicePolicyManager.WIFI_SECURITY_OPEN
|
|
||||||
dpm.wifiSsidPolicy = null
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 28) {
|
|
||||||
dpm.getOverrideApns(receiver).forEach { dpm.removeOverrideApn(receiver, it.id) }
|
|
||||||
dpm.setKeepUninstalledPackages(receiver, listOf())
|
|
||||||
}
|
|
||||||
dpm.setCameraDisabled(receiver, false)
|
|
||||||
dpm.setScreenCaptureDisabled(receiver, false)
|
|
||||||
dpm.setMasterVolumeMuted(receiver, false)
|
|
||||||
try {
|
|
||||||
if(VERSION.SDK_INT >= 31) dpm.isUsbDataSignalingEnabled = true
|
|
||||||
} catch (_: Exception) { }
|
|
||||||
if (VERSION.SDK_INT >= 23) {
|
|
||||||
dpm.setPermissionPolicy(receiver, DevicePolicyManager.PERMISSION_POLICY_PROMPT)
|
|
||||||
dpm.setSystemUpdatePolicy(receiver, SystemUpdatePolicy.createAutomaticInstallPolicy())
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 24) {
|
|
||||||
dpm.setAlwaysOnVpnPackage(receiver, null, false)
|
|
||||||
dpm.setPackagesSuspended(receiver, arrayOf(), false)
|
|
||||||
}
|
|
||||||
dpm.setPermittedInputMethods(receiver, null)
|
|
||||||
dpm.setPermittedAccessibilityServices(receiver, null)
|
|
||||||
packageManager.getInstalledApplications(0).forEach {
|
|
||||||
if (dpm.isUninstallBlocked(receiver, it.packageName)) dpm.setUninstallBlocked(receiver, it.packageName, false)
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 26) {
|
|
||||||
dpm.setRequiredStrongAuthTimeout(receiver, 0)
|
|
||||||
dpm.clearResetPasswordToken(receiver)
|
|
||||||
}
|
|
||||||
if (VERSION.SDK_INT >= 31) {
|
|
||||||
dpm.requiredPasswordComplexity = DevicePolicyManager.PASSWORD_COMPLEXITY_NONE
|
|
||||||
}
|
|
||||||
dpm.setKeyguardDisabledFeatures(receiver, 0)
|
|
||||||
dpm.setMaximumTimeToLock(receiver, 0)
|
|
||||||
dpm.setPasswordExpirationTimeout(receiver, 0)
|
|
||||||
dpm.setMaximumFailedPasswordsForWipe(receiver, 0)
|
|
||||||
dpm.setPasswordHistoryLength(receiver, 0)
|
|
||||||
if (VERSION.SDK_INT < 31) {
|
|
||||||
dpm.setPasswordQuality(receiver, DevicePolicyManager.PASSWORD_QUALITY_UNSPECIFIED)
|
|
||||||
}
|
|
||||||
dpm.setRecommendedGlobalProxy(receiver, null)
|
|
||||||
}
|
|
||||||
|
|
||||||
data class PermissionItem(
|
data class PermissionItem(
|
||||||
val permission: String,
|
val permission: String,
|
||||||
@StringRes val label: Int,
|
@StringRes val label: Int,
|
||||||
|
|||||||
@@ -763,7 +763,7 @@ fun WifiSecurityLevelScreen(onNavigateUp: () -> Unit) {
|
|||||||
val dpm = context.getDPM()
|
val dpm = context.getDPM()
|
||||||
var selectedWifiSecLevel by remember { mutableIntStateOf(0) }
|
var selectedWifiSecLevel by remember { mutableIntStateOf(0) }
|
||||||
LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel }
|
LaunchedEffect(Unit) { selectedWifiSecLevel = dpm.minimumRequiredWifiSecurityLevel }
|
||||||
MySmallTitleScaffold(R.string.min_wifi_security_level, onNavigateUp, 0.dp) {
|
MyScaffold(R.string.min_wifi_security_level, onNavigateUp, 0.dp) {
|
||||||
FullWidthRadioButtonItem(R.string.wifi_security_open, selectedWifiSecLevel == WIFI_SECURITY_OPEN) { selectedWifiSecLevel = WIFI_SECURITY_OPEN }
|
FullWidthRadioButtonItem(R.string.wifi_security_open, selectedWifiSecLevel == WIFI_SECURITY_OPEN) { selectedWifiSecLevel = WIFI_SECURITY_OPEN }
|
||||||
FullWidthRadioButtonItem("WEP, WPA(2)-PSK", selectedWifiSecLevel == WIFI_SECURITY_PERSONAL) { selectedWifiSecLevel = WIFI_SECURITY_PERSONAL }
|
FullWidthRadioButtonItem("WEP, WPA(2)-PSK", selectedWifiSecLevel == WIFI_SECURITY_PERSONAL) { selectedWifiSecLevel = WIFI_SECURITY_PERSONAL }
|
||||||
FullWidthRadioButtonItem("WPA-EAP", selectedWifiSecLevel == WIFI_SECURITY_ENTERPRISE_EAP) { selectedWifiSecLevel = WIFI_SECURITY_ENTERPRISE_EAP }
|
FullWidthRadioButtonItem("WPA-EAP", selectedWifiSecLevel == WIFI_SECURITY_ENTERPRISE_EAP) { selectedWifiSecLevel = WIFI_SECURITY_ENTERPRISE_EAP }
|
||||||
@@ -809,8 +809,6 @@ fun WifiSsidPolicyScreen(onNavigateUp: () -> Unit) {
|
|||||||
AnimatedVisibility(selectedPolicyType != -1) {
|
AnimatedVisibility(selectedPolicyType != -1) {
|
||||||
var inputSsid by remember { mutableStateOf("") }
|
var inputSsid by remember { mutableStateOf("") }
|
||||||
Column(Modifier.padding(horizontal = HorizontalPadding)) {
|
Column(Modifier.padding(horizontal = HorizontalPadding)) {
|
||||||
Text(stringResource(R.string.ssid_list_is))
|
|
||||||
if(ssidList.isEmpty()) Text(stringResource(R.string.none))
|
|
||||||
Column(modifier = Modifier.animateContentSize()) {
|
Column(modifier = Modifier.animateContentSize()) {
|
||||||
for(i in ssidList) {
|
for(i in ssidList) {
|
||||||
ListItem(i.bytes.decodeToString()) { ssidList -= i }
|
ListItem(i.bytes.decodeToString()) { ssidList -= i }
|
||||||
|
|||||||
@@ -247,7 +247,13 @@ fun WorkModesScreen(
|
|||||||
Icon(Icons.Default.MoreVert, null)
|
Icon(Icons.Default.MoreVert, null)
|
||||||
}
|
}
|
||||||
DropdownMenu(expanded, { expanded = false }) {
|
DropdownMenu(expanded, { expanded = false }) {
|
||||||
DropdownMenuItem({ Text(stringResource(R.string.deactivate)) }, { dialog = 4 })
|
DropdownMenuItem(
|
||||||
|
{ Text(stringResource(R.string.deactivate)) },
|
||||||
|
{
|
||||||
|
expanded = false
|
||||||
|
dialog = 4
|
||||||
|
}
|
||||||
|
)
|
||||||
if(!privilege.dhizuku && VERSION.SDK_INT >= 28) DropdownMenuItem(
|
if(!privilege.dhizuku && VERSION.SDK_INT >= 28) DropdownMenuItem(
|
||||||
{ Text(stringResource(R.string.transfer_ownership)) },
|
{ Text(stringResource(R.string.transfer_ownership)) },
|
||||||
{
|
{
|
||||||
@@ -404,7 +410,10 @@ fun WorkModesScreen(
|
|||||||
Text(stringResource(R.string.confirm))
|
Text(stringResource(R.string.confirm))
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onDismissRequest = {}
|
onDismissRequest = {
|
||||||
|
dialog = 0
|
||||||
|
if(operationSucceed && !params.canNavigateUp) onActivate()
|
||||||
|
}
|
||||||
)
|
)
|
||||||
if(dialog == 4) AlertDialog(
|
if(dialog == 4) AlertDialog(
|
||||||
title = { Text(stringResource(R.string.deactivate)) },
|
title = { Text(stringResource(R.string.deactivate)) },
|
||||||
@@ -422,6 +431,7 @@ fun WorkModesScreen(
|
|||||||
dpm.clearProfileOwner(ComponentName(context, Receiver::class.java))
|
dpm.clearProfileOwner(ComponentName(context, Receiver::class.java))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dialog = 0
|
||||||
updatePrivilege(context)
|
updatePrivilege(context)
|
||||||
handlePrivilegeChange(context)
|
handlePrivilegeChange(context)
|
||||||
onDeactivate()
|
onDeactivate()
|
||||||
@@ -498,7 +508,7 @@ fun activateUsingDhizuku(context: Context, callback: (Boolean, Boolean, String?)
|
|||||||
callback(true, false, null)
|
callback(true, false, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if(Dhizuku.init()) {
|
if(Dhizuku.init(context)) {
|
||||||
if(Dhizuku.isPermissionGranted()) {
|
if(Dhizuku.isPermissionGranted()) {
|
||||||
doTransfer()
|
doTransfer()
|
||||||
} else {
|
} else {
|
||||||
@@ -519,7 +529,7 @@ fun activateDhizukuMode(context: Context, callback: (Boolean, Boolean, String?)
|
|||||||
SharedPrefs(context).dhizuku = true
|
SharedPrefs(context).dhizuku = true
|
||||||
callback(true, true, null)
|
callback(true, true, null)
|
||||||
}
|
}
|
||||||
if(Dhizuku.init()) {
|
if(Dhizuku.init(context)) {
|
||||||
if(Dhizuku.isPermissionGranted()) {
|
if(Dhizuku.isPermissionGranted()) {
|
||||||
onSucceed()
|
onSucceed()
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -1,14 +1,19 @@
|
|||||||
package com.bintianqi.owndroid.ui
|
package com.bintianqi.owndroid.ui
|
||||||
|
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.DrawableRes
|
import androidx.annotation.DrawableRes
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.animation.animateContentSize
|
|
||||||
import androidx.compose.animation.core.animateFloatAsState
|
import androidx.compose.animation.core.animateFloatAsState
|
||||||
import androidx.compose.foundation.background
|
import androidx.compose.foundation.background
|
||||||
import androidx.compose.foundation.clickable
|
import androidx.compose.foundation.clickable
|
||||||
import androidx.compose.foundation.layout.*
|
|
||||||
import androidx.compose.foundation.layout.Arrangement
|
import androidx.compose.foundation.layout.Arrangement
|
||||||
|
import androidx.compose.foundation.layout.Box
|
||||||
|
import androidx.compose.foundation.layout.Column
|
||||||
|
import androidx.compose.foundation.layout.ColumnScope
|
||||||
|
import androidx.compose.foundation.layout.Row
|
||||||
|
import androidx.compose.foundation.layout.fillMaxSize
|
||||||
|
import androidx.compose.foundation.layout.fillMaxWidth
|
||||||
|
import androidx.compose.foundation.layout.offset
|
||||||
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.foundation.lazy.LazyListScope
|
import androidx.compose.foundation.lazy.LazyListScope
|
||||||
import androidx.compose.foundation.rememberScrollState
|
import androidx.compose.foundation.rememberScrollState
|
||||||
@@ -18,27 +23,39 @@ import androidx.compose.material.icons.Icons
|
|||||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||||
import androidx.compose.material.icons.filled.ArrowDropDown
|
import androidx.compose.material.icons.filled.ArrowDropDown
|
||||||
import androidx.compose.material.icons.outlined.Info
|
import androidx.compose.material.icons.outlined.Info
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.AlertDialog
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
|
import androidx.compose.material3.LargeTopAppBar
|
||||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||||
import androidx.compose.material3.MaterialTheme.typography
|
import androidx.compose.material3.MaterialTheme.typography
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.material3.RadioButton
|
||||||
|
import androidx.compose.material3.Scaffold
|
||||||
|
import androidx.compose.material3.Switch
|
||||||
|
import androidx.compose.material3.Text
|
||||||
|
import androidx.compose.material3.TextButton
|
||||||
|
import androidx.compose.material3.TopAppBar
|
||||||
|
import androidx.compose.material3.TopAppBarDefaults
|
||||||
|
import androidx.compose.runtime.Composable
|
||||||
|
import androidx.compose.runtime.getValue
|
||||||
|
import androidx.compose.runtime.mutableStateOf
|
||||||
|
import androidx.compose.runtime.remember
|
||||||
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.draw.alpha
|
import androidx.compose.ui.draw.alpha
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.draw.rotate
|
import androidx.compose.ui.draw.rotate
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
||||||
import androidx.compose.ui.platform.LocalContext
|
|
||||||
import androidx.compose.ui.res.painterResource
|
import androidx.compose.ui.res.painterResource
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import androidx.compose.ui.unit.Dp
|
import androidx.compose.ui.unit.Dp
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
import com.bintianqi.owndroid.HorizontalPadding
|
import com.bintianqi.owndroid.HorizontalPadding
|
||||||
import com.bintianqi.owndroid.R
|
import com.bintianqi.owndroid.R
|
||||||
import com.bintianqi.owndroid.writeClipBoard
|
|
||||||
import com.bintianqi.owndroid.zhCN
|
import com.bintianqi.owndroid.zhCN
|
||||||
import kotlinx.coroutines.delay
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
|
|
||||||
@Composable
|
@Composable
|
||||||
fun FunctionItem(
|
fun FunctionItem(
|
||||||
|
|||||||
@@ -85,7 +85,6 @@
|
|||||||
<string name="change_package_state">Изменить состояние пакета</string>
|
<string name="change_package_state">Изменить состояние пакета</string>
|
||||||
<string name="grant_permissions">Предоставить разрешения</string>
|
<string name="grant_permissions">Предоставить разрешения</string>
|
||||||
<string name="add_delegated_admin">Добавить делегированного админа</string>
|
<string name="add_delegated_admin">Добавить делегированного админа</string>
|
||||||
<string name="reset_device_policy">Сбросить политику устройства</string>
|
|
||||||
<string name="device_info">Информация об устройстве</string>
|
<string name="device_info">Информация об устройстве</string>
|
||||||
<string name="support_device_id_attestation">Поддержка аттестации идентификатора устройства</string>
|
<string name="support_device_id_attestation">Поддержка аттестации идентификатора устройства</string>
|
||||||
<string name="support_unique_device_attestation">Поддержка аттестации уникального устройства</string>
|
<string name="support_unique_device_attestation">Поддержка аттестации уникального устройства</string>
|
||||||
@@ -247,7 +246,6 @@
|
|||||||
<string name="wifi_security_open">Открытая</string>
|
<string name="wifi_security_open">Открытая</string>
|
||||||
<string name="lockdown_admin_configured_network">Блокировка сети, настроенной администратором</string>
|
<string name="lockdown_admin_configured_network">Блокировка сети, настроенной администратором</string>
|
||||||
<string name="wifi_ssid_policy">Политика SSID Wi-Fi</string>
|
<string name="wifi_ssid_policy">Политика SSID Wi-Fi</string>
|
||||||
<string name="ssid_list_is">Список SSID:</string>
|
|
||||||
<string name="already_exist">Уже существует</string>
|
<string name="already_exist">Уже существует</string>
|
||||||
<string name="network_stats">Сетевая статистика</string>
|
<string name="network_stats">Сетевая статистика</string>
|
||||||
<string name="type">Тип</string>
|
<string name="type">Тип</string>
|
||||||
|
|||||||
@@ -84,7 +84,6 @@
|
|||||||
<string name="change_package_state">Paket Durumunu Değiştir</string>
|
<string name="change_package_state">Paket Durumunu Değiştir</string>
|
||||||
<string name="grant_permissions">İzinleri Ver</string>
|
<string name="grant_permissions">İzinleri Ver</string>
|
||||||
<string name="add_delegated_admin">Yetkilendirilmiş Yönetici Ekle</string>
|
<string name="add_delegated_admin">Yetkilendirilmiş Yönetici Ekle</string>
|
||||||
<string name="reset_device_policy">Cihaz Politikasını Sıfırla</string>
|
|
||||||
<string name="device_info">Cihaz Bilgisi</string>
|
<string name="device_info">Cihaz Bilgisi</string>
|
||||||
<string name="support_device_id_attestation">Cihaz Kimliği Doğrulamasını Destekler</string>
|
<string name="support_device_id_attestation">Cihaz Kimliği Doğrulamasını Destekler</string>
|
||||||
<string name="support_unique_device_attestation">Benzersiz Cihaz Doğrulamasını Destekler</string>
|
<string name="support_unique_device_attestation">Benzersiz Cihaz Doğrulamasını Destekler</string>
|
||||||
@@ -244,7 +243,6 @@
|
|||||||
<string name="wifi_security_open">Açık</string>
|
<string name="wifi_security_open">Açık</string>
|
||||||
<string name="lockdown_admin_configured_network">Yönetici Tarafından Yapılandırılan Ağı Kilitle</string>
|
<string name="lockdown_admin_configured_network">Yönetici Tarafından Yapılandırılan Ağı Kilitle</string>
|
||||||
<string name="wifi_ssid_policy">Wi-Fi SSID Politikası</string>
|
<string name="wifi_ssid_policy">Wi-Fi SSID Politikası</string>
|
||||||
<string name="ssid_list_is">SSID Listesi:</string>
|
|
||||||
<string name="already_exist">Zaten Mevcut</string>
|
<string name="already_exist">Zaten Mevcut</string>
|
||||||
<string name="network_stats">Ağ İstatistikleri</string>
|
<string name="network_stats">Ağ İstatistikleri</string>
|
||||||
<string name="type">Tür</string>
|
<string name="type">Tür</string>
|
||||||
|
|||||||
@@ -82,7 +82,6 @@
|
|||||||
<string name="change_package_state">修改软件包状态</string>
|
<string name="change_package_state">修改软件包状态</string>
|
||||||
<string name="grant_permissions">授予权限</string>
|
<string name="grant_permissions">授予权限</string>
|
||||||
<string name="add_delegated_admin">添加委托管理员</string>
|
<string name="add_delegated_admin">添加委托管理员</string>
|
||||||
<string name="reset_device_policy">重置设备策略</string>
|
|
||||||
<string name="device_info">设备信息</string>
|
<string name="device_info">设备信息</string>
|
||||||
<string name="support_device_id_attestation">支持设备ID认证</string>
|
<string name="support_device_id_attestation">支持设备ID认证</string>
|
||||||
<string name="support_unique_device_attestation">支持唯一设备认证</string>
|
<string name="support_unique_device_attestation">支持唯一设备认证</string>
|
||||||
@@ -241,7 +240,6 @@
|
|||||||
<string name="wifi_security_open">开放</string>
|
<string name="wifi_security_open">开放</string>
|
||||||
<string name="lockdown_admin_configured_network">锁定由管理员配置的网络</string>
|
<string name="lockdown_admin_configured_network">锁定由管理员配置的网络</string>
|
||||||
<string name="wifi_ssid_policy">Wi-Fi SSID策略</string>
|
<string name="wifi_ssid_policy">Wi-Fi SSID策略</string>
|
||||||
<string name="ssid_list_is">SSID列表:</string>
|
|
||||||
<string name="already_exist">已经存在</string>
|
<string name="already_exist">已经存在</string>
|
||||||
<string name="network_stats">网络统计</string>
|
<string name="network_stats">网络统计</string>
|
||||||
<string name="type">类型</string>
|
<string name="type">类型</string>
|
||||||
|
|||||||
@@ -87,7 +87,6 @@
|
|||||||
<string name="change_package_state">Change package state</string>
|
<string name="change_package_state">Change package state</string>
|
||||||
<string name="grant_permissions">Grant permissions</string>
|
<string name="grant_permissions">Grant permissions</string>
|
||||||
<string name="add_delegated_admin">Add delegated admin</string>
|
<string name="add_delegated_admin">Add delegated admin</string>
|
||||||
<string name="reset_device_policy">Reset device policy</string>
|
|
||||||
<string name="device_info">Device info</string>
|
<string name="device_info">Device info</string>
|
||||||
<string name="support_device_id_attestation">Support Device ID attestation</string>
|
<string name="support_device_id_attestation">Support Device ID attestation</string>
|
||||||
<string name="support_unique_device_attestation">Support unique device attestation</string>
|
<string name="support_unique_device_attestation">Support unique device attestation</string>
|
||||||
@@ -270,7 +269,6 @@
|
|||||||
<string name="wifi_security_open">Open</string>
|
<string name="wifi_security_open">Open</string>
|
||||||
<string name="lockdown_admin_configured_network">Lockdown admin configured network</string>
|
<string name="lockdown_admin_configured_network">Lockdown admin configured network</string>
|
||||||
<string name="wifi_ssid_policy">Wi-Fi SSID policy</string>
|
<string name="wifi_ssid_policy">Wi-Fi SSID policy</string>
|
||||||
<string name="ssid_list_is">SSID list:</string>
|
|
||||||
<string name="already_exist">Already exist</string>
|
<string name="already_exist">Already exist</string>
|
||||||
<string name="network_stats">Network stats</string>
|
<string name="network_stats">Network stats</string>
|
||||||
<string name="type">Type</string>
|
<string name="type">Type</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user