Set organization name and organization id in dialog

ManageSpaceActivity: use dialog
This commit is contained in:
BinTianqi
2024-10-26 09:10:42 +08:00
parent 951231abe3
commit 3a19b1acf9
7 changed files with 106 additions and 165 deletions

View File

@@ -50,7 +50,7 @@
<activity <activity
android:name=".ManageSpaceActivity" android:name=".ManageSpaceActivity"
android:windowSoftInputMode="adjustResize|stateHidden" android:windowSoftInputMode="adjustResize|stateHidden"
android:theme="@style/Theme.OwnDroid"> android:theme="@style/Theme.Transparent">
</activity> </activity>
<activity <activity
android:name=".AutomationActivity" android:name=".AutomationActivity"

View File

@@ -1,83 +1,54 @@
package com.bintianqi.owndroid package com.bintianqi.owndroid
import android.content.Context
import android.os.Bundle import android.os.Bundle
import android.widget.Toast
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge import androidx.activity.enableEdgeToEdge
import androidx.compose.foundation.background import androidx.compose.material3.AlertDialog
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.material3.TextButton
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.core.view.WindowCompat import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentActivity import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
class ManageSpaceActivity: FragmentActivity() { class ManageSpaceActivity: FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge() enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false) WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE) val sharedPref = applicationContext.getSharedPreferences("data", MODE_PRIVATE)
val materialYou = sharedPref.getBoolean("material_you", true) val materialYou = sharedPref.getBoolean("material_you", true)
val blackTheme = sharedPref.getBoolean("black_theme", false) val blackTheme = sharedPref.getBoolean("black_theme", false)
val protected = sharedPref.getBoolean("protect_storage", false)
setContent { setContent {
OwnDroidTheme(materialYou, blackTheme) { OwnDroidTheme(materialYou, blackTheme) {
ManageSpace() AlertDialog(
} title = {
} Text(stringResource(R.string.clear_storage))
} },
text = {
@Composable if(protected) Text(stringResource(R.string.storage_is_protected))
fun ManageSpace() { },
Column( onDismissRequest = { finish() },
verticalArrangement = Arrangement.Center, dismissButton = {
horizontalAlignment = Alignment.CenterHorizontally, if(!protected) TextButton(onClick = { finish() }) {
modifier = Modifier.fillMaxSize().background(MaterialTheme.colorScheme.background) Text(stringResource(R.string.cancel))
) { }
val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE) },
val protected = sharedPref.getBoolean("protect_storage", false) confirmButton = {
if(protected){ TextButton(
Text( onClick = {
text = stringResource(R.string.storage_is_protected), if(!protected) {
color = MaterialTheme.colorScheme.onBackground, applicationContext.filesDir.deleteRecursively()
style = MaterialTheme.typography.titleMedium sharedPref.edit().clear().apply()
) }
Text( finish()
text = stringResource(R.string.you_cant_clear_storage), }
color = MaterialTheme.colorScheme.onBackground ) {
) Text(stringResource(if(protected) R.string.cancel else R.string.confirm))
} }
Button(
onClick = {
lifecycleScope.launch {
sharedPref.edit().clear().apply()
delay(2000)
finishAndRemoveTask()
} }
Toast.makeText(applicationContext, R.string.clear_storage_success, Toast.LENGTH_SHORT).show() )
},
enabled = !protected,
colors = ButtonDefaults.buttonColors(
contentColor = MaterialTheme.colorScheme.onError,
containerColor = MaterialTheme.colorScheme.error
),
modifier = Modifier.padding(top = 10.dp)
) {
Text(text = stringResource(R.string.clear_storage))
} }
} }
} }

View File

@@ -214,6 +214,7 @@ private fun Home(navCtrl:NavHostController, scrollState: ScrollState) {
onValueChange = { input = it }, onValueChange = { input = it },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done), keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }), keyboardActions = KeyboardActions(onDone = { focusMgr.clearFocus() }),
textStyle = typography.bodyLarge,
modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp) modifier = Modifier.fillMaxWidth().padding(bottom = 5.dp)
) )
when(dialog) { when(dialog) {

View File

@@ -75,8 +75,6 @@ fun DpmPermissions(navCtrl:NavHostController) {
composable(route = "ProfileOwner") { ProfileOwner() } composable(route = "ProfileOwner") { ProfileOwner() }
composable(route = "DeviceOwner") { DeviceOwner() } composable(route = "DeviceOwner") { DeviceOwner() }
composable(route = "DeviceInfo") { DeviceInfo() } composable(route = "DeviceInfo") { DeviceInfo() }
composable(route = "OrgID") { OrgID() }
composable(route = "OrgName") { OrgName() }
composable(route = "DisableAccountManagement") { DisableAccountManagement() } composable(route = "DisableAccountManagement") { DisableAccountManagement() }
composable(route = "LockScreenInfo") { LockScreenInfo() } composable(route = "LockScreenInfo") { LockScreenInfo() }
composable(route = "SupportMsg") { SupportMsg() } composable(route = "SupportMsg") { SupportMsg() }
@@ -95,7 +93,7 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
val deviceAdmin = context.isDeviceAdmin val deviceAdmin = context.isDeviceAdmin
val deviceOwner = context.isDeviceOwner val deviceOwner = context.isDeviceOwner
val profileOwner = context.isProfileOwner val profileOwner = context.isProfileOwner
var enrollmentIdDialog by remember { mutableStateOf(false) } var dialog by remember { mutableIntStateOf(0) }
val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) dpm.enrollmentSpecificId else "" val enrollmentSpecificId = if(VERSION.SDK_INT >= 31 && (deviceOwner || profileOwner)) dpm.enrollmentSpecificId else ""
Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) { Column(modifier = Modifier.fillMaxSize().verticalScroll(listScrollState)) {
Text( Text(
@@ -131,13 +129,13 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
SubPageItem(R.string.shizuku,"") { localNavCtrl.navigate("Shizuku") } SubPageItem(R.string.shizuku,"") { localNavCtrl.navigate("Shizuku") }
SubPageItem(R.string.device_info, "", R.drawable.perm_device_information_fill0) { localNavCtrl.navigate("DeviceInfo") } SubPageItem(R.string.device_info, "", R.drawable.perm_device_information_fill0) { localNavCtrl.navigate("DeviceInfo") }
if((VERSION.SDK_INT >= 26 && deviceOwner) || (VERSION.SDK_INT>=24 && profileOwner)) { if((VERSION.SDK_INT >= 26 && deviceOwner) || (VERSION.SDK_INT>=24 && profileOwner)) {
SubPageItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgName") } SubPageItem(R.string.org_name, "", R.drawable.corporate_fare_fill0) { dialog = 2 }
} }
if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) { if(VERSION.SDK_INT >= 31 && (profileOwner || deviceOwner)) {
SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { localNavCtrl.navigate("OrgID") } SubPageItem(R.string.org_id, "", R.drawable.corporate_fare_fill0) { dialog = 3 }
} }
if(enrollmentSpecificId != "") { if(enrollmentSpecificId != "") {
SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { enrollmentIdDialog = true } SubPageItem(R.string.enrollment_specific_id, "", R.drawable.id_card_fill0) { dialog = 1 }
} }
if(deviceOwner || profileOwner) { if(deviceOwner || profileOwner) {
SubPageItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { localNavCtrl.navigate("DisableAccountManagement") } SubPageItem(R.string.disable_account_management, "", R.drawable.account_circle_fill0) { localNavCtrl.navigate("DisableAccountManagement") }
@@ -153,27 +151,76 @@ private fun Home(localNavCtrl:NavHostController,listScrollState:ScrollState) {
} }
Spacer(Modifier.padding(vertical = 30.dp)) Spacer(Modifier.padding(vertical = 30.dp))
} }
if(enrollmentIdDialog) AlertDialog( if(dialog != 0) {
title = { Text(stringResource(R.string.enrollment_specific_id)) }, var input by remember { mutableStateOf("") }
text = { AlertDialog(
val esid = dpm.enrollmentSpecificId title = {
OutlinedTextField( Text(stringResource(
value = esid, when(dialog){
onValueChange = {}, readOnly = true, modifier = Modifier.fillMaxWidth(), 1 -> R.string.enrollment_specific_id
trailingIcon = { 2 -> R.string.org_name
IconButton(onClick = { writeClipBoard(context, esid) }) { 3 -> R.string.org_id
Icon(painter = painterResource(R.drawable.content_copy_fill0), contentDescription = stringResource(R.string.copy)) else -> R.string.permission
} }
))
},
text = {
val focusMgr = LocalFocusManager.current
LaunchedEffect(Unit) {
if(dialog == 1) input = dpm.enrollmentSpecificId
}
OutlinedTextField(
value = input,
onValueChange = { input = it }, readOnly = dialog == 1, modifier = Modifier.fillMaxWidth(),
label = {
Text(stringResource(
when(dialog){
1 -> R.string.enrollment_specific_id
2 -> R.string.org_name
3 -> R.string.org_id
else -> R.string.permission
}
))
},
trailingIcon = {
if(dialog == 1) IconButton(onClick = { writeClipBoard(context, input) }) {
Icon(painter = painterResource(R.drawable.content_copy_fill0), contentDescription = stringResource(R.string.copy))
}
},
supportingText = {
if(dialog == 3) Text(stringResource(R.string.length_6_to_64))
},
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions { focusMgr.clearFocus() },
textStyle = typography.bodyLarge
)
},
onDismissRequest = { dialog = 0 },
dismissButton = {
TextButton(
onClick = { dialog = 0 }
) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
try {
if(dialog == 2) dpm.setOrganizationName(receiver, input)
if(dialog == 3) dpm.setOrganizationId(input)
dialog = 0
} catch(_: IllegalStateException) {
Toast.makeText(context, R.string.failed, Toast.LENGTH_SHORT).show()
}
},
enabled = (dialog == 3 && input.length in 6..64) || dialog != 3
) {
Text(stringResource(R.string.confirm))
} }
)
},
onDismissRequest = { enrollmentIdDialog = false },
confirmButton = {
TextButton(onClick = { enrollmentIdDialog = false }) {
Text(stringResource(R.string.confirm))
} }
} )
) }
} }
private fun toggleDhizukuMode(status: Boolean, context: Context) { private fun toggleDhizukuMode(status: Boolean, context: Context) {
@@ -481,78 +528,6 @@ fun DeviceInfo() {
} }
} }
@SuppressLint("NewApi")
@Composable
private fun OrgID() {
val context = LocalContext.current
val dpm = context.getDPM()
val focusMgr = LocalFocusManager.current
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())) {
var orgId by remember { mutableStateOf("") }
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.org_id), style = typography.headlineLarge)
Spacer(Modifier.padding(vertical = 5.dp))
OutlinedTextField(
value = orgId, onValueChange = { orgId=it },
label = { Text(stringResource(R.string.org_id)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Ascii, imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() }),
modifier = Modifier.fillMaxWidth()
)
Spacer(Modifier.padding(vertical = 2.dp))
AnimatedVisibility(orgId.length !in 6..64) {
Text(text = stringResource(R.string.length_6_to_64))
}
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
try {
dpm.setOrganizationId(orgId)
Toast.makeText(context, R.string.success,Toast.LENGTH_SHORT).show()
} catch(e: IllegalStateException) {
Toast.makeText(context, R.string.failed,Toast.LENGTH_SHORT).show()
}
},
enabled = orgId.length in 6..64,
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.apply))
}
}
}
@SuppressLint("NewApi")
@Composable
private fun OrgName() {
val context = LocalContext.current
val dpm = context.getDPM()
val receiver = context.getReceiver()
val focusMgr = LocalFocusManager.current
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState()).padding(horizontal = 8.dp)) {
var orgName by remember { mutableStateOf(try{dpm.getOrganizationName(receiver).toString() }catch(e:SecurityException) {""}) }
Spacer(Modifier.padding(vertical = 10.dp))
Text(text = stringResource(R.string.org_name), style = typography.headlineLarge)
Spacer(Modifier.padding(vertical = 5.dp))
OutlinedTextField(
value = orgName, onValueChange = { orgName = it }, modifier = Modifier.fillMaxWidth().padding(vertical = 3.dp),
label = { Text(stringResource(R.string.org_name)) },
keyboardOptions = KeyboardOptions(imeAction = ImeAction.Done),
keyboardActions = KeyboardActions(onDone = {focusMgr.clearFocus() })
)
Spacer(Modifier.padding(vertical = 5.dp))
Button(
onClick = {
focusMgr.clearFocus()
dpm.setOrganizationName(receiver,orgName)
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
},
modifier = Modifier.fillMaxWidth()
) {
Text(stringResource(R.string.apply))
}
}
}
@SuppressLint("NewApi") @SuppressLint("NewApi")
@Composable @Composable
private fun SupportMsg() { private fun SupportMsg() {

View File

@@ -554,10 +554,8 @@
<string name="auth_with_bio">OwnDroid\'u biyometri ile doğrula</string> <string name="auth_with_bio">OwnDroid\'u biyometri ile doğrula</string>
<string name="lock_in_background">Arka plana geçince kilitle</string> <string name="lock_in_background">Arka plana geçince kilitle</string>
<string name="protect_storage">Depolamayı koru</string> <string name="protect_storage">Depolamayı koru</string>
<string name="storage_is_protected">Depolama korunuyor</string> <string name="storage_is_protected">Depolama korunuyor</string> <!--TODO-->
<string name="you_cant_clear_storage">OwnDroid\'un depolamasını temizleyemezsiniz</string>
<string name="clear_storage">Depolamayı temizle</string> <string name="clear_storage">Depolamayı temizle</string>
<string name="clear_storage_success">Depolama başarıyla temizlendi\nUygulama kapanacak</string>
<string name="automation_api">Automation API</string> <!--TODO--> <string name="automation_api">Automation API</string> <!--TODO-->
<string name="automation_debug">Debug mode</string> <!--TODO--> <string name="automation_debug">Debug mode</string> <!--TODO-->

View File

@@ -546,10 +546,8 @@
<string name="auth_with_bio">使用生物识别进行验证</string> <string name="auth_with_bio">使用生物识别进行验证</string>
<string name="lock_in_background">处于后台时锁定</string> <string name="lock_in_background">处于后台时锁定</string>
<string name="protect_storage">保护存储空间</string> <string name="protect_storage">保护存储空间</string>
<string name="storage_is_protected">存储空间受到保护</string> <string name="storage_is_protected">存储空间受到保护你不能清除OwnDroid的存储空间</string>
<string name="you_cant_clear_storage">你不能清除OwnDroid的存储空间</string>
<string name="clear_storage">清除存储空间</string> <string name="clear_storage">清除存储空间</string>
<string name="clear_storage_success">清除存储空间成功\n应用即将退出</string>
<string name="automation_api">自动化API</string> <string name="automation_api">自动化API</string>
<string name="automation_debug">调试模式</string> <string name="automation_debug">调试模式</string>

View File

@@ -559,10 +559,8 @@
<string name="auth_with_bio">Authenticate OwnDroid with biometrics</string> <string name="auth_with_bio">Authenticate OwnDroid with biometrics</string>
<string name="lock_in_background">Lock when switch to background</string> <string name="lock_in_background">Lock when switch to background</string>
<string name="protect_storage">Protect storage</string> <string name="protect_storage">Protect storage</string>
<string name="storage_is_protected">Storage is protected</string> <string name="storage_is_protected">Storage is protected, you can\'t clear storage of OwnDroid</string>
<string name="you_cant_clear_storage">You can\'t clear storage of OwnDroid</string>
<string name="clear_storage">Clear storage</string> <string name="clear_storage">Clear storage</string>
<string name="clear_storage_success">Clear storage success\nApplication will exit</string>
<string name="automation_api">Automation API</string> <string name="automation_api">Automation API</string>
<string name="automation_debug">Debug mode</string> <string name="automation_debug">Debug mode</string>