mirror of
https://github.com/awfixers-stuff/OwnDroid.git
synced 2026-03-23 19:15:58 +00:00
simplify code of get file with MutableStateFlow
This commit is contained in:
@@ -42,9 +42,10 @@ import com.bintianqi.owndroid.dpm.*
|
||||
import com.bintianqi.owndroid.ui.Animations
|
||||
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.util.Locale
|
||||
|
||||
var backToHome = false
|
||||
var backToHomeStateFlow = MutableStateFlow(false)
|
||||
@ExperimentalMaterial3Api
|
||||
class MainActivity : FragmentActivity() {
|
||||
private val showAuth = mutableStateOf(false)
|
||||
@@ -98,11 +99,9 @@ fun Home(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>){
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val pkgName = mutableStateOf("")
|
||||
val dialogStatus = mutableIntStateOf(0)
|
||||
val backToHome by backToHomeStateFlow.collectAsState()
|
||||
LaunchedEffect(Unit){
|
||||
while(true){
|
||||
if(backToHome){ navCtrl.navigateUp(); backToHome=false }
|
||||
delay(200)
|
||||
}
|
||||
if(backToHome) { navCtrl.navigateUp(); backToHomeStateFlow.value = false }
|
||||
}
|
||||
NavHost(
|
||||
navController = navCtrl,
|
||||
|
||||
@@ -38,7 +38,7 @@ fun PermissionPicker(navCtrl: NavHostController){
|
||||
.fillMaxWidth()
|
||||
.clickable{
|
||||
selectedPermission = it.first
|
||||
applySelectedPermission = true
|
||||
applySelectedPermission.value = true
|
||||
navCtrl.navigateUp()
|
||||
}
|
||||
.padding(vertical = 6.dp, horizontal = 8.dp)
|
||||
|
||||
@@ -3,7 +3,10 @@ package com.bintianqi.owndroid
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.widget.Toast
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.lazy.items
|
||||
@@ -24,8 +27,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.navigation.NavHostController
|
||||
import com.bintianqi.owndroid.ui.NavIcon
|
||||
import com.google.accompanist.drawablepainter.rememberDrawablePainter
|
||||
import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.coroutines.withContext
|
||||
|
||||
private data class PkgInfo(
|
||||
val pkgName: String,
|
||||
@@ -48,7 +53,7 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState<String>){
|
||||
var filter by remember{mutableStateOf("data")}
|
||||
val scrollState = rememberLazyListState()
|
||||
val co = rememberCoroutineScope()
|
||||
val getPkgList:suspend ()->Unit = {
|
||||
val getPkgList: suspend ()->Unit = {
|
||||
show = false
|
||||
progress = 0
|
||||
hideProgress = false
|
||||
@@ -65,11 +70,10 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState<String>){
|
||||
else if(srcDir.contains("apex")){"apex"}
|
||||
else{"system"}
|
||||
)
|
||||
progress+=1
|
||||
delay(1)
|
||||
withContext(Dispatchers.Main) { progress += 1 }
|
||||
}
|
||||
show = true
|
||||
delay(300)
|
||||
delay(500)
|
||||
hideProgress = true
|
||||
}
|
||||
Scaffold(
|
||||
@@ -114,7 +118,6 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState<String>){
|
||||
.clip(RoundedCornerShape(50))
|
||||
.clickable{
|
||||
co.launch{
|
||||
delay(100)
|
||||
getPkgList()
|
||||
}
|
||||
}
|
||||
@@ -153,9 +156,8 @@ fun PackageSelector(navCtrl:NavHostController, pkgName: MutableState<String>){
|
||||
}
|
||||
}
|
||||
}
|
||||
LaunchedEffect(Unit){
|
||||
delay(250)
|
||||
if(pkgs.size==0){getPkgList()}
|
||||
LaunchedEffect(Unit) {
|
||||
if(pkgs.size==0) { getPkgList() }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,12 +9,13 @@ import androidx.activity.result.ActivityResultLauncher
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import com.bintianqi.owndroid.dpm.addDeviceAdmin
|
||||
import com.bintianqi.owndroid.dpm.createManagedProfile
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import java.io.FileNotFoundException
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
|
||||
lateinit var getFile: ActivityResultLauncher<Intent>
|
||||
var fileUri: Uri? = null
|
||||
val fileUriFlow = MutableStateFlow(Uri.parse(""))
|
||||
|
||||
var zhCN = true
|
||||
|
||||
@@ -71,7 +72,7 @@ fun registerActivityResult(context: ComponentActivity){
|
||||
if(it==null){
|
||||
Toast.makeText(context.applicationContext, R.string.file_not_exist, Toast.LENGTH_SHORT).show()
|
||||
}else{
|
||||
fileUri = it.data
|
||||
fileUriFlow.value = it.data
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -79,7 +80,7 @@ fun registerActivityResult(context: ComponentActivity){
|
||||
addDeviceAdmin = context.registerForActivityResult(ActivityResultContracts.StartActivityForResult()) {
|
||||
val dpm = context.applicationContext.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||
if(dpm.isAdminActive(ComponentName(context.applicationContext, Receiver::class.java))){
|
||||
backToHome = true
|
||||
backToHomeStateFlow.value = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.bintianqi.owndroid.*
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.ui.*
|
||||
import kotlinx.coroutines.delay
|
||||
import java.io.IOException
|
||||
import java.io.InputStream
|
||||
import java.util.concurrent.Executors
|
||||
@@ -263,9 +262,7 @@ private fun Home(navCtrl:NavHostController, pkgName: String, dialogStatus: Mutab
|
||||
SubPageItem(R.string.set_default_dialer,"",R.drawable.call_fill0){navCtrl.navigate("DefaultDialer")}
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
LaunchedEffect(Unit) {
|
||||
fileUri = null
|
||||
}
|
||||
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,10 +345,10 @@ private fun PermissionManage(pkgName: String, navCtrl: NavHostController){
|
||||
PERMISSION_GRANT_STATE_GRANTED to stringResource(R.string.granted),
|
||||
PERMISSION_GRANT_STATE_DENIED to stringResource(R.string.denied)
|
||||
)
|
||||
LaunchedEffect(Unit) {
|
||||
while(true){
|
||||
if(applySelectedPermission){inputPermission = selectedPermission; applySelectedPermission = false}
|
||||
delay(100)
|
||||
LaunchedEffect(applySelectedPermission.collectAsState()) {
|
||||
if(applySelectedPermission.value) {
|
||||
inputPermission = selectedPermission
|
||||
applySelectedPermission.value = false
|
||||
}
|
||||
}
|
||||
LaunchedEffect(pkgName) {
|
||||
@@ -794,6 +791,7 @@ private fun UninstallApp(pkgName: String){
|
||||
private fun InstallApp(){
|
||||
val context = LocalContext.current
|
||||
val focusMgr = LocalFocusManager.current
|
||||
val selected = fileUriFlow.collectAsState().value != Uri.parse("")
|
||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.install_app), style = typography.headlineLarge)
|
||||
@@ -810,13 +808,11 @@ private fun InstallApp(){
|
||||
) {
|
||||
Text(stringResource(R.string.select_apk))
|
||||
}
|
||||
var selected by remember{mutableStateOf(false)}
|
||||
LaunchedEffect(selected){while(true){ delay(800); selected = fileUri!=null}}
|
||||
AnimatedVisibility(selected) {
|
||||
Spacer(Modifier.padding(vertical = 3.dp))
|
||||
Column(modifier = Modifier.fillMaxWidth()){
|
||||
Button(
|
||||
onClick = { uriToStream(context, fileUri){stream -> installPackage(context,stream)} },
|
||||
onClick = { uriToStream(context, fileUriFlow.value){stream -> installPackage(context,stream)} },
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
) {
|
||||
Text(stringResource(R.string.silent_install))
|
||||
@@ -824,7 +820,7 @@ private fun InstallApp(){
|
||||
Button(
|
||||
onClick = {
|
||||
val intent = Intent(Intent.ACTION_INSTALL_PACKAGE)
|
||||
intent.setData(fileUri)
|
||||
intent.setData(fileUriFlow.value)
|
||||
intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||
context.startActivity(intent)
|
||||
},
|
||||
|
||||
@@ -2,11 +2,11 @@ package com.bintianqi.owndroid.dpm
|
||||
|
||||
import android.app.admin.DevicePolicyManager
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import androidx.activity.result.ActivityResultLauncher
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
|
||||
var selectedPermission = ""
|
||||
var applySelectedPermission = false
|
||||
var applySelectedPermission = MutableStateFlow(false)
|
||||
lateinit var createManagedProfile: ActivityResultLauncher<Intent>
|
||||
lateinit var addDeviceAdmin: ActivityResultLauncher<Intent>
|
||||
|
||||
|
||||
@@ -129,7 +129,7 @@ fun ShizukuActivate(){
|
||||
coScope.launch{
|
||||
outputText = service!!.execute(context.getString(R.string.dpm_activate_po_command))
|
||||
outputTextScrollState.animateScrollTo(0, scrollAnim())
|
||||
delay(600)
|
||||
delay(500)
|
||||
showProfileOwnerButton = !isProfileOwner(dpm)
|
||||
}
|
||||
},
|
||||
|
||||
@@ -11,6 +11,7 @@ import android.app.admin.SystemUpdatePolicy.TYPE_POSTPONE
|
||||
import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.Build.VERSION
|
||||
import android.os.UserManager
|
||||
@@ -19,11 +20,14 @@ import android.widget.Toast
|
||||
import androidx.activity.ComponentActivity
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.animateContentSize
|
||||
import androidx.compose.foundation.*
|
||||
import androidx.compose.foundation.ScrollState
|
||||
import androidx.compose.foundation.focusable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
import androidx.compose.foundation.text.selection.SelectionContainer
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.MaterialTheme.colorScheme
|
||||
import androidx.compose.material3.MaterialTheme.typography
|
||||
@@ -44,7 +48,6 @@ import androidx.navigation.compose.rememberNavController
|
||||
import com.bintianqi.owndroid.*
|
||||
import com.bintianqi.owndroid.R
|
||||
import com.bintianqi.owndroid.ui.*
|
||||
import kotlinx.coroutines.delay
|
||||
import java.util.Date
|
||||
|
||||
@Composable
|
||||
@@ -150,7 +153,7 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState){
|
||||
}
|
||||
SubPageItem(R.string.wipe_data,"",R.drawable.warning_fill0){navCtrl.navigate("WipeData")}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
LaunchedEffect(Unit){fileUri=null}
|
||||
LaunchedEffect(Unit){ fileUriFlow.value = Uri.parse("") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -593,26 +596,23 @@ private fun CaCert(){
|
||||
val context = LocalContext.current
|
||||
val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||
val receiver = ComponentName(context,Receiver::class.java)
|
||||
val uri by fileUriFlow.collectAsState()
|
||||
var exist by remember{mutableStateOf(false)}
|
||||
var uriPath by remember{mutableStateOf("")}
|
||||
var caCertByteArray = byteArrayOf()
|
||||
val refresh = {
|
||||
if(uriPath!=fileUri?.path){
|
||||
if(caCertByteArray.isEmpty()){
|
||||
uriToStream(context, fileUri){
|
||||
val array = it.readBytes()
|
||||
caCertByteArray = if(array.size<10000){
|
||||
array
|
||||
}else{
|
||||
byteArrayOf()
|
||||
}
|
||||
val uriPath = uri.path ?: ""
|
||||
var caCertByteArray by remember{ mutableStateOf(byteArrayOf()) }
|
||||
LaunchedEffect(uri) {
|
||||
if(uri != Uri.parse("")) {
|
||||
uriToStream(context, uri){
|
||||
val array = it.readBytes()
|
||||
caCertByteArray = if(array.size<10000){
|
||||
array
|
||||
}else{
|
||||
byteArrayOf()
|
||||
}
|
||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
||||
}
|
||||
uriPath = fileUri?.path?:""
|
||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
||||
}
|
||||
}
|
||||
LaunchedEffect(exist){ while(true){ refresh();delay(500) } }
|
||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.ca_cert), style = typography.headlineLarge)
|
||||
@@ -642,7 +642,7 @@ private fun CaCert(){
|
||||
onClick = {
|
||||
val result = dpm.installCaCert(receiver, caCertByteArray)
|
||||
Toast.makeText(context, if(result){R.string.success}else{R.string.fail}, Toast.LENGTH_SHORT).show()
|
||||
refresh()
|
||||
exist = dpm.hasCaCertInstalled(receiver, caCertByteArray)
|
||||
},
|
||||
modifier = Modifier.fillMaxWidth(0.49F)
|
||||
) {
|
||||
|
||||
@@ -6,6 +6,7 @@ import android.content.ComponentName
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.BitmapFactory
|
||||
import android.net.Uri
|
||||
import android.os.Binder
|
||||
import android.os.Build.VERSION
|
||||
import android.os.Process
|
||||
@@ -119,9 +120,7 @@ private fun Home(navCtrl: NavHostController,scrollState: ScrollState){
|
||||
SubPageItem(R.string.affiliation_id,"",R.drawable.id_card_fill0){navCtrl.navigate("AffiliationID")}
|
||||
}
|
||||
Spacer(Modifier.padding(vertical = 30.dp))
|
||||
LaunchedEffect(Unit) {
|
||||
fileUri = null
|
||||
}
|
||||
LaunchedEffect(Unit) { fileUriFlow.value = Uri.parse("") }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -495,7 +494,7 @@ private fun UserIcon(){
|
||||
val dpm = context.getSystemService(ComponentActivity.DEVICE_POLICY_SERVICE) as DevicePolicyManager
|
||||
val receiver = ComponentName(context,Receiver::class.java)
|
||||
var getContent by remember{mutableStateOf(false)}
|
||||
var canApply by remember{mutableStateOf(false)}
|
||||
val canApply = fileUriFlow.collectAsState().value != Uri.parse("")
|
||||
Column(modifier = Modifier.fillMaxSize().padding(horizontal = 8.dp).verticalScroll(rememberScrollState())){
|
||||
Spacer(Modifier.padding(vertical = 10.dp))
|
||||
Text(text = stringResource(R.string.change_user_icon), style = typography.headlineLarge)
|
||||
@@ -515,11 +514,10 @@ private fun UserIcon(){
|
||||
) {
|
||||
Text(stringResource(R.string.select_picture))
|
||||
}
|
||||
LaunchedEffect(Unit){ delay(600); canApply = fileUri!=null }
|
||||
AnimatedVisibility(canApply) {
|
||||
Button(
|
||||
onClick = {
|
||||
uriToStream(context, fileUri){stream ->
|
||||
uriToStream(context, fileUriFlow.value){stream ->
|
||||
val bitmap = BitmapFactory.decodeStream(stream)
|
||||
dpm.setUserIcon(receiver,bitmap)
|
||||
Toast.makeText(context, R.string.success, Toast.LENGTH_SHORT).show()
|
||||
|
||||
Reference in New Issue
Block a user