ソースを参照

improve stk menu handling (#162)

Reviewed-on: https://gitea.angry.im/PeterCxy/OpenEUICC/pulls/162
Co-authored-by: septs <github@septs.pw>
Co-committed-by: septs <github@septs.pw>
septs 11 ヶ月 前
コミット
d068261ff9

+ 19 - 12
app-unpriv/src/main/java/im/angry/openeuicc/ui/UnprivilegedEuiccManagementFragment.kt

@@ -4,6 +4,7 @@ import android.content.pm.PackageManager
 import android.provider.Settings
 import android.view.Menu
 import android.view.MenuInflater
+import android.view.MenuItem
 import android.widget.Toast
 import im.angry.easyeuicc.R
 import im.angry.openeuicc.util.SIMToolkit
@@ -26,21 +27,27 @@ class UnprivilegedEuiccManagementFragment : EuiccManagementFragment() {
     override fun onCreateOptionsMenu(menu: Menu, inflater: MenuInflater) {
         super.onCreateOptionsMenu(menu, inflater)
         inflater.inflate(R.menu.fragment_sim_toolkit, menu)
+    }
+
+    override fun onPrepareOptionsMenu(menu: Menu) {
+        super.onPrepareOptionsMenu(menu)
         menu.findItem(R.id.open_sim_toolkit).apply {
-            val slot = stk[slotId] ?: return@apply
-            isVisible = slot.intent != null
-            setOnMenuItemClickListener {
-                val intent = slot.intent ?: return@setOnMenuItemClickListener false
-                if (intent.action == Settings.ACTION_APPLICATION_DETAILS_SETTINGS) {
-                    val packageName = intent.data!!.schemeSpecificPart
-                    val label = requireContext().packageManager.getApplicationLabel(packageName)
-                    val message = requireContext().getString(R.string.toast_prompt_to_enable_sim_toolkit, label)
-                    Toast.makeText(context, message, Toast.LENGTH_LONG).show()
-                }
-                startActivity(intent)
-                true
+            intent = stk[slotId]?.intent
+            isVisible = intent != null
+        }
+    }
+
+    override fun onOptionsItemSelected(item: MenuItem) = when (item.itemId) {
+        R.id.open_sim_toolkit -> {
+            SIMToolkit.getDisabledPackageName(item.intent)?.also { packageName ->
+                val label = requireContext().packageManager.getApplicationLabel(packageName)
+                val message = getString(R.string.toast_prompt_to_enable_sim_toolkit, label)
+                Toast.makeText(requireContext(), message, Toast.LENGTH_LONG).show()
             }
+            super.onOptionsItemSelected(item) // handling intent
         }
+
+        else -> super.onOptionsItemSelected(item)
     }
 }
 

+ 20 - 23
app-unpriv/src/main/java/im/angry/openeuicc/util/SIMToolkit.kt

@@ -7,7 +7,6 @@ import android.content.pm.ActivityInfo
 import android.content.pm.PackageManager
 import android.net.Uri
 import android.provider.Settings
-import android.widget.Toast
 import androidx.annotation.ArrayRes
 import im.angry.easyeuicc.R
 import im.angry.openeuicc.core.EuiccChannelManager
@@ -32,9 +31,10 @@ class SIMToolkit(private val context: Context) {
     data class Slot(private val packageManager: PackageManager, private val components: Set<ComponentName>) {
         private val packageNames: Iterable<String>
             get() = components.map(ComponentName::getPackageName).toSet()
+                .filter(packageManager::isInstalledApp)
 
         private val launchIntent: Intent?
-            get() = packageNames.firstNotNullOfOrNull(packageManager::getLaunchIntent)
+            get() = packageNames.firstNotNullOfOrNull(packageManager::getLaunchIntentForPackage)
 
         private val activities: Iterable<ComponentName>
             get() = packageNames.flatMap(packageManager::getActivities)
@@ -50,23 +50,23 @@ class SIMToolkit(private val context: Context) {
         }
 
         private fun getDisabledPackageIntent(): Intent? {
-            val disabledPackageName = packageNames.find {
-                try {
-                    isDisabledState(packageManager.getApplicationEnabledSetting(it))
-                } catch (_: IllegalArgumentException) {
-                    false
-                }
-            }
-            if (disabledPackageName == null) return null
-            return Intent(
-                Settings.ACTION_APPLICATION_DETAILS_SETTINGS,
-                Uri.fromParts("package", disabledPackageName, null)
-            )
+            val disabledPackageName = packageNames
+                .find { isDisabledState(packageManager.getApplicationEnabledSetting(it)) }
+                ?: return null
+            val uri = Uri.fromParts("package", disabledPackageName, null)
+            return Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS, uri)
         }
 
         val intent: Intent?
             get() = getActivityIntent() ?: getDisabledPackageIntent()
     }
+
+    companion object {
+        fun getDisabledPackageName(intent: Intent?): String? {
+            if (intent?.action != Settings.ACTION_APPLICATION_DETAILS_SETTINGS) return null
+            return intent.data?.schemeSpecificPart
+        }
+    }
 }
 
 private fun isDisabledState(state: Int) = when (state) {
@@ -75,15 +75,12 @@ private fun isDisabledState(state: Int) = when (state) {
     else -> false
 }
 
-private fun PackageManager.getLaunchIntent(packageName: String) = try {
-    getLaunchIntentForPackage(packageName)
+private fun PackageManager.isInstalledApp(packageName: String) = try {
+    getPackageInfo(packageName, 0)
+    true
 } catch (_: PackageManager.NameNotFoundException) {
-    null
+    false
 }
 
-private fun PackageManager.getActivities(packageName: String) = try {
-    getPackageInfo(packageName, PackageManager.GET_ACTIVITIES)
-        .activities?.toList() ?: emptyList()
-} catch (_: PackageManager.NameNotFoundException) {
-    emptyList()
-}
+private fun PackageManager.getActivities(packageName: String) =
+    getPackageInfo(packageName, PackageManager.GET_ACTIVITIES).activities?.toList() ?: emptyList()