未调用内容提供者query()(Android TV)

Mar*_*arc 2 android android-contentprovider android-search android-tv

根据要创建的文档,我试图将我的应用程序包含在Android TV全局搜索中:

  • 内容提供商
  • Searchable.xml

当然,将它们包括在清单中。这就是我所做的,我的contentprovider非常简单。它不返回任何数据,但是当它获得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();
}
Run Code Online (Sandbox Code Playgroud)

}

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"
    >
Run Code Online (Sandbox Code Playgroud)

这段代码几乎直接来自Android TV leanback示例,我提取了这一部分,因为它是唯一处理全局搜索的部分。

我还在清单中包括了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" >...
Run Code Online (Sandbox Code Playgroud)

如我所见,ContentProvider确实得到了onCreate调用,因此它正确地位于清单中。但是问题是,Android TV在搜索时不会通过我的应用程序,不会调用查询方法。

我还看到该应用程序未在Android TV设置>首选项>搜索>可搜索的应用程序中列出,我认为这确实很奇怪,因为据说在searchable.xml中将提供程序包括在全局搜索中。因为此代码几乎是从leanback示例中复制的,所以我没有主意,因此该示例可以完美运行,并且在复制后立即中断。

任何帮助将不胜感激!

psk*_*ink 5

如果你打开这个,你会看到,无论是android:label和android:hint必须是“字符串资源”(@字符串/某事),我认为,构建系统(或棉绒工具或其他)抓现在的情况(我花了几个小时确切的问题就像您三,四年前一样),但是不,即使现在,开发人员似乎也束手无策,所以只需替换一下:

android:label="test leanback api demo"
android:hint="searching for videos test"
Run Code Online (Sandbox Code Playgroud)

与:

android:label="@string/search_label"
android:hint="@string/search_hint"
Run Code Online (Sandbox Code Playgroud)

我不确定,android:searchSettingsDescription因为在一个地方它说:“字符串资源”,但在详细描述中它是简单的“字符串”