Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> Android開發 >> 關於android開發 >> 將語音搜索集成到Google Now中,googlenow

將語音搜索集成到Google Now中,googlenow

編輯:關於android開發

將語音搜索集成到Google Now中,googlenow


原文標題:Use Voice Search to integrate with Google Now

原文鏈接:http://antonioleiva.com/voice_search_google_now/

原文作者:Antonio Leiva(http://antonioleiva.com/about/)

原文發布:2015-10-14

 

 

Android最棒的能力之一就是可以將我們的APP以不同的方式集成到它的生態鏈中。APP相互之間可以進行“交流”,這給予我們極大的靈活性來創建獨特的應用體驗。

 

集成Google應用就是一個典型的例子。有很多不同的特性可以幫助我們提升APP的知名度,如APP索引或一組強大的語音功能。

 

語音搜索

 

盡管,在APP中實現語音搜索的過程與任何其他語音功能類似,但是,在這篇文章中,我還是會聚焦在怎樣在APP中實現語音搜索功能。你也可以在Play Music中嘗試這個例子:

 

  • 好,GooglePlay Music中,搜索Beatles

 

這句指令將在Play Music APP中開啟搜索Beatles。

 

怎樣實現語音搜索

 

當語音搜索啟動後,我們的APP將收到一個查詢文字的Intent,我們必須捕捉和分析這段文字。所以,這第一部分是指定哪個Activity接收這條Intent:

1 <activity android:name=".MainActivity" android:launchMode="singleTask" >
2     <intent-filter>
3         <action android:name="com.google.android.gms.actions.SEARCH_ACTION"/>
4         <category android:name="android.intent.category.DEFAULT"/>
5     </intent-filter>
6 </activity>

 

這個動作(action)稱為com.google.android.gms.actions.SEARCH_ACTION,所以我們說MainActivity是處理這類Intent。另外,我用singleTask啟動模式,這樣MainActivity就僅僅創建一次。否則,每次收到這條Intent就要創建一個新的Activity實例。

 

接下來的一步是要在MainActivity內進行處理它。當我們用singleTask模式時,在Activity的兩個不同位置上可以接收Intent:首先是用getIntent()創建Activity,接著是onNewIntent方法中。這樣就要創建一個處理方法在需要它的時候調用它:

1     private static final String ACTION_VOICE_SEARCH = "com.google.android.gms.actions.SEARCH_ACTION";
2   ...
3     private void handleVoiceSearch(Intent intent) {
4         if (intent != null && ACTION_VOICE_SEARCH.equals(intent.getAction())) {
5             String query = intent.getStringExtra(SearchManager.QUERY);
6             setSearchViewVisible(true);
7             searchView.setQuery(query, true);
8         }
9     }

 

這個方法檢查Intent是否為空(null)或者是否是在收到查詢文字前要檢測的動作,它是Intent內部的額外動作。查詢的額外動作關鍵字是SearchManager.QUERY。

 

在searchView後,設置查詢,提交執行查詢。其方法是onNewIntent:

1 @Override protected void onNewIntent(Intent intent) {
2     super.onNewIntent(intent);
3     handleVoiceSearch(intent);
4 }

 

UI也准備好(在我們的例子中,當菜單彈出時,我們訪問SearchView),你稍後將看到。

 

在我的例子中,UI是基於工具欄(Toolbar)內部的SearchView。你可以在前面的文章中看到怎樣實現SearchView,不過我還是稍作解釋怎樣做。首先,產生菜單動作(menu action):

1 <menu xmlns:android="http://schemas.android.com/apk/res/android"
2       xmlns:app="http://schemas.android.com/apk/res-auto">
3     <item
4         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>

 

然後,在菜單彈出時,你請求SearchView:

 1 @Override public boolean onCreateOptionsMenu(Menu menu) {
 2     getMenuInflater().inflate(R.menu.main, menu);
 3  
 4     MenuItem searchItem = menu.findItem(R.id.action_search);
 5     searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
 6  
 7     searchView.setOnSearchClickListener(new View.OnClickListener() {
 8         @Override public void onClick(View v) {
 9             setSearchViewVisible(true);
10         }
11     });
12  
13     searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
14         @Override public boolean onQueryTextSubmit(String query) {
15             Toast.makeText(MainActivity.this, query, Toast.LENGTH_LONG).show();
16             searchView.clearFocus();
17             return true;
18         }
19  
20         @Override public boolean onQueryTextChange(String newText) {
21             return false;
22         }
23     });
24  
25     handleVoiceSearch(getIntent());
26  
27     return true;
28 }
29  
30 private void setSearchViewVisible(boolean visible) {
31  
32     if (searchView.isIconified() == visible) {
33         searchView.setIconified(!visible);
34     }
35  
36     if (getSupportActionBar() != null) {
37         getSupportActionBar().setDisplayHomeAsUpEnabled(visible);
38     }
39 }

 

怎樣嘗試

 

由於APP需要發布到Play商店中,Google Now才能檢測到APP,所以我們還不能直接從Google Now嘗試這個例子。但是,我們可以用ADB來調試它。這條命令是:

 

  • adb shell am start -a com.google.android.gms.actions.SEARCH_ACTION -e query searchquery app_package

 

對於從我的代碼庫下載的例子,就可以這樣做:

 

  • adb shell am start -a com.google.android.gms.actions.SEARCH_ACTION -e query VoiceSearch com.antonioleiva.googlenowsearch

 

在APP完全關閉和啟動時,都可以嘗試本例了。這樣,就可以測試兩種可能的途徑了。

 

附加說明:Kotlin語言的實現

 

你可能知道,因為我認為Kotlin語言可以非常好替代Java語言,Kotlin可以使我們的代碼更簡潔、可讀性更好,所以這些天討論了許多Kotlin語言的特性。作為例子,我將簡化onCreateOptionsMenu,你可以在同一個代碼庫中找到完整的代碼。

 

實現擴展函數的能力可以幫助我們減少冗長代碼。例如,可以為Menu創建一個擴展函數,基於action id找到ActionView,返回層級視圖:

1 inline fun <reified T : View?> Menu.findCompatActionView(actionRes: Int): T {
2     val searchItem = findItem(actionRes)
3     return MenuItemCompat.getActionView(searchItem) as T
4 }

 

現在可以這樣做:

1 searchView = menu.findCompatActionView(R.id.action_search)

 

另一個擴展函數可以以清晰的方式幫助我們編寫OueryTextListener:

 1 fun SearchView.onQueryText(submit: (String) -> Boolean = { false }, textChange: (String) -> Boolean = { false }) {
 2  
 3     this.setOnQueryTextListener(object : SearchView.OnQueryTextListener {
 4  
 5         override fun onQueryTextSubmit(query: String): Boolean = submit(query)
 6  
 7         override fun onQueryTextChange(newText: String): Boolean = textChange(newText)
 8  
 9     })
10 }

 

這個函數接收一對函數,一個用於偵聽器中的每個方法,並給出它們的默認值。這樣我們僅需要定義我們要用的。如果我們僅僅要第一個函數(對於第二個我們用默認的),現在我就可以這樣做:

1 searchView.onQueryText ({
2     longToast(it)
3     searchView.clearFocus()
4     true
5 })

 

最終,這個函數就是這樣的:

 1 override fun onCreateOptionsMenu(menu: Menu): Boolean {
 2     menuInflater.inflate(R.menu.main, menu)
 3  
 4     searchView = menu.findCompatActionView(R.id.action_search)
 5     searchView.setOnSearchClickListener { setSearchViewVisible(true) }
 6  
 7     searchView.onQueryText ({
 8         longToast(it)
 9         searchView.clearFocus()
10         true
11     })
12  
13     intent?.let { handleVoiceSearch(it) }
14  
15     return true
16 }

 

如你所見,如果在這個位置上(例如:在一個常規activity創建上),Intent可以為null,就必須在使用它之前檢查它是否為null。用let函數,可以避免if條件的創建,在對象調用時不為null,就可只進入對象內部。

如果你對Kotlin有興趣,可以搜索Kotlin文章,或購買我編寫的《Android開發者的Kotlin》一書。

 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved