inputmethod_imf/README_zh.md
ma-shaoyin c2cf129638 Signed-off-by: ma-shaoyin <mashaoyin1@huawei.com>
Changes to be committed:
2022-08-12 09:34:33 +08:00

45 KiB
Raw Blame History

miscservices_inputmethod

介绍

输入法框架,主要作用是拉通应用和输入法,保证应用可以通过输入法进行文本输入

图 1 子系统架构图

仓路径

/base/inputmethod/imf

框架代码介绍

输入法框架目前有四大模块,具体如下:

  1. 应用客户端

路径:/base/inputmethod/imf/frameworks/inputmethod_controller

作用:实现应用和输入法框架服务交付,包括应用与输入法服务的绑定、应用对输入法的显示和隐藏请求等等

  1. 输入法客户端

路径:/base/inputmethod/imf/frameworks/inputmethod_ability

作用:实现输入法框架服务与输入法交付的中间桥梁,包括监听输入法当前的状态等等

  1. 输入法服务

路径:/base/inputmethod/imf/services

作用:作为输入法框架的核心,输入法的主要处理逻辑都是在这里完成

  1. 输入法Js接口

路径:/base/inputmethod/imf/interfaces/kits/js

作用暂时对外暴露的js接口主要是留给输入法进行调用使用的

说明

接口说明

表 1 inputMethod开放的主要方法

接口名

描述

function getInputMethodController(): InputMethodController;

获取客户端实例InputMethodController

function getInputMethodSetting(): InputMethodSetting;

获取客户端设置实例InputMethodSetting

function switchInputMethod(target: InputMethodProperty, callback: AsyncCallback<boolean>): void;

切换输入法使用callback形式返回结果。参数个数为2否则抛出异常

function switchInputMethod(target: InputMethodProperty): Promise<boolean>;

切换输入法使用promise形式返回结果。参数个数为1否则抛出异常

常量值
名称 参数类型 可读 可写 说明
MAX_TYPE_NUM number 可支持的最大输入法个数。
使用说明
// 导入模块
import inputmethod from '@ohos.inputmethod';

// 获取客户端实例
console.log('Get inputMethodController');
let inputMethodController = inputmethod.getInputMethodController();

// 获取客户端设置实例
console.log('Get inputMethodSetting');
let inputMethodSetting = inputmethod.getInputMethodSetting();

// 切换输入法callback
inputmethod.switchInputMethod({packageName:"com.example.kikakeyboard", methodId:"com.example.kikakeyboard"} ,(err,result) => {
    if (err) {
        console.info("switchInputMethod callback result---err: " + err.msg);
        return;
    }
    if (result) {
        console.info("Success to switchInputMethod.(callback)");
    } else {
        console.info("Failed to switchInputMethod.(callback)");
    }
});

// 切换输入法promise
await inputMethod.switchInputMethod({packageName:"com.example.kikakeyboard", methodId:"com.example.kikakeyboard"}).then((res) => {
    if (result) {
        console.info("Success to switchInputMethod.(promise)");
    } else {
        console.info("Failed to switchInputMethod.(promise)");
    }
}).catch((err) => {
    console.info("switchInputMethod promise err: " + err.msg);
});

表 2 InputMethodController开放的主要方法

接口名

描述

stopInput(callback: AsyncCallback<boolean>): void;

隐藏输入法使用callback形式返回结果。参数个数为1否则抛出异常

stopInput(): Promise<boolean>;

隐藏输入法使用promise形式返回结果。参数个数为0否则抛出异常

使用说明
// 导入模块
import inputmethod from '@ohos.inputmethod';

console.log('Get inputMethodController');
let inputMethodController = inputmethod.getInputMethodController();

// 隐藏输入法callback
inputMethodController.stopInput((err, result) => {
    if (err) {
        console.error("stopInput callback result---err: " + err.msg);
        return;
    }
    if (result) {
        console.info("Success to stopInput.(callback)");
    } else {
        console.info("Failed to stopInput.(callback)");
    }
});

// 隐藏输入法promise
await inputMethodCtrl.stopInput().then((result)=>{
    if (result) {
        console.info("Success to stopInput.(promise)");
    } else {
        console.info("Failed to stopInput.(promise)");
    }
}).catch((err) => {
    console.error("stopInput promise err: " + err.msg);
});

表 3 InputMethodSetting开放的主要方法

接口名

描述

listInputMethod(callback: AsyncCallback<Array<InputMethodProperty>>): void;

查询已安装的输入法列表使用callback形式返回结果。参数个数为1否则抛出异常。

listInputMethod(): Promise<Array<InputMethodProperty>>;

查询已安装的输入法列表使用promise形式返回结果。参数个数为0否则抛出异常。

displayOptionalInputMethod(callback: AsyncCallback<void>): void;

显示输入法选择对话框使用callback形式返回结果。参数个数为1否则抛出异常。

displayOptionalInputMethod(): Promise<void>;

显示输入法选择对话框使用promise形式返回结果。参数个数为0否则抛出异常。

使用说明
// 导入模块
import inputmethod from '@ohos.inputmethod';

console.log('Get inputMethodSetting');
let inputMethodSetting = inputmethod.getInputMethodSetting();

// 查询已安装的输入法列表callback
inputMethodSetting.listInputMethod((err,data) => {
    if (err) {
        console.error("listInputMethod callback result---err: " + err.msg);
        return;
    }
    console.info("listInputMethod callback result---data: " + JSON.stringify(data));
 });

// 查询已安装的输入法列表promise
await inputMethodSetting.listInputMethod().then((data)=>{
    console.info("listInputMethod promise result---data: " + JSON.stringify(data));
}).catch((err) => {
    console.info("listInputMethod promise err:" + err.msg);
});

// 显示输入法选择对话框callback
inputMethodSetting.displayOptionalInputMethod((err) => {
    if (err) {
        console.error("displayOptionalInputMethod callback---err: " + err.msg);
        return;
    }
    console.info("displayOptionalInputMethod callback");
});
        
// 显示输入法选择对话框promise
await inputMethodSetting.displayOptionalInputMethod().then(()=>{
    console.info("displayOptionalInputMethod promise");
}).catch((err) => {
    console.info("listInputMethod promise err: " + err.msg);
});

表 4 inputMethodEngine开放的主要方法

接口名

描述

function getInputMethodEngine(): InputMethodEngine;

获取服务端实例

function createKeyboardDelegate(): KeyboardDelegate;

获取客户端监听实例

常量值

名称 参数类型 可读 可写 说明
ENTER_KEY_TYPE_UNSPECIFIED number 无功能键。
ENTER_KEY_TYPE_GO number “前往”功能键。
ENTER_KEY_TYPE_SEARCH number “搜索”功能键。
ENTER_KEY_TYPE_SEND number “发送”功能键。
ENTER_KEY_TYPE_NEXT number “下一个”功能键。
ENTER_KEY_TYPE_DONE number “回车”功能键。
ENTER_KEY_TYPE_PREVIOUS number “前一个”功能键。
PATTERN_NULL number 无特殊性编辑框。
PATTERN_TEXT number 文本编辑框。
PATTERN_NUMBER number 数字编辑框。
PATTERN_PHONE number 电话号码编辑框。
PATTERN_DATETIME number 日期编辑框。
PATTERN_EMAIL number 邮件编辑框。
PATTERN_URI number 超链接编辑框。
PATTERN_PASSWORD number 密码编辑框。
OPTION_ASCII number 允许输入ASCII值。
OPTION_NONE number 不指定编辑框输入属性。
OPTION_AUTO_CAP_CHARACTERS number 允许输入字符。
OPTION_AUTO_CAP_SENTENCES number 允许输入句子。
OPTION_AUTO_WORDS number 允许输入单词。
OPTION_MULTI_LINE number 允许输入多行。
OPTION_NO_FULLSCREEN number 半屏样式。
FLAG_SELECTING number 编辑框处于选择状态。
FLAG_SINGLE_LINE number 编辑框为单行。
DISPLAY_MODE_PART number 编辑框显示为半屏。
DISPLAY_MODE_FULL number 编辑框显示为全屏。

使用说明

// 导入模块
import inputmethodengine from '@ohos.inputmethodengine';

// 获取服务端实例
console.log('Get inputMethodEngine');
let inputMethodEngine = inputmethodengine.getInputMethodEngine();

// 获取客户端监听实例
console.log('Get keyboardDelegate');
let keyboardDelegate = inputmethodengine.createKeyboardDelegate();

表 5 InputMethodEngine开放的主要方法

接口名

描述

on(type: 'inputStart', callback: (kbController: KeyboardController, textInputClient: TextInputClient) => void): void;

订阅输入法绑定成功事件使用callback回调返回输入法操作相关实例。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'inputStart', callback?: (kbController: KeyboardController, textInputClient: TextInputClient) => void): void;

取消订阅输入法绑定成功事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

on(type: 'keyboardShow'|'keyboardHide', callback: () => void): void;

订阅输入法事件。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'keyboardShow'|'keyboardHide', callback?: () => void): void;

取消订阅输入法事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

使用说明

// 导入模块
import inputmethodengine from '@ohos.inputmethodengine';

// 获取服务端实例
console.log('Get inputMethodEngine');
let inputMethodEngine = inputmethodengine.getInputMethodEngine();

// 订阅输入法绑定成功事件
inputMethodEngine.on('inputStart', (kbController, textInputClient) => {
    console.log("inputMethodEngine inputStart, kbController:" + JSON.stringify(kbController));
    console.log("inputMethodEngine inputStart, textInputClient:" + JSON.stringify(textInputClient));
});

// 取消订阅输入法绑定成功事件
inputMethodEngine.off('inputStart', (kbController, textInputClient) => {
    console.log("delete inputStart notification.");
});

// 订阅输入法事件
inputMethodEngine.on('keyboardShow', () => {
    console.log("inputMethodEngine keyboardShow.");
});
inputMethodEngine.on('keyboardHide', () => {
    console.log("inputMethodEngine keyboardHide.");
});

// 取消订阅输入法事件
inputMethodEngine.off('keyboardShow', () => {
    console.log("inputMethodEngine delete keyboardShow notification.");
});
inputMethodEngine.off('keyboardHide', () => {
    console.log("inputMethodEngine delete keyboardHide notification.");
});

表 6 KeyboardDelegate开放的主要方法

接口名

描述

on(type: 'keyDown'|'keyUp', callback: (event: KeyEvent) => boolean): void;

订阅硬键盘事件使用callback回调返回按键信息。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'keyDown'|'keyUp', callback?: (event: KeyEvent) => boolean): void;

取消订阅硬键盘事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

on(type: 'cursorContextChange', callback: (x: number, y:number, height:number) => void): void;

订阅光标变化事件使用callback回调返回光标信息使用callback回调返回按键信息。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'cursorContextChange', callback?: (x: number, y:number, height:number) => void): void;

取消订阅光标变化事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

on(type: 'selectionChange', callback: (oldBegin: number, oldEnd: number, newBegin: number, newEnd: number) => void): void;

订阅文本选择变化事件使用callback回调返回文本选择信息使用callback回调返回按键信息。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'selectionChange', callback?: (oldBegin: number, oldEnd: number, newBegin: number, newEnd: number) => void): void;

取消订阅文本选择变化事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

on(type: 'textChange', callback: (text: string) => void): void;

订阅文本变化事件使用callback回调返回当前文本内容使用callback回调返回按键信息。参数个数为2参数1为napi_string参数2为napi_function否则抛出异常。

off(type: 'textChange', callback?: (text: string) => void): void;

取消订阅文本变化事件。参数个数不为1或2抛出异常若为1参数不为napi_string抛出异常若为2参数1不为napi_string参数2不为napi_function抛出异常。参数若为1取消此类型所有监听参数若为2取消此类型当前监听。

使用说明

// 导入模块
import inputmethodengine from '@ohos.inputmethodengine';

// 获取客户端监听实例
console.log('Get keyboardDelegate');
let keyboardDelegate = inputmethodengine.createKeyboardDelegate();

// 订阅硬键盘事件
keyboardDelegate.on('keyUp', (keyEvent) => {
    console.info("inputMethodEngine keyCode.(keyUp):" + JSON.stringify(keyEvent.keyCode));
    console.info("inputMethodEngine keyAction.(keyUp):" + JSON.stringify(keyEvent.keyAction));
    return true;
});
keyboardDelegate.on('keyDown', (keyEvent) => {
    console.info("inputMethodEngine keyCode.(keyDown):" + JSON.stringify(keyEvent.keyCode));
    console.info("inputMethodEngine keyAction.(keyDown):" + JSON.stringify(keyEvent.keyAction));
    return true;
});

// 取消订阅硬键盘事件
keyboardDelegate.off('keyUp', (keyEvent) => {
    console.log("delete keyUp notification.");
    return true;
});
keyboardDelegate.off('keyDown', (keyEvent) => {
    console.log("delete keyDown notification.");
    return true;
});

// 订阅光标变化事件
keyboardDelegate.on('cursorContextChange', (x, y, height) => {
    console.log("inputMethodEngine cursorContextChange x:" + x);
    console.log("inputMethodEngine cursorContextChange y:" + y);
    console.log("inputMethodEngine cursorContextChange height:" + height);
});

// 取消订阅光标变化事件
keyboardDelegate.off('cursorContextChange', (x, y, height) => {
    console.log("delete cursorContextChange notification. x:" + x);
    console.log("delete cursorContextChange notification. y:" + y);
    console.log("delete cursorContextChange notification. height:" + height);
});

// 订阅文本选择变化事件
keyboardDelegate.on('selectionChange', (oldBegin, oldEnd, newBegin, newEnd) => {
    console.log("inputMethodEngine beforeEach selectionChange oldBegin:" + oldBegin);
    console.log("inputMethodEngine beforeEach selectionChange oldEnd:" + oldEnd);
    console.log("inputMethodEngine beforeEach selectionChange newBegin:" + newBegin);
    console.log("inputMethodEngine beforeEach selectionChange newEnd:" + newEnd);
});

// 取消订阅文本选择变化事件
keyboardDelegate.off('selectionChange', (oldBegin, oldEnd, newBegin, newEnd) => {
  console.log("delete selectionChange notification. oldBegin:" + oldBegin);
  console.log("delete selectionChange notification. oldEnd:" + oldEnd);
  console.log("delete selectionChange notification. newBegin:" + newBegin);
  console.log("delete selectionChange notification. newEnd:" + newEnd);
});

// 订阅文本变化事件
keyboardDelegate.on('textChange', (text) => {
    console.log("inputMethodEngine textChange. text:" + text);
});

// 取消订阅文本变化事件
keyboardDelegate.off('textChange', (text) => {
    console.log("delete textChange notification. text:" + text);
});

表 7 KeyboardController开放的主要方法

接口名

描述

hideKeyboard(callback: AsyncCallback<void>): void;

隐藏输入法使用callback形式返回结果。参数个数为1否则抛出异常。

hideKeyboard(): Promise<void>;

隐藏输入法使用peomise形式返回结果。参数个数为0否则抛出异常。

使用说明

// 导入模块
import inputmethodengine from '@ohos.inputmethodengine';

var kbCtrl = null;
console.log('Get inputMethodEngine');
let inputMethodEngine = inputmethodengine.getInputMethodEngine();
inputMethodEngine.on('inputStart', (kbController, textInputClient) => {
    console.log("inputMethodEngine beforeEach inputStart:" + JSON.stringify(kbController));
    kbCtrl = kbController;
});

// 隐藏输入法callback
kbCtrl.hideKeyboard((err) => {
    if (err) {
        console.error("hideKeyboard callback result---err: " + err.msg);
        return;
    }
    console.log("hideKeyboard callback.");
});

// 隐藏输入法promise
await kbCtrl.hideKeyboard().then(() => {
    console.info("hideKeyboard promise.");
}).catch((err) => {
    console.info("hideKeyboard promise err: " + err.msg);
});

表 8 TextInputClient开放的主要方法

接口名

描述

getForward(length:number, callback: AsyncCallback<string>): void;

获取光标前固定长度的文本使用callback形式返回结果。参数个数为2否侧抛出异常。

getForward(length:number): Promise<string>;

获取光标前固定长度的文本,使用promise形式返回结果。参数个数为1否侧抛出异常。

getBackward(length:number, callback: AsyncCallback<string>): void;

获取光标后固定长度的文本使用callback形式返回结果。参数个数为2否侧抛出异常。

getBackward(length:number): Promise<string>;

获取光标后固定长度的文本使用promise形式返回结果。参数个数为1否侧抛出异常。

deleteForward(length:number, callback: AsyncCallback<boolean>): void;

删除光标前固定长度的文本使用callback形式返回结果。参数个数为2否侧抛出异常。

deleteForward(length:number): Promise<boolean>;

删除光标前固定长度的文本使用promise形式返回结果。参数个数为1否侧抛出异常。

deleteBackward(length:number, callback: AsyncCallback<boolean>): void;

删除光标后固定长度的文本使用callback形式返回结果。参数个数为2否侧抛出异常。

deleteBackward(length:number): Promise<boolean>;

删除光标后固定长度的文本使用promise形式返回结果。参数个数为1否侧抛出异常。

sendKeyFunction(action:number, callback: AsyncCallback<boolean>): void;

发送功能键使用callback形式返回结果。参数个数为2否侧抛出异常。

sendKeyFunction(action:number): Promise<boolean>;

发送功能键使用promise形式返回结果。参数个数为1否侧抛出异常。

insertText(text:string, callback: AsyncCallback<boolean>): void;

插入文本使用callback形式返回结果。参数个数为2否侧抛出异常。

insertText(text:string): Promise<boolean>;

插入文本使用promise形式返回结果。参数个数为1否侧抛出异常。

getEditorAttribute(callback: AsyncCallback<EditorAttribute>): void;

获取编辑框属性值使用callback形式返回结果。参数个数为1否侧抛出异常。

getEditorAttribute(): Promise<EditorAttribute>;

获取编辑框属性值使用promise形式返回结果。参数个数为0否侧抛出异常。

使用说明

// 导入模块
import inputmethodengine from '@ohos.inputmethodengine';

var client = null;
var length = 1;
var keyFunction = 0;
console.log('Get inputMethodEngine');
let inputMethodEngine = inputmethodengine.getInputMethodEngine();
inputMethodEngine.on('inputStart', (kbController, textInputClient) => {
    console.log("inputMethodEngine inputStart:" + JSON.stringify(textInputClient));
    client = textInputClient;
});

// 获取光标前固定长度的文本callback
client.getForward(length, (err, text) => {
    if (err) {
        console.error("getForward callback result---err: " + err.msg);
        return;
    }
    console.log("getForward callback result---text: " + text);
});

// 获取光标前固定长度的文本promise
await client.getForward(length).then((text) => {
    console.info("getForward promise result---res: " + text);
}).catch((err) => {
    console.error("getForward promise err: " + err.msg);
});

// 获取光标后固定长度的文本callback
client.getBackward(length, (err, text) => {
    if (err) {
        console.error("getBackward callback result---err: " + err.msg);
        return;
    }
    console.log("getBackward callback result---text: " + text);
});

// 获取光标后固定长度的文本promise
await client.getBackward(length).then((text) => {
    console.info("getBackward promise result---res: " + text);
}).catch((err) => {
    console.error("getBackward promise err: " + err.msg);
});

// 删除光标前固定长度的文本callback
client.deleteForward(length, (err, result) => {
    if (err) {
        console.error('deleteForward callback result---err: ' + err.msg);
        return;
    }
    if (result) {
        console.info("Success to deleteForward.(callback) ");
    } else {
        console.error("Failed to deleteForward.(callback) ");
    }
});

// 删除光标前固定长度的文本promise
await client.deleteForward(length).then((res) => {
    if (result) {
        console.info("Success to deleteForward.(promise) ");
    } else {
        console.error("Failed to deleteForward.(promise) ");
    }
}).catch((err) => {
    console.error("deleteForward promise err: " + err.msg);
});

// 删除光标前固定长度的文本callback
client.deleteBackward(length, (err, result) => {
    if (err) {
        console.error("deleteBackward callback result---err: " + err.msg);
        return;
    }
    if (result) {
        console.info("Success to deleteBackward.(callback) ");
    } else {
        console.error("Failed to deleteBackward.(callback) ");
    }
});

// 删除光标前固定长度的文本promise
await client.deleteBackward(length).then((result) => {
    if (result) {
        console.info("Success to deleteBackward.(promise) ");
    } else {
        console.error("Failed to deleteBackward.(promise) ");
    }
}).catch((err) => {
    console.error("deleteBackward promise err: " + err.msg);
});

// 发送功能键callback
client.sendKeyFunction(keyFunction, (err, result) => {
    if (err) {
        console.error("sendKeyFunction callback result---err: " + err.msg);
        return;
    }
    if (result) {
        console.info("Success to sendKeyFunction.(callback) ");
    } else {
        console.error("Failed to sendKeyFunction.(callback) ");
    }
});

// 发送功能键promise
await client.sendKeyFunction(keyFunction).then((result) => {
    if (result) {
        console.info("Success to sendKeyFunction.(promise) ");
    } else {
        console.error("Failed to sendKeyFunction.(promise) ");
    }
}).catch((err) => {
    console.error("sendKeyFunction promise err:" + err.msg);
});

// 插入文本callback
client.insertText('test', (err, result) => {
    if (err) {
        console.error("insertText callback result---err: " + err.msg);
        return;
    }
    if (result) {
        console.info("Success to insertText.(callback) ");
    } else {
        console.error("Failed to insertText.(callback) ");
    }
});

// 插入文本promise
await client.insertText('test').then((result) => {
    if (result) {
        console.info("Success to insertText.(promise) ");
    } else {
        console.error("Failed to insertText.(promise) ");
    }
}).catch((err) => {
    console.error("insertText promise err: " + err.msg);
});

// 获取编辑框属性值callback
client.getEditorAttribute((err, editorAttribute) => {
    if (err) {
        console.error("getEditorAttribute callback result---err: " + err.msg);
        return;
    }
    console.log("editorAttribute.inputPattern(callback): " + JSON.stringify(editorAttribute.inputPattern));
    console.log("editorAttribute.enterKeyType(callback): " + JSON.stringify(editorAttribute.enterKeyType));
});

// 获取编辑框属性值promise
await client.getEditorAttribute().then((editorAttribute) => {
    console.info("editorAttribute.inputPattern(promise): " + JSON.stringify(editorAttribute.inputPattern));
    console.info("editorAttribute.enterKeyType(promise): " + JSON.stringify(editorAttribute.enterKeyType));
}).catch((err) => {
    console.error("getEditorAttribute promise err: " + err.msg);
});

EditorAttribute

编辑框属性值

名称 参数类型 可读 可写 说明
enterKeyType number 编辑框的功能属性。
inputPattern number 编辑框的文本属性。

KeyEvent

按键属性值

名称 参数类型 可读 可写 说明
keyCode number 按键的键值。
keyAction number 按键的状态。

框架主要支持功能

1.在编辑属性的控件中进行点击操作,即可通过输入法框架调起默认输入法应用

2.通过输入法应用可以进行打字,并上屏输入字符到应用客户端

本框架编译调试方法

  1. 编译命令

./build.sh --product-name (填写具体的产品名Hi3516DV300) --build-target imf

  1. 推送so文件

将工程目录下out\ohos-arm-release\inputmethod\imf 下的libinputmethod_client.z.so libinputmethod_ability.z.so libinputmethod_service.z.so libinputmethod_para.z.so推送到system/lib将libinputmethodengine.z.so libinputmethod.z.so 推送到system/lib/module下并确保六个so至少为可读状态。

  1. 重启设备

参与贡献

  1. Fork 本仓库
  2. 提交代码
  3. 新建 Pull Request
  4. commit完成即可