Невозможно выполнить поиск в панели действий.

Я новичок в разработке java и android; и я работал над приложением в witch. Я хочу панель действий с SearchView. Я просмотрел примеры Google, но я не могу заставить его работать. Я должен делать что-то неправильно, и я собираюсь отказаться от разработки приложений: D Я искал, но я не нашел ничего полезного. Может быть, вы, ребята, можете мне помочь:)

Проблема: я открываю окно поиска так, как должно, но после этого ничего не происходит вообще, я заметил, что мой searchManager.getSearchableInfo(getComponentName()) возвращает значение null. Также мой намек, который я дал, не отображается в моем окне поиска, ведьма заставляет меня думать, что, возможно, приложение не может найти мой searchable.xml? Достаточно поговорить:)

MainActivity.java

public class MainActivity extends Activity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.activity_main, menu);

        // Get the SearchView and set the searchable configuration
        SearchManager searchManager =
            (SearchManager) getSystemService(Context.SEARCH_SERVICE);
        SearchView searchView =
            (SearchView) menu.findItem(R.id.menu_search).getActionView();
        searchView.setSearchableInfo(
            searchManager.getSearchableInfo(getComponentName()));

        return true;
    }
}

searchable.xml

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/search_hint"
    android:label="@string/app_label">
</searchable>

Androidmanifest

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.example.searchapp"
    android:versionCode="1"
    android:versionName="1.0" >

    <uses-sdk
        android:minSdkVersion="14"
        android:targetSdkVersion="15" />

    <application
        android:icon="@drawable/ic_launcher"
        android:label="@string/app_name"
        android:theme="@style/AppTheme" >

        <activity android:name=".SearchableActivity" >
            <intent-filter>
                <action android:name="android.intent.action.SEARCH" />
            </intent-filter>
        </activity>

        <activity
            android:name=".MainActivity"
            android:label="@string/title_activity_main" >
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />
                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>           
        </activity>

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

    </application>

</manifest>

SearchableActivity.java

package com.example.searchapp;

import android.app.ListActivity;
import android.app.SearchManager;
import android.content.Intent;
import android.os.Bundle;
import android.util.Log;

public class SearchableActivity extends ListActivity {

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.search);

        // Get the intent, verify the action and get the query
        Intent intent = getIntent();
        if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
          String query = intent.getStringExtra(SearchManager.QUERY);
          doMySearch(query);
        }
    }

    private void doMySearch(String query) {
        Log.d("Event",query);
    }
}

И вот ссылка на упомянутый проект, я был бы вечно благодарен, если бы кто-то помог мне с этим!

Исходный код

Ответ 1

Ваша проблема в вашем AndroidManifest. У меня это было почти так же, как и у вас, потому что это то, что я получаю после документации. Но это неясно или ошибочно.

Наблюдая за источником API Demos, я обнаружил, что метаданные "android.app.searchable" должны идти в вашем "результатах", а в основном действии (или в деятельности, где вы размещаете SearchView) вы указываете на другой один с "android.app.default_searchable".

Вы можете увидеть это в следующем файле, который является манифестом из моего тестового проекта:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
    android:minSdkVersion="8"
    android:targetSdkVersion="15" />

<application
    android:icon="@drawable/ic_launcher"
    android:label="@string/app_name"
    android:theme="@style/AppTheme" >
    <activity
        android:name=".MainActivity"
        android:label="@string/title_activity_main" >
        <intent-filter>
            <action android:name="android.intent.action.MAIN" />

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

        <meta-data
            android:name="android.app.default_searchable"
            android:value=".SearchActivity" />
    </activity>
    <activity
        android:name=".SearchActivity"
        android:label="@string/app_name" >

        <!-- This intent-filter identifies this activity as "searchable" -->

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

            <category android:name="android.intent.category.DEFAULT" />
        </intent-filter>

        <!-- This metadata entry provides further configuration details for searches -->
        <!-- that are handled by this activity. -->

        <meta-data
            android:name="android.app.searchable"
            android:resource="@xml/searchable" />
    </activity>
</application>

Также важно, чтобы подсказка и метка в файле searchable.xml были ссылками, а не жестко закодированными строками.

Надеюсь, он решает вашу проблему. Мне потребовался целый день, чтобы понять это: (

Ответ 2

В руководствах Android явно указано:

// Assumes current activity is the searchable activity
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));

Что в вашем случае НЕ ИСТИНА. Потому что вы не хотите искать в MainActivity, но в SearchableActivity. Это означает, что вы должны использовать это ComponentName вместо метода getComponentName():

ComponentName cn = new ComponentName(this, SearchableActivity.class);
searchView.setSearchableInfo(searchManager.getSearchableInfo(cn));

Ответ 3

Также кажется, что атрибуты android: hint и android: label MUST относятся к строкам в файле strings.xml. Быть ленивым и жестко кодировать значения строк не работает вообще:)

то есть. Не выполнять:

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="Search for something..."
    android:label="My App">
</searchable>

Но определенно сделайте (как правильно сделал OP):

<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
    android:hint="@string/search_hint"
    android:label="@string/app_label">
</searchable>

Ответ 4

Если вы используете Android Studio,

<meta-data
            android:name="android.app.default_searchable"
            android:value=".SearchActivity" />

часть может не работать.

напишите полное имя пакета, например

<meta-data
                android:name="android.app.default_searchable"
                android:value="com.example.test.SearchActivity" />

Ответ 5

будьте осторожны с "xml/searchable.xml". Если вы сделали HARD CODE с android:hint и android:label. Это не сработает. ха-ха Должно быть:

<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="@string/app_name"
android:label="@string/search_lb"
android:voiceSearchMode="showVoiceSearchButton|launchRecognizer"/>

Ответ 6

На самом деле нет необходимости использовать "недостающую часть", как описано в ответах выше. Этот метод (с использованием SearchView) работает точно так, как говорят официальные документы до Использование виджета поиска. Здесь небольшое изменение необходимо сделать следующим образом:

Свойства в SearchableInfo используются для отображения меток, подсказок, предложений, создания намерений для запуска экранов результатов поиска и контроля других возможностей, таких как голосовая кнопка (документы).

Таким образом, объект SearchableInfo, который мы передаем в SearchView.setSearchableInfo(SearchableInfo s), должен содержать правильные ссылки на целевую активность, которые должны отображаться для отображения результатов поиска. Это делается путем передачи ComponentName ComponentName нашей целевой активности. Один конструктор для создания ComponentName -

public ComponentName (String pkg, String cls)

pkg и cls - имена пакетов и имена классов целевой активности, которые будут запущены для отображения результатов поиска. Обратите внимание:

pkg должен указывать на имя корневого пакета вашего проекта и

cls должно быть полностью квалифицированным именем класса (т.е. всего объекта)

например:.

@Override
public boolean onCreateOptionsMenu(Menu menu) {
    getMenuInflater().inflate(R.menu.activity_main, menu);
    // Get the SearchView and set the searchable configuration
String pkg = "com.example.musicapp"
String cls = "com.example.musicapp.search.SearchActivity"
ComponentName mycomponent = new ComponentName(pkg,cls);       
SearchManager searchManager =(SearchManager)getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) menu.findItem(R.id.menu_search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(mycomponent));
searchView.setIconifiedByDefault(false);   //if using on actionbar
return true;
}

В зависимости от ваших требований взгляните на другие конструкторы ComponentName.

Ответ 7

Убедитесь, что ваш файл searchables.xml находится в правильном месте (т.е. в вашей папке res/xml/) и что тот же файл не содержит ошибок - в противном случае вы обнаружите, что (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName) вернет значение null, нарушив ваш функции поиска.

(Кроме того, убедитесь, что вы правильно установили componentName, потому что пример, показанный в руководстве для Android, выполняется только тогда, когда вы выполняете поиск и показываете поиски в той же самой Деятельности.)

Ответ 8

Двойная проверка, присутствует ли соответствующая запись (например, search_hint и app_label) в значениях /strings.xml

например,

      <string name="app_label">FunApp</string>
      <string name="search_hint">Caps Off</string>