manager: add support for opening zip file and directly flash module
- refine zip intent method - use MMRL method to handle zip, fix failed to open zip from Chrome Co-Authored-By: Der_Googler <54764558+dergoogler@users.noreply.github.com> Co-authored-by: rifsxd <rifat.44.azad.rifs@gmail.com> Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -30,6 +30,13 @@
|
||||
<action android:name="android.intent.action.MAIN" />
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
<intent-filter>
|
||||
<action android:name="android.intent.action.VIEW" />
|
||||
<category android:name="android.intent.category.DEFAULT" />
|
||||
<category android:name="android.intent.category.BROWSABLE" />
|
||||
<data android:mimeType="application/zip" />
|
||||
<data android:scheme="content" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
|
||||
<activity-alias
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.sukisu.ultra.ui
|
||||
|
||||
import android.content.Context
|
||||
import android.content.res.Configuration
|
||||
import android.net.Uri
|
||||
import android.os.Build
|
||||
import android.os.Bundle
|
||||
import androidx.activity.ComponentActivity
|
||||
@@ -25,7 +26,9 @@ import com.ramcosta.composedestinations.DestinationsNavHost
|
||||
import com.ramcosta.composedestinations.animations.NavHostAnimatedDestinationStyle
|
||||
import com.ramcosta.composedestinations.generated.NavGraphs
|
||||
import com.ramcosta.composedestinations.generated.destinations.ExecuteModuleActionScreenDestination
|
||||
import com.ramcosta.composedestinations.generated.destinations.FlashScreenDestination
|
||||
import com.ramcosta.composedestinations.spec.NavHostGraphSpec
|
||||
import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator
|
||||
import com.sukisu.ultra.Natives
|
||||
import com.sukisu.ultra.ui.screen.BottomBarDestination
|
||||
import com.sukisu.ultra.ui.theme.KernelSUTheme
|
||||
@@ -34,6 +37,7 @@ import com.sukisu.ultra.ui.util.install
|
||||
import com.sukisu.ultra.ui.viewmodel.HomeViewModel
|
||||
import com.sukisu.ultra.ui.viewmodel.SuperUserViewModel
|
||||
import com.sukisu.ultra.ui.webui.initPlatform
|
||||
import com.sukisu.ultra.ui.screen.FlashIt
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.launch
|
||||
import zako.zako.zako.zakoui.activity.component.BottomBar
|
||||
@@ -83,6 +87,18 @@ class MainActivity : ComponentActivity() {
|
||||
isInitialized = true
|
||||
}
|
||||
|
||||
// Check if launched with a ZIP file
|
||||
val zipUri: ArrayList<Uri>? = if (intent.data != null) {
|
||||
arrayListOf(intent.data!!)
|
||||
} else {
|
||||
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
|
||||
intent.getParcelableArrayListExtra("uris", Uri::class.java)
|
||||
} else {
|
||||
@Suppress("DEPRECATION")
|
||||
intent.getParcelableArrayListExtra("uris")
|
||||
}
|
||||
}
|
||||
|
||||
setContent {
|
||||
KernelSUTheme {
|
||||
val navController = rememberNavController()
|
||||
@@ -93,6 +109,18 @@ class MainActivity : ComponentActivity() {
|
||||
BottomBarDestination.entries.map { it.direction.route }.toSet()
|
||||
}
|
||||
|
||||
val navigator = navController.rememberDestinationsNavigator()
|
||||
|
||||
LaunchedEffect(zipUri) {
|
||||
if (!zipUri.isNullOrEmpty()) {
|
||||
navigator.navigate(
|
||||
FlashScreenDestination(
|
||||
FlashIt.FlashModules(zipUri)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
val showBottomBar = when (currentDestination?.route) {
|
||||
ExecuteModuleActionScreenDestination.route -> false
|
||||
else -> true
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.sukisu.ultra.ui.screen
|
||||
|
||||
import android.content.Intent
|
||||
import android.net.Uri
|
||||
import android.os.Environment
|
||||
import android.os.Parcelable
|
||||
@@ -30,6 +31,7 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.activity.ComponentActivity
|
||||
import com.ramcosta.composedestinations.annotation.Destination
|
||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||
import com.ramcosta.composedestinations.generated.destinations.FlashScreenDestination
|
||||
@@ -119,6 +121,24 @@ fun setModuleVerificationStatus(uri: Uri, isVerified: Boolean) {
|
||||
@Destination<RootGraph>
|
||||
fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
|
||||
val context = LocalContext.current
|
||||
|
||||
// 是否通过从外部启动的模块安装
|
||||
val isExternalInstall = remember {
|
||||
when (flashIt) {
|
||||
is FlashIt.FlashModule -> {
|
||||
(context as? ComponentActivity)?.intent?.let { intent ->
|
||||
intent.action == Intent.ACTION_VIEW || intent.action == Intent.ACTION_SEND
|
||||
} ?: false
|
||||
}
|
||||
is FlashIt.FlashModules -> {
|
||||
(context as? ComponentActivity)?.intent?.let { intent ->
|
||||
intent.action == Intent.ACTION_VIEW || intent.action == Intent.ACTION_SEND
|
||||
} ?: false
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
var text by rememberSaveable { mutableStateOf("") }
|
||||
var tempText: String
|
||||
val logContent = rememberSaveable { StringBuilder() }
|
||||
@@ -203,8 +223,21 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
|
||||
if (showReboot) {
|
||||
text += "\n\n\n"
|
||||
showFloatAction = true
|
||||
|
||||
// 如果是内部安装,显示重启按钮后不自动返回
|
||||
if (isExternalInstall) {
|
||||
return@flashModuleUpdate
|
||||
}
|
||||
}
|
||||
hasUpdateCompleted = true
|
||||
|
||||
// 如果是外部安装的模块更新且不需要重启,延迟后自动返回
|
||||
if (isExternalInstall) {
|
||||
scope.launch {
|
||||
kotlinx.coroutines.delay(2000)
|
||||
(context as? ComponentActivity)?.finish()
|
||||
}
|
||||
}
|
||||
}, onStdout = {
|
||||
tempText = "$it\n"
|
||||
if (tempText.startsWith("[H[J")) { // clear command
|
||||
@@ -297,6 +330,18 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
|
||||
kotlinx.coroutines.delay(500)
|
||||
navigator.navigate(FlashScreenDestination(nextFlashIt))
|
||||
}
|
||||
} else if (isExternalInstall && flashIt is FlashIt.FlashModules && flashIt.currentIndex >= flashIt.uris.size - 1) {
|
||||
// 如果是外部安装且是最后一个模块,安装完成后自动返回
|
||||
scope.launch {
|
||||
kotlinx.coroutines.delay(2000)
|
||||
(context as? ComponentActivity)?.finish()
|
||||
}
|
||||
} else if (isExternalInstall && flashIt is FlashIt.FlashModule) {
|
||||
// 如果是外部安装单个模块,安装完成后自动返回
|
||||
scope.launch {
|
||||
kotlinx.coroutines.delay(2000)
|
||||
(context as? ComponentActivity)?.finish()
|
||||
}
|
||||
}
|
||||
}, onStdout = {
|
||||
tempText = "$it\n"
|
||||
@@ -319,6 +364,9 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
|
||||
}
|
||||
|
||||
if (canGoBack) {
|
||||
if (isExternalInstall) {
|
||||
(context as? ComponentActivity)?.finish()
|
||||
} else {
|
||||
if (flashIt is FlashIt.FlashModules || flashIt is FlashIt.FlashModuleUpdate) {
|
||||
viewModel.markNeedRefresh()
|
||||
viewModel.fetchModuleList()
|
||||
@@ -330,6 +378,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BackHandler(enabled = true) {
|
||||
onBack()
|
||||
|
||||
Reference in New Issue
Block a user