Ca cert manage, update readme.md

This commit is contained in:
BinTianqi
2024-02-06 18:29:43 +08:00
parent 5677deda4f
commit d91d638b3a
3 changed files with 110 additions and 24 deletions

View File

@@ -4,7 +4,9 @@ import android.app.admin.DevicePolicyManager
import android.app.admin.DevicePolicyManager.*
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION
import android.util.Log
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.compose.animation.AnimatedVisibility
@@ -29,6 +31,8 @@ import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun DeviceControl(){
@@ -144,13 +148,6 @@ fun DeviceControl(){
}
}
}
if(isDeviceOwner(myDpm)||isProfileOwner(myDpm)){
Button(
onClick = {myDpm.uninstallAllUserCaCerts(myComponent);Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()},
modifier = Modifier.align(Alignment.CenterHorizontally)
) {
Text(text = "清除用户Ca证书")
}}
if(VERSION.SDK_INT>=28){
Column(modifier = sections()){
@@ -368,6 +365,64 @@ fun DeviceControl(){
}
}
if(isDeviceOwner(myDpm)||isProfileOwner(myDpm)){
var exist by remember{mutableStateOf(false)}
var isEmpty by remember{mutableStateOf(false)}
val refresh = {
isEmpty = caCert.isEmpty()
exist = if(!isEmpty){ myDpm.hasCaCertInstalled(myComponent, caCert) }else{ false }
}
LaunchedEffect(exist){ launch{isCaCertSelected(600){refresh()}} }
Column(modifier = sections()){
Text(text = "Ca证书", style = typography.titleLarge)
if(isEmpty){ Text(text = "请选择Ca证书(.0)") }else{ Text(text = "证书已安装:$exist") }
Button(
onClick = {
val caCertIntent = Intent(Intent.ACTION_GET_CONTENT)
caCertIntent.setType("*/*")
caCertIntent.addCategory(Intent.CATEGORY_OPENABLE)
getCaCert.launch(caCertIntent)
},
modifier = Modifier.fillMaxWidth()
) {
Text("选择证书...")
}
Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){
Button(
onClick = {
val result = myDpm.installCaCert(myComponent, caCert)
Toast.makeText(myContext, if(result){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show()
refresh()
},
modifier = Modifier.fillMaxWidth(0.49F)
) {
Text("安装")
}
Button(
onClick = {
if(exist){
myDpm.uninstallCaCert(myComponent, caCert)
exist = myDpm.hasCaCertInstalled(myComponent, caCert)
Toast.makeText(myContext, if(exist){"失败"}else{"成功"}, Toast.LENGTH_SHORT).show()
}else{ Toast.makeText(myContext, "不存在", Toast.LENGTH_SHORT).show() }
},
modifier = Modifier.fillMaxWidth(0.96F)
) {
Text("卸载")
}
}
Button(
onClick = {
myDpm.uninstallAllUserCaCerts(myComponent)
Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show()
},
modifier = Modifier.fillMaxWidth()
){
Text("清除用户Ca证书")
}
}
}
if(isDeviceOwner(myDpm)){
SysUpdatePolicy()
}
@@ -470,3 +525,10 @@ fun DeviceCtrlItem(
)
}
}
suspend fun isCaCertSelected(delay:Long,operation:()->Unit){
while(true){
delay(delay)
operation()
}
}

View File

@@ -4,11 +4,14 @@ import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
import android.content.Intent
import android.os.Build.VERSION
import android.os.Bundle
import android.widget.Toast
import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.compose.animation.*
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.foundation.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -17,7 +20,8 @@ import androidx.compose.material.icons.outlined.ArrowBack
import androidx.compose.material.icons.outlined.Home
import androidx.compose.material3.*
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
@@ -35,22 +39,32 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.binbin.androidowner.ui.theme.AndroidOwnerTheme
import java.io.FileNotFoundException
import java.io.IOException
/*lateinit var getOtaPackage: ActivityResultLauncher<Intent>
var installOta = false
lateinit var otaUri:Uri*/
lateinit var getCaCert: ActivityResultLauncher<Intent>
var caCert = byteArrayOf()
@ExperimentalMaterial3Api
class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
WindowCompat.setDecorFitsSystemWindows(window, false)
super.onCreate(savedInstanceState)
/*otaUri = Uri.EMPTY
getOtaPackage = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
val data = it.data?.data
installOta = true
otaUri = data ?: Uri.EMPTY
}*/
getCaCert = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
val uri = it.data?.data
if(uri!=null){
try{
val stream = contentResolver.openInputStream(uri)
if(stream!=null) {
caCert = stream.readBytes()
if(caCert.size>50000){ Toast.makeText(applicationContext, "太大了", Toast.LENGTH_SHORT).show(); caCert = byteArrayOf() }
}else{ Toast.makeText(applicationContext, "空的流", Toast.LENGTH_SHORT).show() }
stream?.close()
}
catch(e:FileNotFoundException){ Toast.makeText(applicationContext, "文件不存在", Toast.LENGTH_SHORT).show() }
catch(e:IOException){ Toast.makeText(applicationContext, "IO异常", Toast.LENGTH_SHORT).show() }
}else{ Toast.makeText(applicationContext, "空URI", Toast.LENGTH_SHORT).show() }
}
setContent {
AndroidOwnerTheme {
MyScaffold()
@@ -148,6 +162,7 @@ fun HomePage(navCtrl:NavHostController){
val activateType = if(isDeviceOwner(myDpm)){"Device Owner"}else if(isProfileOwner(myDpm)){"Profile Owner"}else if(myDpm.isAdminActive(myComponent)){"Device Admin"}else{""}
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val isWear = sharedPref.getBoolean("isWear",false)
caCert = byteArrayOf()
Column(modifier = Modifier.verticalScroll(rememberScrollState()), horizontalAlignment = Alignment.CenterHorizontally) {
if(isWear){ Spacer(Modifier.padding(vertical = 3.dp)) }
Row(
@@ -273,7 +288,7 @@ fun isProfileOwner(dpm:DevicePolicyManager): Boolean {
return dpm.isProfileOwnerApp("com.binbin.androidowner")
}
@SuppressLint("ModifierFactoryExtensionFunction")
@SuppressLint("ModifierFactoryExtensionFunction", "ComposableModifierFactory")
@Composable
fun sections(bgColor:Color=MaterialTheme.colorScheme.primaryContainer):Modifier{
val backgroundColor = if(isSystemInDarkTheme()){bgColor.copy(0.4F)}else{bgColor.copy(0.6F)}