From 2eedf0ac9c26eda88100c568a06f79f9b80e3b11 Mon Sep 17 00:00:00 2001 From: Baidaidai_GFWD <1302064396@qq.com> Date: Tue, 7 Apr 2026 13:57:23 +0800 Subject: [PATCH] feat(intent): Add implicit ZIP import flow --- app/src/main/AndroidManifest.xml | 7 ++- .../baidaidai/rootless_store/MainActivity.kt | 45 ++++++++++++++++++- .../ui/screens/StartScreenContainer.kt | 34 ++++++++++---- 3 files changed, 75 insertions(+), 11 deletions(-) diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index d93a6b0..afb08fd 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -20,12 +20,17 @@ android:name=".MainActivity" android:exported="true" android:label="@string/app_name" + android:launchMode="singleTask" android:theme="@style/Theme.RootLessStore"> - + + + + + { error("No Context Provide") @@ -24,8 +32,18 @@ class RootlessStoreApp : Application() @AndroidEntryPoint class MainActivity : ComponentActivity(){ + + private var fileIntentUri: Uri? by mutableStateOf(null) + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) @OptIn(ExperimentalMaterial3ExpressiveApi::class) override fun onCreate(savedInstanceState: Bundle?) { + + // save Intent if hot-start from an implicit invocation + if (fileIntentUri == null){ + handleFileIntent(intent) + } + super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { @@ -35,9 +53,34 @@ class MainActivity : ComponentActivity(){ CompositionLocalProvider( RootLessStoreLocalContext provides context, ) { - RootlessStoreStartScreenContainer() + RootlessStoreStartScreenContainer( + fileIntentUri = fileIntentUri, + onHandlerEnded = { + fileIntentUri = null + } + ) } } } + + } + + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + override fun onNewIntent(intent: Intent) { + super.onNewIntent(intent) + setIntent(intent) + + // save Intent if cold-start from an implicit invocation + handleFileIntent(intent) + } + + @RequiresApi(Build.VERSION_CODES.TIRAMISU) + private fun handleFileIntent(intent: Intent?) { + if (intent?.action != Intent.ACTION_SEND) { + this.fileIntentUri = null + } + val uri = intent?.getParcelableExtra(Intent.EXTRA_STREAM, Uri::class.java) + this.fileIntentUri = uri } } \ No newline at end of file diff --git a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/StartScreenContainer.kt b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/StartScreenContainer.kt index 1b6c427..e5cc187 100644 --- a/app/src/main/java/com/baidaidai/rootless_store/ui/screens/StartScreenContainer.kt +++ b/app/src/main/java/com/baidaidai/rootless_store/ui/screens/StartScreenContainer.kt @@ -2,8 +2,10 @@ package com.baidaidai.rootless_store.ui.screens import android.content.Intent import android.net.Uri +import android.os.Build import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.contract.ActivityResultContracts +import androidx.annotation.RequiresApi import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi import androidx.compose.material3.Scaffold @@ -38,11 +40,14 @@ import com.baidaidai.rootless_store.ui.model.RootLessStorePluginScreenViewModel import com.baidaidai.rootless_store.ui.model.RootLessStoreSourceScreenViewModel import com.baidaidai.rootless_store.ui.theme.RootlessStoreTheme +@RequiresApi(Build.VERSION_CODES.TIRAMISU) @OptIn(ExperimentalMaterial3Api::class) @Composable fun RootlessStoreStartScreenContainer( pluginScreenViewModel: RootLessStorePluginScreenViewModel = hiltViewModel(), - sourceScreenViewModel: RootLessStoreSourceScreenViewModel = hiltViewModel() + sourceScreenViewModel: RootLessStoreSourceScreenViewModel = hiltViewModel(), + fileIntentUri:Uri?, + onHandlerEnded:()-> Unit ){ // VM & VM Data val marketScreenViewModel = hiltViewModel() @@ -65,6 +70,16 @@ fun RootlessStoreStartScreenContainer( } } + LaunchedEffect(fileIntentUri) { + val uri = fileIntentUri ?: return@LaunchedEffect + navController.navigate("PluginScreen") { + launchSingleTop = true + } + pluginScreenViewModel.updateFileURI(uri) + pluginScreenViewModel.installPlugin() + onHandlerEnded() + } + // Local Data var alertDialogStatus by rememberSaveable{ mutableStateOf(false) } var sourceDomainContent by rememberSaveable{ mutableStateOf("") } @@ -229,11 +244,12 @@ fun RootlessStoreStartScreenContainer( -@OptIn(ExperimentalMaterial3ExpressiveApi::class) -@PreviewLightDark -@Composable -private fun _RootlessStoreStratScreenContainerPrevierer_(){ - RootlessStoreTheme() { - RootlessStoreStartScreenContainer() - } -} +//@RequiresApi(Build.VERSION_CODES.TIRAMISU) +//@OptIn(ExperimentalMaterial3ExpressiveApi::class) +//@PreviewLightDark +//@Composable +//private fun _RootlessStoreStratScreenContainerPrevierer_(){ +// RootlessStoreTheme() { +// RootlessStoreStartScreenContainer() +// } +//}