一、Android自帶的語音播報
1.查看是否支持中文,在測試的設備中打開‘設置’ –>找到 ‘語言和輸入法’–>查看語音選項,是否支持中文,默認僅支持英文.
使用如下:
public class AndroidTTSActivity extends AppCompatActivity implements View.OnClickListener {
private TextToSpeech textToSpeech = null;//創建自帶語音對象
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.android_tts_layout);
findViewById(R.id.btn0).setOnClickListener(this);
initTTS();
}
private void initTTS() {
//實例化自帶語音對象
textToSpeech = new TextToSpeech(this, new TextToSpeech.OnInitListener() {
@Override
public void onInit(int status) {
if (status == textToSpeech.SUCCESS) {
// Toast.makeText(MainActivity.this,"成功輸出語音",
// Toast.LENGTH_SHORT).show();
// Locale loc1=new Locale("us");
// Locale loc2=new Locale("china");
textToSpeech.setPitch(1.0f);//方法用來控制音調
textToSpeech.setSpeechRate(1.0f);//用來控制語速
//判斷是否支持下面兩種語言
int result1 = textToSpeech.setLanguage(Locale.US);
int result2 = textToSpeech.setLanguage(Locale.
SIMPLIFIED_CHINESE);
boolean a = (result1 == TextToSpeech.LANG_MISSING_DATA || result1 == TextToSpeech.LANG_NOT_SUPPORTED);
boolean b = (result2 == TextToSpeech.LANG_MISSING_DATA || result2 == TextToSpeech.LANG_NOT_SUPPORTED);
Log.i("zhh_tts", "US支持否?--》" + a +
"\nzh-CN支持否》--》" + b);
} else {
Toast.makeText(AndroidTTSActivity.this, "數據丟失或不支持", Toast.LENGTH_SHORT).show();
}
}
});
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.btn0) {
startAuto("big sea");
}
}
private void startAuto(String data) {
// 設置音調,值越大聲音越尖(女生),值越小則變成男聲,1.0是常規
textToSpeech.setPitch(1.0f);
// 設置語速
textToSpeech.setSpeechRate(0.3f);
textToSpeech.speak(data,//輸入中文,若不支持的設備則不會讀出來
TextToSpeech.QUEUE_FLUSH, null);
}
@Override
protected void onStop() {
super.onStop();
textToSpeech.stop(); // 不管是否正在朗讀TTS都被打斷
textToSpeech.shutdown(); // 關閉,釋放資源
}
}
二、訊飛語音播報封裝(直接用)
1.接入項目前準備:
1.申請APPID(步驟):
I.登錄訊飛官網–>創建應用–》創建完成在”我的應用”中即可看見自己新建的項目&APPID–>
II.添加需要開通的服務:這裏選擇在線語音合成+sdk下載(so+jar文件),注意:so文件必須用你對應的項目的,用別人so文件,會導致與你的APPID不匹配,
2.使用說明+接入高頻易發問題:
- 語音次數是有限制的,提高次數需要實名認證+上傳項目
- 引入的so文件必須是你項目所對應的
- 不可多次初始化合成對象
3.接入項目(AndroidStudio):
I.相關sdk文件引入,如圖(再次說明:so文件用的是你新建項目的so文件,不要用他人so):
II.初始化語音播報(API>=23需要授權,所以先授權,再初始化,如下:)
public class StartActivity extends AppCompatActivity {
private List<String> permissionList = null;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
SystemClock.sleep(1000);//延時加載
requestPermissions();
}
private void openActivity(Class<? extends AppCompatActivity> clazz) {
initTTS();
startActivity(new Intent(this, clazz));
finish();
}
//權限申請
private void requestPermissions() {
// 版本判斷。當手機系統大於 23 時,纔有必要去判斷權限是否獲取
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
addListPermission();
boolean isGranted = false;//是否全部授權
// 權限是否已經 授權 GRANTED---授權 DINIED---拒絕
Iterator<String> iterator = permissionList.iterator();
while (iterator.hasNext()) {
// 檢查該權限是否已經獲取
int granted = ContextCompat.checkSelfPermission(this, iterator.next());
if (granted == PackageManager.PERMISSION_GRANTED) {
iterator.remove();//已授權則remove
}
}
if (permissionList.size() > 0) {
// 如果沒有授予該權限,就去提示用戶請求
//將List轉爲數組
String[] permissions = permissionList.toArray(new String[permissionList.size()]);
// 開始提交請求權限
ActivityCompat.requestPermissions(this, permissions, 0x10);
} else {
Log.i("zhh", "權限已申請");
openActivity(MainActivity.class);
}
} else {
openActivity(MainActivity.class);
}
}
//初始化語音合成
private void initTTS() {
//訊飛語音播報平臺
SpeechUtility.createUtility(this, "appid=");//=號後面寫自己應用的APPID
Setting.setShowLog(true); //設置日誌開關(默認爲true),設置成false時關閉語音雲SDK日誌打印
TTSUtils.getInstance().init(); //初始化工具類
}
/**
* 權限申請返回結果
*
* @param requestCode 請求碼
* @param permissions 權限數組
* @param grantResults 申請結果數組,裏面都是int類型的數
*/
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
switch (requestCode) {
case 0x10:
if(grantResults.length>0&&ifGrantResult(grantResults)){
Toast.makeText(this, "同意權限申請", Toast.LENGTH_SHORT).show();
openActivity(MainActivity.class);
}else{
Toast.makeText(this, "權限被拒絕了", Toast.LENGTH_SHORT).show();
finish();
}
break;
default:
break;
}
}
private boolean ifGrantResult(int[] grants) {
boolean isGrant = true;
for (int grant : grants) {
if (grant == PackageManager.PERMISSION_DENIED) {
isGrant = false;
break;
}
}
return isGrant;
}
//敏感權限添加
private void addListPermission() {
if (null == permissionList) {
permissionList = new ArrayList<>();
permissionList.add(Manifest.permission.WRITE_EXTERNAL_STORAGE);
permissionList.add(Manifest.permission.READ_PHONE_STATE);
permissionList.add(Manifest.permission.RECORD_AUDIO);
}
}
}
III.語音播報封裝(部分代碼)
public class TTSUtils implements InitListener, SynthesizerListener {
private static volatile TTSUtils instance = null;
private boolean isInitSuccess = false;
private SpeechSynthesizer mTts;
//單例模式
public static TTSUtils getInstance() {
if (instance == null) {
synchronized (TTSUtils.class) {
if (instance == null) {
instance = new TTSUtils();
}
}
}
return instance;
}
public TTSUtils() {
}
// 初始化合成對象
public void init() {
//判斷進程是否已啓動,初始化多次會報錯
//個人遇到問題:極光推送引入後,不加該條件回報錯
if (CourseUtils.resultProcess("com.zhanghai.ttsapp")) {
mTts = SpeechSynthesizer.createSynthesizer(App.getContext(), this);
// 清空參數
mTts.setParameter(SpeechConstant.PARAMS, null);
// 設置在線雲端
mTts.setParameter(SpeechConstant.ENGINE_TYPE,
SpeechConstant.TYPE_CLOUD);
// 設置發音人--發音人選擇--具體見values-string
mTts.setParameter(SpeechConstant.VOICE_NAME, "xiaoqi");
// 設置發音語速
mTts.setParameter(SpeechConstant.SPEED, "50");
// 設置音調
mTts.setParameter(SpeechConstant.PITCH, "50");
// 設置合成音量
mTts.setParameter(SpeechConstant.VOLUME, "100");
// 設置播放器音頻流類型
mTts.setParameter(SpeechConstant.STREAM_TYPE, "3");
// 設置播放合成音頻打斷音樂播放,默認爲true
mTts.setParameter(SpeechConstant.KEY_REQUEST_FOCUS, "true");
// 設置音頻保存路徑,需要申請WRITE_EXTERNAL_STORAGE權限,如不需保存註釋該行代碼
// mTts.setParameter(SpeechConstant.TTS_AUDIO_PATH,"./sdcard/iflytek.pcm");
Log.i("zhh", "--初始化成完成-");
}
}
//開始合成
public void speak(String msg) {
if (isInitSuccess) {
if (mTts.isSpeaking()) {
stop();
}
mTts.startSpeaking(msg, this);
} else {
init();
}
}
}
IV:調用實例
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
private static final String TAG = MainActivity.class.getSimpleName();
private EditText et = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
et = findViewById(R.id.et);
findViewById(R.id.btn0).setOnClickListener(this);
findViewById(R.id.btn1).setOnClickListener(this);
findViewById(R.id.btn2).setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn0:
TTSUtils.getInstance().speak("bigsea是大海");
break;
case R.id.btn1:
String msg = et.getText().toString();
TTSUtils.getInstance().speak(TextUtils.isEmpty(msg) ? "輸入信息爲空" : msg);
break;
case R.id.btn2:
startActivity(new Intent(this, AndroidTTSActivity.class));
break;
default:
break;
}
}
@Override
protected void onResume() {
//移動數據統計分析--不用可不用加入
FlowerCollector.onResume(MainActivity.this);
FlowerCollector.onPageStart(TAG);
super.onResume();
}
@Override
protected void onPause() {
//移動數據統計分析
FlowerCollector.onPageEnd(TAG);
FlowerCollector.onPause(MainActivity.this);
super.onPause();
}
@Override
protected void onDestroy() {
super.onDestroy();
TTSUtils.getInstance().release();//釋放資源
}
}