diff --git a/.idea/.gitignore b/.idea/.gitignore
index 26d3352..15161eb 100644
--- a/.idea/.gitignore
+++ b/.idea/.gitignore
@@ -1,3 +1,4 @@
# Default ignored files
/shelf/
/workspace.xml
+/deploymentTargetDropDown.xml
\ No newline at end of file
diff --git a/.idea/kotlinScripting.xml b/.idea/kotlinScripting.xml
deleted file mode 100644
index 26da98e..0000000
--- a/.idea/kotlinScripting.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
- 2147483647
-
-
-
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 48e55b4..c16f060 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -1,5 +1,6 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/DetailsActivity.kt b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/DetailsActivity.kt
index 4e4daf6..736e4bd 100644
--- a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/DetailsActivity.kt
+++ b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/DetailsActivity.kt
@@ -70,9 +70,9 @@ class DetailsActivity : ComponentActivity() {
private fun getPreferences() {
val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this)
skipFileDetails =
- sharedPreferences.getBoolean(SharedPreferenceKeys.skipFileDetailsKey, false)
+ sharedPreferences.getBoolean(SharedPreferenceKeys.SKIP_FILE_DETAILS_KEY, false)
val defaultSaveLocationRaw =
- sharedPreferences.getString(SharedPreferenceKeys.defaultSaveLocationKey, null)
+ sharedPreferences.getString(SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY, null)
Log.d("details] defaultSaveLocationRaw", defaultSaveLocationRaw.toString())
defaultSaveLocation = if (defaultSaveLocationRaw != null) Uri.parse(defaultSaveLocationRaw)
else null
@@ -84,8 +84,7 @@ class DetailsActivity : ComponentActivity() {
if (intent.action == Intent.ACTION_SEND) {
val fileUri: Uri? =
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) intent.getParcelableExtra(
- Intent.EXTRA_STREAM,
- Uri::class.java
+ Intent.EXTRA_STREAM, Uri::class.java
)
else @Suppress("DEPRECATION") intent.getParcelableExtra(Intent.EXTRA_STREAM)
Log.d("fileUri", fileUri.toString())
diff --git a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/MainActivity.kt b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/MainActivity.kt
index 676f1e6..1fd9202 100644
--- a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/MainActivity.kt
+++ b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/MainActivity.kt
@@ -46,7 +46,7 @@ class MainActivity : ComponentActivity() {
enableEdgeToEdge()
super.onCreate(savedInstanceState)
- settingsViewModel.receiveContext(applicationContext)
+ settingsViewModel.initializeWithContext(applicationContext)
settingsViewModel.assignSaveLocationDirIntent(getSaveLocationDirIntent)
settingsViewModel.initPreferences()
diff --git a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/SettingsViewModel.kt b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/SettingsViewModel.kt
index 0ea1024..66ecc18 100644
--- a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/SettingsViewModel.kt
+++ b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/SettingsViewModel.kt
@@ -17,10 +17,15 @@
package com.mateusrodcosta.apps.share2storage
+import android.content.ComponentName
import android.content.ContentResolver
import android.content.Context
import android.content.Intent
import android.content.SharedPreferences
+import android.content.pm.PackageManager
+import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+import android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED
+import android.content.pm.PackageManager.DONT_KILL_APP
import android.net.Uri
import android.util.Log
import androidx.activity.result.ActivityResultLauncher
@@ -34,8 +39,10 @@ import kotlinx.coroutines.flow.StateFlow
class SettingsViewModel : ViewModel() {
private lateinit var sharedPreferences: SharedPreferences
+ private lateinit var packageManager: PackageManager
private lateinit var contentResolver: ContentResolver
private lateinit var getSaveLocationDirIntent: ActivityResultLauncher
+ private lateinit var packageName: String
private val _defaultSaveLocation = MutableStateFlow(null)
val defaultSaveLocation: StateFlow = _defaultSaveLocation
@@ -43,6 +50,10 @@ class SettingsViewModel : ViewModel() {
private val _skipFileDetails = MutableStateFlow(false)
val skipFileDetails: StateFlow = _skipFileDetails
+
+ private val _interceptActionViewIntents = MutableStateFlow(false)
+ val interceptActionViewIntents: StateFlow = _interceptActionViewIntents
+
fun assignSaveLocationDirIntent(intent: ActivityResultLauncher) {
getSaveLocationDirIntent = intent
}
@@ -51,14 +62,16 @@ class SettingsViewModel : ViewModel() {
return getSaveLocationDirIntent
}
- fun receiveContext(context: Context) {
+ fun initializeWithContext(context: Context) {
sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
contentResolver = context.contentResolver
+ packageManager = context.packageManager
+ packageName = context.packageName
}
fun initPreferences() {
val spDefaultSaveLocationRaw =
- sharedPreferences.getString(SharedPreferenceKeys.defaultSaveLocationKey, null)
+ sharedPreferences.getString(SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY, null)
val spDefaultSaveLocation = if (spDefaultSaveLocationRaw != null) try {
val uri = Uri.parse(spDefaultSaveLocationRaw)
@@ -72,22 +85,30 @@ class SettingsViewModel : ViewModel() {
else null
val spSkipFileDetails =
- sharedPreferences.getBoolean(SharedPreferenceKeys.skipFileDetailsKey, false)
+ sharedPreferences.getBoolean(SharedPreferenceKeys.SKIP_FILE_DETAILS_KEY, false)
Log.d("settings] initSharedPreferences] skipFileDetails", spSkipFileDetails.toString())
+ val spInterceptActionViewIntents = sharedPreferences.getBoolean(
+ SharedPreferenceKeys.INTERCEPT_ACTION_VIEW_INTENTS_KEY, false
+ )
+ Log.d(
+ "settings] initSharedPreferences] interceptActionViewIntents",
+ spInterceptActionViewIntents.toString()
+ )
_defaultSaveLocation.value = spDefaultSaveLocation
_skipFileDetails.value = spSkipFileDetails
+ _interceptActionViewIntents.value = spInterceptActionViewIntents
}
fun updateDefaultSaveLocation(value: Uri?) {
val currentSaveLocationRaw =
- sharedPreferences.getString(SharedPreferenceKeys.defaultSaveLocationKey, null)
+ sharedPreferences.getString(SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY, null)
sharedPreferences.edit(commit = true) {
if (value != null) putString(
- SharedPreferenceKeys.defaultSaveLocationKey, value.toString()
+ SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY, value.toString()
)
- else remove(SharedPreferenceKeys.defaultSaveLocationKey)
+ else remove(SharedPreferenceKeys.DEFAULT_SAVE_LOCATION_KEY)
}
@@ -126,9 +147,32 @@ class SettingsViewModel : ViewModel() {
fun updateSkipFileDetails(value: Boolean) {
sharedPreferences.edit(commit = true) {
- putBoolean(SharedPreferenceKeys.skipFileDetailsKey, value)
+ putBoolean(SharedPreferenceKeys.SKIP_FILE_DETAILS_KEY, value)
}
_skipFileDetails.value = value
}
+
+ fun updateInterceptActionViewIntents(value: Boolean) {
+ sharedPreferences.edit(commit = true) {
+ putBoolean(SharedPreferenceKeys.INTERCEPT_ACTION_VIEW_INTENTS_KEY, value)
+ Log.e("settings] updateInterceptActionViewIntents", value.toString())
+
+ try {
+ val component = ComponentName(
+ packageName,
+ "com.mateusrodcosta.apps.share2storage.DetailsActivityActionViewIntentInterceptor"
+ )
+ packageManager.setComponentEnabledSetting(
+ component,
+ if (value) COMPONENT_ENABLED_STATE_ENABLED else COMPONENT_ENABLED_STATE_DISABLED,
+ DONT_KILL_APP
+ )
+
+ _interceptActionViewIntents.value = value
+ } catch (e: Exception) {
+ Log.e("settings] updateInterceptActionViewIntents", e.toString())
+ }
+ }
+ }
}
\ No newline at end of file
diff --git a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/screens/SettingsScreen.kt b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/screens/SettingsScreen.kt
index 1675c17..eaa6dbf 100644
--- a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/screens/SettingsScreen.kt
+++ b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/screens/SettingsScreen.kt
@@ -63,25 +63,29 @@ import kotlinx.coroutines.flow.StateFlow
fun SettingsScreenPreview() {
val mockDefaultSaveLocation = MutableStateFlow(null)
val mockSkipFileDetails = MutableStateFlow(false)
+ val mockInterceptActionViewIntents = MutableStateFlow(false)
SettingsScreenContent(
spDefaultSaveLocation = mockDefaultSaveLocation,
spSkipFileDetails = mockSkipFileDetails,
+ spInterceptActionViewIntents = mockInterceptActionViewIntents,
)
}
@Composable
fun SettingsScreen(navController: NavController, settingsViewModel: SettingsViewModel) {
- SettingsScreenContent(
- navController = navController,
+ SettingsScreenContent(navController = navController,
spDefaultSaveLocation = settingsViewModel.defaultSaveLocation,
spSkipFileDetails = settingsViewModel.skipFileDetails,
+ spInterceptActionViewIntents = settingsViewModel.interceptActionViewIntents,
launchFilePicker = { settingsViewModel.getSaveLocationDirIntent().launch(null) },
clearSaveDirectory = { settingsViewModel.clearSaveDirectory() },
updateSkipFileDetails = { value: Boolean ->
settingsViewModel.updateSkipFileDetails(value)
},
- )
+ updateInterceptActionViewIntents = { value: Boolean ->
+ settingsViewModel.updateInterceptActionViewIntents(value)
+ })
}
@OptIn(ExperimentalMaterial3Api::class)
@@ -90,9 +94,11 @@ fun SettingsScreenContent(
navController: NavController? = null,
spDefaultSaveLocation: StateFlow,
spSkipFileDetails: StateFlow,
+ spInterceptActionViewIntents: StateFlow,
launchFilePicker: () -> Unit = {},
clearSaveDirectory: () -> Unit = {},
updateSkipFileDetails: (Boolean) -> Unit = {},
+ updateInterceptActionViewIntents: (Boolean) -> Unit = {},
) {
val settingsPadding = PaddingValues(horizontal = 16.dp, vertical = 8.dp)
@@ -123,6 +129,12 @@ fun SettingsScreenContent(
paddingValues = settingsPadding,
)
AppBasicDivider()
+ InterceptActionViewIntentsSetting(
+ updateInterceptActionViewIntents = updateInterceptActionViewIntents,
+ spInterceptActionViewIntents = spInterceptActionViewIntents,
+ paddingValues = settingsPadding,
+ )
+ AppBasicDivider()
DefaultSaveLocationSetting(
launchFilePicker = launchFilePicker,
clearSaveDirectory = clearSaveDirectory,
@@ -167,6 +179,39 @@ fun SkipFileDetailsSetting(
}
}
+
+@Composable
+fun InterceptActionViewIntentsSetting(
+ updateInterceptActionViewIntents: (Boolean) -> Unit,
+ spInterceptActionViewIntents: StateFlow,
+ paddingValues: PaddingValues,
+) {
+
+ val interceptActionViewIntents by spInterceptActionViewIntents.collectAsState()
+
+
+ Row(modifier = Modifier
+ .clickable { updateInterceptActionViewIntents(!interceptActionViewIntents) }
+ .padding(paddingValues)
+ .heightIn(min = 48.dp),
+ verticalAlignment = Alignment.CenterVertically) {
+ Column(modifier = Modifier.weight(1.0f)) {
+ Text(
+ stringResource(id = R.string.settings_intercept_action_view_intents),
+ style = MaterialTheme.typography.titleLarge,
+ )
+ Text(
+ stringResource(R.string.settings_intercept_action_view_intents_info),
+ style = MaterialTheme.typography.bodyLarge
+ )
+ }
+ Spacer(modifier = Modifier.width(8.dp))
+ Switch(checked = interceptActionViewIntents, onCheckedChange = { value ->
+ updateInterceptActionViewIntents(value)
+ })
+ }
+}
+
@Composable
fun DefaultSaveLocationSetting(
launchFilePicker: () -> Unit,
diff --git a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/utils/SharedPreferenceKeys.kt b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/utils/SharedPreferenceKeys.kt
index 842f014..b279a49 100644
--- a/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/utils/SharedPreferenceKeys.kt
+++ b/app/src/main/kotlin/com/mateusrodcosta/apps/share2storage/utils/SharedPreferenceKeys.kt
@@ -18,6 +18,7 @@
package com.mateusrodcosta.apps.share2storage.utils
object SharedPreferenceKeys {
- const val skipFileDetailsKey: String = "skip_file_details"
- const val defaultSaveLocationKey: String = "default_save_location"
+ const val SKIP_FILE_DETAILS_KEY: String = "skip_file_details"
+ const val DEFAULT_SAVE_LOCATION_KEY: String = "default_save_location"
+ const val INTERCEPT_ACTION_VIEW_INTENTS_KEY: String = "intercept_action_view_intents"
}
\ No newline at end of file
diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml
index 3d5c85d..bb4bf45 100644
--- a/app/src/main/res/values-pt-rBR/strings.xml
+++ b/app/src/main/res/values-pt-rBR/strings.xml
@@ -17,6 +17,8 @@
Configurações
Pular página de Detalhes do arquivo
Abrir seletor de arquivos assim que receber arquivo
+ Intercepta intents do tipo ACTION_VIEW
+ Permite registrar como uma opção quando aplicativos tentam automaticamente abrir um visualizador de arquivos
Local de salvamento padrão
Última pasta usada
Limpar
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index e6f73c6..1572bca 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -17,6 +17,8 @@
Settings
Skip File Details page
Open file picker as soon as file is received
+ Intercept ACTION_VIEW intents
+ Allow registering as an option when apps try to automatically open a file viewer
Default save location
Last used folder
Clear