From 9042fa24727d8fd6bb1f374ed6eb815b24296110 Mon Sep 17 00:00:00 2001 From: BinTianqi <1220958406@qq.com> Date: Tue, 13 Feb 2024 18:03:59 +0800 Subject: [PATCH] set keepUninstalledPkgs and userIcon --- Guide.md | 36 ++++- Readme.md | 11 +- app/build.gradle.kts | 4 +- .../binbin/androidowner/ApplicationManage.kt | 148 +++++++++++++----- .../com/binbin/androidowner/DeviceControl.kt | 23 ++- .../com/binbin/androidowner/MainActivity.kt | 14 +- .../java/com/binbin/androidowner/Password.kt | 3 +- .../java/com/binbin/androidowner/Receiver.kt | 4 +- .../java/com/binbin/androidowner/Setting.kt | 2 +- .../main/java/com/binbin/androidowner/User.kt | 61 ++++++-- 10 files changed, 221 insertions(+), 85 deletions(-) diff --git a/Guide.md b/Guide.md index aafe806..1a2af35 100644 --- a/Guide.md +++ b/Guide.md @@ -345,9 +345,11 @@ MTE: Memory Tagging Extension(内存标记拓展)[安卓开发者:MTE](htt 或者清除所有用户证书 -### 安全日志 +### 安全日志&&重启前安全日志 -需要的权限:Device owner +需要的权限:Device owner或由组织拥有的工作资料的Profile owner + +如果被Device owner使用,设备上不能有非附属用户,否则不会有输出 需要API24或以上 @@ -462,6 +464,10 @@ API34或以上将不能在系统用户中使用WipeData,如果要恢复出厂 需要的权限:Device owner或工作资料的Profile owner +工作资料中使用此功能只会记录工作资料的网络日志 + +如果被Device owner使用,设备上不能有非附属用户 + 需要API26或以上 功能开发中 @@ -673,7 +679,17 @@ adb shell pm list permissions 需要的权限:Device owner或Profile owner -设置许可的无障碍应用和输入法 +无障碍应用:强制启用无障碍应用 + +输入法:强制启用输入法,但是不强制用户使用输入法 + +### 保持卸载的应用 + +需要Device owner + +需要API28或以上 + +作用未知 ### 清除应用存储 @@ -878,6 +894,16 @@ Device owner无论在何时都是附属于设备的用户 需要Device owner或Profile owner +### 用户图标 + +选择一个图片并设置为当前用户的图标 + +需要Device owner或Profile owner + +需要API23或以上 + +尽量选择一个正方形的图片,分辨率不要太大,以免产生问题 + ### 用户会话开始/结束消息 用户会话开始消息:切换到非系统用户时的消息 @@ -892,13 +918,13 @@ Device owner无论在何时都是附属于设备的用户 ### 密码信息 -当前密码复杂度:参考要求密码复杂度 +当前密码复杂度:参考[密码复杂度要求](#密码复杂度要求)(需要API29或以上) 密码达到要求:当前密码复杂度是否达到了要求的密码复杂度 密码已错误次数:你能看到这个数字的时候,这个数字一定是0 -个人与工作应用密码一致:需要是工作资料的Profile owner +个人与工作应用密码一致:需要是工作资料的Profile owner,需要API28或以上 ### 密码重置令牌 diff --git a/Readme.md b/Readme.md index 25ed154..c64b3ab 100644 --- a/Readme.md +++ b/Readme.md @@ -13,9 +13,9 @@ ### 缺点 -不支持一些功能。如果追求功能齐全,谷歌官方的 [TestDPC](https://github.com/googlesamples/android-testdpc) 可能更适合你 +功能不完整。如果追求功能齐全,谷歌官方的 [TestDPC](https://github.com/googlesamples/android-testdpc) 可能更适合你 -### 功能简介 +### 功能 适配了一些预见式返回动画(需安卓13或14),可能不太稳定,如果有问题请向我反馈 @@ -27,12 +27,7 @@ - 用户管理 - 密码与锁屏 -所有功能的详细介绍请看 [用户指南](Guide.md) - -### 这个应用十分危险!!! - -在使用各个功能之前,请仔细阅读相应的说明。红色的按钮一定要谨慎使用! -如果操作不慎,可能会意外地丢失数据或者让你无法解锁你的设备! +[用户指南](Guide.md)(一定要看,应用里只有功能的简单介绍) ### 正在开发的功能 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index ffea19d..df1e40d 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -11,8 +11,8 @@ android { applicationId = "com.binbin.androidowner" minSdk = 21 targetSdk = 34 - versionCode = 14 - versionName = "3.1" + versionCode = 15 + versionName = "3.2" testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" vectorDrawables { diff --git a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt index f098f67..0f02715 100644 --- a/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt +++ b/app/src/main/java/com/binbin/androidowner/ApplicationManage.kt @@ -47,6 +47,9 @@ import java.util.concurrent.Executors private var credentialList = mutableSetOf() private var crossProfilePkg = mutableSetOf() +private var keepUninstallPkg = mutableListOf() +private var permittedIme = mutableListOf() +private var permittedAccessibility = mutableListOf() @Composable fun ApplicationManage(){ val myContext = LocalContext.current @@ -218,7 +221,6 @@ fun ApplicationManage(){ var inputPermission by remember{mutableStateOf("android.permission.")} var currentState by remember{mutableStateOf(grantState[myDpm.getPermissionGrantState(myComponent,pkgName,inputPermission)])} Text(text = "权限管理", style = typography.titleLarge) - Text(text = "查看系统支持的权限:adb shell pm list permissions", style = bodyTextStyle) OutlinedTextField( value = inputPermission, label = { Text("权限")}, @@ -258,6 +260,7 @@ fun ApplicationManage(){ Text("由用户决定") } Text(text ="设为允许或拒绝后,用户不能改变状态", style = bodyTextStyle) + if(VERSION.SDK_INT>=31){Text(text = "可以修改传感器相关权限:${myDpm.canAdminGrantSensorsPermissions()}", style = bodyTextStyle)} } } @@ -413,85 +416,140 @@ fun ApplicationManage(){ if(isProfileOwner(myDpm)||isDeviceOwner(myDpm)){ Column(modifier = sections()) { Text(text = "许可的无障碍应用", style = typography.titleLarge,color = colorScheme.onPrimaryContainer) - var list = mutableListOf("") var listText by remember{ mutableStateOf("") } val refreshList = { - list = myDpm.getPermittedAccessibilityServices(myComponent) ?: mutableListOf("") listText = "" - var count = list.size - for(eachAccessibility in list) { - count -= 1 - listText += eachAccessibility - if(count>0) { listText += "\n" } - } + var count = permittedAccessibility.size + for(eachAccessibility in permittedAccessibility){ count-=1; listText+=eachAccessibility; if(count>0){listText+="\n"} } } var inited by remember{mutableStateOf(false)} - if(!inited){refreshList(); inited=true} + if(!inited){ + val getList = myDpm.getPermittedAccessibilityServices(myComponent) + if(getList!=null){ permittedAccessibility = getList } + refreshList(); inited=true + } Text(text = if(listText!=""){listText}else{"无"}, style = bodyTextStyle) Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ Button( - onClick = { - focusMgr.clearFocus() - list.plus(pkgName) - Toast.makeText(myContext, if(myDpm.setPermittedAccessibilityServices(myComponent,list)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() - refreshList() - }, + onClick = { permittedAccessibility.add(pkgName); refreshList()}, modifier = Modifier.fillMaxWidth(0.49F) ) { Text("添加") } Button( - onClick = { - focusMgr.clearFocus() - list.remove(pkgName) - Toast.makeText(myContext, if(myDpm.setPermittedAccessibilityServices(myComponent,list)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() - refreshList() - }, + onClick = { permittedAccessibility.remove(pkgName); refreshList() }, modifier = Modifier.fillMaxWidth(0.96F) ) { Text("移除") } } + Button( + onClick = { + focusMgr.clearFocus() + Toast.makeText(myContext, if(myDpm.setPermittedAccessibilityServices(myComponent, permittedAccessibility)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() + val getList = myDpm.getPermittedAccessibilityServices(myComponent) + if(getList!=null){ permittedAccessibility = getList } + refreshList() + }, + modifier = Modifier.fillMaxWidth() + ) { + Text(text = "应用") + } } } if(isDeviceOwner(myDpm)||isProfileOwner(myDpm)){ Column(modifier = sections()) { Text(text = "许可的输入法", style = typography.titleLarge,color = colorScheme.onPrimaryContainer) - var imeList = mutableListOf() var imeListText by remember{ mutableStateOf("") } val refreshList = { - if(myDpm.getPermittedInputMethods(myComponent)!=null){ imeList = myDpm.getPermittedInputMethods(myComponent)!! } imeListText = "" - for(eachIme in imeList){ imeListText += "$eachIme \n" } + for(eachIme in permittedIme){ imeListText += "$eachIme \n" } } var inited by remember{mutableStateOf(false)} - if(!inited){refreshList();inited=true} + if(!inited){ + val getList = myDpm.getPermittedInputMethods(myComponent) + if(getList!=null){ permittedIme = getList } + refreshList();inited=true + } Text(text = if(imeListText!=""){imeListText}else{"无"}, style = bodyTextStyle) Row(modifier = Modifier.fillMaxWidth(),horizontalArrangement = Arrangement.SpaceBetween){ Button( - onClick = { - focusMgr.clearFocus() - imeList.plus(pkgName) - Toast.makeText(myContext, if(myDpm.setPermittedInputMethods(myComponent, imeList)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() - refreshList() - }, + onClick = { permittedIme.add(pkgName); refreshList() }, modifier = Modifier.fillMaxWidth(0.49F) ) { Text("添加") } Button( - onClick = { - focusMgr.clearFocus() - imeList.remove(pkgName) - Toast.makeText(myContext, if(myDpm.setPermittedInputMethods(myComponent, imeList)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() - refreshList() - }, + onClick = { permittedIme.remove(pkgName); refreshList()}, modifier = Modifier.fillMaxWidth(0.96F) ) { Text("移除") } } + Button( + onClick = { + Toast.makeText(myContext, if(myDpm.setPermittedInputMethods(myComponent, permittedIme)){"成功"}else{"失败"}, Toast.LENGTH_SHORT).show() + val getList = myDpm.getPermittedInputMethods(myComponent) + if(getList!=null){ permittedIme = getList } + refreshList() + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("应用") + } + } + } + + if(VERSION.SDK_INT>=28&&isDeviceOwner(myDpm)){ + Column(modifier = sections()){ + Text(text = "保持卸载的应用", style = typography.titleLarge) + Text(text = "作用未知", style = bodyTextStyle) + var listText by remember{mutableStateOf("")} + val refresh = { + listText = "" + var count = keepUninstallPkg.size + for(each in keepUninstallPkg){ count-=1; listText+=each; if(count>0){listText+="\n"} } + } + var inited by remember{mutableStateOf(false)} + if(!inited){ + val getList = myDpm.getKeepUninstalledPackages(myComponent) + if(getList!=null){ keepUninstallPkg = getList } + refresh(); inited=true + } + Text(text = if(listText==""){"无"}else{listText}, style = bodyTextStyle) + Row(modifier = Modifier.fillMaxWidth(), horizontalArrangement = Arrangement.SpaceBetween){ + Button( + onClick = { + keepUninstallPkg.add(pkgName) + refresh() + }, + modifier = Modifier.fillMaxWidth(0.49F) + ){ + Text("添加") + } + Button( + onClick = { + keepUninstallPkg.remove(pkgName) + refresh() + }, + modifier = Modifier.fillMaxWidth(0.96F) + ){ + Text("移除") + } + } + Button( + onClick = { + focusMgr.clearFocus() + myDpm.setKeepUninstalledPackages(myComponent, keepUninstallPkg) + val getList = myDpm.getKeepUninstalledPackages(myComponent) + if(getList!=null){ keepUninstallPkg = getList } + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + }, + modifier = Modifier.fillMaxWidth() + ){ + Text("应用") + } } } @@ -509,7 +567,7 @@ fun ApplicationManage(){ myDpm.clearApplicationUserData(myComponent,pkgName,executor,onClear) }, enabled = isDeviceOwner(myDpm)||isProfileOwner(myDpm), - modifier = Modifier.fillMaxWidth().padding(horizontal = 8.dp) + modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp) ) { Text("清除应用存储") } @@ -584,10 +642,14 @@ fun ApplicationManage(){ } Button( onClick = { - val intent = Intent(Intent.ACTION_INSTALL_PACKAGE) - intent.setData(apkUri) - intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) - myContext.startActivity(intent) + if(apkUri!=null){ + val intent = Intent(Intent.ACTION_INSTALL_PACKAGE) + intent.setData(apkUri) + intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) + myContext.startActivity(intent) + }else{ + Toast.makeText(myContext, "请先选择APK", Toast.LENGTH_SHORT).show() + } }, modifier = Modifier.fillMaxWidth(0.96F) ) { diff --git a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt index 0aee4d2..a3da0a0 100644 --- a/app/src/main/java/com/binbin/androidowner/DeviceControl.kt +++ b/app/src/main/java/com/binbin/androidowner/DeviceControl.kt @@ -485,16 +485,31 @@ fun DeviceControl(){ onClick = { val log = myDpm.retrieveSecurityLogs(myComponent) if(log!=null){ - for(i in log){ Log.d("NetLog",i.toString()) } + for(i in log){ Log.d("SecureLog",i.toString()) } Toast.makeText(myContext,"已输出至Log",Toast.LENGTH_SHORT).show() }else{ - Log.d("NetLog","无") - Toast.makeText(myContext,"无",Toast.LENGTH_SHORT).show() + Log.d("Secure5Log","无") + Toast.makeText(myContext,"无日志",Toast.LENGTH_SHORT).show() } }, modifier = Modifier.fillMaxWidth() ) { - Text("收集") + Text("安全日志") + } + Button( + onClick = { + val log = myDpm.retrievePreRebootSecurityLogs(myComponent) + if(log!=null){ + for(i in log){ Log.d("SecureLog",i.toString()) } + Toast.makeText(myContext,"已输出至Log",Toast.LENGTH_SHORT).show() + }else{ + Log.d("SecureLog","无") + Toast.makeText(myContext,"无日志",Toast.LENGTH_SHORT).show() + } + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("重启前安全日志") } } } diff --git a/app/src/main/java/com/binbin/androidowner/MainActivity.kt b/app/src/main/java/com/binbin/androidowner/MainActivity.kt index f75eb71..13363db 100644 --- a/app/src/main/java/com/binbin/androidowner/MainActivity.kt +++ b/app/src/main/java/com/binbin/androidowner/MainActivity.kt @@ -34,7 +34,6 @@ import androidx.compose.ui.res.painterResource import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.core.view.WindowCompat -import androidx.navigation.NavGraph.Companion.findStartDestination import androidx.navigation.NavHostController import androidx.navigation.compose.NavHost import androidx.navigation.compose.composable @@ -50,7 +49,9 @@ lateinit var getCaCert: ActivityResultLauncher lateinit var createUser:ActivityResultLauncher lateinit var createManagedProfile:ActivityResultLauncher lateinit var getApk:ActivityResultLauncher -lateinit var apkUri: Uri +lateinit var getUserIcon:ActivityResultLauncher +var userIconUri:Uri? = null +var apkUri: Uri? = null var caCert = byteArrayOf() @ExperimentalMaterial3Api @@ -58,10 +59,13 @@ class MainActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { WindowCompat.setDecorFitsSystemWindows(window, false) super.onCreate(savedInstanceState) + getUserIcon = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { + userIconUri = it.data?.data + if(userIconUri==null){ Toast.makeText(applicationContext, "空URI", Toast.LENGTH_SHORT).show() } + } getApk = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { - val uri = it.data?.data - if(uri!=null){ apkUri = uri } - else{ Toast.makeText(applicationContext, "空URI", Toast.LENGTH_SHORT).show() } + apkUri = it.data?.data + if(apkUri==null){ Toast.makeText(applicationContext, "空URI", Toast.LENGTH_SHORT).show() } } getCaCert = registerForActivityResult(ActivityResultContracts.StartActivityForResult()) { uriToStream(applicationContext,it.data?.data){stream-> diff --git a/app/src/main/java/com/binbin/androidowner/Password.kt b/app/src/main/java/com/binbin/androidowner/Password.kt index 77d5ac7..05c21a5 100644 --- a/app/src/main/java/com/binbin/androidowner/Password.kt +++ b/app/src/main/java/com/binbin/androidowner/Password.kt @@ -80,7 +80,7 @@ fun Password(){ } val pwdFailedAttempts = myDpm.currentFailedPasswordAttempts Text(text = "密码已错误次数:$pwdFailedAttempts",style=bodyTextStyle) - if(VERSION.SDK_INT>=28&&(myDpm.isManagedProfile(myComponent)||myDpm.isProfileOwnerApp("com.binbin.androidowner"))){ + if(VERSION.SDK_INT>=28&&isProfileOwner(myDpm)&&myDpm.isManagedProfile(myComponent)){ val unifiedPwd = myDpm.isUsingUnifiedPassword(myComponent) Text("个人与工作应用密码一致:$unifiedPwd",style=bodyTextStyle) } @@ -137,7 +137,6 @@ fun Password(){ } if(isWear){ Text(text = "(可以水平滚动)",style=typography.bodyMedium) } Text("没有密码时会自动激活令牌",style=bodyTextStyle) - Text("有可能无法设置密码重置令牌,因机而异",style=bodyTextStyle) } } Column( diff --git a/app/src/main/java/com/binbin/androidowner/Receiver.kt b/app/src/main/java/com/binbin/androidowner/Receiver.kt index 0d368eb..97c90ab 100644 --- a/app/src/main/java/com/binbin/androidowner/Receiver.kt +++ b/app/src/main/java/com/binbin/androidowner/Receiver.kt @@ -20,10 +20,10 @@ class MyDeviceAdminReceiver : DeviceAdminReceiver() { override fun onTransferOwnershipComplete(context: Context, bundle: PersistableBundle?) { super.onTransferOwnershipComplete(context, bundle) if(bundle!=null){ - Toast.makeText(context,"转移控制权完毕,附加内容长度:${bundle.size()}",Toast.LENGTH_SHORT).show() + Toast.makeText(context,"转移所有权完毕,附加内容长度:${bundle.size()}",Toast.LENGTH_SHORT).show() Log.d("TransferOwnerShip",bundle.toString()) }else{ - Toast.makeText(context,"转移控制权完毕,无附加内容}",Toast.LENGTH_SHORT).show() + Toast.makeText(context,"转移所有权完毕,无附加内容}",Toast.LENGTH_SHORT).show() } } diff --git a/app/src/main/java/com/binbin/androidowner/Setting.kt b/app/src/main/java/com/binbin/androidowner/Setting.kt index 5b92c07..c0a945a 100644 --- a/app/src/main/java/com/binbin/androidowner/Setting.kt +++ b/app/src/main/java/com/binbin/androidowner/Setting.kt @@ -70,7 +70,7 @@ fun AppSetting(navCtrl:NavHostController){ verticalAlignment = Alignment.CenterVertically, modifier = Modifier .fillMaxWidth() - .clickable { shareLink(myContext, "https://github.com/BinTianqi/AndroidOwner/Guide.md") } + .clickable { shareLink(myContext, "https://github.com/BinTianqi/AndroidOwner/blob/master/Guide.md") } .padding(start = 8.dp, bottom = 4.dp) ){ Icon( diff --git a/app/src/main/java/com/binbin/androidowner/User.kt b/app/src/main/java/com/binbin/androidowner/User.kt index c47f9d5..6b64671 100644 --- a/app/src/main/java/com/binbin/androidowner/User.kt +++ b/app/src/main/java/com/binbin/androidowner/User.kt @@ -3,9 +3,12 @@ package com.binbin.androidowner import android.app.admin.DevicePolicyManager import android.content.ComponentName import android.content.Context +import android.content.Intent +import android.graphics.BitmapFactory import android.os.Build.VERSION import android.os.UserHandle import android.os.UserManager +import android.provider.MediaStore import android.widget.Toast import androidx.activity.ComponentActivity import androidx.compose.foundation.clickable @@ -32,6 +35,7 @@ import androidx.compose.ui.text.input.KeyboardType import androidx.compose.ui.unit.dp import androidx.core.os.UserManagerCompat + var affiliationID = mutableSetOf() @Composable fun UserManage() { @@ -290,31 +294,62 @@ fun UserManage() { } } - UserSessionMessage("用户名","用户名",true,myDpm,myContext,{null},{msg -> myDpm.setProfileName(myComponent, msg.toString())}) + UserSessionMessage("用户名", "用户名", true, {null}) {msg-> myDpm.setProfileName(myComponent, msg.toString())} + + if(VERSION.SDK_INT>=23&&(isDeviceOwner(myDpm)||isProfileOwner(myDpm))){ + Column(modifier = sections()){ + var getContent by remember{mutableStateOf(false)} + Text(text = "用户图标", style = typography.titleLarge) + Text(text = "尽量选择正方形的图片,以免产生问题", style = bodyTextStyle) + CheckBoxItem("使用文件选择器而不是相册",{getContent},{getContent=!getContent}) + Button( + onClick = { + val intent = Intent(if(getContent){Intent.ACTION_GET_CONTENT}else{Intent.ACTION_PICK}) + if(getContent){intent.addCategory(Intent.CATEGORY_OPENABLE)} + intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*") + getUserIcon.launch(intent) + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("选择图片...") + } + Button( + onClick = { + if(userIconUri!=null){ + uriToStream(myContext, userIconUri){stream -> + val bitmap = BitmapFactory.decodeStream(stream) + myDpm.setUserIcon(myComponent,bitmap) + Toast.makeText(myContext, "成功", Toast.LENGTH_SHORT).show() + } + }else{ + Toast.makeText(myContext, "请先选择图片", Toast.LENGTH_SHORT).show() + } + }, + modifier = Modifier.fillMaxWidth() + ) { + Text("应用") + } + } + } + if(VERSION.SDK_INT>=28){ - UserSessionMessage("用户会话开始消息","消息",false,myDpm,myContext,{myDpm.getStartUserSessionMessage(myComponent)},{msg -> myDpm.setStartUserSessionMessage(myComponent,msg)}) - UserSessionMessage("用户会话结束消息","消息",false,myDpm,myContext,{myDpm.getEndUserSessionMessage(myComponent)},{msg -> myDpm.setEndUserSessionMessage(myComponent,msg)}) + UserSessionMessage("用户会话开始消息", "消息", false, {myDpm.getStartUserSessionMessage(myComponent)}) {msg-> myDpm.setStartUserSessionMessage(myComponent, msg)} + UserSessionMessage("用户会话结束消息", "消息", false, {myDpm.getEndUserSessionMessage(myComponent)}) {msg-> myDpm.setEndUserSessionMessage(myComponent, msg)} } Spacer(Modifier.padding(vertical = 30.dp)) } } @Composable -private fun UserSessionMessage( - text:String, - textField:String, - profileOwner:Boolean, - myDpm:DevicePolicyManager, - myContext: Context, - get:()->CharSequence?, - setMsg:(msg:CharSequence?)->Unit -){ +private fun UserSessionMessage(text:String, textField:String, profileOwner:Boolean, get: ()->CharSequence?, setMsg:(msg: CharSequence?)->Unit){ Column( modifier = sections() ) { + val myContext = LocalContext.current + val myDpm = myContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager val focusMgr = LocalFocusManager.current var msg by remember{ mutableStateOf(if(isDeviceOwner(myDpm)||(isProfileOwner(myDpm)&&profileOwner)){ if(get()==null){""}else{get().toString()} }else{""}) } - val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE) + val sharedPref = myContext.getSharedPreferences("data", Context.MODE_PRIVATE) val isWear = sharedPref.getBoolean("isWear",false) Text(text = text, style = typography.titleLarge, color = colorScheme.onPrimaryContainer) TextField(