Skip to content

Commit b766b77

Browse files
committed
Handle sharing system files crash
1 parent bf31a52 commit b766b77

File tree

20 files changed

+308
-25
lines changed

20 files changed

+308
-25
lines changed

app/src/main/java/com/ismartcoding/plain/helpers/ShareHelper.kt

Lines changed: 105 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ import com.ismartcoding.plain.Constants
1111
import com.ismartcoding.plain.R
1212
import com.ismartcoding.plain.features.locale.LocaleHelper.getString
1313
import com.ismartcoding.plain.ui.MainActivity
14+
import com.ismartcoding.plain.ui.helpers.DialogHelper
1415
import java.io.File
16+
import java.io.IOException
1517

1618
object ShareHelper {
1719
fun shareUri(
@@ -99,27 +101,94 @@ object ShareHelper {
99101
}
100102
}
101103

104+
/**
105+
* Check if a file can be accessed by the FileProvider
106+
*/
107+
private fun isFileAccessibleByProvider(file: File): Boolean {
108+
if (!file.exists() || !file.canRead()) {
109+
return false
110+
}
111+
112+
val path = file.absolutePath
113+
// Files in /apex/ directory are modular system components and cannot be shared via FileProvider
114+
if (path.startsWith("/apex/")) {
115+
return false
116+
}
117+
118+
// Files in other system directories may also be inaccessible
119+
if (path.startsWith("/system/") || path.startsWith("/vendor/") || path.startsWith("/product/")) {
120+
// Try to access the file to see if it's readable
121+
try {
122+
file.inputStream().use { it.read() }
123+
return true
124+
} catch (e: Exception) {
125+
return false
126+
}
127+
}
128+
129+
return true
130+
}
131+
102132
fun shareFile(
103133
context: Context,
104134
file: File
105135
) {
106-
val intent = Intent(Intent.ACTION_SEND)
107-
intent.type = file.path.getMimeType()
108-
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context, Constants.AUTHORITY, file))
109-
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
110-
val chooserIntent = Intent.createChooser(intent, getString(R.string.share))
111-
chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, getExcludeComponentNames(context).toTypedArray())
112-
context.startActivity(chooserIntent)
136+
// Check if the file can be accessed by FileProvider
137+
if (!isFileAccessibleByProvider(file)) {
138+
// Show a message that this system file cannot be shared
139+
val errorMessage = if (file.absolutePath.startsWith("/apex/")) {
140+
getString(R.string.cannot_share_system_component)
141+
} else {
142+
getString(R.string.cannot_share_system_file)
143+
}
144+
DialogHelper.showErrorMessage(errorMessage)
145+
return
146+
}
147+
148+
try {
149+
val intent = Intent(Intent.ACTION_SEND)
150+
intent.type = file.path.getMimeType()
151+
intent.putExtra(Intent.EXTRA_STREAM, FileProvider.getUriForFile(context, Constants.AUTHORITY, file))
152+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
153+
val chooserIntent = Intent.createChooser(intent, getString(R.string.share))
154+
chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, getExcludeComponentNames(context).toTypedArray())
155+
context.startActivity(chooserIntent)
156+
} catch (e: IllegalArgumentException) {
157+
// This handles the "Failed to find configured root" error
158+
val errorMessage = getString(R.string.cannot_share_file_not_accessible)
159+
DialogHelper.showErrorMessage(errorMessage)
160+
} catch (e: Exception) {
161+
DialogHelper.showErrorMessage(e.message ?: getString(R.string.unknown_error))
162+
}
113163
}
114164

115165
fun shareFiles(
116166
context: Context,
117167
files: List<File>,
118168
) {
119169
val fileUris = arrayListOf<Uri>()
170+
val inaccessibleFiles = mutableListOf<String>()
120171

121172
for (file in files) {
122-
fileUris.add(FileProvider.getUriForFile(context, Constants.AUTHORITY, file))
173+
if (isFileAccessibleByProvider(file)) {
174+
try {
175+
fileUris.add(FileProvider.getUriForFile(context, Constants.AUTHORITY, file))
176+
} catch (e: IllegalArgumentException) {
177+
inaccessibleFiles.add(file.name)
178+
}
179+
} else {
180+
inaccessibleFiles.add(file.name)
181+
}
182+
}
183+
184+
if (fileUris.isEmpty()) {
185+
DialogHelper.showErrorMessage(getString(R.string.cannot_share_any_files))
186+
return
187+
}
188+
189+
if (inaccessibleFiles.isNotEmpty()) {
190+
val message = getString(R.string.some_files_cannot_be_shared) + ": ${inaccessibleFiles.joinToString(", ")}"
191+
DialogHelper.showErrorMessage(message)
123192
}
124193

125194
val intent = Intent(Intent.ACTION_SEND_MULTIPLE)
@@ -135,16 +204,33 @@ object ShareHelper {
135204
context: Context,
136205
path: String,
137206
) {
138-
val intent = Intent()
139-
intent.action = Intent.ACTION_VIEW
140-
intent.addCategory(Intent.CATEGORY_DEFAULT)
141-
val uri = FileProvider.getUriForFile(context, Constants.AUTHORITY, File(path))
142-
val mimeType = path.getMimeType()
143-
intent.setDataAndType(uri, mimeType)
144-
intent.putExtra("mimeType", mimeType)
145-
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
146-
val chooserIntent = Intent.createChooser(intent, getString(R.string.open_with))
147-
chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, getExcludeComponentNames(context).toTypedArray())
148-
context.startActivity(chooserIntent)
207+
val file = File(path)
208+
if (!isFileAccessibleByProvider(file)) {
209+
val errorMessage = if (file.absolutePath.startsWith("/apex/")) {
210+
getString(R.string.cannot_open_system_component)
211+
} else {
212+
getString(R.string.cannot_open_system_file)
213+
}
214+
DialogHelper.showErrorMessage(errorMessage)
215+
return
216+
}
217+
218+
try {
219+
val intent = Intent()
220+
intent.action = Intent.ACTION_VIEW
221+
intent.addCategory(Intent.CATEGORY_DEFAULT)
222+
val uri = FileProvider.getUriForFile(context, Constants.AUTHORITY, file)
223+
val mimeType = path.getMimeType()
224+
intent.setDataAndType(uri, mimeType)
225+
intent.putExtra("mimeType", mimeType)
226+
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
227+
val chooserIntent = Intent.createChooser(intent, getString(R.string.open_with))
228+
chooserIntent.putExtra(Intent.EXTRA_EXCLUDE_COMPONENTS, getExcludeComponentNames(context).toTypedArray())
229+
context.startActivity(chooserIntent)
230+
} catch (e: IllegalArgumentException) {
231+
DialogHelper.showErrorMessage(getString(R.string.cannot_open_file_not_accessible))
232+
} catch (e: Exception) {
233+
DialogHelper.showErrorMessage(e.message ?: getString(R.string.unknown_error))
234+
}
149235
}
150236
}

app/src/main/java/com/ismartcoding/plain/ui/helpers/DialogHelper.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,14 @@ object DialogHelper {
2525
ToastManager.showInfoToast(message, durationMs)
2626
}
2727

28+
fun showErrorMessage(
29+
message: String,
30+
duration: Int = Toast.LENGTH_SHORT,
31+
) {
32+
val durationMs = if (duration == Toast.LENGTH_SHORT) 2000L else 3500L
33+
ToastManager.showErrorToast(message, durationMs)
34+
}
35+
2836
fun showSuccess(resId: Int) {
2937
ToastManager.showSuccessToast(getString(resId), 2000L)
3038
}

app/src/main/java/com/ismartcoding/plain/ui/page/apps/AppPage.kt

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,34 @@ import kotlinx.coroutines.Dispatchers
6161
import kotlinx.coroutines.launch
6262
import java.io.File
6363

64+
/**
65+
* Check if a file can be shared through the app's FileProvider
66+
*/
67+
private fun isFileShareable(file: File): Boolean {
68+
if (!file.exists() || !file.canRead()) {
69+
return false
70+
}
71+
72+
val path = file.absolutePath
73+
// Files in /apex/ directory are modular system components and cannot be shared via FileProvider
74+
if (path.startsWith("/apex/")) {
75+
return false
76+
}
77+
78+
// Files in other system directories may also be inaccessible
79+
if (path.startsWith("/system/") || path.startsWith("/vendor/") || path.startsWith("/product/")) {
80+
// Try to access the file to see if it's readable
81+
try {
82+
file.inputStream().use { it.read() }
83+
return true
84+
} catch (e: Exception) {
85+
return false
86+
}
87+
}
88+
89+
return true
90+
}
91+
6492
@SuppressLint("MissingPermission")
6593
@OptIn(ExperimentalMaterial3Api::class)
6694
@Composable
@@ -71,6 +99,7 @@ fun AppPage(
7199
val context = LocalContext.current
72100
val scope = rememberCoroutineScope()
73101
var item by remember { mutableStateOf<DPackageDetail?>(null) }
102+
var isShareable by remember { mutableStateOf(true) }
74103
val lifecycleEvent = rememberLifecycleEvent()
75104
LaunchedEffect(lifecycleEvent) {
76105
if (lifecycleEvent == Lifecycle.Event.ON_RESUME) {
@@ -83,6 +112,10 @@ fun AppPage(
83112
LaunchedEffect(Unit) {
84113
scope.launch(Dispatchers.IO) {
85114
item = PackageHelper.getPackageDetail(id)
115+
// Check if the APK file can be shared
116+
item?.let { packageDetail ->
117+
isShareable = isFileShareable(File(packageDetail.path))
118+
}
86119
}
87120
}
88121

@@ -92,12 +125,14 @@ fun AppPage(
92125
navController = navController,
93126
title = item?.name ?: "",
94127
actions = {
95-
PIconButton(
96-
icon = R.drawable.share_2,
97-
contentDescription = stringResource(R.string.share),
98-
tint = MaterialTheme.colorScheme.onSurface,
99-
) {
100-
ShareHelper.shareFile(context, File(item?.path ?: ""))
128+
if (isShareable) {
129+
PIconButton(
130+
icon = R.drawable.share_2,
131+
contentDescription = stringResource(R.string.share),
132+
tint = MaterialTheme.colorScheme.onSurface,
133+
) {
134+
ShareHelper.shareFile(context, File(item?.path ?: ""))
135+
}
101136
}
102137
},
103138
)

app/src/main/res/values-bn/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,4 +564,13 @@
564564
<string name="no_internet_connection">নেটওয়ার্ক সংযোগ বন্ধ রয়েছে। দয়া করে আবার চেষ্টা করুন।</string>
565565
<string name="access_phone_web">একটি কম্পিউটার ব্রাউজার থেকে আপনার ফোন অ্যাক্সেস করুন।</string>
566566
<string name="scan_qrcode_to_access_web">ওয়েব ঠিকানা অ্যাক্সেস করতে QR কোড স্ক্যান করুন</string>
567+
<string name="cannot_share_system_component">সিস্টেম কম্পোনেন্ট শেয়ার করা যাবে না। এই ফাইলটি একটি সুরক্ষিত সিস্টেম মডিউল।</string>
568+
<string name="cannot_share_system_file">সিস্টেম ফাইল শেয়ার করা যাবে না। এই ফাইলটি অ্যাক্সেস করা যাবে না।</string>
569+
<string name="cannot_share_file_not_accessible">ফাইল শেয়ার করা যাবে না। এই ফাইলটি অ্যাপ দ্বারা অ্যাক্সেস করা যাবে না।</string>
570+
<string name="cannot_share_any_files">কোনও ফাইল শেয়ার করা যাবে না। সকল চয়নকৃত ফাইলগুলি অ্যাক্সেস করা যাবে না।</string>
571+
<string name="some_files_cannot_be_shared">কিছু ফাইলগুলি শেয়ার করা যাবে না</string>
572+
<string name="cannot_open_system_component">সিস্টেম কম্পোনেন্ট খুলতে ব্যর্থ। এই ফাইলটি একটি সুরক্ষিত সিস্টেম মডিউল।</string>
573+
<string name="cannot_open_system_file">সিস্টেম ফাইল খুলতে ব্যর্থ। এই ফাইলটি অ্যাক্সেস করা যাবে না।</string>
574+
<string name="cannot_open_file_not_accessible">ফাইল খুলতে ব্যর্থ। এই ফাইলটি অ্যাপ দ্বারা অ্যাক্সেস করা যাবে না।</string>
575+
<string name="unknown_error">অজানা ত্রুটি ঘটেছে।</string>
567576
</resources>

app/src/main/res/values-de/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,4 +564,13 @@
564564
<string name="no_internet_connection">Keine Internetverbindung. Bitte überprüfen Sie Ihre Verbindung.</string>
565565
<string name="access_phone_web">Greifen Sie über einen Computerbrowser auf Ihr Telefon zu.</string>
566566
<string name="scan_qrcode_to_access_web">Scannen Sie den QR-Code, um auf die Webadresse zuzugreifen</string>
567+
<string name="cannot_share_system_component">Systemkomponente kann nicht geteilt werden. Diese Datei ist ein geschütztes Systemmodul.</string>
568+
<string name="cannot_share_system_file">Systemdatei kann nicht geteilt werden. Diese Datei ist nicht zugänglich.</string>
569+
<string name="cannot_share_file_not_accessible">Datei kann nicht geteilt werden. Diese Datei ist nicht über die App zugänglich.</string>
570+
<string name="cannot_share_any_files">Keine Dateien können geteilt werden. Alle ausgewählten Dateien sind nicht zugänglich.</string>
571+
<string name="some_files_cannot_be_shared">Einige Dateien können nicht geteilt werden</string>
572+
<string name="cannot_open_system_component">Systemkomponente kann nicht geöffnet werden. Diese Datei ist ein geschütztes Systemmodul.</string>
573+
<string name="cannot_open_system_file">Systemdatei kann nicht geöffnet werden. Diese Datei ist nicht zugänglich.</string>
574+
<string name="cannot_open_file_not_accessible">Datei kann nicht geöffnet werden. Diese Datei ist nicht über die App zugänglich.</string>
575+
<string name="unknown_error">Ein unbekannter Fehler ist aufgetreten.</string>
567576
</resources>

app/src/main/res/values-es/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,4 +564,13 @@
564564
<string name="no_internet_connection">No hay conexión a internet. Por favor, verifica tu conexión.</string>
565565
<string name="access_phone_web">Accede a tu teléfono desde el navegador de una computadora.</string>
566566
<string name="scan_qrcode_to_access_web">Escanea el código QR para acceder a la dirección web</string>
567+
<string name="cannot_share_system_component">No se puede compartir el componente del sistema. Este archivo es un módulo del sistema protegido.</string>
568+
<string name="cannot_share_system_file">No se puede compartir el archivo del sistema. Este archivo no es accesible.</string>
569+
<string name="cannot_share_file_not_accessible">No se puede compartir el archivo. Este archivo no es accesible a través de la aplicación.</string>
570+
<string name="cannot_share_any_files">No se puede compartir ningún archivo. Todos los archivos seleccionados no son accesibles.</string>
571+
<string name="some_files_cannot_be_shared">Algunos archivos no se pueden compartir</string>
572+
<string name="cannot_open_system_component">No se puede abrir el componente del sistema. Este archivo es un módulo del sistema protegido.</string>
573+
<string name="cannot_open_system_file">No se puede abrir el archivo del sistema. Este archivo no es accesible.</string>
574+
<string name="cannot_open_file_not_accessible">No se puede abrir el archivo. Este archivo no es accesible a través de la aplicación.</string>
575+
<string name="unknown_error">Se produjo un error desconocido.</string>
567576
</resources>

app/src/main/res/values-fr/strings.xml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -563,4 +563,14 @@
563563
<string name="remove_from_playlist">Supprimer de la liste</string>
564564
<string name="no_internet_connection">Aucune connexion internet. Veuillez vérifier votre connexion.</string>
565565
<string name="access_phone_web">Accédez à votre téléphone depuis un navigateur sur un ordinateur.</string>
566+
<string name="scan_qrcode_to_access_web">Scannez le code QR ci-dessus pour accéder à votre téléphone depuis un navigateur sur un ordinateur.</string>
567+
<string name="cannot_share_system_component">Impossible de partager le composant du système. Ce fichier est un module du système protégé.</string>
568+
<string name="cannot_share_system_file">Impossible de partager le fichier du système. Ce fichier n\'est pas accessible.</string>
569+
<string name="cannot_share_file_not_accessible">Impossible de partager le fichier. Ce fichier n\'est pas accessible via l\'application.</string>
570+
<string name="cannot_share_any_files">Impossible de partager aucun fichier. Tous les fichiers sélectionnés ne sont pas accessibles.</string>
571+
<string name="some_files_cannot_be_shared">Certains fichiers ne peuvent pas être partagés</string>
572+
<string name="cannot_open_system_component">Impossible d\'ouvrir le composant du système. Ce fichier est un module du système protégé.</string>
573+
<string name="cannot_open_system_file">Impossible d\'ouvrir le fichier du système. Ce fichier n\'est pas accessible.</string>
574+
<string name="cannot_open_file_not_accessible">Impossible d\'ouvrir le fichier. Ce fichier n\'est pas accessible via l\'application.</string>
575+
<string name="unknown_error">Une erreur inconnue est survenue.</string>
566576
</resources>

app/src/main/res/values-hi/strings.xml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -564,4 +564,13 @@
564564
<string name="no_internet_connection">इंटरनेट कनेक्शन नहीं है। कृपया अपना नेटवर्क जांचें।</string>
565565
<string name="access_phone_web">कंप्यूटर ब्राउज़र से अपने फ़ोन तक पहुँचें।</string>
566566
<string name="scan_qrcode_to_access_web">वेब पता तक पहुँचने के लिए QR कोड स्कैन करें</string>
567+
<string name="cannot_share_system_component">सिस्टम घटक साझा करना संभव नहीं है। यह फ़ाइल एक सुरक्षित सिस्टम मॉड्यूल है।</string>
568+
<string name="cannot_share_system_file">सिस्टम फ़ाइल साझा करना संभव नहीं है। यह फ़ाइल पहुँच योग्य नहीं है।</string>
569+
<string name="cannot_share_file_not_accessible">फ़ाइल साझा करना संभव नहीं है। यह फ़ाइल ऐप द्वारा पहुँच योग्य नहीं है।</string>
570+
<string name="cannot_share_any_files">कोई फ़ाइल साझा करना संभव नहीं है। सभी चुने हुए फ़ाइलें पहुँच योग्य नहीं हैं।</string>
571+
<string name="some_files_cannot_be_shared">कुछ फ़ाइलें साझा करना संभव नहीं है</string>
572+
<string name="cannot_open_system_component">सिस्टम घटक खोलना संभव नहीं है। यह फ़ाइल एक सुरक्षित सिस्टम मॉड्यूल है।</string>
573+
<string name="cannot_open_system_file">सिस्टम फ़ाइल खोलना संभव नहीं है। यह फ़ाइल पहुँच योग्य नहीं है।</string>
574+
<string name="cannot_open_file_not_accessible">फ़ाइल खोलना संभव नहीं है। यह फ़ाइल ऐप द्वारा पहुँच योग्य नहीं है।</string>
575+
<string name="unknown_error">अजगर हो गया है।</string>
567576
</resources>

0 commit comments

Comments
 (0)