Android自帶語音播報+訊飛語音播報封裝(直接用)

来源:https://www.cnblogs.com/xxdh/archive/2018/07/13/9303377.html
-Advertisement-
Play Games

Android自帶的語音播報+訊飛語音播報封裝(直接用)。 涉及功能: 1.多個許可權申請 2.自帶語音實現 3.訊飛語音播報封裝... ...


一、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();//釋放資源
    }

}

 

源碼下載...

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 目錄: (3)Android 官方網站 對 MediaPlayer的介紹 正文: Android 官方網站 對 MediaPlayer的介紹 MediaPlayer public class MediaPlayer extends Object implements VolumeAutomation ...
  • 啟動spark#啟動spark之前先要把hadoop節點啟動起來#cd /usr/hadoop/hadoop-3.1.0/#sbin/start-all.sh#jps //檢查啟動的線程是否已經把hadoop啟動起來了#cd /usr/spark/spark-2.3.1-bin-hadoop2.7# ...
  • 1. ImageView 繪製圖片 ...
  • 前提:已經通過USB設備線連接過電腦,併成功安裝驅動。 adb連接手機進行調試有兩種方式,一種是使用USB線,另一種是使用無線WiFi。 第一種 使用USB線連接 1. 在手機上啟用USB調試 2. 打開DOS命令視窗,輸入 cd D:\Android\sdk\platform-tools 回車 3 ...
  • Android的Service也運行在主線程,但是在服務裡面是沒法直接調用更改UI,如果需要服務傳遞消息給Activity,通過廣播是其中的一種方法: 一、在服務裡面發送廣播 通過intent傳送數據、通過setAction 設置Activity接收廣播時要過濾的動作名 二、在Activity中創建 ...
  • Mac 關於本機-磁碟管理,如果發現系統占用超過80g以上的小伙伴們可以做以下操作只需要以下4個步驟,輕鬆降到30g以內!!!!!!!(僅適用於安裝了Xcode的小伙伴) 打開Finder,command + shift +g (前往文件夾),刪除一下路徑的文件即可~ 1、 iOS DeviceSu ...
  • 引言 學習《android第一行代碼》根據書本開發的天氣預報app,主要用於熟練操作android開發(android studio3.0平臺)。 今天主要分享一下從伺服器上獲取天氣信息,通過ListView綁定數據的操作(可以採用RecycleView),然後進行頁面點擊跳轉。 一、 伺服器返回數 ...
  • 這篇文章的重點不在於說是對終端語法的講解,而是方便大家做語法備忘. 方便查找對應終端語法.所以使用了表格形式對常用終端語法進行了彙總, 但是並沒有很多的講解部分. 當然了這裡記錄的也都是十分基礎的語法部分, 我相信大家都是可以看得懂的,畢竟大家都是十分優秀的程式猿哦~ 路徑相關 指令表示含義 pwd ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...