mirror of
https://github.com/revanced/revanced-manager-compose-old.git
synced 2025-04-30 06:24:28 +02:00
feat: select apk from storage
This commit is contained in:
parent
477ec3e182
commit
b41f483f1c
@ -80,7 +80,7 @@ dependencies {
|
||||
implementation("androidx.core:core-splashscreen:1.0.0")
|
||||
|
||||
// AndroidX activity
|
||||
implementation("androidx.activity:activity-compose:1.6.0-rc02")
|
||||
implementation("androidx.activity:activity-compose:1.6.0")
|
||||
implementation("androidx.work:work-runtime-ktx:2.7.1")
|
||||
|
||||
// Koin
|
||||
@ -93,7 +93,7 @@ dependencies {
|
||||
val composeVersion = "1.3.0-alpha03"
|
||||
implementation("androidx.compose.ui:ui:${composeVersion}")
|
||||
debugImplementation("androidx.compose.ui:ui-tooling:${composeVersion}")
|
||||
implementation("androidx.compose.material3:material3:1.0.0-beta02")
|
||||
implementation("androidx.compose.material3:material3:1.0.0-beta03")
|
||||
implementation("androidx.compose.material:material-icons-extended:${composeVersion}")
|
||||
|
||||
// Accompanist
|
||||
@ -134,5 +134,5 @@ dependencies {
|
||||
// ListenableFuture
|
||||
implementation("com.google.guava:guava:31.0.1-android")
|
||||
implementation("androidx.concurrent:concurrent-futures:1.1.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.0")
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-guava:1.6.4")
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ import java.util.*
|
||||
|
||||
|
||||
object Variables {
|
||||
val selectedAppPackage = mutableStateOf(Optional.empty<String>())
|
||||
val selectedAppPackage = mutableStateOf(Optional.empty<ApplicationInfo>())
|
||||
val selectedPatches = mutableStateListOf<String>()
|
||||
val patches = mutableStateOf<Resource<List<Class<out Patch<Context>>>>>(Resource.Loading)
|
||||
val patchesState by patches
|
||||
|
@ -89,7 +89,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
|
||||
applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath
|
||||
val integrationsCacheDir =
|
||||
applicationContext.filesDir.resolve("integrations-cache").also { it.mkdirs() }
|
||||
val appInfo = applicationContext.packageManager.getApplicationInfo(selectedAppPackage.value.get(), 3)
|
||||
val appInfo = selectedAppPackage.value.get()
|
||||
|
||||
Logging.log += "Checking prerequisites\n"
|
||||
val patches = findPatchesByIds(selectedPatches)
|
||||
@ -151,9 +151,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
|
||||
|
||||
Logging.log += "Applying ${patches.size} patch(es)\n"
|
||||
patcher.executePatches().forEach { (patch, result) ->
|
||||
|
||||
if (result.isFailure) {
|
||||
Logging.log += "Failed to apply $patch \n" + result.exceptionOrNull()!!.message
|
||||
Logging.log += "Failed to apply $patch" + result.exceptionOrNull()!!.cause + "\n"
|
||||
return@forEach
|
||||
}
|
||||
|
||||
|
@ -71,7 +71,10 @@ fun PatcherScreen(
|
||||
)
|
||||
Text(
|
||||
text = if (patchesLoaded) {
|
||||
selectedAppPackage.orElse(stringResource(R.string.card_application_not_selected))
|
||||
if (selectedAppPackage.isPresent) {
|
||||
selectedAppPackage.get().packageName
|
||||
}
|
||||
else {stringResource(R.string.card_application_not_selected)}
|
||||
} else {
|
||||
stringResource(R.string.card_application_not_loaded)
|
||||
},
|
||||
|
@ -11,7 +11,6 @@ import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material.icons.filled.Done
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.runtime.saveable.rememberSaveable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
@ -31,7 +30,7 @@ fun PatchingScreen(
|
||||
navigator: BackstackNavigator<AppDestination>,
|
||||
vm: PatchingScreenViewModel = getViewModel()
|
||||
) {
|
||||
var patching by rememberSaveable {mutableStateOf(false)}
|
||||
var patching by mutableStateOf(false)
|
||||
val scrollState = rememberScrollState()
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
LaunchedEffect(patching) {
|
||||
|
@ -1,14 +1,19 @@
|
||||
package app.revanced.manager.ui.screen.subscreens
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import android.widget.Toast
|
||||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.SdStorage
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.revanced.manager.R
|
||||
import app.revanced.manager.Variables.filteredApps
|
||||
@ -28,32 +33,45 @@ fun AppSelectorSubscreen(
|
||||
navigator: BackstackNavigator<AppDestination>,
|
||||
vm: AppSelectorViewModel = getViewModel(),
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
|
||||
val launcher = rememberLauncherForActivityResult(ActivityResultContracts.OpenDocument()) {
|
||||
it?.let { uri ->
|
||||
vm.setSelectedAppPackageFromFile(uri)
|
||||
navigator.pop()
|
||||
return@rememberLauncherForActivityResult
|
||||
}
|
||||
Toast.makeText(context, "Couldn't load APK file.", Toast.LENGTH_SHORT).show()
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
topBar = {
|
||||
MediumTopAppBar(
|
||||
title = { Text(stringResource(R.string.app_selector_title)) },
|
||||
MediumTopAppBar(title = { Text(stringResource(R.string.app_selector_title)) },
|
||||
navigationIcon = {
|
||||
IconButton(onClick = navigator::pop) {
|
||||
Icon(
|
||||
imageVector = Icons.Default.ArrowBack,
|
||||
contentDescription = null
|
||||
)
|
||||
Icon(Icons.Default.ArrowBack, contentDescription = null)
|
||||
}
|
||||
},
|
||||
})
|
||||
},
|
||||
floatingActionButton = {
|
||||
ExtendedFloatingActionButton(
|
||||
onClick = { launcher.launch(arrayOf("application/vnd.android.package-archive")) },
|
||||
icon = { Icon(Icons.Default.SdStorage, contentDescription = null) },
|
||||
text = { Text("Storage") },
|
||||
)
|
||||
}
|
||||
},
|
||||
) { paddingValues ->
|
||||
when (patchesState) {
|
||||
is Resource.Success -> {
|
||||
LazyColumn(modifier = Modifier.padding(paddingValues)) {
|
||||
items(count = filteredApps.size) {
|
||||
val app = filteredApps[it]
|
||||
val app = filteredApps.distinct()[it]
|
||||
val label = vm.applicationLabel(app)
|
||||
val packageName = app.packageName
|
||||
|
||||
val same = packageName == label
|
||||
ListItem(modifier = Modifier.clickable {
|
||||
vm.setSelectedAppPackage(app.packageName)
|
||||
vm.setSelectedAppPackage(app)
|
||||
navigator.pop()
|
||||
}, leadingContent = {
|
||||
AppIcon(vm.loadIcon(app), packageName)
|
||||
|
@ -2,7 +2,9 @@ package app.revanced.manager.ui.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import android.content.pm.ApplicationInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.graphics.drawable.Drawable
|
||||
import android.net.Uri
|
||||
import android.util.Log
|
||||
import androidx.lifecycle.ViewModel
|
||||
import app.revanced.manager.Variables
|
||||
@ -11,6 +13,8 @@ import app.revanced.manager.Variables.patches
|
||||
import app.revanced.manager.Variables.selectedAppPackage
|
||||
import app.revanced.manager.ui.Resource
|
||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.StandardCopyOption
|
||||
import java.util.*
|
||||
|
||||
class AppSelectorViewModel(
|
||||
@ -28,7 +32,7 @@ class AppSelectorViewModel(
|
||||
patch.compatiblePackages?.forEach { pkg ->
|
||||
try {
|
||||
val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0)
|
||||
if (appInfo !in filteredApps) {
|
||||
if (!filteredApps.contains(appInfo)) {
|
||||
filteredApps.add(appInfo)
|
||||
return@forEach
|
||||
}
|
||||
@ -51,11 +55,25 @@ class AppSelectorViewModel(
|
||||
return info.loadIcon(app.packageManager)
|
||||
}
|
||||
|
||||
fun setSelectedAppPackage(appId: String) {
|
||||
fun setSelectedAppPackage(appId: ApplicationInfo) {
|
||||
selectedAppPackage.value.ifPresent { s ->
|
||||
if (s != appId) Variables.selectedPatches.clear()
|
||||
}
|
||||
selectedAppPackage.value = Optional.of(appId)
|
||||
}
|
||||
|
||||
fun setSelectedAppPackageFromFile(file: Uri?) {
|
||||
val apkDir = app.filesDir.resolve("input.apk").toPath()
|
||||
Files.copy(
|
||||
app.contentResolver.openInputStream(file!!),
|
||||
apkDir,
|
||||
StandardCopyOption.REPLACE_EXISTING
|
||||
)
|
||||
setSelectedAppPackage(
|
||||
app.packageManager.getPackageArchiveInfo(
|
||||
apkDir.toString(),
|
||||
PackageManager.GET_META_DATA
|
||||
)!!.applicationInfo
|
||||
)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package app.revanced.manager.ui.viewmodel
|
||||
|
||||
import android.app.Application
|
||||
import android.content.pm.PackageInfo
|
||||
import android.content.pm.PackageManager
|
||||
import android.os.Parcelable
|
||||
import android.util.Log
|
||||
@ -64,13 +65,15 @@ class PatcherScreenViewModel(private val app: Application, private val api: API)
|
||||
}
|
||||
|
||||
|
||||
fun getSelectedPackageInfo() =
|
||||
if (selectedAppPackage.value.isPresent)
|
||||
app.packageManager.getPackageInfo(
|
||||
selectedAppPackage.value.get(),
|
||||
fun getSelectedPackageInfo(): PackageInfo? {
|
||||
if (selectedAppPackage.value.isPresent) {
|
||||
return app.packageManager.getPackageArchiveInfo(
|
||||
selectedAppPackage.value.get().publicSourceDir,
|
||||
PackageManager.GET_META_DATA
|
||||
)
|
||||
else null
|
||||
}
|
||||
else {return null}
|
||||
}
|
||||
|
||||
fun checkSplitApk(): Boolean {
|
||||
if (getSelectedPackageInfo()!!.applicationInfo!!.metaData!!.getBoolean(
|
||||
|
Loading…
x
Reference in New Issue
Block a user