这个需求其实也是应用预装。这里多说一句权限的授予,一般应用都会申请权限。要么在运行中申请,要么提前设置权限默认允许,一般系统应用都默认允许。权限授予有两种,一种是将在权限文件中声明,一种是文中的使用权限文件授予,提倡这样,因为这样方便迁移。
首先说下集成的步骤
- 创建目录放入对应系统版本的讯飞语音引擎apk
- 同级目录下创建Android.mk然后做相应的配置
- 同级目录下创建权限文件
- 在framework/base下配置使其系统默认引擎
- 在编译文件下添加其编译和权限文件的编译
ps:权限配置也可以在系统priv-app-permission.xml中配置,可以查看其他资料处理
一 集成讯飞语音引擎
创建的目录以及文件列表如下
lib 是反编译的so库,
Android.mk 是编译文件
default_permissions_speechservice.xml //默认应用权限文件
privapp-permissions-speechservice.xml//应用权限的权限列表
将以上截图中的文件内容 列举如下
Android.mk如下
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := SpeechService
LOCAL_MODULE_STEM := SpeechService.apk
LOCAL_MODULE_CLASS := APPS
LOCAL_CERTIFICATE := platform
LOCAL_MODULE_PATH := $(TARGET_OUT)/priv-app
LOCAL_SRC_FILES := xunfei_engine_64.apk
LOCAL_PRIVILEGED_MODULE := true
LOCAL_ENFORCE_USES_LIBRARIES := false
LOCAL_PREBUILT_JNI_LIBS := $(subst $(LOCAL_PATH)/,,$(wildcard $(LOCAL_PATH)/lib/arm64-v8a/*.so))
include $(BUILD_PREBUILT)
#==================================================
# Install priv-app default-permisison file
#==================================================
include $(CLEAR_VARS)
LOCAL_MODULE := default_permissons_speechservice.xml
LOCAL_MODULE_CLASS := ETC
LOCAL_MODULE_PATH := $(TARGET_OUT_ETC)/default-permissions
LOCAL_SRC_FILES := $(LOCAL_MODULE)
include $(BUILD_PREBUILT)
#==================================================
# Install priv-app permisison file
#==================================================
include $(CLEAR_VARS)
LOCAL_MODULE:=privapp-permissions-speechservice.xml
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE_CLASS:=ETC
LOCAL_MODULE_PATH:=${TARGET_OUT_ETC}/permissions
LOCAL_SRC_FILES:=${LOCAL_MODULE}
include ${BUILD_PREBUILT}
default_permissons_speechservice.xml 如下
//default_permissons_speechservice.xml
<exceptions>
<exception package="com.iflytek.speechsuite">
<permission name="android.permission.READ_CONTACTS" fixed="false"/>
<permission name="android.permission.WAKE_LOCK" fixed="false"/>
<permission name="android.permission.RECORD_AUDIO" fixed="false"/>
<permission name="android.permission.WAKE_LOCK" fixed="false"/>
<permission name="android.permission.INTERNET" fixed="false"/>
<permission name="android.permission.ACCESS_NETWORK_STATE" fixed="false"/>
<permission name="android.permission.ACCESS_WIFI_STATE" fixed="false"/>
<permission name="android.permission.CHANGE_NETWORK_STATE" fixed="false"/>
<permission name="android.permission.CHANGE_WIFI_STATE" fixed="false"/>
<permission name="android.permission.READ_PHONE_STATE" fixed="false"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" fixed="false"/>
<permission name="android.permission.WRITE_EXTERNAL_STORAGE" fixed="false"/>
<permission name="android.permission.RECEIVE_BOOT_COMPLETED" fixed="false"/>
<permission name="android.permission.MODIFY_AUDIO_SETTINGS" fixed="false"/>
<permission name="android.permission.WRITE_SETTINGS" fixed="false"/>
<permission name="android.permission.GET_TASKS" fixed="false"/>
<permission name="android.permission.READ_LOGS" fixed="false"/>
</exception>
</exceptions>
privapp-permissions-speechservice.xml 如下
<?xml version="1.0" encoding="utf-8"?>
<permissions>
<privapp-permissions package="com.iflytek.speechsuite">
<permission name="android.permission.READ_CONTACTS"/>
<permission name="android.permission.WAKE_LOCK"/>
<permission name="android.permission.RECORD_AUDIO"/>
<permission name="android.permission.WAKE_LOCK"/>
<permission name="android.permission.INTERNET"/>
<permission name="android.permission.ACCESS_NETWORK_STATE"/>
<permission name="android.permission.ACCESS_WIFI_STATE"/>
<permission name="android.permission.CHANGE_NETWORK_STATE"/>
<permission name="android.permission.CHANGE_WIFI_STATE"/>
<permission name="android.permission.READ_PHONE_STATE"/>
<permission name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>
<permission name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<permission name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<permission name="android.permission.MODIFY_AUDIO_SETTINGS"/>
<permission name="android.permission.WRITE_SETTINGS"/>
<permission name="android.permission.GET_TASKS"/>
<permission name="android.permission.READ_LOGS"/>
</privapp-permissions>
</permissions>
二配置该语音引擎默认为系统引擎,修改如下
Date: Thu Feb 6 14:47:38 2025 +0800
设置讯飞语音引擎为系统默认引擎
Change-Id: I6fb048a51133534b022108539a584a4b29410cb2
diff --git a/packages/SettingsProvider/res/values/defaults.xml b/packages/SettingsProvider/res/values/defaults.xml
index a85639eee8a7..a6049526cd94 100755
--- a/packages/SettingsProvider/res/values/defaults.xml
+++ b/packages/SettingsProvider/res/values/defaults.xml
@@ -24,6 +24,7 @@
<!-- 设置默认输入法 -->
<!-- <string name="config_enabled_input_methods" translatable="false">com.iflytek.inputmethod/.FlyIME</string>
<string name="config_default_input_method" translatable="false">com.iflytek.inputmethod/.FlyIME</string> -->
+ <string name="default_tts" translatable="false">com.iflytek.speechsuite</string>
<string name="def_display_density">170</string>
<bool name="def_dim_screen">true</bool>
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
index 3e7ae6d8a431..14a14bea9856 100755
--- a/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/DatabaseHelper.java
@@ -2353,7 +2353,10 @@ class DatabaseHelper extends SQLiteOpenHelper {
//方法名 private void loadSecureSettings(SQLiteDatabase db)中
loadStringSetting(stmt, Settings.Secure.DEFAULT_INPUT_METHOD,
R.string.config_default_input_method);
- loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
+ loadStringSetting(stmt, Settings.Secure.TTS_DEFAULT_SYNTH,R.string.default_tts);
+
+
+ loadBooleanSetting(stmt, Settings.Secure.MOUNT_PLAY_NOTIFICATION_SND,
R.bool.def_mount_play_notification_snd);
loadBooleanSetting(stmt, Settings.Secure.MOUNT_UMS_AUTOSTART,
异常:若这里不做配置,进行编译时,应用直接调用TTS初始化是失败的(也可以手动在设置中设置其默认tts引擎)
三 集成编译
build/make/target/product/ 下
commit 5be1653b0563cece08f7797f5c374bd34fe2e502 (HEAD -> droid13/poc/ft18)
Author: admin <bianjb@flyscale.cn>
Date: Thu Feb 6 14:46:40 2025 +0800
讯飞语音引擎权限设置
Change-Id: Ia6560f12ec14410867372ef663fb82b8061133c9
diff --git a/target/product/handheld_product.mk b/target/product/handheld_product.mk
index 2affec887..5ef8ec11d 100644
--- a/target/product/handheld_product.mk
+++ b/target/product/handheld_product.mk
@@ -38,6 +38,8 @@ PRODUCT_PACKAGES += \
default_permissons_dmr.xml \
privapp-permissions-flydmr.xml \
SpeechService \
+ default_permissons_speechservice.xml \
+ privapp-permissions-speechservice.xml \
Music \
OneTimeInitializer \
preinstalled-packages-platform-handheld-product.xml \
集成以上操作编译就可以了。
编译的异常处理:
做以上操作时,你会有疑问,
- apk包是哪里来的? 答曰:网上自己找的,
- 包名和权限怎么晓得的?答曰反编译apk晓得的 (直接使用android studio file选项中打开apk就可以了)
- 权限文件怎么创建的?答曰:反编译后查看mainifest文件中可以看到包名和权限,将权限复制后修改成文中的格式就可以了。
大家可以使用sublime Text工具 或你擅长的工具进行权限文件编辑!
放一个开发中遇到的问题(以上配置直接可用不包含该问题),截图如下
这个我撤销权限编译时正常的,放上权限文件编译异常,刷机报错如下,无法进入主页,说明权限文件有问题, 原来我在做权限文件处理中,格式是不对的,直接复制过来格式是这样的
... 略
<permission
android:name="com.iflytek.speechsuite.permission.BROADCAST"/>
,,,略
看到问题了么?对的,多了一个android 节点,这个是不要的,删除就可以了!
成大事者应该拘小节~
---------------------同日update-------------------
四TTS的使用
按照以上操作,那么设备就有了默认的语音引擎,接下来我们在应用中直接调用系统api实现文本转语音
android app应用, 创建工具类 如下
package com.flyscale.dmr;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.speech.tts.TextToSpeech;
import android.util.Log;
import com.flyscale.dmr.utils.ToastUtil;
import java.util.List;
import java.util.Locale;
public class TextToSpeechUtils {
private static final String TAG = "TextToSpeechUtils";
private static TextToSpeech mTts;
private TextToSpeechUtils() {
}
public static class InstanceHolder {
public static TextToSpeechUtils instance = new TextToSpeechUtils();
}
// 初始化TTS引擎
public void initTTS(Context context) {
mTts = new TextToSpeech(context, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
Log.e(TAG, "status:" + status);
if (status == TextToSpeech.SUCCESS) {
// TTS引擎初始化成功
Locale language = Locale.getDefault(); // 获取当前系统语言
int result = mTts.setLanguage(Locale.CHINA); // 设置TTS引擎语言
if (result == TextToSpeech.LANG_MISSING_DATA || result == TextToSpeech.LANG_NOT_SUPPORTED) {
// 不支持当前语言
Log.e(TAG, "TextToSpeech Language not supported");
} else {
// TTS引擎初始化成功,可以进行后续操作
Log.i(TAG, "TTS engine initialized");
}
} else {
// TTS引擎初始化失败
Log.e(TAG, "TTS engine initialization failed");
}
}
},"com.iflytek.speechsuite");
}
public void convertTextToSpeech(String text) {
if (mTts != null && !mTts.isSpeaking()) {
mTts.speak(text, TextToSpeech.QUEUE_FLUSH, null, null);
}
}
public void stopSpeaking() {
if (mTts != null && mTts.isSpeaking()) {
mTts.stop();
}
}
public static void checkTTSValid (Context context) {
PackageManager packageManager = context.getPackageManager();
List<ResolveInfo> list = packageManager.queryIntentActivities(
new Intent(TextToSpeech.Engine.ACTION_CHECK_TTS_DATA),
PackageManager.MATCH_DEFAULT_ONLY
);
// 检查TTS是否可用
if (list.isEmpty()) {
// 处理不支持TTS的情况
Log.e("TTS", "设备不支持TTS功能");
ToastUtil.getInstance().show("TTS不可用");
}else {
ToastUtil.getInstance().show("TTS可用");
}
}
}
然后在你需要的地方进行播放就可以了。
遇到的问题:在做tts 初始化时,一直提示初始化失败,stauts值是-1,最近解决方案是初始化的方法使用带包名的方法,将讯飞语音引擎设置进去就可以了
下载链接: