fix: WFD IE 反射参数类型修复 + 日志改为 Log.i

问题:getMethod 使用 Int::class.java (java.lang.Integer) 查
找方法,但方法参数是原生 int (Integer.TYPE),导致 NoSuchMethod
Exception 被静默吞掉,WFD IE 实际从未生效。

修复:
1. 所有原生类型参数改为 Boolean.TYPE / Integer.TYPE
2. 日志从 Log.d 改为 Log.i,确保 logcat 可见
3. 每步操作加详细日志,方便排查 OEM 裁剪情况
This commit is contained in:
yuqianhe
2026-05-30 06:30:11 +00:00
parent 1c9696d282
commit 3ee99aa1b2

View File

@@ -160,10 +160,14 @@ class WiFiDirectManager(
*
* WifiP2pWfdInfo 是公开类API 29+),但 setWfdInfo 是 @SystemApi
* 隐藏方法,需要反射调用。
*
* 注意:部分 OEM华为/小米等)可能裁剪了此 API此时反射会失败。
*/
private fun trySetWfdInfo() {
Log.i(TAG, "尝试设置 WFD IE (Wi-Fi Display)...")
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.Q) {
Log.d(TAG, "WFD IE 需要 API 29+,当前版本不支持")
Log.i(TAG, "WFD IE 需要 API 29+,当前版本不支持,跳过")
return
}
try {
@@ -171,24 +175,26 @@ class WiFiDirectManager(
val wfdInfoClass = Class.forName("android.net.wifi.p2p.WifiP2pWfdInfo")
val wfdInfo = wfdInfoClass.getDeclaredConstructor().newInstance()
// setWfdEnabled(true)
val setWfdEnabled = wfdInfoClass.getMethod("setWfdEnabled", Boolean::class.java)
// setWfdEnabled(boolean) — 注意用 Boolean.TYPE 匹配原生 boolean 参数
val setWfdEnabled = wfdInfoClass.getMethod("setWfdEnabled", Boolean.TYPE)
setWfdEnabled.invoke(wfdInfo, true)
Log.i(TAG, " ✓ setWfdEnabled(true)")
// setDeviceType(PRIMARY_SINK) — 1 = WFD_PRIMARY_SINK
// WFD 设备类型: 0=SOURCE, 1=PRIMARY_SINK, 2=SECONDARY_SINK, 3=SOURCE_OR_PRIMARY_SINK
val setDeviceType = wfdInfoClass.getMethod("setDeviceType", Int::class.java)
setDeviceType.invoke(wfdInfo, 1) // WFD_PRIMARY_SINK
// setDeviceType(int) — 1 = WFD_PRIMARY_SINK
// WFD 设备类型: 0=SOURCE, 1=PRIMARY_SINK, 2=SECONDARY_SINK
val setDeviceType = wfdInfoClass.getMethod("setDeviceType", Integer.TYPE)
setDeviceType.invoke(wfdInfo, 1)
Log.i(TAG, " ✓ setDeviceType(PRIMARY_SINK)")
// setControlPort(7236) — RTSP 端口
val setControlPort = wfdInfoClass.getMethod("setControlPort", Int::class.java)
// setControlPort(int) — RTSP 端口
val setControlPort = wfdInfoClass.getMethod("setControlPort", Integer.TYPE)
setControlPort.invoke(wfdInfo, 7236)
// setSessionAvailable(true)
val setSessionAvailable = wfdInfoClass.getMethod("setSessionAvailable", Boolean::class.java)
// setSessionAvailable(boolean)
val setSessionAvailable = wfdInfoClass.getMethod("setSessionAvailable", Boolean.TYPE)
setSessionAvailable.invoke(wfdInfo, true)
// WifiP2pManager.setWfdInfo(channel, wfdInfo, listener) — 隐藏 API
// WifiP2pManager.setWfdInfo(Channel, WifiP2pWfdInfo, ActionListener) — 隐藏 API
val setWfdInfoMethod = p2pManager.javaClass.getMethod(
"setWfdInfo",
WifiP2pManager.Channel::class.java,
@@ -198,20 +204,26 @@ class WiFiDirectManager(
setWfdInfoMethod.invoke(p2pManager, p2pChannel, wfdInfo,
object : WifiP2pManager.ActionListener {
override fun onSuccess() {
Log.i(TAG, "WFD IE 设置成功,设备已注册为 Miracast 接收器 (PRIMARY_SINK)")
Log.i(TAG, "WFD IE 设置成功,设备已注册为 Miracast 接收器 (PRIMARY_SINK)")
}
override fun onFailure(reason: Int) {
Log.w(TAG, "WFD IE 设置失败: reason=$reason(可能不支持)")
val r = when (reason) {
0 -> "ERROR"
1 -> "P2P_UNSUPPORTED"
2 -> "BUSY"
else -> "UNKNOWN($reason)"
}
Log.w(TAG, "✗ WFD IE 设置失败: reason=$r")
}
}
)
} catch (e: ClassNotFoundException) {
Log.d(TAG, "WifiP2pWfdInfo 类不存在API < 29")
Log.i(TAG, "WifiP2pWfdInfo 类不存在API < 29 或 OEM 裁剪): ${e.message}")
} catch (e: NoSuchMethodException) {
Log.d(TAG, "setWfdInfo 方法不存在(非公开 API 不可用: ${e.message}")
Log.i(TAG, "setWfdInfo 方法不存在(OEM 裁剪或 API 差异: ${e.message}")
} catch (e: Exception) {
Log.d(TAG, "设置 WFD IE 失败: ${e.message}")
Log.i(TAG, "设置 WFD IE 失败: ${e.message}")
}
}