AI摘要:本文介绍了如何在小新Pad Pro 12.7上解锁联想手写笔(Lenovo Tab Pen Plus)的使用限制。由于系统限制,手写笔连接后无法书写。ZUI15通过“开光”方法,先连接小新触控笔二代后再连接手写笔,可以实现手写功能。文章详细分析了ZUI16系统服务的工作原理,并提供了修改系统设置的具体步骤,包括使用终端指令和修改services.jar文件。最终,用户可以通过这些方法使手写笔正常工作。

前言

联想手写笔(Lenovo Tab Pen Plus)本身是可以在小新pad pro 12.7上使用的,但万恶资本家为了卖小新触控笔二代(Lenovo Precision Pen 3),限制了手写笔的使用,具体表现为连接以后无法写字,但笔按键可用。之前ZUI15的时候有人发现先连接二代触控笔后再连接手写笔即可使用,该方法称为“开光”。开光过后的平板升级到ZUI16仍可以使用,但没“开光”的升级到ZUI16后无法再通过“开光”后使用手写笔。本人最近需要一只手写笔,二代触控笔停产,现在一只三百多,而联想手写笔不到一百,该选哪个不言而喻。既然选择了联想手写笔,那就要解锁相应限制,使它能够正常使用。基于最新系统ZUI16.0.474分析修改,理论ZUI15也可以通用该方法。

准备工作

1.一个灵活的脑子
2.Magisk、mt管理器
3.一些root、刷机的基本知识(对系统服务进行修改存在变砖可能)

解锁手写笔界面

首先联想手写笔连接以后设置里手写笔界面仍然显示未连接,功能处于灰色状态无法点击。那是因为TB371FC的ZUI16系统服务会在手写笔蓝牙连接以后,读取设备的PIDVID和系统指定PIDVID进行比对,不相同就不会更改lenovo_pen_status的值。关键代码如下:

public void udpateStylusPenState(InputDevice inputDevice, int state) {
    if (!isStylusPen(inputDevice)) {
        return;
    }
    
    if (state == 1) { // 设备连接
        this.mStylusPenCount++;
    }
    
    int newState = this.mStylusPenCount > 0 ? 1 : 0;
    setStylusPenConnectState(newState); // 这里会设置为1
}

public boolean isStylusPen(InputDevice inputDevice) {
    return inputDevice != null && 
           inputDevice.getProductId() == BluetoothPenUtils.getInstance().getStylusPenPID() && 
           inputDevice.getVendorId() == BluetoothPenUtils.getInstance().getStylusPenVID();
}

这里提供两个可行的方法:

su
settings put global lenovo_pen_status 1


1.手写笔App中Lcom/lenovo/pen/cap/util;类下,getPenBtStatus方法,hook或者直接修改赋值为1即可。
2.services.jar中Lcom/zui/server/input/styluspen/pen/bluetooth/policy/BluetoothPenInputPolicy;类下isStylusPen方法,返回值改为1
两个任选一个即可解锁手写笔全功能。

解锁手写笔书写问题

一开始以为是手写笔软件层面的问题,一直尝试去修改手写笔App,实际并无效果。酷安“开光”方法一直强调固件版本问题,但根据分析手写笔固件下载更新代码来看,并无什么关联,固件更新仅仅更新手写笔固件,并不会修改平板系统或解锁什么功能,因此问题只能出在系统层面。将手写笔连接平板后,终端输入以下命令查看输入设备日志:

su
dumppsys input


通过日志可以知道,平板系统将手写笔识别为了三个独立的设备:两个用于蓝牙连接,一个用于屏幕数字化仪本身。
1. 蓝牙手写笔 (外部设备)
当手写笔通过蓝牙连接时,它会同时告诉系统它是两种不同的设备:
设备 19: Lenovo Tab Pen Plus Consumer Control (消费者控制)
作用: 这是手写笔的按键。
依据: 系统将其分类为 Classes: KEYBOARD | EXTERNAL (键盘 | 外部)。这意味着当你单击、双击或按住按钮时,手写笔会像外部蓝牙键盘一样发送一个“按键”信号。联想的后台服务会拦截这些“按键”信号来启动应用程序或执行快捷操作。
标识: bluetoothAddress=2A:CD:16:01:A3:GC
设备 18: Lenovo Tab Pen Plus Mouse (鼠标)
作用: 这是隔空鼠标 / 远程控制功能(使用手写笔的内部陀螺仪)。
依据: 系统将其分类为 Classes: CURSOR | EXTERNAL (光标 | 外部) 和 Sources: MOUSE (鼠标)。这允许你在空中移动手写笔来控制鼠标光标,就像一个演示遥控器。
标识: bluetoothAddress=2A:CD:16:01:A3:GC (请注意,MAC地址相同,证明它们是同一个物理设备)
2. 数字化仪 (内部屏幕传感器)
这个设备是你平板屏幕的一部分,而不是手写笔本身。
设备 5: NVTCapacitivePen (电容笔)
作用: 这是内置在屏幕中的有源数字化仪层。它才是真正负责检测笔尖以进行书写和绘画的部分。
依据: 系统将其 Sources 列为 KEYBOARD | TOUCHSCREEN | STYLUS (键盘 | 触摸屏 | 手写笔)。该设备负责向系统报告笔的 X/Y 坐标、PRESSURE (压力) 和 TILT (倾斜度)。它是一个内部设备 (IsExternal: false)。
3.总结:它们如何协同工作
这份日志清晰地回答了关于手写笔为什么按键功能可用,书写不可用的问题:
系统识别出两个笔:
蓝牙笔 (设备 18 & 19):Lenovo Tab Pen Plus。它负责处理按键和空中鼠标。
数字化仪 (设备 5):NVTCapacitivePen。它内置在屏幕里,负责检测笔尖的位置、压力、倾斜度。
融合 (Fusion) 失败:
一套完整的手写笔体验,需要系统将蓝牙笔和数字化仪的输入融合在一起。系统需要知道,这个蓝牙笔(的按键)和屏幕上这个笔尖(的位置)是同一个设备。在你的 dumpsys 日志中,NVTCapacitivePen (设备 5) 的状态显示:

Stylus Fusion:
  ExternalStylusConnected: false

这行 ExternalStylusConnected: false 是关键证据。它表明:尽管你的蓝牙笔(Lenovo Tab Pen Plus)已经连接,但系统(或联想的服务)故意没有将它与屏幕数字化仪关联或融合。
限制的实现:
联想的某个后台服务在检测到蓝牙连接时,会读取这支笔的硬件信息与自己的数据库里允许的硬件信息进行比对,发现这是便宜的笔。于是,它拒绝执行融合操作,导致系统拉黑了来自 NVTCapacitivePen 的所有常规输入(如书写、悬停、点击)。
为什么“按键+触摸”可以调出便签?
这是一个特殊的组合快捷键。这个功能绕过了常规的输入系统。它被设计为同时监听两个独立的硬件事件:
Lenovo Tab Pen Plus (蓝牙) 发出的“按键”信号。
NVTCapacitivePen (屏幕) 发出的“触摸”信号。
当两个事件同时发生时,它就触发便签应用。这反而证明了手写笔的按键和屏幕的数字化仪在硬件上都是好的,只是在系统层面被分开了。
开光是如何实现的:
当先连接Lenovo Precision Pen 3时,系统服务将NVTCapacitivePen 的 ExternalStylusConnected 状态设为 true。数字化仪的输入被“解锁”。之后换用Lenovo Tab Pen Plus因为 ExternalStylusConnected 的状态已经被激活,所以手写笔仍然可用。ZUI16修复该bug,断开连接后状态重置,就无法再开光了。


结合ai的分析以及后续查找,确定问题出在services.jar中:

这个服务(BluetoothPenConnectPolicy.java)的工作流程揭示了“屏蔽”是如何实现的:

  1. 硬件“审问”
    当你的 Lenovo Tab Pen Plus (PICASSO) 连上蓝牙时,这个系统服务会做一件事,它会通过GATT连接去“审问”这支笔的硬件信息。
    在 onBluetoothCharacteristicRead 方法中,它会去读取一个关键的UUID:HARD_CHAR (硬件型号)。
  2. “白名单”验证
    在拿到硬件型号字符串后,它会执行一个致命的 if 检查:

    // (代码来自 onBluetoothCharacteristicRead)
    
    if (bluetoothGattCharacteristic.getUuid().equals(HARD_CHAR)) {
     String stringValue2 = bluetoothGattCharacteristic.getStringValue(0);
     Log.d("BluetoothManagerPolicy", "hardVersion: " + stringValue2);
     
     // 关键的 "if...else if" 逻辑
     if ("PALADIN".equals(stringValue2)) {
         Log.d("BluetoothManagerPolicy", "B old pen");
         updateTpModeStatus(true, 0); // <-- 授权!
     } else if ("PALADIN-C".equals(stringValue2)) {
         Log.d("BluetoothManagerPolicy", "C new pen");
         updateTpModeStatus(true, 1); // <-- 授权!
     }
    }
  3. 揭晓谜底
    PALADIN (Lenovo Precision Pen 3):当它连接时,stringValue2 是 "PALADIN"。检查通过。程序执行 updateTpModeStatus(true, ...)。
    PICASSO (Lenovo Tab Pen Plus):当它连接时,stringValue2 是 "PICASSO-CD1"。检查失败。程序跳过了整个 if 块,什么也不做。
  4. 什么是 updateTpModeStatus(true, ...)?
    这就是“融合” (Fusion) 的那一步。这个方法会调用 TouchscreenServiceManager.getInstance(...).setPenMode(true, i)。这个 setPenMode(true, ...) 方法就是那个最终的“授权”命令,它告诉 Android 底层输入系统:“我已确认这是一支合法的笔,现在请激活触摸屏数字化仪对笔尖的识别”。一旦这个命令被执行,InputManager 就会把 ExternalStylusConnected 设为 true,你的笔尖就可以写字了。


知道了问题坐在就很简单了mt管理器复制一份services.jar出来修改相应判断,将PANDALIN修改为PICASSO-CD1或者修改判断逻辑,当HARD_CHAR不等于PANDALIN时执行授权操作均可。

总结及解锁效果

其实关键点都在services.jar中,手动修改好之后打包成面具模块刷入即可,或者编写Lsposed模块hook相应点也行,最后解锁效果如下:

联想手写笔及小新触控笔二代固件

在之前分析的时候,通过抓包下载了两份联想手写笔(Lenovo Tab Pen Plus)的升级固件,分别为2.24和2.27,以及一份小新触控笔二代(Lenovo Precision Pen 3)的2.58版本升级固件。固件升级可以使用nRF Connect
点击下载手写笔固件

后记

因为没有磁吸充电触点,所以手写笔是无法判断吸附状态的,因此取下笔打开软件的功能无法使用,不过一个作为不到百元的平替笔还是不错的。

END
本文作者:
文章标题:小新Pad Pro 12.7(TB371FC)免二代笔开光解锁联想手写笔使用教程
本文地址:https://233.517128.xyz/archives/43.html
版权说明:若无注明,本文皆学习笔记原创,转载请保留文章出处。
最后修改:2025 年 11 月 14 日
如果觉得我的文章对你有用,请随意赞赏