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地址

目录
相关文章
|
4月前
|
Android开发
Android实现语音播报的两种方式
Android实现语音播报的两种方式
262 0
|
4月前
|
XML 缓存 Android开发
Android开发,使用kotlin学习多媒体功能(详细)
Android开发,使用kotlin学习多媒体功能(详细)
136 0
|
4月前
|
安全 Linux Android开发
Android 安全功能
Android 安全功能
72 0
|
1月前
|
编解码 测试技术 Android开发
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
本文详细介绍了如何利用CameraX库实现高质量的照片及视频拍摄功能,包括添加依赖、初始化、权限请求、配置预览与捕获等关键步骤。此外,还特别针对不同分辨率和帧率的视频拍摄提供了性能优化策略,确保应用既高效又稳定。
84 1
Android经典实战之用 CameraX 库实现高质量的照片和视频拍摄功能
|
4天前
|
Android开发 开发者
Android平台无纸化同屏如何实现实时录像功能
Android平台无纸化同屏,如果需要本地录像的话,实现难度不大,只要复用之前开发的录像模块的就可以,对我们来说,同屏采集这块,只是数据源不同而已,如果是自采集的其他数据,我们一样可以编码录像。
|
1月前
|
图形学 Android开发
小功能⭐️Unity调用Android常用事件
小功能⭐️Unity调用Android常用事件
|
3月前
|
数据库 Android开发 数据安全/隐私保护
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
在 Android Studio 中结合使用 SQLite 数据库实现简单的注册和登录功能
177 2
|
3月前
|
Android开发
Android中如何快速的实现RecycleView的拖动重排序功能
使用`ItemTouchHelper`和自定义`Callback`,在`RecyclerView`中实现拖动排序功能。定义`ItemTouchHelperAdapter`接口,`Adapter`实现它以处理`onItemMove`方法。`SimpleItemTouchHelperCallback`设置拖动标志,如`LEFT`或`RIGHT`(水平拖动),并绑定到`RecyclerView`以启用拖动。完成这些步骤后,即可实现拖放排序。关注公众号“AntDream”获取更多内容。
84 3
|
4月前
|
移动开发 监控 Android开发
构建高效Android应用:从内存优化到电池寿命代码之美:从功能实现到艺术创作
【5月更文挑战第28天】 在移动开发领域,特别是针对Android系统,性能优化始终是关键议题之一。本文深入探讨了如何通过细致的内存管理和电池使用策略,提升Android应用的运行效率和用户体验。文章不仅涵盖了现代Android设备上常见的内存泄漏问题,还提出了有效的解决方案,包括代码级优化和使用工具进行诊断。同时,文中也详细阐述了如何通过减少不必要的后台服务、合理管理设备唤醒锁以及优化网络调用等手段延长应用的电池续航时间。这些方法和技术旨在帮助开发者构建更加健壮、高效的Android应用程序。
|
4月前
|
Android开发 数据安全/隐私保护 iOS开发
ios和安卓测试包发布网站http://fir.im的注册与常用功能
ios和安卓测试包发布网站http://fir.im的注册与常用功能
155 0
ios和安卓测试包发布网站http://fir.im的注册与常用功能