Android SearchView + Toolbar 的语音搜索功能

简介: searchView的语音搜索功能 Google的官方组件越来越丰富,功能也越来越多但是由于Google服务没有入华的原因导致一系列的服务不可用,今天就踩了Google语音的坑 前几天看到无聊看设计的时候看到了Google 官方的设计图 效果图 觉得还不错,真好我要做一版blog的Anndro.

searchView的语音搜索功能

Google的官方组件越来越丰富,功能也越来越多但是由于Google服务没有入华的原因导致一系列的服务不可用,今天就踩了Google语音的坑

我的效果图

giphy_1_

前几天看到无聊看设计的时候看到了Google 官方的设计图

image
image

觉得还不错,真好我要做一版blog的Anndroid 端,于是就采用了这个非常常见的ToolBar的,我接触ToolBar也不是第一次了,对他的印象就是轻便好用,二话不说,先上代码(Java部分采用kotlin语言)

首先在activity的layout文件上将toolbar放入AppBarLayout

<android.support.design.widget.AppBarLayout    android:layout_height="wrap_content"
    android:layout_width="match_parent"
        android:theme="@style/AppTheme.AppBarOverlay">
        
       <android.support.v7.widget.Toolbar
            android:id="@+id/toolbar"
            app:title="首页"
               android:layout_width="match_parent"
            android:layout_height="?attr/actionBarSize"
            android:background="?attr/colorPrimary"
            app:popupTheme="@style/AppTheme.PopupOverlay" />
    </android.support.design.widget.AppBarLayout>

然后在res文件下的menu目录下(没有的话自己创建一个)新建menu.xml

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto">
    <item
        android:id="@+id/action_search"
        android:imeOptions="actionSearch"
        android:title="@string/search"
        app:actionViewClass="android.support.v7.widget.SearchView"
        app:showAsAction="ifRoom" />
    <item
        android:id="@+id/action_settings"
        android:orderInCategory="100"
        android:title="@string/action_settings"
        app:showAsAction="never" />
</menu>

最后重写Activity的onCreateOptionsMenu()方法

override fun onCreateOptionsMenu(menu: Menu): Boolean {
    menuInflater.inflate(R.menu.main, menu)
        return true
    }

来看看效果

200w_d

然后就是语音按钮了,习惯性百度,但是却没有相关资料,只能去看看Google 官方文档了

https://developer.android.google.cn/guide/topics/search/search-dialog.html#SearchableConfiguration
我这这里找到了相关的说明
原来SearchView依赖一个叫Searchable类作为配置类,不过这个类是final修饰的不能够new 可以通过xml文件来写配置,总体来说分为以下几步

第一步

在res/xml/ 路径下新建一个searchable.xml 文件
image
内容

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="@string/search"
    android:hint="请输入内容"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"
    >
</searchable>

其中 android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" 这句话就是显示语音按钮,官网也给了解释
image

第二步

在manifests的activity加一个 action 和一个meta-data,将我们刚才创建的xml引入 具体如下

<activity
            android:name=".MainActivity"
            android:label="@string/app_name"
            android:launchMode="singleTop"
            android:theme="@style/AppTheme.NoActionBar" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH"/>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
            <meta-data android:name="android.app.searchable"
                android:resource="@xml/searchable"/>
        </activity>

第三步

修改代码让SearchView 加载 searchable

     override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main, menu)
        val searchMenuItem = menu.findItem(R.id.action_search)
        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
       val searchView = searchMenuItem.actionView as SearchView
        val searchView = menu.findItem(R.id.action_search).actionView as SearchView
        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
        return true
    }

大功告成,于是立马去运行下看看效果,然后并没卵用,语音按钮还是没出来,百思不得其解,还是老老实实去看看SearchView的源码吧,不懂原理始终是被人牵着走呀
Google的源码还是很规范的

    ......
    final ImageView mSearchButton;
    final ImageView mGoButton;
    final ImageView mCloseButton;
    final ImageView mVoiceButton;
    ......

顾名思义 mVoiceButton就是语音按钮
`

private boolean mVoiceButtonEnabled;

`
又发现个boolean参数,猜的没错的话这个就是控制语音按钮显示的吧,接着看源码,找到了这段

    private void updateVoiceButton(boolean empty) {
        int visibility = GONE;
        if (mVoiceButtonEnabled && !isIconified() && empty) {
            visibility = VISIBLE;
            mGoButton.setVisibility(GONE);
        }
        mVoiceButton.setVisibility(visibility);
    }

果然是这样的,不过voice不仅仅受限制于它,还有其他的参数限制,看到这里我突然想到,是不是我没安装Google搜索服务导致的,立马打开我的GooglePlay
WechatIMG157_jpeg
安装了这货然后
语音图标就出来了,如果要完整的实现语音功能还是要在Activity解析Google语音返回回来的消息还是要在Activity里解析的,所以完整的第三步是这样的
### 完整的第三步

private lateinit var searchView: SearchView
    override fun onCreateOptionsMenu(menu: Menu): Boolean {
        menuInflater.inflate(R.menu.main, menu)
        val searchMenuItem = menu.findItem(R.id.action_search)
        val searchManager = getSystemService(Context.SEARCH_SERVICE) as SearchManager
        searchView = searchMenuItem.actionView as SearchView
        val searchView = menu.findItem(R.id.action_search).actionView as SearchView
        searchView.setSearchableInfo(searchManager.getSearchableInfo(componentName))
        return true
    }
    override fun onNewIntent(intent: Intent) {
        setIntent(intent)
        handleIntent(intent)
    }

    private fun handleIntent(intent: Intent) {
        if (Intent.ACTION_SEARCH == intent.action) {
            val query = intent.getStringExtra(SearchManager.QUERY)
            searchView.setQuery(query,false)
            searchView.setIconifiedByDefault(true)
        }
    }

注意!!
Activity 的启动模式要设置为singleTop 否则会无限次打开

终于知道为什么百度都找不到方案了,原来这货需要Google服务的支持,

所以忙活了半天也是瞎忙活,好在阿里云提供了免费的语音解析服务(好歹也是用的云栖社区,肯定要给阿里个面子),看来要手动造轮子了下周见,源码见附件,完整blog上线我会提供github地址

目录
相关文章
|
1月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
90 0
|
3月前
|
安全 Linux Android开发
Android 安全功能
Android 安全功能
37 0
|
4月前
|
JSON 自然语言处理 Java
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
Android App开发语音处理之系统自带的语音引擎、文字转语音、语音识别的讲解及实战(超详细 附源码)
115 0
|
4月前
|
XML 前端开发 Java
Android App实战项目之实现手写签名APP功能(附源码,简单易懂 可直接实用)
Android App实战项目之实现手写签名APP功能(附源码,简单易懂 可直接实用)
45 0
|
4月前
|
XML Android开发 数据格式
[Android]Toolbar
[Android]Toolbar
28 0
|
4月前
|
传感器 物联网 Android开发
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
【Android App】物联网中查看手机支持的传感器及实现摇一摇功能-加速度传感器(附源码和演示 超详细)
62 1
|
4月前
|
XML Java 定位技术
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
【Android App】定位导航GPS中开启手机定位功能讲解及实战(附源码和演示 超详细)
106 0
|
4月前
|
XML 前端开发 Java
【Android App】三维处理中三维投影OpenGL功能的讲解及实战(附源码和演示 超详细必看)
【Android App】三维处理中三维投影OpenGL功能的讲解及实战(附源码和演示 超详细必看)
33 1
|
4月前
|
机器学习/深度学习 TensorFlow 语音技术
【Android +Tensroflow Lite】实现从基于机器学习语音中识别指令讲解及实战(超详细 附源码和演示视频)
【Android +Tensroflow Lite】实现从基于机器学习语音中识别指令讲解及实战(超详细 附源码和演示视频)
28 0
|
4月前
|
JSON 语音技术 Android开发
【Android App】在线语音识别功能实现(使用云知声平台与WebSocket 超详细 附源码)
【Android App】在线语音识别功能实现(使用云知声平台与WebSocket 超详细 附源码)
34 0