一、使用说明
- 笔迹预测:根据实际输入点,输出预测点,用于绘制预测轨迹
- 一笔成形:记录一段笔迹的所有输入点,停顿一段时间后输出对应标准图形的绘制路径
- 文字识别:记录多段笔迹的所有输入点,以字符串的形式输出对应的识别结果
- 跨应用取色:记录用户点击位置,获取对应位置的像素值和色域空间
- 手写笔侧旋:通过手写笔惯性传感器解算出笔身转动角度,并实时反馈到应用
- 手写笔悬浮预览:根据手写笔接近屏幕时的悬浮事件,将笔刷提前展示到笔尖指向的位置
- 手写笔触控按键:同时获取笔身触控状态和相关手写笔设置项,将触发的功能通知到应用
二、开发流程
1、鉴权
| 序号 | 步骤 | 说明 |
| 1 | 初始化鉴权服务 | 使用笔迹预测、一笔成形和文字识别(其它能力目前无主动执行鉴权操作)能力前需要初始化鉴权服务,初始化时会默认执行一次鉴权 |
| 2 | 执行鉴权(可选) | 若初始化时鉴权失败,可重复触发鉴权 |
| 3 | 销毁鉴权服务 | 销毁键权服务释放资源 |
2、笔记预测
| 序号 | 步骤 | 说明 |
| 1 | 查询系统环境是否支持笔迹预测 | 获取当前机型或系统环境是否支持笔迹预测,经过该步骤后才可使用笔迹预测能力 |
| 2 | 设置刷新率 | 设置画板View上下文中的刷新率 |
| 3 | 获取预测点 | 在onTouchEvent中收集预测输入点,在合适的时机调用响应的接口获取预测输出点 |
| 4 | 通过预测输出点获取绘制路径(可选) | 根据接口输出的预测点获取绘制路径,用于绘制预轨迹 |
3、一笔成形
| 序号 | 步骤 | 说明 |
| 1 | 查询系统环境是否支持一笔成形 | 获取当前机型或系统环境是否支持一笔成形,经过该步骤后才可使用一笔成形能力 |
| 2 | 设置触发一笔成形功能力的停顿时间(可选) | 可以在初始化阶段设置写画停顿后触发能力的时间 |
| 3 | 传入Touch事件 | 在onTouchEvent中传入MotionEvent,用于图形识别 |
| 4 | 获取Path形式的一笔成形输出结果 | 在合适的时机调用对应接口,获取一笔成形能力输出的图形绘制路径 |
| 5 | 销毁一笔成形能力 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
4、文字识别
| 序号 | 步骤 | 说明 |
| 1 | 查询系统环境是否支持文字识别 | 获取当前机型或系统环境是否支持文字识别,经过该步骤后才可使用文字识别能力 |
| 2 | 收集文字识别输入点 | 在onTouchEvent中,记录所有笔画的点信息,用于做文字识别输入数据 |
| 3 | 获取String形式的文字识别结果 | 在合适的时机调用对应接口,获取文字识别能力输出的字符串 |
| 4 | 销毁文字识别能力 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
5、跨应用取色
| 序号 | 步骤 | 说明 |
| 1 | 查询系统环境是否支持跨应用取色 | 获取当前机型或系统环境是否支持,经过该步骤后才可使用跨应用取色 |
| 2 | 注册跨应用取色回调 | 注册跨应用取色回调,用户取色完毕后会将取色结果传入回调 |
| 3 | 触发跨应用取色 | 在用户尝试取色时调用对应接口,触发跨应用取色,调起取色器 |
| 4 | 销毁跨应用取色 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
6、手写笔侧旋
| 序号 | 步骤 | 说明 |
| 1 | 查询系统环境是否支持侧旋 | 获取当前机型或系统环境是否支持侧旋,经过该步骤后才可使用手写笔侧旋 |
| 2 | 将输入事件传入手写笔侧旋能力 | 在dispatchGenericMotionEvent中,将输入事件传入手写笔侧旋接口 |
| 3 | 获取侧旋角度 | 在需要获取侧旋角度时,调用对应接口来实时获取当前笔身旋转角度 |
| 4 | 设置悬浮预览图层(可选) | 可结合悬浮预览能力,实现悬浮预览光标同步随笔身旋转 |
| 5 | 销毁侧旋能力 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
7、手写笔悬浮预览
| 序号 | 步骤 | 说明 |
| 1 | 初始化悬浮预览能力 | 对手写笔悬浮预览笔刷进行初始化 |
| 2 | 设置预览笔刷样式 | 将想要展示的笔刷的Bitmap传入对应接口 |
| 3 | 笔刷缩放(可选) | 在需要的时候,设置缩放参数实现预览笔刷或者光标缩放 |
| 4 | 设置侧旋预览笔刷(可选) | 可结合悬浮预览能力,实现悬浮预览光标或笔刷随笔身旋转 |
| 5 | 销毁悬浮预览能力 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
8、手写笔触控按键
| 序号 | 步骤 | 说明 |
| 1 | 初始化手写笔触控按键能力 | 对能力进行初始化,并实现能力触发后的回调接口 |
| 2 | 将输入事件传入手写笔触控按键能力 | 在dispatchKeyEvent中,获取并处理手写笔触控按键能力输入事件 |
| 3 | 销毁手写笔触控按键能力 | 在不需要该能力时,可调用对应接口销毁该能力,释放相关资源 |
三、使用约束
- 笔迹预测:N/A
- 一笔成形:仅支持Xiaomi HyperOS 2及以上的系统版本
- 文字识别:仅支持Xiaomi HyperOS 2及以上的系统版本
- 手写笔触控按键:适用于支持小米焦点触控笔Pro的机型
- 手写笔侧旋:仅支持Xiaomi Pad 8/Xiaomi Pad 8 Pro及后续机型,且需要搭配小米焦点触控笔Pro
三、开发步骤
添加 App Id 和构建版本 Debug 标识
- App Id
com.xiaomi.xms.APP_ID
当开通服务时,会生成 App Id 唯一标识,用于鉴权
必须配置 App Id,调用服务时会通过 App Id 进行鉴权
- 构建版本 Debug 标识
com.xiaomi.xms.BUILD_TYPE_DEBUG
当前 APK 是否为 Debug 构建版本。若不配置,默认为 false
备注:鉴权时会验证应用 apk 签名。开发调试阶段,一般不会运行 Release 签名的 apk,通常都是运行 Debug 签名 apk,为了保证在开发阶段仍然可以鉴权成功,开发者可以在平台同时添加正式证书指纹(Release 签名)和测试证书指纹(Debug 签名),用于不同场景下鉴权。
- 在应用的 AndroidManifest.xml 中添加
meta-data配置
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application>
<meta-data
android:name="com.xiaomi.xms.APP_ID"
android:value="your app id here" />
<meta-data
android:name="com.xiaomi.xms.BUILD_TYPE_DEBUG"
android:value="true or false" />
</application>
</manifest>鉴权
- 初始化鉴权服务
在应用初始化流程中或者使用笔迹预测、一笔成形和文字识别(其它能力目前无需主动执行鉴权操作)能力前请先初始化鉴权服务,初始化时会默认执行一次异步鉴权,鉴权成功后除销毁鉴权服务外无需再执行其它操作,即可正常使用手写笔套件的笔迹预测、一笔成形和文字识别:
MiuiAuthHelper.initAuthService(getApplicationContext(), new MiuiAuthHelper.AuthResultListener() {
@Override
public void onAuthComplete(boolean isSuccess) {
Log.i(TAG, "get auth result = " + isSuccess);
if (isSuccess) {
// 执行相关业务逻辑
}
}
});- 执行鉴权(可选)
初始化鉴权服务时发生异常导致鉴权失败,可通过如下方式再次触发鉴权:
MiuiAuthHelper.runAuthConnect();- 销毁鉴权服务
不再需要鉴权或者鉴权成功后,可通过如下方式销毁鉴权服务以释放资源:
MiuiAuthHelper.destroyAuthService();1、笔迹预测
1.1 查询当前运行环境是否支持报点预测
获取当前机型是否具备支持报点预测的能力:
boolean isEnable = MiuiStrokeEstimate.isFeatureEnable(context);
if (!isEnable) {
Log.d(TAG, "Not support device.")
}1.2 设置刷新率
在onVisibilityChanged方法中设置当前画板View上下文中屏幕的刷新率:
float refreshRate = context.getDisplay().getRefreshRate();
MiuiStrokeEstimate.setRefreshRate(refreshRate);
Log.d(TAG, "estimate, setRefreshRate:" + String.valueOf(refreshRate));1.3 获取预测报点信息
在onTouchEvent中,针对Down和Move事件进行处理,以获取预测输出点:
private List<MiuiMotionEventInfo> freshPointList = new ArrayList<>();
private List<MiuiMotionEventInfo> predictPointList = new ArrayList<>();
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
/* 获取预测输入点 */
MiuiMotionEventInfo predictInputPoint = MiuiMotionEventInfo.createByMotionEvent(event);
switch (action) {
case MotionEvent.ACTION_DOWN:
freshPointList.add(predictInputPoint);
break;
case MotionEvent.ACTION_MOVE:
int size = event.getHistorySize();
/* 获取历史点信息 */
for (int i = 0; i < size; i++) {
MiuiMotionEventInfo historyPoint = MiuiMotionEventInfo.createByMotionEvent(event, i);
/* 将历史点添加至freshPointList */
freshPointList.add(historyPoint);
}
/* 将当前点添加至freshPointList */
freshPointList.add(predictInputPoint);
/* 预测前先清除预测输出点 */
predictPointList.clear();
/* 获取预测点信息 */
int result = MiuiStrokeEstimate.getEstimateEvent(freshPointList, predictPointList);
/* 0成功,输出其它值代表出现异常 */
if (result == 0) {
/* 此处可进行下一步处理,如获取预测点绘制路径 */
/**
* getPredictPath(freshPointList.get(freshPointList.size() - 1), predictPointList)
*/
}
/* 清除预测输入点 */
freshPointList.clear();
break;
case MotionEvent.ACTION_UP:
break;
}
return true;
}1.4 通过预测点获取预测轨迹的Path(可选)
private static Path getPredictPath(MiuiMotionEventInfo lastPoint, List<MiuiMotionEventInfo> predictPointList){
if (predictPointList != null && !predictPointList.isEmpty()) {
Path path = new Path();
path.moveTo(lastPoint.getX(), lastPoint.getY());
for (MiuiMotionEventInfo p : predictPointList) {
path.lineTo(p.getX(), p.getY());
}
return path;
}
return null;
}2、一笔成形
2.1 查询当前运行环境是否支持一笔成形
获取当前机型是否具备支持一笔成形的能力:
boolean isEnable = MiuiOneStroke.isFeatureEnable(context);
if (!isEnable) {
Log.d(TAG, "Not support device.");
}2.2(可选)设置触发一笔成形功能图形识别的停顿时间(单位:ms)
设置触发能力的停顿时间,可以在初始化阶段设置。若不设置则默认为800ms;若设置的值小于0或大于5000,则使用默认值。
MiuiOneStroke.setStopTime(stopTime);
Log.d(TAG, "Set stop time: " + stopTime);2.3 传入触摸事件
在onTouchEvent中,获取和处理一笔成形输入点。
@Override
public boolean onTouchEvent(MotionEvent event) {
MiuiOneStroke.processTouchEvent(event);
/* 进行其它处理 */
}2.4 获取Path形式的一笔成形输出结果
触发一笔成形能力,且一笔成形识别成功后,可以通过getPath方法获取到一笔成形的输出结果。如果触发一笔成形能力后,输入点没有匹配上任何SDK所支持的图形,或者有抬笔动作,一笔成形输出结果会被清除,即此时getPath方法会返回空的Path(path.isEmpty() == true)。可以自行选择在ACTION_MOVE的事件处理中直接获取,或者在onDraw的时候获取。
private Path shapePath = new Path();
private Path origninalPath = new Path();
@Override
public void onDraw(Canvas canvas) {
/* 绘制原始笔迹 */
canvas.drawPath(origninalPath, origninalPaint);
/* 获取一笔成形识别结果 */
shapePath = MiuiOneStroke.getPath();
if (shapePath != null) {
/* 绘制规整图形 */
canvas.drawPath(shapePath, shapePaint);
}
}
...
@Override
public boolean onTouchEvent(MotionEvent event) {
/* 传入触摸事件 */
MiuiOneStroke.processTouchEvent(event);
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
break;
case MotionEvent.ACTION_MOVE:
/* 可在此处获取一笔成形识别结果 */
/**
* shapePath = MiuiOneStroke.getPath();
*/
break;
case MotionEvent.ACTION_UP:
/* 可在此处用一笔成形识别结果替换原始笔迹 */
/**
* replaceOrigninalPath(shapePath);
*/
break;
}
return true;
}
...
private void replaceOrigninalPath(Path path) {
if (path == null) {
return;
}
if (path.isEmpty()) {
return;
}
/* 做替换原始笔迹的操作 */
}2.5 销毁一笔成形能力
在不再需要该能力时,可以调用destroyShapeRecognize方法销毁相关能力:
MiuiOneStroke.destroyShapeRecognize();3、文字识别
3.1 查询当前运行环境是否支持文字识别
获取当前机型是否具备支持文字识别能力:
isEnable = MiuiRecognize.isFeatureEnable(context);
if (!isEnable) {
Log.d(TAG, "Not support device.");
}3.2 收集文字识别输入点
在onTouchEvent中,记录画板上所有笔画的点信息,用于做文字识别输入数据:
/* 数据类MiuiInk.Builder,用于记录当前所有笔画 */
private MiuiInk.Builder mInkBuilder;
/* 数据类MiuiInk.Stroke.Builder,用于记录当前这一笔的所有点信息 */
private MiuiInk.Stroke.Builder mStrokeBuilder;
@Override
public boolean onTouchEvent(MotionEvent event) {
if (mInkBuilder == null) {
/* 获取MiuiInk.Builder的实例 */
mInkBuilder = MiuiInk.builder();
}
int action = event.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
/* 在下笔时获取MiuiInk.Stroke.builder实例 */
mStrokeBuilder = MiuiInk.Stroke.builder();
/* 保存手写笔下笔时点信息 */
mStrokeBuilder.addPoint(event);
break;
case MotionEvent.ACTION_MOVE:
if (mStrokeBuilder == null) {
mStrokeBuilder = MiuiInk.Stroke.builder();
}
/* 保存手写笔移动时的所有点信息 */
mStrokeBuilder.addPoint(event);
break;
case MotionEvent.ACTION_UP:
if (mStrokeBuilder == null) {
mStrokeBuilder = MiuiInk.Stroke.builder();
}
/* 保存手写笔抬笔时的点信息 */
mStrokeBuilder.addPoint(event);
/* 在抬笔时将当前这一笔的所有点信息保存到mInkBuilder */
mInkBuilder.addStroke(mStrokeBuilder.build());
break;
case MotionEvent.ACTION_CANCEL:
/* APP收到cancel事件,清空当前这笔的点信息 */
mStrokeBuilder = null;
}
return true;
}3.3 触发文字识别能力
在需要触发文字识别能力时,将当前保存的所有笔画数据传入算法,需要注意的是如果当前机型不支持文字识别,则recognizeText方法可能会返回空:
public String doRecognize() {
if (mInkBuilder == null) {
return null;
}
/* 获取当前保存的所有笔画数据 */
MiuiInk ink = mInkBuilder.build();
/* 确认笔画数量不为零 */
if (ink.getStrokesCount() == 0) {
return null;
}
/* 执行文字识别,会将文字识别结果以字符串的形式返回 */
String recognizeResult = MiuiRecognize.recognizeText(ink);
/* 可以选择将文字识别结果打印出来 */
if (recognizeResult != null) {
Log.i(TAG, "Recognize result: " + String);
} else {
Log.w(TAG, "Text recognition failed");
}
/* 可以在这里清空已输入文字识别的笔画数据,为下一次文字识别做准备 */
mInkBuilder = null;
mStrokeBuilder = null;
return recognizeResult;
}3.4 销毁文字识别能力
在不再需要该能力时,可以调用destroyTextRecognize方法销毁相关能力,在销毁后如果想重启该能力,则需要再次调用isFeatureEnable方法来初始化:
MiuiRecognize.destroyTextRecognize();4、跨应用取色
4.1 初始化跨应用取色能力
初始化跨应用取色能力,如果返回false则代表初始化失败,即当前运行环境不支持跨应用取色:
isEnable = MiuiColorPick.init(context);
if (!isEnable) {
Log.d(TAG, "Not support device.");
}4.2 注册跨应用取色能力回调
实现回调接口并注册回调,能力触发成功后,手写笔服务会将用户抬笔位置的色域空间和颜色值传入回调函数:
MiuiColorPick.registerColorListener(new MiuiColorPick.ColorListener() {
@Override
public void onChange(ColorSpace colorSpace, int color) {
Log.i(TAG, "Get pixel color = " + color);
/* 对色域空间判空 */
if (colorSpace != null) {
/* 获取色域空间和色彩值,并设置画笔颜色 */
}
}
}4.3 触发跨应用取色能力
在需要触发跨应用取色能力时,调用triggerColorPicking方法来触发相关能力:
MiuiColorPick.triggerColorPicking();4.4 销毁跨应用取色能力
在不再需要跨应用取色能力时,可以调用destroy方法销毁相关能力,在销毁后如果想重启该能力,则需要再次调用init方法来初始化:
MiuiColorPick.destroy();5、手写笔侧旋
5.1 初始化侧旋能力
初始化侧旋能力,如果返回false则代表初始化失败,即当前运行环境不支持手写笔侧旋:
isEnable = MiuiStylusPosture.init(context);
if (!isEnable) {
Log.d(TAG, "Not support device.");
}5.2 将输入事件传入手写笔侧旋能力
在dispatchGenericMotionEvent中,获取并处理侧旋能力输入点:
@Override
public boolean dispatchGenericMotionEvent(MotionEvent ev) {
/* 获取输入点信息 */
MiuiStylusPosture.genericMotionEvent(ev);
return super.dispatchGenericMotionEvent(ev);
}5.3 获取侧旋角度
在需要获取侧旋角度时,调用getDegree方法来实时获取当前角度:
int degree = MiuiStylusPosture.getDegree();5.4(可选)设置悬浮预览图层
在初始化时,可结合悬浮预览能力,实现悬浮预览光标自动随笔身旋转:
MiuiStylusPosture.setPreviewBrush(MiuiHoverPreview.getPreviewBrush());5.5 销毁侧旋能力
在不再需要侧旋能力时,可以调用destroy方法销毁相关能力,在销毁后如果想重启该能力,则需要再次调用init方法来初始化:
MiuiStylusPosture.destroy();6、悬浮预览
6.1 初始化悬浮预览能力
对手写笔悬浮预览笔刷进行初始化,传入需要实现预览的画板View对象:
MiuiHoverPreview.init(context, view);6.2 设置预览笔刷样式
在初始化后,设置笔刷Bitmap:
/* 将想要展示的笔刷或者光标的bitmap传入setBrush */
MiuiHoverPreview.setBrush(Bitmap.createBitmap(40, 20, Bitmap.Config.ARGB_8888));6.3 (可选)笔刷缩放
在需要的时候,设置缩放参数实现预览笔刷或者光标缩放:
MiuiHoverPreview.sizeBrush(coefficient);6.4 (可选)设置侧旋预览笔刷
可结合悬浮预览能力,实现悬浮预览光标或笔刷随笔身旋转:
MiuiStylusPosture.setPreviewBrush(MiuiHoverPreview.getPreviewBrush());6.5 销毁预览能力
在不再需要悬浮预览能力时,可以调用destroy方法销毁相关能力,在销毁后如果想重启该能力,则需要再次调用init方法来初始化:
MiuiHoverPreview.destroy();7、手写笔触控按键
7.1 初始化手写笔触控按键能力
对手写笔触控按键能力进行初始化,并实现回调接口,能力触发成功后,会将触发的按键能力值或笔刷预览开关状态传入回调函数。为了确保能及时获取手写笔最新设置状态,最好在当前Activity的onResume中初始化:
@Override
protected void onResume() {
super.onResume();
MiuiTouchFilmUtils.init(getApplicationContext(), new MiuiTouchFilmUtils.TouchFilmListener() {
@Override
public void onTouchFilmTriggered (int function) {
/* 处理手写笔笔身触控按键事件 */
switch (function) {
/* 未知事件,可以不做处理 */
case MiuiTouchFilmUtils.UNKNOWN_SETTINGS_FUNCTION:
break;
/* 执行切换笔刷和橡皮擦 */
case MiuiTouchFilmUtils.SWITCH_BETWEEN_BRUSH_AND_ERASER:
break;
/* 执行切换当前笔刷和上次使用笔刷 */
case MiuiTouchFilmUtils.SWITCH_TO_PREVIOUS_BRUSH:
break;
/* 显示调色盘 */
case MiuiTouchFilmUtils.SHOW_COLOR_WHEEL
break;
/* 显示笔刷参数板 */
case MiuiTouchFilmUtils.SHOW_BRUSH_SETTINGS
break;
/* 触发手写笔笔身上滑,可自定义对应功能 */
case MiuiTouchFilmUtils.STYLUS_SLIDE_UP
break;
/* 触发手写笔笔身下滑,可自定义对应功能 */
case MiuiTouchFilmUtils.STYLUS_SLIDE_DOWN
break;
default:
break;
}
}
@Override
public void onBrushPreviewChanged(boolean enable) {
/* 处理笔刷预览开关变更事件 */
}
});
}7.2 将按键事件传入手写笔触控按键能力接口
在dispatchKeyEvent中,获取并处理手写笔触控按键能力输入事件:
@Override
public boolean dispatchKeyEvent(KeyEvent event) {
if (MiuiTouchFilmUtils.onDispatchKeyEvent(event)) {
/* onDispatchKeyEvent返回true,代表触控按键能力对该事件感兴趣,该事件已被处理 */
} else {
/* onDispatchKeyEvent返回false,代表这是与触控按键能力无关的事件,该事件没有被处理 */
}
return super.dispatchKeyEvent(event);
}7.3 销毁手写笔触控按键能力
在不再需要手写笔触控按键能力时,可以调用destroy方法销毁相关能力,在销毁后如果想重启该能力,则需要再次调用init方法来初始化,推荐在当前Activity的onPause中执行销毁动作:
MiuiTouchFilmUtils.onDestroy();五、调测验证
1、笔迹预测
在实现的报点预测应用中,可以绘制出该预测点从而提升跟手性。
2、一笔成形
在实现的一笔成形能力的应用中,绘制一笔结束时,手写笔不离开屏幕并保持不动停顿一定时间(具体时间由自行设置,默认为800ms)后,可以获取到图形识别结果,并按需绘制出来。
3、文字识别
在实现文字识别能力的应用中,可以在触发一笔成形能力后将识别结果打印出来,或者通过Toast.makeText方法,以消息提示的形式将识别结果显示出来。
4、跨应用取色
在实现文字识别能力的应用中,可以在触发跨应用取色能力后将取色结果打印出来,或者修改画笔颜色,以笔画的形式将获取的色彩展示出来。
5、手写笔侧旋
在实现侧旋能力的应用中,可以实时笔身旋转角度打印出来,或者设置预览光标,将笔身旋转角度展示出来。
6、悬浮预览
在实现悬浮预览能力的应用中,可以设置预览笔刷或光标,将手写笔悬浮状态展示出来。
7、手写笔触控按键
在实现手写笔触控按键能力的应用中,将回调接口中传入的参数打印出来,并分别执行手写笔轻捏、双击、上滑和下滑动作,确认输出日志是否和手写笔设置相对应。
六、接口说明/API参考文档/调用方式说明
1、API接口文档
1.1 接口概述
- 能力类
| 类名 | 说明 |
| MiuiStrokeEstimate | 笔迹预测能力类 |
| MiuiRecognize | 文字识别能力类 |
| MiuiOneStroke | 一笔成形能力类 |
| MiuiAuthHelper | 鉴权能力类 |
| MiuiStylusPosture | 手写笔侧旋能力类 |
| MiuiHoverPreview | 手写笔悬浮预览能力类 |
| MiuiColorPick | 跨应用取色能力类 |
| MiuiTouchFilmUtils | 手写笔触控按键能力类 |
- 数据类
| 类名 | 说明 |
| MiuiMotionEventInfo | 笔迹预测数据类,用于构造笔迹预测输入数据 |
| MiuiInk | 文字识别数据类,用于构造文字识别输入数据 |