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")
|
implementation("androidx.core:core-splashscreen:1.0.0")
|
||||||
|
|
||||||
// AndroidX activity
|
// 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")
|
implementation("androidx.work:work-runtime-ktx:2.7.1")
|
||||||
|
|
||||||
// Koin
|
// Koin
|
||||||
@ -93,7 +93,7 @@ dependencies {
|
|||||||
val composeVersion = "1.3.0-alpha03"
|
val composeVersion = "1.3.0-alpha03"
|
||||||
implementation("androidx.compose.ui:ui:${composeVersion}")
|
implementation("androidx.compose.ui:ui:${composeVersion}")
|
||||||
debugImplementation("androidx.compose.ui:ui-tooling:${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}")
|
implementation("androidx.compose.material:material-icons-extended:${composeVersion}")
|
||||||
|
|
||||||
// Accompanist
|
// Accompanist
|
||||||
@ -134,5 +134,5 @@ dependencies {
|
|||||||
// ListenableFuture
|
// ListenableFuture
|
||||||
implementation("com.google.guava:guava:31.0.1-android")
|
implementation("com.google.guava:guava:31.0.1-android")
|
||||||
implementation("androidx.concurrent:concurrent-futures:1.1.0")
|
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 {
|
object Variables {
|
||||||
val selectedAppPackage = mutableStateOf(Optional.empty<String>())
|
val selectedAppPackage = mutableStateOf(Optional.empty<ApplicationInfo>())
|
||||||
val selectedPatches = mutableStateListOf<String>()
|
val selectedPatches = mutableStateListOf<String>()
|
||||||
val patches = mutableStateOf<Resource<List<Class<out Patch<Context>>>>>(Resource.Loading)
|
val patches = mutableStateOf<Resource<List<Class<out Patch<Context>>>>>(Resource.Loading)
|
||||||
val patchesState by patches
|
val patchesState by patches
|
||||||
|
@ -89,7 +89,7 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
|
|||||||
applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath
|
applicationContext.filesDir.resolve("framework").also { it.mkdirs() }.absolutePath
|
||||||
val integrationsCacheDir =
|
val integrationsCacheDir =
|
||||||
applicationContext.filesDir.resolve("integrations-cache").also { it.mkdirs() }
|
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"
|
Logging.log += "Checking prerequisites\n"
|
||||||
val patches = findPatchesByIds(selectedPatches)
|
val patches = findPatchesByIds(selectedPatches)
|
||||||
@ -151,9 +151,8 @@ class PatcherWorker(context: Context, parameters: WorkerParameters, private val
|
|||||||
|
|
||||||
Logging.log += "Applying ${patches.size} patch(es)\n"
|
Logging.log += "Applying ${patches.size} patch(es)\n"
|
||||||
patcher.executePatches().forEach { (patch, result) ->
|
patcher.executePatches().forEach { (patch, result) ->
|
||||||
|
|
||||||
if (result.isFailure) {
|
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
|
return@forEach
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,10 @@ fun PatcherScreen(
|
|||||||
)
|
)
|
||||||
Text(
|
Text(
|
||||||
text = if (patchesLoaded) {
|
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 {
|
} else {
|
||||||
stringResource(R.string.card_application_not_loaded)
|
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.material.icons.filled.Done
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.*
|
import androidx.compose.runtime.*
|
||||||
import androidx.compose.runtime.saveable.rememberSaveable
|
|
||||||
import androidx.compose.ui.Alignment
|
import androidx.compose.ui.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
import androidx.compose.ui.text.style.TextOverflow
|
||||||
@ -31,7 +30,7 @@ fun PatchingScreen(
|
|||||||
navigator: BackstackNavigator<AppDestination>,
|
navigator: BackstackNavigator<AppDestination>,
|
||||||
vm: PatchingScreenViewModel = getViewModel()
|
vm: PatchingScreenViewModel = getViewModel()
|
||||||
) {
|
) {
|
||||||
var patching by rememberSaveable {mutableStateOf(false)}
|
var patching by mutableStateOf(false)
|
||||||
val scrollState = rememberScrollState()
|
val scrollState = rememberScrollState()
|
||||||
val coroutineScope = rememberCoroutineScope()
|
val coroutineScope = rememberCoroutineScope()
|
||||||
LaunchedEffect(patching) {
|
LaunchedEffect(patching) {
|
||||||
|
@ -1,14 +1,19 @@
|
|||||||
package app.revanced.manager.ui.screen.subscreens
|
package app.revanced.manager.ui.screen.subscreens
|
||||||
|
|
||||||
import android.annotation.SuppressLint
|
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.clickable
|
||||||
import androidx.compose.foundation.layout.padding
|
import androidx.compose.foundation.layout.padding
|
||||||
import androidx.compose.foundation.lazy.LazyColumn
|
import androidx.compose.foundation.lazy.LazyColumn
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.ArrowBack
|
import androidx.compose.material.icons.filled.ArrowBack
|
||||||
|
import androidx.compose.material.icons.filled.SdStorage
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material3.*
|
||||||
import androidx.compose.runtime.Composable
|
import androidx.compose.runtime.Composable
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.platform.LocalContext
|
||||||
import androidx.compose.ui.res.stringResource
|
import androidx.compose.ui.res.stringResource
|
||||||
import app.revanced.manager.R
|
import app.revanced.manager.R
|
||||||
import app.revanced.manager.Variables.filteredApps
|
import app.revanced.manager.Variables.filteredApps
|
||||||
@ -28,32 +33,45 @@ fun AppSelectorSubscreen(
|
|||||||
navigator: BackstackNavigator<AppDestination>,
|
navigator: BackstackNavigator<AppDestination>,
|
||||||
vm: AppSelectorViewModel = getViewModel(),
|
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(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
MediumTopAppBar(
|
MediumTopAppBar(title = { Text(stringResource(R.string.app_selector_title)) },
|
||||||
title = { Text(stringResource(R.string.app_selector_title)) },
|
|
||||||
navigationIcon = {
|
navigationIcon = {
|
||||||
IconButton(onClick = navigator::pop) {
|
IconButton(onClick = navigator::pop) {
|
||||||
Icon(
|
Icon(Icons.Default.ArrowBack, contentDescription = null)
|
||||||
imageVector = 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 ->
|
) { paddingValues ->
|
||||||
when (patchesState) {
|
when (patchesState) {
|
||||||
is Resource.Success -> {
|
is Resource.Success -> {
|
||||||
LazyColumn(modifier = Modifier.padding(paddingValues)) {
|
LazyColumn(modifier = Modifier.padding(paddingValues)) {
|
||||||
items(count = filteredApps.size) {
|
items(count = filteredApps.size) {
|
||||||
val app = filteredApps[it]
|
val app = filteredApps.distinct()[it]
|
||||||
val label = vm.applicationLabel(app)
|
val label = vm.applicationLabel(app)
|
||||||
val packageName = app.packageName
|
val packageName = app.packageName
|
||||||
|
|
||||||
val same = packageName == label
|
val same = packageName == label
|
||||||
ListItem(modifier = Modifier.clickable {
|
ListItem(modifier = Modifier.clickable {
|
||||||
vm.setSelectedAppPackage(app.packageName)
|
vm.setSelectedAppPackage(app)
|
||||||
navigator.pop()
|
navigator.pop()
|
||||||
}, leadingContent = {
|
}, leadingContent = {
|
||||||
AppIcon(vm.loadIcon(app), packageName)
|
AppIcon(vm.loadIcon(app), packageName)
|
||||||
|
@ -2,7 +2,9 @@ package app.revanced.manager.ui.viewmodel
|
|||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
import android.content.pm.ApplicationInfo
|
import android.content.pm.ApplicationInfo
|
||||||
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.drawable.Drawable
|
import android.graphics.drawable.Drawable
|
||||||
|
import android.net.Uri
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import app.revanced.manager.Variables
|
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.Variables.selectedAppPackage
|
||||||
import app.revanced.manager.ui.Resource
|
import app.revanced.manager.ui.Resource
|
||||||
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
import app.revanced.patcher.extensions.PatchExtensions.compatiblePackages
|
||||||
|
import java.nio.file.Files
|
||||||
|
import java.nio.file.StandardCopyOption
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class AppSelectorViewModel(
|
class AppSelectorViewModel(
|
||||||
@ -28,7 +32,7 @@ class AppSelectorViewModel(
|
|||||||
patch.compatiblePackages?.forEach { pkg ->
|
patch.compatiblePackages?.forEach { pkg ->
|
||||||
try {
|
try {
|
||||||
val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0)
|
val appInfo = app.packageManager.getApplicationInfo(pkg.name, 0)
|
||||||
if (appInfo !in filteredApps) {
|
if (!filteredApps.contains(appInfo)) {
|
||||||
filteredApps.add(appInfo)
|
filteredApps.add(appInfo)
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
@ -51,11 +55,25 @@ class AppSelectorViewModel(
|
|||||||
return info.loadIcon(app.packageManager)
|
return info.loadIcon(app.packageManager)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun setSelectedAppPackage(appId: String) {
|
fun setSelectedAppPackage(appId: ApplicationInfo) {
|
||||||
selectedAppPackage.value.ifPresent { s ->
|
selectedAppPackage.value.ifPresent { s ->
|
||||||
if (s != appId) Variables.selectedPatches.clear()
|
if (s != appId) Variables.selectedPatches.clear()
|
||||||
}
|
}
|
||||||
selectedAppPackage.value = Optional.of(appId)
|
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
|
package app.revanced.manager.ui.viewmodel
|
||||||
|
|
||||||
import android.app.Application
|
import android.app.Application
|
||||||
|
import android.content.pm.PackageInfo
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.os.Parcelable
|
import android.os.Parcelable
|
||||||
import android.util.Log
|
import android.util.Log
|
||||||
@ -64,13 +65,15 @@ class PatcherScreenViewModel(private val app: Application, private val api: API)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun getSelectedPackageInfo() =
|
fun getSelectedPackageInfo(): PackageInfo? {
|
||||||
if (selectedAppPackage.value.isPresent)
|
if (selectedAppPackage.value.isPresent) {
|
||||||
app.packageManager.getPackageInfo(
|
return app.packageManager.getPackageArchiveInfo(
|
||||||
selectedAppPackage.value.get(),
|
selectedAppPackage.value.get().publicSourceDir,
|
||||||
PackageManager.GET_META_DATA
|
PackageManager.GET_META_DATA
|
||||||
)
|
)
|
||||||
else null
|
}
|
||||||
|
else {return null}
|
||||||
|
}
|
||||||
|
|
||||||
fun checkSplitApk(): Boolean {
|
fun checkSplitApk(): Boolean {
|
||||||
if (getSelectedPackageInfo()!!.applicationInfo!!.metaData!!.getBoolean(
|
if (getSelectedPackageInfo()!!.applicationInfo!!.metaData!!.getBoolean(
|
||||||
|
Loading…
x
Reference in New Issue
Block a user