Original title: Use Voice Search to integrate with Google now
Original link:http://antonioleiva.com/voice_search_google_now/
Original Antonio Leiva (http://antonioleiva.com/about/)
Published in the original: 2015-10-14
One of the best capabilities of Android is the ability to integrate our app into its ecosystem in a different way. Apps can "communicate" with each other, giving us great flexibility to create unique app experiences.
The integration of Google Apps is a classic example. There are many different features that can help us improve app visibility, such as app indexing or a powerful set of voice features .
Voice Search
Although the process of implementing voice search in apps is similar to any other speech feature, in this article, I'll focus on how to implement voice search in the app. You can also try this example in play music:
- Good, Google in the Play Music , Search Beatles
This command will open the search Beatles in the play Music app.
How to achieve voice search
When the voice search starts, our app will receive a intent of the query text, which we must capture and analyze. So, this first part is specifying which activity receives this intent:
1 <ActivityAndroid:name=". Mainactivity "Android:launchmode= "Singletask" >2 <Intent-filter>3 <ActionAndroid:name= "Com.google.android.gms.actions.SEARCH_ACTION"/>4 <categoryAndroid:name= "Android.intent.category.DEFAULT"/>5 </Intent-filter>6 </Activity>
This action is called Com.google.android.gms.actions.SEARCH_ACTION, so we say mainactivity is dealing with such Intent. In addition, I use singletask startup mode so that mainactivity is created only once. Otherwise, each time you receive this intent, you will create a new activity instance.
The next step is to process it within the mainactivity. When we use singletask mode, we can receive Intent in two different locations of activity : First , create activity with getintent () , then The Onnewintent method. This will create a processing method to call it when it is needed:
1 Private Static FinalString action_voice_search = "Com.google.android.gms.actions.SEARCH_ACTION";2 ...3 Private voidHandlevoicesearch (Intent Intent) {4 if(Intent! =NULL&&action_voice_search.equals (Intent.getaction ())) {5String query =Intent.getstringextra (searchmanager.query);6Setsearchviewvisible (true);7Searchview.setquery (Query,true);8 }9}
This method checks whether intent is empty (null) or whether it is an action to be detected before the query text is received, which is an extra action inside the intent. The additional action keyword for the query is searchmanager.query.
after Searchview, set up the query and submit the execution query. The method is onnewintent:
1 protected void onnewintent (Intent Intent) {2 Super . Onnewintent (intent); 3 Handlevoicesearch (intent); 4 }
The UI is also ready (in our example, when the menu pops up, we visit Searchview), which you will see later.
In my example, theUI is based onthe Searchview inside the toolbar (Toolbar) . You can see how to implement Searchview in the previous article , but I'll explain how to do it a little bit. First, the menu action is generated:
1 <Menuxmlns:android= "Http://schemas.android.com/apk/res/android"2 Xmlns:app= "Http://schemas.android.com/apk/res-auto">3 <Item4 Android:id= "@+id/action_search"5 Android:title= "@string/action_search"6 Android:icon= "@drawable/ic_search"7 App:actionviewclass= "Android.support.v7.widget.SearchView"8 app:showasaction= "Ifroom" />9 </Menu>
Then, when the menu pops up, you request Searchview:
1@Override Public BooleanOncreateoptionsmenu (Menu menu) {2 getmenuinflater (). Inflate (R.menu.main, menu);3 4MenuItem Searchitem =Menu.finditem (r.id.action_search);5Searchview =(Searchview) Menuitemcompat.getactionview (searchitem);6 7Searchview.setonsearchclicklistener (NewView.onclicklistener () {8@Override Public voidOnClick (View v) {9Setsearchviewvisible (true);Ten } One }); A -Searchview.setonquerytextlistener (NewSearchview.onquerytextlistener () { -@Override Public Booleanonquerytextsubmit (String query) { theToast.maketext (mainactivity. This, query, Toast.length_long). Show (); - Searchview.clearfocus (); - return true; - } + -@Override Public BooleanOnquerytextchange (String newtext) { + return false; A } at }); - - Handlevoicesearch (Getintent ()); - - return true; - } in - Private voidSetsearchviewvisible (Booleanvisible) { to + if(searchview.isiconified () = =visible) { -Searchview.seticonified (!visible); the } * $ if(Getsupportactionbar ()! =NULL) {Panax Notoginseng Getsupportactionbar (). setdisplayhomeasupenabled (visible); - } the}
How to try
Because the app needs to be posted to the Play store, Google Now detects the app, so we can't try this example directly from Google Now. However, we can use ADB to debug it. This command is:
- ADB shell am start-a com.google.android.gms.actions.search_action-e Query searchquery app_package
For An example downloaded from my code base , you can do this:
- ADB shell am start-a com.google.android.gms.actions.search_action-e Query Voicesearch Com.antonioleiva.googlenowsearch
You can try this example when the app is completely closed and started. In this way, you can test two possible pathways.
Additional instructions:Kotlinthe realization of language
You probably know, because I think Kotlin language can be very good alternative to the Java language, Kotlin can make our code more concise, more readable, so these days discussed the characteristics of many Kotlin languages. As an example, I will simplify oncreateoptionsmenu, and you can find the complete code in the same code base .
The ability to implement extension functions can help us reduce verbose code. For example, you can create an extension function for menu, find Actionview based on the action ID, and return to the hierarchical view:
1 inline fun <reified t:view?> menu.findcompatactionview (actionres:int): T {2 Val Searchitem = findItem (actionres)3 return Menuitemcompat.getactionview ( Searchitem) as T4 }
You can now do this:
1 searchview = Menu.findcompatactionview (R.id.action_search)
Another extension function can help us write ouerytextlistener in a clear way :
1Fun Searchview.onquerytext (Submit: (String), Boolean = {false}, TextChange: (String), Boolean = {false }) {2 3 This. Setonquerytextlistener (Object:SearchView.OnQueryTextListener {4 5Override Fun Onquerytextsubmit (query:string): Boolean =Submit (query)6 7Override Fun Onquerytextchange (newtext:string): Boolean =TextChange (NewText)8 9 })Ten}
This function receives a pair of functions, one for each method in the listener, and gives their default values. So we just need to define what we want to use. If we just want the first function (for the second one we use the default), now I can do it:
1 Searchview.onquerytext ({2 longtoast (IT)3 searchview.clearfocus ()4 true5 })
In the end, this function is like this:
1 Override Fun Oncreateoptionsmenu (Menu:menu): Boolean {2 menuinflater.inflate (R.menu.main, menu)3 4Searchview =Menu.findcompatactionview (R.id.action_search)5Searchview.setonsearchclicklistener {setsearchviewvisible (true) }6 7 Searchview.onquerytext ({8 Longtoast (IT)9 Searchview.clearfocus ()Ten true One }) A -Intent?. Let {handlevoicesearch (it)} - the return true -}
As you can see, if in this position (for example: on a regular activity creation),intent is nullable, you must check whether it is null before using it . With the let function, you can avoid the creation of the If condition, which is not NULL when the object is called, and can only go inside the object.
If you are interested in Kotlin, you can search for Kotlin articles , or buy the book "Android developer Kotlin" I wrote.
Integrate voice search into Google Now