web-dev-qa-db-fra.com

Android: renvoyer la requête de recherche à l'activité en cours

J'ai suivi les étapes décrites sur http://developer.Android.com/guide/topics/search/search-dialog.html pour implémenter une fonction de recherche dans mon application de bloc-notes.

Mon problème est que lorsque je termine la recherche, une nouvelle activité s'ouvre pour capturer ma requête de recherche. Mais ce que je veux vraiment, c'est que la requête soit renvoyée à l'activité en cours au lieu d'en démarrer une nouvelle.

Est-ce possible?

MISE À JOUR:

AndroidManifest.xml


<activity Android:name="MyNotepad"
                  Android:label="@string/app_name">
            <intent-filter>
                <action Android:name="Android.intent.action.MAIN" />
                <category Android:name="Android.intent.category.LAUNCHER" />
                <action Android:name="Android.intent.action.SEARCH"></action>
            </intent-filter>
            <meta-data Android:resource="@xml/searchable" Android:name="Android.app.searchable"></meta-data>
        </activity><activity Android:name="Preferences" Android:label="Preferences" >
</activity>

consultable.xml


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

Java-code


@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main_pad);
    Intent intent = getIntent();
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String query = intent.getStringExtra(SearchManager.QUERY);
        Toast.makeText(getApplicationContext(), query, Toast.LENGTH_LONG).show();
    }
}

@Override
public boolean onOptionsItemSelected(MenuItem item)
{
    switch(item.getItemId())
    {
        case R.id.menuItemSearch:
            startSearch("", false, null, false);
    break;
    }
    return true;
}

Même si j'utilise le bouton de recherche du téléphone, cela ne fonctionne pas. Je pense donc que le problème est dans le AndroidManifest.xml

46
Christian Tang

Dans votre manifeste d'application, vous devez définir l'activité actuelle comme une activité consultable.

<activity Android:name="BrowseItems" Android:label="@string/browseitems"
            Android:launchMode="singleTop">
            <intent-filter>
                <action Android:name="Android.intent.action.SEARCH" />
            </intent-filter>
            <meta-data Android:name="Android.app.searchable"
                Android:resource="@xml/itemsearchable" />
</activity>

Vous utilisez ensuite le code suivant, qui provient de http://developer.Android.com/guide/topics/search/search-dialog.html#LifeCycle

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

@Override
protected void onNewIntent(Intent intent) {
    setIntent(intent);
    handleIntent(intent);
}

private void handleIntent(Intent intent) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
      String query = intent.getStringExtra(SearchManager.QUERY);
      // Do work using string
    }
}

Vous pouvez ensuite utiliser la chaîne pour recharger votre activité, s'il s'agit d'une activité de liste, vous pouvez appeler votre code que vous utilisez pour charger des données et utiliser la chaîne à cet effet.

61
Lachlan Ennis

Ajoutez à AndroidManifest.xml dans votre activité consultable:

Android:launchMode="singleTop" 

ainsi, votre AndroidManifest.xml ressemble à:

<activity Android:name="MyNotepad"
              Android:label="@string/app_name"
              Android:launchMode="singleTop">
        <intent-filter>
            <action Android:name="Android.intent.action.MAIN" />
            <category Android:name="Android.intent.category.LAUNCHER" />
            <action Android:name="Android.intent.action.SEARCH"></action>
        </intent-filter>
        <meta-data Android:resource="@xml/searchable" Android:name="Android.app.searchable"></meta-data>
    </activity><activity Android:name="Preferences" Android:label="Preferences" >

La raison:

De ce message :

Le mode de lancement d'activité a quatre valeurs valides:

"standard" "singleTop" "singleTask" "singleInstance"

Le "standard" est la valeur par défaut. Les quatre valeurs se répartissent en deux groupes:

'standard' et 'singleTop' peuvent instancier plusieurs instances d'activité et l'instance restera dans la même tâche. Pour 'singleTask' ou 'singleInstance', la classe d'activité utilise le modèle singleton, et cette instance sera l'activité racine d'une nouvelle tâche. Examinons chaque valeur: "standard":

Plusieurs instances de la classe d'activités peuvent être instanciées et plusieurs instances peuvent être ajoutées à la même tâche ou à différentes tâches. Il s'agit du mode commun pour la plupart des activités.

"singleTop":

La différence avec 'standard' est que, si une instance d'activité existe déjà en haut de la tâche actuelle et que les routes système sont destinées à cette activité, aucune nouvelle instance ne sera créée car elle déclenchera une méthode onNewIntent () au lieu de créer un nouvel objet.

18

J'utilise simplement ceci: -

searchView.setOnQueryTextListener(new SearchView.OnQueryTextListener() {
        @Override
        public boolean onQueryTextSubmit(String s) {
            //on submit
            return false;
        }

        @Override
        public boolean onQueryTextChange(String s) {
            //get all text changes
            return false;
        }
});

Il est préférable de l'utiliser lorsque vous devez rechercher dans une liste et filtrer les éléments. Je ne vais jamais en implémentant la fonction de recherche en utilisant le fichier manifeste. Les 2 méthodes font tout le travail.

5
khandelwaldeval

J'étais également confronté au même problème, puis j'ai écrit ce code et cela a résolu mon problème.

implémentez ceci dans votre activité

**implements SearchView.OnQueryTextListener, SearchView.OnCloseListener**

Ajoutez cette fonction dans la classe:

private void setupSearchView()
        {

            searchView.setIconifiedByDefault(true);

            SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            if (searchManager != null)
                {
                    List<SearchableInfo> searchables = searchManager.getSearchablesInGlobalSearch();

                    // Try to use the "applications" global search provider
                    SearchableInfo info = searchManager.getSearchableInfo(getComponentName());
                    for (SearchableInfo inf : searchables)
                        {
                            if (inf.getSuggestAuthority() != null && inf.getSuggestAuthority().startsWith("applications"))
                                {
                                    info = inf;
                                }
                        }
                    searchView.setSearchableInfo(info);
                }

            searchView.setOnQueryTextListener(this);
            searchView.setOnCloseListener(this);
        }

Appelez la fonction dans le menu onCreateOptionsMenu (menu Menu)

@Override
    public boolean onCreateOptionsMenu(Menu menu)
        {
            MenuInflater inflater = getMenuInflater();
            inflater.inflate(R.menu.menu, menu);
            //restoreActionBar();
            // Associate searchable configuration with the SearchView
            //SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
            searchView = (SearchView) menu.findItem(R.id.action_search).getActionView();
            //searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
            setupSearchView();
            return super.onCreateOptionsMenu(menu);
        }

Cela résoudra totalement votre problème ..

Codage heureux !!

4
Trideep

Brièvement:

  1. Ajouter Android:launchMode="singleTop" à la searchable activity définition dans le AndroidManifest.xml
  2. Implémentez onNewIntent dans le searchable activity et gérez-y la recherche.
2
Mahmoud Badri

J'ai suivi indice de Lachlan de "Vous pouvez ensuite utiliser la chaîne pour recharger votre activité", et j'ai finalement résolu cela. Veuillez donc d'abord lire le post de Lachlan, puis suivre les 3 étapes suivantes "pour recharger votre activité":

  1. Enregistrez la chaîne de requête dans ApplicationContext.
  2. Terminez la nouvelle activité de recherche ouverte.
  3. Remplacez OnResume, récupérez la chaîne de requête que vous venez d'enregistrer, puis actualisez la liste.

Codes dans l'activité de liste:

private void handleIntent(Intent intent) {
    if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
        String searchText = intent.getStringExtra(SearchManager.QUERY);
        ((MyApp)this.getApplicationContext()).setSearchText(searchText);
        this.finish();
    }
}

protected void onResume() {
    super.onResume();

    String searchText = ((MyApp)this.getApplicationContext()).getSearchText();
    //refresh your list here...
}

Classe MyApp: (Cette idée originale est d'ici: Android: Comment déclarer des variables globales? )

public class MyApp extends Application {

    private String mSearchText;

    public String getSearchText() {
        return mSearchText;
    }

    public void setSearchText(String searchText) {
        this.mSearchText = searchText;
    }
}

N'oubliez pas d'ajouter une propriété Android:name=".MyApp" à votre application dans le fichier Manifest. Bonne chance!

1
Jason Lu

dans le fichier manifeste, ajoutez:

Android:launchMode="singleTop"

À votre activité de recherche. Ensuite, laissez votre activité de recherche implémenter SearchView.OnSuggestionListener enfin:

mSearchView.setOnSuggestListener(this)

de cette façon, vous pouvez gérer l'événement de clic de suggestion sans créer de nouvelle instance de votre activité de recherche.

1
guy.gc

Il n'apparaît pas une nouvelle activité si le SearchView.OnSuggestionListener Sur le SearchView est défini, et les méthodes substituées retournent true ( outrepassant le comportement par défaut ). Vous pouvez le faire dans l'implémentation onCreateOptionsMenu(), comme ceci:

    searchView.setOnSuggestionListener(new SearchView.OnSuggestionListener() {
        @Override
        public boolean onSuggestionSelect(int position) {
            return true;
        }

        @Override
        public boolean onSuggestionClick(int position) {
            CursorAdapter selectedView = searchView.getSuggestionsAdapter();
            Cursor cursor = (Cursor) selectedView.getItem(position);
            int index = cursor.getColumnIndexOrThrow(SearchManager.SUGGEST_COLUMN_TEXT_1);
            searchView.setQuery(cursor.getString(index), true);
            return true;
        }
    });

Pas besoin de forcer l'activité à singleTop ou à d'autres hacks.

0
Bernd S