copy code to activate privilege

This commit is contained in:
BinTianqi
2024-03-24 17:48:28 +08:00
parent 75e9e199ba
commit f0abc00076
11 changed files with 99 additions and 15 deletions

View File

@@ -23,7 +23,6 @@ android {
buildTypes {
release {
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"

View File

@@ -83,6 +83,7 @@ fun MyScaffold(){
val myComponent = ComponentName(myContext,MyDeviceAdminReceiver::class.java)
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val focusMgr = LocalFocusManager.current
SetDarkTheme()
NavHost(
navController = navCtrl,
startDestination = "HomePage",
@@ -129,7 +130,6 @@ private fun HomePage(navCtrl:NavHostController){
stringResource(if(VERSION.SDK_INT>=24&&myDpm.isManagedProfile(myComponent)){R.string.work_profile_owner}else{R.string.profile_owner})
}
else if(myDpm.isAdminActive(myComponent)){"Device Admin"}else{""}
SetDarkTheme()
Column(modifier = Modifier.statusBarsPadding().verticalScroll(rememberScrollState())) {
Spacer(Modifier.padding(vertical = 25.dp))
Text(text = stringResource(R.string.app_name), style = typography.headlineLarge, modifier = Modifier.padding(start = 10.dp), color = colorScheme.onBackground)

View File

@@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme.colorScheme
import androidx.compose.material3.MaterialTheme.typography
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Text
@@ -16,6 +17,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -78,10 +80,12 @@ private fun Settings(){
R.string.dynamic_color, stringResource(R.string.dynamic_color_desc),null,
{sharedPref.getBoolean("dynamicColor",false)},{sharedPref.edit().putBoolean("dynamicColor",it).apply()}
)
if(colorScheme.background!=Color(0xFF000000)){
SwitchItem(
R.string.blackTheme, stringResource(R.string.blackTheme_desc),null,
{sharedPref.getBoolean("blackTheme",false)},{sharedPref.edit().putBoolean("blackTheme",it).apply()}
)
}
Box(modifier = Modifier.padding(10.dp)){
Information {
Text(text = stringResource(R.string.need_relaunch))

View File

@@ -1,8 +1,13 @@
package com.binbin.androidowner
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build.VERSION
import android.widget.Toast
import androidx.core.content.ContextCompat.startActivity
import java.io.FileNotFoundException
import java.io.IOException
import java.io.InputStream
@@ -44,3 +49,21 @@ fun Set<Any>.toText():String{
}
return output
}
fun writeClipBoard(context: Context, string: String):Boolean{
val clipboardManager = context.getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
try {
if(VERSION.SDK_INT>=23){
val hasPermission: Boolean = clipboardManager.hasPrimaryClip()
if(!hasPermission) {
val intent = Intent(android.provider.Settings.ACTION_MANAGE_WRITE_SETTINGS)
intent.setData(Uri.parse("package:"+context.packageName))
startActivity(context,intent,null)
}
}
clipboardManager.setPrimaryClip(ClipData.newPlainText("", string))
}catch(e:Exception){
return false
}
return true
}

View File

@@ -84,19 +84,19 @@ private fun Home(navCtrl: NavHostController){
Column(modifier = Modifier.fillMaxSize().verticalScroll(rememberScrollState())){
Text(text = stringResource(R.string.work_profile), style = typography.headlineLarge, modifier = Modifier.padding(top = 8.dp, bottom = 5.dp, start = 15.dp))
if(VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){
SubPageItem(R.string.org_owned_work_profile,""){navCtrl.navigate("OrgOwnedWorkProfile")}
SubPageItem(R.string.org_owned_work_profile,"",R.drawable.corporate_fare_fill0){navCtrl.navigate("OrgOwnedWorkProfile")}
}
if(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isProvisioningAllowed(ACTION_PROVISION_MANAGED_PROFILE))){
SubPageItem(R.string.create_work_profile,""){navCtrl.navigate("CreateWorkProfile")}
SubPageItem(R.string.create_work_profile,"",R.drawable.work_fill0){navCtrl.navigate("CreateWorkProfile")}
}
if(VERSION.SDK_INT>=30&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)&&myDpm.isOrganizationOwnedDeviceWithManagedProfile){
SubPageItem(R.string.suspend_personal_app,""){navCtrl.navigate("SuspendPersonalApp")}
SubPageItem(R.string.suspend_personal_app,"",R.drawable.block_fill0){navCtrl.navigate("SuspendPersonalApp")}
}
if(isProfileOwner(myDpm)&&(VERSION.SDK_INT<24||(VERSION.SDK_INT>=24&&myDpm.isManagedProfile(myComponent)))){
SubPageItem(R.string.intent_filter,""){navCtrl.navigate("IntentFilter")}
SubPageItem(R.string.intent_filter,"",R.drawable.filter_alt_fill0){navCtrl.navigate("IntentFilter")}
}
if(VERSION.SDK_INT>=31&&(isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent))){
SubPageItem(R.string.org_id,""){navCtrl.navigate("OrgID")}
SubPageItem(R.string.org_id,"",R.drawable.corporate_fare_fill0){navCtrl.navigate("OrgID")}
}
Spacer(Modifier.padding(vertical = 30.dp))
}
@@ -154,6 +154,7 @@ private fun OrgOwnedProfile(){
color = colorScheme.onTertiaryContainer
)
}
CopyTextButton(myContext, R.string.copy_code, stringResource(R.string.activate_org_profile_command, Binder.getCallingUid()/100000))
}
}
}

View File

@@ -36,10 +36,7 @@ import androidx.navigation.compose.composable
import androidx.navigation.compose.currentBackStackEntryAsState
import androidx.navigation.compose.rememberNavController
import com.binbin.androidowner.R
import com.binbin.androidowner.ui.Animations
import com.binbin.androidowner.ui.Information
import com.binbin.androidowner.ui.SubPageItem
import com.binbin.androidowner.ui.TopBar
import com.binbin.androidowner.ui.*
import com.binbin.androidowner.ui.theme.bgColor
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@@ -219,6 +216,7 @@ private fun DeviceAdmin(navCtrl: NavHostController){
SelectionContainer {
Text(text = stringResource(R.string.activate_device_admin_command))
}
CopyTextButton(myContext, R.string.copy_code, stringResource(R.string.activate_device_admin_command))
}
}
}
@@ -242,6 +240,7 @@ private fun ProfileOwner(){
SelectionContainer{
Text(text = stringResource(R.string.activate_profile_owner_command))
}
CopyTextButton(myContext, R.string.copy_code, stringResource(R.string.activate_profile_owner_command))
}
}
}
@@ -271,6 +270,7 @@ private fun DeviceOwner(navCtrl: NavHostController){
SelectionContainer{
Text(text = stringResource(R.string.activate_device_owner_command))
}
CopyTextButton(myContext, R.string.copy_code, stringResource(R.string.activate_device_owner_command))
}
}
}

View File

@@ -1,8 +1,10 @@
package com.binbin.androidowner.ui
import android.content.Context
import android.widget.Toast
import androidx.annotation.DrawableRes
import androidx.annotation.StringRes
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
@@ -22,6 +24,9 @@ import androidx.navigation.NavBackStackEntry
import androidx.navigation.NavHostController
import com.binbin.androidowner.R
import com.binbin.androidowner.ui.theme.bgColor
import com.binbin.androidowner.writeClipBoard
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
@Composable
fun SubPageItem(
@@ -161,3 +166,27 @@ fun TopBar(
colors = TopAppBarDefaults.topAppBarColors(containerColor = bgColor)
)
}
@Composable
fun CopyTextButton(context: Context, @StringRes label: Int, content: String){
var ok by remember{mutableStateOf(false)}
val scope = rememberCoroutineScope()
Button(
onClick = {
if(!ok){
scope.launch{
if(writeClipBoard(context,content)){ ok = true; delay(2000); ok = false }
else{ Toast.makeText(context,context.getString(R.string.fail),Toast.LENGTH_SHORT).show() }
}
}
}
){
Row(
verticalAlignment = Alignment.CenterVertically, modifier = Modifier.animateContentSize()
){
Icon(painter = painterResource(if(ok){R.drawable.check_fill0}else{R.drawable.content_copy_fill0}),contentDescription = null)
Spacer(modifier = Modifier.padding(horizontal = 2.dp))
Text(text = stringResource(if(ok){R.string.success}else{label}))
}
}
}

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M382,720 L154,492l57,-57 171,171 367,-367 57,57 -424,424Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M360,720q-33,0 -56.5,-23.5T280,640v-480q0,-33 23.5,-56.5T360,80h360q33,0 56.5,23.5T800,160v480q0,33 -23.5,56.5T720,720L360,720ZM360,640h360v-480L360,160v480ZM200,880q-33,0 -56.5,-23.5T120,800v-560h80v560h440v80L200,880ZM360,640v-480,480Z"/>
</vector>

View File

@@ -0,0 +1,9 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="960"
android:viewportHeight="960">
<path
android:fillColor="#FF000000"
android:pathData="M440,800q-17,0 -28.5,-11.5T400,760v-240L168,224q-15,-20 -4.5,-42t36.5,-22h560q26,0 36.5,22t-4.5,42L560,520v240q0,17 -11.5,28.5T520,800h-80ZM480,492 L678,240L282,240l198,252ZM480,492Z"/>
</vector>

View File

@@ -41,6 +41,7 @@
<string name="try_again">请再试一次</string>
<string name="unknown_effect">效果未知</string>
<string name="options">选项</string>
<string name="copy_code">复制代码</string>
<!--Permissions-->
<string name="device_admin">Device admin</string>