Copyright notice: This article is the original translation of the blogger, please indicate the source.
Recommendation: welcome attention I create Android TV Jane books project, regularly to share some AndroidTv related content: www.jianshu.com/c/37efc6e97…
### Search within Android TV app
One of the biggest differences between Android phones and Android TVS is their input method. Since TVS don’t support touchpads, we shouldn’t expect users to use a TV keyboard, which is cumbersome to type words for.
Google suggests using voice input for searches within the TV app
###BrowseFragment an in-app search icon
BrowseFragment includes a design layout for searching, and displaying in-app ICONS on your app is very simple. Only need to implement setOnSearchClickedListener is ok.
// Existence of this method make In-app search icon visible
setOnSearchClickedListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
}
});
Copy the code
The setSearchAffordanceColor method can be used to specify search icon colors.
// set search icon color
setSearchAffordanceColor(getResources().getColor(R.color.search_opaque));
Copy the code
private void setupEventListeners() {
setOnItemViewSelectedListener(new ItemViewSelectedListener());
setOnItemViewClickedListener(new ItemViewClickedListener());
// Existence of this method make In-app search icon visible
setOnSearchClickedListener(new View.OnClickListener() { @Override public void onClick(View view) { Intent intent = new Intent(getActivity(), SearchActivity.class); startActivity(intent); }}); }Copy the code
Start creating the SearchActivity by right-clicking on the package name Create → New Activity → Blank Activity → typing “SearchActivity”. After creating the SearchActivity class and the activity_search.xml layout, modify res/acitivity_search.xml as shown below.
<? xml version="1.0" encoding="utf-8"? > <fragment xmlns:android="http://schemas.android.com/apk/res/android"
android:name="com.corochann.androidtvapptutorial.SearchFragment"
android:id="@+id/search_fragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
/>
Copy the code
It attaches the SearchFragment. Again, through the Create – > New – > Java class – SearchFragment, and make it become an android. Support. V17. Leanback. App. SearchFragment subclass.
If you build and run an application here, the application will crash because SearchFragment will automatically start getting search queries from the internal speech recognizer. # # # realize voice input/voice search – setSpeechRecognitionCallback
Official documents say,
If you don’t pass setSpeechRecognitionCallback (SpeechRecognitionCallback) provides a callback, will use the internal speech recognizer, Your application will need it to request android. Permission. RECORD_AUDIO.
So you need:
- Implement setSpeechRecognitionCallback
- In AndroidManifest. XML request on android. Permission. RECORD_AUDIO
As follows.
public class SearchFragment extends android.support.v17.leanback.app.SearchFragment {
private static final String TAG = SearchFragment.class.getSimpleName();
private static final int REQUEST_SPEECH = 0x00000010;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
if(! Utils.hasPermission(getActivity(), Manifest.permission.RECORD_AUDIO)) { // SpeechRecognitionCallback is not required andif not provided recognition will be handled
// using internal speech recognizer, in which case you must have RECORD_AUDIO permission
setSpeechRecognitionCallback(new SpeechRecognitionCallback() {
@Override
public void recognizeSpeech() {
Log.v(TAG, "recognizeSpeech");
try {
startActivityForResult(getRecognizerIntent(), REQUEST_SPEECH);
} catch (ActivityNotFoundException e) {
Log.e(TAG, "Cannot find activity for speech recognizer", e); }}}); }}Copy the code
utils.java
public static boolean hasPermission(final Context context, final String permission) {
returnPackageManager.PERMISSION_GRANTED == context.getPackageManager().checkPermission( permission, context.getPackageName()); }Copy the code
### Override onSearchRequeseted to enable in-app search
When the user attempts a voice-typed search, the onSearchRequested callback is executed and Google’s global content search is started by default.
If you want to enable in-application application search, you need to override this method.
It is written in the description of the startSearch method
It is usually from onSearchRequested () directly from the Activity. OnSearchRequested () or cover versions of any given Activity. If your goal is just to activate the search, it is best to call onSearchRequested (), which may already be overridden elsewhere in your Activity. If your goal is to inject specific data such as context data, override onSearchRequested () first so that any caller will benefit from the override.
We override the onSearchRequested methods of MainActivity and SearchActivity.
@Override
public boolean onSearchRequested() {
startActivity(new Intent(this, SearchActivity.class));
return true;
}
Copy the code
### Customize in-app search – SearchResultProvider
The SearchResultProvider interface is the interface of the Leanback library and is used to listen for search-related events. We need to rewrite three methods.
- GetResultsAdapter – Returns the adapter that contains the search results to display the search results on the SearchFragment.
- OnQueryTextChange – Event listener that is invoked when the user changes the text of the search query.
- OnQueryTextSubmit – Event listener that is invoked when the user submits the text of the search query.
We need to register the SearchResultProvider using the setSearchResultProvider method, which is the minimal implementation,
public class SearchFragment extends android.support.v17.leanback.app.SearchFragment
implements android.support.v17.leanback.app.SearchFragment.SearchResultProvider {
private static final String TAG = SearchFragment.class.getSimpleName();
private static final int REQUEST_SPEECH = 0x00000010;
private ArrayObjectAdapter mRowsAdapter;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mRowsAdapter = new ArrayObjectAdapter(new ListRowPresenter());
setSearchResultProvider(this); . }... @Override public ObjectAdaptergetResultsAdapter() {
Log.d(TAG, "getResultsAdapter");
Log.d(TAG, mRowsAdapter.toString());
// It should return search result here,
// but static Movie Item list will be returned here now for practice.
ArrayList<Movie> mItems = MovieProvider.getMovieItems();
ArrayObjectAdapter listRowAdapter = new ArrayObjectAdapter(new CardPresenter());
listRowAdapter.addAll(0, mItems);
HeaderItem header = new HeaderItem("Search results");
mRowsAdapter.add(new ListRow(header, listRowAdapter));
return mRowsAdapter;
}
@Override
public boolean onQueryTextChange(String newQuery){
Log.i(TAG, String.format("Search Query Text Change %s", newQuery));
return true;
}
@Override
public boolean onQueryTextSubmit(String query) {
Log.i(TAG, String.format("Search Query Text Submit %s", query));
return true;
}
Copy the code
### Build and run
The SearchActivity can be started in two ways,
1. Click the search icon of BrowseFragment. 2. When the user launches voice input search *1 from a specific controller (onSearchRequested will be called.)
*1 This depends on the Android TV device. SONY BRAVIA, for example, offers touch-pad remote controls from which voice searches can be performed.
SearchFragment now displays mock search results.
github
We should implement OnItemViewClickedListener to define the click on the search results. This OnItemViewClickedListener can be set
setOnItemViewClickedListener(new ItemViewClickedListener());
Copy the code
(In this case) BrowseFragment in onCreate.
Pay attention to wechat public number, regularly recommend mobile development related articles for you.