Android: Use OpenDocument for NFC figures and fix crash (Fixes #13956)

- Switch from ActivityResultContracts.GetContent() to OpenDocument()
  which restores ACTION_OPEN_DOCUMENT behavior, granting write access
  to file descriptors opened in C++ via ContentHandler.openFd().
- Replace unsafe force-unwraps (!!) in EmulationActivity with null checks.
This commit is contained in:
Sergio Torres
2026-08-26 00:49:43 +02:00
parent 123d32248e
commit b1e360e1e4
4 changed files with 21 additions and 13 deletions
@@ -43,6 +43,7 @@ import org.dolphinemu.dolphinemu.features.infinitybase.ui.FigureSlotAdapter
import org.dolphinemu.dolphinemu.features.input.model.ControllerInterface
import org.dolphinemu.dolphinemu.features.input.model.DolphinSensorEventListener
import org.dolphinemu.dolphinemu.features.settings.model.BooleanSetting
import org.dolphinemu.dolphinemu.utils.ContentHandler
import org.dolphinemu.dolphinemu.features.settings.model.IntSetting
import org.dolphinemu.dolphinemu.features.settings.model.Settings
import org.dolphinemu.dolphinemu.features.settings.model.StringSetting
@@ -104,17 +105,21 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
}
val requestSkylanderFile = registerForActivityResult(
ActivityResultContracts.GetContent()
ActivityResultContracts.OpenDocument()
) { uri: Uri? ->
if (uri != null) {
val slot = SkylanderConfig.loadSkylander(
skylanderSlots[skylanderSlot].portalSlot,
uri.toString()
)!!
clearSkylander(skylanderSlot)
skylanderSlots[skylanderSlot].portalSlot = slot.first!!
skylanderSlots[skylanderSlot].label = slot.second!!
skylandersBinding.figureManager.adapter!!.notifyItemChanged(skylanderSlot)
)
if (slot != null && slot.first != null && slot.second != null) {
clearSkylander(skylanderSlot)
skylanderSlots[skylanderSlot].portalSlot = slot.first!!
skylanderSlots[skylanderSlot].label = slot.second!!
skylandersBinding.figureManager.adapter?.notifyItemChanged(skylanderSlot)
} else {
Toast.makeText(this, R.string.skylander_load_failed, Toast.LENGTH_SHORT).show()
}
skylanderSlot = -1
skylanderData = Skylander.BLANK_SKYLANDER
}
@@ -131,10 +136,12 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
uri.toString(),
skylanderSlots[skylanderSlot].portalSlot
)
clearSkylander(skylanderSlot)
skylanderSlots[skylanderSlot].portalSlot = slot.first
skylanderSlots[skylanderSlot].label = slot.second
skylandersBinding.figureManager.adapter?.notifyItemChanged(skylanderSlot)
if (slot.first != -1) {
clearSkylander(skylanderSlot)
skylanderSlots[skylanderSlot].portalSlot = slot.first
skylanderSlots[skylanderSlot].label = slot.second
skylandersBinding.figureManager.adapter?.notifyItemChanged(skylanderSlot)
}
skylanderSlot = -1
skylanderData = Skylander.BLANK_SKYLANDER
}
@@ -142,7 +149,7 @@ class EmulationActivity : AppCompatActivity(), ThemeProvider {
}
val requestInfinityFigureFile = registerForActivityResult(
ActivityResultContracts.GetContent()
ActivityResultContracts.OpenDocument()
) { uri: Uri? ->
if (uri != null) {
val label = InfinityConfig.loadFigure(infinityPosition, uri.toString())
@@ -51,7 +51,7 @@ class FigureSlotAdapter(
holder.binding.buttonLoadFigure.setOnClickListener {
activity.setInfinityFigureData(0, "", figure.position, position)
activity.requestInfinityFigureFile.launch("*/*")
activity.requestInfinityFigureFile.launch(arrayOf("*/*"))
}
val inflater = LayoutInflater.from(activity)
@@ -47,7 +47,7 @@ class SkylanderSlotAdapter(
holder.binding.buttonLoadFigure.setOnClickListener {
activity.setSkylanderData(0, 0, "", position)
activity.requestSkylanderFile.launch("*/*")
activity.requestSkylanderFile.launch(arrayOf("*/*"))
}
val inflater = LayoutInflater.from(activity)
@@ -956,6 +956,7 @@ It can efficiently compress both junk data and encrypted Wii data.
<string name="skylander_id">ID</string>
<string name="skylander_variant">Variant</string>
<string name="invalid_skylander">Invalid Skylander Selection</string>
<string name="skylander_load_failed">Failed to load Skylander figure</string>
<string name="emulate_infinity_base">Infinity Base</string>
<string name="infinity_manager">Infinity Manager</string>