app installer: get basic apk info

This commit is contained in:
BinTianqi
2024-07-06 11:03:54 +08:00
parent 4d8c3a7a60
commit 89cfafb03a
9 changed files with 866 additions and 18 deletions

View File

@@ -8,7 +8,9 @@ import android.os.Bundle
import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.LinearProgressIndicator
import androidx.compose.material3.Text
@@ -17,13 +19,21 @@ import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.DialogProperties
import androidx.core.view.WindowCompat
import androidx.fragment.app.FragmentActivity
import androidx.lifecycle.lifecycleScope
import com.bintianqi.owndroid.dpm.installPackage
import com.bintianqi.owndroid.ui.theme.OwnDroidTheme
import com.github.fishb1.apkinfo.ApkInfo
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.io.FileInputStream
class InstallAppActivity: FragmentActivity() {
override fun onNewIntent(intent: Intent?) {
@@ -34,37 +44,64 @@ class InstallAppActivity: FragmentActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
enableEdgeToEdge()
WindowCompat.setDecorFitsSystemWindows(window, false)
val context = applicationContext
val sharedPref = applicationContext.getSharedPreferences("data", Context.MODE_PRIVATE)
window.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val uri = this.intent.data!!
var apkInfoText by mutableStateOf(context.getString(R.string.parsing_apk_info))
var status by mutableStateOf("parsing")
this.lifecycleScope.launch(Dispatchers.IO) {
val fd = applicationContext.contentResolver.openFileDescriptor(uri, "r")
val apkInfo = ApkInfo.fromInputStream(
FileInputStream(fd?.fileDescriptor)
)
fd?.close()
withContext(Dispatchers.Main) {
status = "waiting"
apkInfoText = "${context.getString(R.string.package_name)}: ${apkInfo.packageName}\n"
apkInfoText += "${context.getString(R.string.version_name)}: ${apkInfo.versionName}\n"
apkInfoText += "${context.getString(R.string.version_code)}: ${apkInfo.versionCode}"
}
}
setContent {
var installing by remember { mutableStateOf(false) }
OwnDroidTheme(
sharedPref.getBoolean("material_you", true),
sharedPref.getBoolean("black_theme", false)
) {
AlertDialog(
properties = DialogProperties(dismissOnBackPress = false, dismissOnClickOutside = false),
title = {
Text(stringResource(R.string.install_app))
},
onDismissRequest = {
finish()
if(status != "installing") finish()
},
text = {
AnimatedVisibility(installing) {
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
Column {
AnimatedVisibility(status != "waiting") {
LinearProgressIndicator(modifier = Modifier.fillMaxWidth())
}
Text(text = apkInfoText, modifier = Modifier.padding(top = 4.dp))
}
},
dismissButton = {
TextButton(onClick = { finish() }) { Text(stringResource(R.string.cancel)) }
TextButton(
onClick = { finish() },
enabled = status != "installing"
) {
Text(stringResource(R.string.cancel))
}
},
confirmButton = {
TextButton(
onClick = {
installing = true
status = "installing"
uriToStream(applicationContext, this.intent.data) { stream -> installPackage(applicationContext, stream) }
}
},
enabled = status != "installing"
) {
Text(stringResource(R.string.confirm))
Text(stringResource(R.string.install))
}
},
modifier = Modifier.fillMaxWidth()

View File

@@ -1,6 +1,5 @@
package com.bintianqi.owndroid
import android.annotation.SuppressLint
import android.app.admin.DevicePolicyManager
import android.content.ComponentName
import android.content.Context
@@ -41,7 +40,6 @@ import androidx.navigation.compose.rememberNavController
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
@@ -50,7 +48,6 @@ var backToHomeStateFlow = MutableStateFlow(false)
class MainActivity : FragmentActivity() {
private val showAuth = mutableStateOf(false)
@SuppressLint("UnrememberedMutableState")
override fun onCreate(savedInstanceState: Bundle?) {
registerActivityResult(this)
enableEdgeToEdge()
@@ -63,8 +60,8 @@ class MainActivity : FragmentActivity() {
val locale = applicationContext.resources?.configuration?.locale
zhCN = locale == Locale.SIMPLIFIED_CHINESE || locale == Locale.CHINESE || locale == Locale.CHINA
setContent {
val materialYou = mutableStateOf(sharedPref.getBoolean("material_you", true))
val blackTheme = mutableStateOf(sharedPref.getBoolean("black_theme", false))
val materialYou = remember { mutableStateOf(sharedPref.getBoolean("material_you", true)) }
val blackTheme = remember { mutableStateOf(sharedPref.getBoolean("black_theme", false)) }
OwnDroidTheme(materialYou.value, blackTheme.value) {
Home(materialYou, blackTheme)
if(showAuth.value) {
@@ -87,7 +84,6 @@ class MainActivity : FragmentActivity() {
}
@SuppressLint("UnrememberedMutableState")
@ExperimentalMaterial3Api
@Composable
fun Home(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
@@ -97,8 +93,8 @@ fun Home(materialYou:MutableState<Boolean>, blackTheme:MutableState<Boolean>) {
val receiver = ComponentName(context,Receiver::class.java)
val sharedPref = LocalContext.current.getSharedPreferences("data", Context.MODE_PRIVATE)
val focusMgr = LocalFocusManager.current
val pkgName = mutableStateOf("")
val dialogStatus = mutableIntStateOf(0)
val pkgName = remember { mutableStateOf("") }
val dialogStatus = remember { mutableIntStateOf(0) }
val backToHome by backToHomeStateFlow.collectAsState()
LaunchedEffect(backToHome) {
if(backToHome) { navCtrl.navigateUp(); backToHomeStateFlow.value = false }