Skip to content

Commit 268303d

Browse files
committed
fix: prevent image picker crash
1 parent 5daa457 commit 268303d

2 files changed

Lines changed: 54 additions & 10 deletions

File tree

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ android {
1212
minSdk = 30
1313
targetSdk = 36
1414
versionCode = 1
15-
versionName = "0.3"
15+
versionName = "0.4"
1616
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
1717
}
1818

app/src/main/java/com/yureitzk/nophotopickerapi/MainHook.kt

Lines changed: 53 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import android.content.Intent
55
import android.os.Build
66
import android.os.ext.SdkExtensions
77
import android.provider.MediaStore
8+
import android.util.Log
89
import de.robv.android.xposed.IXposedHookLoadPackage
910
import de.robv.android.xposed.XC_MethodHook
1011
import de.robv.android.xposed.XposedBridge
@@ -15,6 +16,7 @@ class MainHook : IXposedHookLoadPackage {
1516

1617
companion object {
1718
private const val TAG = "NoPhotoPicker"
19+
private const val FLAG = "x_handled_by_nophoto"
1820
}
1921

2022
fun XC_LoadPackage.LoadPackageParam.isSystemFramework(): Boolean {
@@ -27,14 +29,14 @@ class MainHook : IXposedHookLoadPackage {
2729
hookSystemServices(lpparam)
2830
}
2931
lpparam.packageName != null -> {
32+
hookInstrumentation(lpparam)
3033
hookActivity(lpparam)
3134
hookActivityResult(lpparam)
3235
}
3336
}
3437
}
3538

3639
private fun hookSystemServices(lpparam: XC_LoadPackage.LoadPackageParam) {
37-
// Try to find which service class exists
3840
val classLoader = lpparam.classLoader
3941
val serviceClasses = listOf(
4042
"com.android.server.wm.ActivityTaskManagerService",
@@ -50,11 +52,39 @@ class MainHook : IXposedHookLoadPackage {
5052
"startActivity",
5153
createIntentInterceptor("System:$className")
5254
)
53-
XposedBridge.log("$TAG: Hooked $className")
55+
56+
Log.d(TAG, "Hooked $className")
5457
return
5558
}
5659
}
5760
}
61+
private fun hookInstrumentation(lpparam: XC_LoadPackage.LoadPackageParam) {
62+
try {
63+
XposedHelpers.findAndHookMethod(
64+
android.app.Instrumentation::class.java,
65+
"execStartActivity",
66+
android.content.Context::class.java,
67+
android.os.IBinder::class.java,
68+
android.os.IBinder::class.java,
69+
Activity::class.java,
70+
Intent::class.java,
71+
Int::class.javaPrimitiveType,
72+
android.os.Bundle::class.java,
73+
object : XC_MethodHook() {
74+
override fun beforeHookedMethod(param: MethodHookParam) {
75+
val intent = param.args[4] as? Intent ?: return
76+
if (isPhotoPickerIntent(intent)) {
77+
logIntentDetails(intent, "Instrumentation.execStartActivity")
78+
param.args[4] = buildDocumentPickerIntent(intent)
79+
}
80+
}
81+
}
82+
)
83+
Log.d(TAG, "Hooked Instrumentation for ${lpparam.packageName}")
84+
} catch (t: Throwable) {
85+
XposedBridge.log("$TAG: Failed to hook Instrumentation: ${t.message}")
86+
}
87+
}
5888

5989
private fun createIntentInterceptor(source: String): XC_MethodHook {
6090
return object : XC_MethodHook() {
@@ -63,9 +93,18 @@ class MainHook : IXposedHookLoadPackage {
6393
for (i in args.indices) {
6494
if (args[i] is Intent) {
6595
val intent = args[i] as Intent
96+
6697
if (isPhotoPickerIntent(intent)) {
6798
logIntentDetails(intent, "$source.startActivity")
68-
args[i] = buildDocumentPickerIntent(intent)
99+
100+
val newIntent = buildDocumentPickerIntent(intent)
101+
102+
args[i] = newIntent
103+
104+
if (i + 1 < args.size && (args[i + 1] == null || args[i + 1] is String)) {
105+
val newType = newIntent.type ?: "*/*"
106+
args[i + 1] = newType
107+
Log.d(TAG, "Updated resolvedType to $newType") }
69108
return
70109
}
71110
}
@@ -83,6 +122,9 @@ class MainHook : IXposedHookLoadPackage {
83122
object : XC_MethodHook() {
84123
override fun beforeHookedMethod(param: MethodHookParam) {
85124
val intent = param.args[0] as? Intent ?: return
125+
126+
if (intent.hasExtra(FLAG)) return
127+
86128
if (isPhotoPickerIntent(intent)) {
87129
logIntentDetails(intent, "App.Activity.startActivity")
88130
param.args[0] = buildDocumentPickerIntent(intent)
@@ -107,7 +149,7 @@ class MainHook : IXposedHookLoadPackage {
107149
}
108150
)
109151

110-
XposedBridge.log("$TAG: Successfully hooked Activity methods for ${lpparam.packageName}")
152+
Log.d(TAG, "Successfully hooked Activity methods for ${lpparam.packageName}")
111153
} catch (t: Throwable) {
112154
XposedBridge.log("$TAG: Failed to hook Activity: ${t.message}")
113155
}
@@ -141,7 +183,7 @@ class MainHook : IXposedHookLoadPackage {
141183
}
142184

143185
if (!hasContent) {
144-
XposedBridge.log("$TAG: Empty result detected for request $requestCode")
186+
Log.d(TAG, "Empty result detected for request $requestCode")
145187
param.args[1] = Activity.RESULT_CANCELED
146188
param.args[2] = null
147189
}
@@ -165,6 +207,7 @@ class MainHook : IXposedHookLoadPackage {
165207
}
166208

167209
private fun isPhotoPickerIntent(intent: Intent): Boolean {
210+
if (intent.hasExtra(FLAG)) return false
168211
return when {
169212
Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU ->
170213
intent.action == MediaStore.ACTION_PICK_IMAGES
@@ -177,8 +220,8 @@ class MainHook : IXposedHookLoadPackage {
177220
}
178221

179222
private fun logIntentDetails(intent: Intent, source: String) {
180-
XposedBridge.log("$TAG: [$source] Photo picker detected")
181-
XposedBridge.log(" Action: ${intent.action}")
223+
Log.d(TAG, "[$source] Photo picker detected")
224+
Log.d(TAG, " Action: ${intent.action}")
182225
}
183226

184227
private fun buildDocumentPickerIntent(original: Intent): Intent {
@@ -208,11 +251,12 @@ class MainHook : IXposedHookLoadPackage {
208251

209252
if (shouldAllowMultiple) {
210253
putExtra(Intent.EXTRA_ALLOW_MULTIPLE, true)
211-
XposedBridge.log("$TAG: Multi-select enabled")
254+
Log.d(TAG, "Multi-select enabled")
212255
}
213256

257+
putExtra(FLAG, true)
214258
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
215-
XposedBridge.log("$TAG: Created document picker intent")
259+
Log.d(TAG, "Created document picker intent")
216260
}
217261
}
218262
}

0 commit comments

Comments
 (0)