web-dev-qa-db-fra.com

Impossible de faire fonctionner la vue de recherche dans la barre d'actions

Je suis assez nouveau pour Java et Android; et je travaille sur une application dans laquelle je veux une barre d'action avec un SearchView. J'ai regardé les exemples de google mais je n'arrive pas à le faire fonctionner. Je dois faire quelque chose de mal et je suis sur le point d'abandonner le développement d'applications: DI a cherché mais je n'ai rien trouvé d'utile. Peut-être que vous les gars peuvent m'aider :)

Le problème : je fais ouvrir la vue de recherche comme il se doit, mais après cela rien ne se passe du tout, j'ai remarqué que mon searchManager.getSearchableInfo (getComponentName ()) renvoie null. De plus, mon indice que j'ai donné ne s'affiche pas dans ma zone de recherche, ce qui m'amène à croire que l'application ne trouve peut-être pas mon fichier de recherche.xml? Assez parlé :)

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;
    }
}

consultable.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>

Manifeste Android

<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);
    }
}

Et voici un lien vers le projet référé, je serais éternellement reconnaissant si quelqu'un devait m'aider avec ça!

Code source

66
Jonathan Andersson

Votre problème est dans votre AndroidManifest. Je l'avais presque exactement comme vous, car c'est ce que j'obtiens en suivant la documentation. Mais ce n'est pas clair ou c'est faux.

En regardant la source des démonstrations d'API, j'ai constaté que les métadonnées "Android.app.searchable" doivent aller dans votre activité "résultats", et dans l'activité principale (ou l'activité où vous placez le SearchView) vous pointez sur l'autre avec " Android.app.default_searchable ".

Vous pouvez le voir dans le fichier suivant, qui est le manifeste de mon projet de test:

<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>

Il est également important que l'indicateur et l'étiquette dans le fichier searchable.xml soient des références et non des chaînes codées en dur.

J'espère que cela résout votre problème. Il m'a fallu toute la journée pour le comprendre :(

147
Sloy

Les guides Android disent explicitement:

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

Ce qui est dans votre cas PAS VRAI. Parce que vous ne voulez pas rechercher dans MainActivity mais dans SearchableActivity. Cela signifie que vous devez utiliser ce ComponentName au lieu de la méthode getComponentName ():

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

Il semble également que les attributs Android: hint et Android: label DOIVENT être des références à des chaînes dans strings.xml. Être paresseux et coder en dur les valeurs de chaîne ne semble pas fonctionner du tout :)

c'est-à-dire ne pas faire:

<?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>

Mais certainement (comme l'OP l'a fait correctement):

<?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>
13
NPike

Si vous utilisez Android Studio,

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

une partie peut ne pas fonctionner.

écrire le nom complet du package comme

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

soyez prudent avec "xml/searchable.xml". Si vous avez créé HARD CODE avec Android:hint et Android:label.Ça ne marchera pas. Haha devrait être:

<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
Son Nguyen Thanh

Assurez-vous que votre searchables.xml le fichier est au bon endroit (c'est-à-dire dans votre res/xml/ dossier) et que le même fichier ne contient aucune erreur - sinon vous constaterez que (SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName) renverra null, brisant votre fonctionnalité de recherche.

(Assurez-vous également que vous définissez componentName de la manière appropriée, car l'exemple illustré dans le guide Android est destiné uniquement lorsque vous effectuez des recherches et affichez des recherches dans la même activité). )

2
ban-geoengineering

Il n'est en fait pas nécessaire d'utiliser la "partie manquante" comme décrit dans les réponses ci-dessus. Cette méthode (en utilisant un SearchView) fonctionne exactement comme le disent les documents officiels jusqu'à en utilisant le widget de recherche . Ici, une légère modification doit être effectuée comme suit:

Les propriétés d'un SearchableInfo sont utilisées pour afficher des étiquettes, des conseils, des suggestions, créer des intentions pour lancer des écrans de résultats de recherche et contrôler d'autres options telles qu'un bouton vocal ( docs ).

Ainsi, l'objet SearchableInfo que nous transmettons à la fonction SearchView.setSearchableInfo(SearchableInfo s) doit contenir des références appropriées à l'activité cible qui doit être affichée pour afficher les résultats de la recherche. Cela se fait en passant manuellement le ComponentName de notre activité cible. Un constructeur pour créer un ComponentName est

public ComponentName (String pkg, String cls)

pkg et cls sont les noms de package et les noms de classe de l'activité cible à lancer pour afficher les résultats de la recherche. Notez que:

pkg doit pointer vers le nom du package racine de votre projet et,

cls doit être un nom complet de la classe (c.-à-d. le tout)

par exemple.:

@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;
}

En fonction de vos besoins, jetez un œil aux autres constructeurs ComponentName.

2
Kedar Paranjape