diff --git a/docs/api/public/PackageParam.md b/docs/api/public/PackageParam.md index e56fb758..9b98d4c7 100644 --- a/docs/api/public/PackageParam.md +++ b/docs/api/public/PackageParam.md @@ -733,4 +733,18 @@ fun onConfigurationChanged(initiate: (self: Application, config: Configuration) **功能描述** -> 监听当前 Hook APP 装载 `Application.onConfigurationChanged`。 \ No newline at end of file +> 监听当前 Hook APP 装载 `Application.onConfigurationChanged`。 + +#### registerReceiver [method] + +```kotlin +fun registerReceiver(vararg action: String, initiate: (context: Context, intent: Intent) -> Unit) +``` + +**变更记录** + +`v1.0.88` `新增` + +**功能描述** + +> 注册系统广播监听。 \ No newline at end of file diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt index 42ff4cd1..5188045f 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/param/PackageParam.kt @@ -31,6 +31,7 @@ package com.highcapable.yukihookapi.hook.param import android.app.Application import android.content.Context +import android.content.Intent import android.content.pm.ApplicationInfo import android.content.res.Configuration import android.content.res.Resources @@ -46,6 +47,8 @@ import com.highcapable.yukihookapi.hook.factory.hasClass import com.highcapable.yukihookapi.hook.factory.hookClass import com.highcapable.yukihookapi.hook.param.type.HookEntryType import com.highcapable.yukihookapi.hook.param.wrapper.PackageParamWrapper +import com.highcapable.yukihookapi.hook.utils.putIfAbsentCompat +import com.highcapable.yukihookapi.hook.utils.value import com.highcapable.yukihookapi.hook.xposed.bridge.YukiHookBridge import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiModuleResources import com.highcapable.yukihookapi.hook.xposed.bridge.dummy.YukiResources @@ -456,6 +459,16 @@ open class PackageParam internal constructor(@PublishedApi internal var wrapper: YukiHookBridge.AppLifecycleCallback.onConfigurationChangedCallback = initiate } + /** + * 注册系统广播监听 + * @param action 系统广播 Action + * @param initiate 回调 - ([Context] 当前上下文,[Intent] 当前 Intent) + */ + fun registerReceiver(vararg action: String, initiate: (context: Context, intent: Intent) -> Unit) { + if (action.isNotEmpty()) + YukiHookBridge.AppLifecycleCallback.onReceiversCallback.putIfAbsentCompat(action.value(), Pair(action, initiate)) + } + /** 设置创建生命周期监听回调 */ @PublishedApi internal fun build() { diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt index da4c1d88..0aebc3e6 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/utils/UtilsFactory.kt @@ -30,6 +30,17 @@ package com.highcapable.yukihookapi.hook.utils import android.os.Build import com.highcapable.yukihookapi.annotation.YukiPrivateApi +/** + * 获取数组内容依次列出的字符串表示 + * @return [String] + */ +@YukiPrivateApi +inline fun Array.value() = if (isNotEmpty()) { + var value = "" + forEach { value += it.toString() + ", " } + "[${value.trim().let { it.substring(0, it.lastIndex) }}]" +} else "[]" + /** * 不重复写入 [HashMap] * diff --git a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookBridge.kt b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookBridge.kt index d711d71f..b18542d6 100644 --- a/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookBridge.kt +++ b/yukihookapi/src/api/kotlin/com/highcapable/yukihookapi/hook/xposed/bridge/YukiHookBridge.kt @@ -30,7 +30,10 @@ package com.highcapable.yukihookapi.hook.xposed.bridge import android.app.Application +import android.content.BroadcastReceiver import android.content.Context +import android.content.Intent +import android.content.IntentFilter import android.content.pm.ApplicationInfo import android.content.res.Configuration import android.content.res.Resources @@ -265,6 +268,14 @@ object YukiHookBridge { (wrapper.args?.get(0) as? Application?)?.also { hostApplication = it AppLifecycleCallback.onCreateCallback?.invoke(it) + AppLifecycleCallback.onReceiversCallback.takeIf { e -> e.isNotEmpty() }?.forEach { (_, e) -> + if (e.first.isNotEmpty()) it.registerReceiver(object : BroadcastReceiver() { + override fun onReceive(context: Context?, intent: Intent?) { + if (context == null || intent == null) return + if (e.first.any { a -> a == intent.action }) e.second(context, intent) + } + }, IntentFilter().apply { e.first.forEach { a -> addAction(a) } }) + } if (isDataChannelRegister) return isDataChannelRegister = true runCatching { YukiHookDataChannel.instance().register(it, packageName) } @@ -397,6 +408,9 @@ object YukiHookBridge { /** [Application.onConfigurationChanged] 回调 */ internal var onConfigurationChangedCallback: ((Application, Configuration) -> Unit)? = null + + /** 系统广播监听回调 */ + internal val onReceiversCallback = HashMap, (Context, Intent) -> Unit>>() } /**