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.