Вопрос:

Запрос поставщика контента () не вызывается (Android TV)

android android-contentprovider android-search android-tv

961 просмотра

2 ответа

614 Репутация автора

Я пытаюсь включить свое приложение в глобальный поиск Android TV, в соответствии с документацией, которую я должен создать:

  • Поставщик услуг
  • Searchable.xml

И, конечно, включить их в манифест. Вот что я сделал, мой контент-провайдер очень прост. Он не возвращает никаких данных, но когда он получает вызов query (), он напечатает несколько строк в журнале, чего еще не сделал.

public class VideoContentProvider extends ContentProvider {
private static String TAG = "VideoContentProvider";
public static String AUTHORITY = "test.tvsearch";

// UriMatcher stuff
private static final int SEARCH_SUGGEST = 0;
private static final int REFRESH_SHORTCUT = 1;
private static final UriMatcher URI_MATCHER = buildUriMatcher();

//private VideoDatabase mVideoDatabase;

/**
 * Builds up a UriMatcher for search suggestion and shortcut refresh queries.
 */
private static UriMatcher buildUriMatcher() {
    UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
    // to get suggestions...
    Log.d(TAG, "suggest_uri_path_query: " + SearchManager.SUGGEST_URI_PATH_QUERY);
    matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY, SEARCH_SUGGEST);
    matcher.addURI(AUTHORITY, SearchManager.SUGGEST_URI_PATH_QUERY + "/*", SEARCH_SUGGEST);
    return matcher;
}

@Override
public boolean onCreate() {
    Log.d(TAG, "onCreate");
    //mVideoDatabase = new VideoDatabase(getContext());
    return true;
}

/**
 * Handles all the video searches and suggestion queries from the Search Manager.
 * When requesting a specific word, the uri alone is required.
 * When searching all of the video for matches, the selectionArgs argument must carry
 * the search query as the first element.
 * All other arguments are ignored.
 */
@Override
public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
                    String sortOrder) {
    // Use the UriMatcher to see what kind of query we have and format the db query accordingly
    switch (URI_MATCHER.match(uri)) {
        case SEARCH_SUGGEST:
            Log.d(TAG, "search suggest: " + selectionArgs[0] + " URI: " + uri);
            if (selectionArgs == null) {
                throw new IllegalArgumentException(
                        "selectionArgs must be provided for the Uri: " + uri);
            }
            Log.i("...", "WORKED");
            return null;
        default:
            throw new IllegalArgumentException("Unknown Uri: " + uri);
    }
}

/**
 * This method is required in order to query the supported types.
 * It's also useful in our own query() method to determine the type of Uri received.
 */
@Override
public String getType(Uri uri) {
    switch (URI_MATCHER.match(uri)) {
        case SEARCH_SUGGEST:
            return SearchManager.SUGGEST_MIME_TYPE;
        case REFRESH_SHORTCUT:
            return SearchManager.SHORTCUT_MIME_TYPE;
        default:
            throw new IllegalArgumentException("Unknown URL " + uri);
    }
}

// Other required implementations...

@Override
public Uri insert(Uri uri, ContentValues values) {
    throw new UnsupportedOperationException();
}

@Override
public int delete(Uri uri, String selection, String[] selectionArgs) {
    throw new UnsupportedOperationException();
}

@Override
public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
    throw new UnsupportedOperationException();
}

}

Searchable.xml:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:label="test leanback api demo"
    android:hint="searching for videos test"
    android:searchSettingsDescription="settings text desc"
    android:searchSuggestAuthority="test.tvsearch"
    android:searchSuggestIntentAction="android.intent.action.VIEW"
    android:searchSuggestSelection=" ?"
    android:searchSuggestThreshold="1"
    android:includeInGlobalSearch="true"
    >

Этот код взят почти напрямую из примера Android TV. Я извлек эту часть, потому что это единственная часть, которая обрабатывает глобальный поиск.

Я включил провайдера и фильтр намерений для searchable.xml также в манифест:

<activity
        android:name=".MainActivity"
        android:label="@string/app_name"
        android:theme="@style/AppTheme.NoActionBar" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

            <category android:name="android.intent.category.LAUNCHER" />
            <category android:name="android.intent.category.LEANBACK_LAUNCHER" />

            <action android:name="android.intent.action.SEARCH" />

        </intent-filter>

        <!-- Points to searchable meta data. -->
        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />

    </activity>

    <provider
        android:name=".VideoContentProvider"
        android:authorities="test.tvsearch"
        android:exported="true" >...

Как я уже видел, ContentProvider действительно получает вызов onCreate, поэтому он правильно указан в манифесте. Однако проблема в том, что Android TV при поиске не проходит через мое приложение, метод запроса не вызывается.

Я также видел, что приложение не отображается в настройках Android TV> «Настройки»> «Поиск»> «Приложения с возможностью поиска», что, на мой взгляд, очень странно, поскольку в searchable.xml говорится, что оно включает провайдера в глобальный поиск. Поскольку этот код почти скопирован из примера упрощенной версии, у меня нет идей, этот пример работает отлично, и при копировании он сразу же ломается.

Любая помощь будет оценена!

Автор: Marc Источник Размещён: 10.09.2015 09:04

Ответы (2)


3 плюса

16841 Репутация автора

Решение

Если вы откроете это, вы увидите, что оба android:labelи android:hintдолжны быть «строковым ресурсом» (@ string / что-то), и я подумал, что система сборки (или инструмент lint или что-то еще) теперь ловит эти случаи (я потратил пару часов на точную проблему как у вас три или четыре года назад), но нет, кажется, что разработчики тянут волосы за голову даже сейчас, поэтому просто замените:

android:label="test leanback api demo"
android:hint="searching for videos test"

с:

android:label="@string/search_label"
android:hint="@string/search_hint"

Я не уверен, android:searchSettingsDescriptionпотому что в одном месте написано: «строковый ресурс», но в подробном описании это просто «строка»

Автор: pskink Размещён: 10.09.2015 05:27

2 плюса

893 Репутация автора

Для всех, кто борется, то, что Google не включает в свое руководство, - это то, что вы должны включить свое приложение для поиска в настройках устройства. В противном случае ваш контент-провайдер создается, но никогда не запрашивается. Нашел это в поисковой конфигурации :

android: includeInGlobalSearch Boolean. (Требуется для предоставления предложений поиска в окне быстрого поиска.) Установите значение «true», если вы хотите, чтобы ваши предложения были включены в глобально доступное окно быстрого поиска. Пользователь по-прежнему должен включить ваше приложение в качестве элемента поиска в настройках поиска системы, прежде чем ваши предложения появятся в окне быстрого поиска.

Автор: Mihaela Romanca Размещён: 19.05.2016 08:14
Вопросы из категории :
32x32