Android: Return search query to current activity

徘徊边缘 提交于 2019-12-28 08:04:10

问题


I followed the steps described on http://developer.android.com/guide/topics/search/search-dialog.html to implement a search feature in my notepad application.

My problem is, that when I finish the search a new activity opens capturing my search query. But what I really want, is the query returned to the current activity instead of starting a new one.

Is this possible?

UPDATE:

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>

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

Even if I use the search-button on the phone it doesn't work. I therefor believe that the problem is in the AndroidManifest.xml


回答1:


In your Application Manifest you need to define the current activity as a searchable activity.

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

You then use the following code, which is from 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
    }
}

You can then use the string to reload your activity, if its a list activity you can call your code that you use to load data and use the string in that.




回答2:


Add to AndroidManifest.xml in your Searchable Activity:

android:launchMode="singleTop" 

so, your AndroidManifest.xml looks like:

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

The reason:

From this post:

The activity launch mode has four valid values:

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

The 'standard' is the default value. The four values fall into two groups:

'standard' and 'singleTop' can instantiate multiple activity instances and the instance will stay in the same task. For 'singleTask' or 'singleInstance', the activity class uses the singleton pattern, and that instance will be the root activity of a new task. Let's examine each value: "standard":

Multiple instances of the activity class can be instantiated and multiple instances can be added to the same task or different tasks. This is the common mode for most of the activities.

"singleTop":

The difference from 'standard' is, if an instance of activity already exists at the top of the current task and system routes intent to this activity, no new instance will be created because it will fire off an onNewIntent() method instead of creating a new object.




回答3:


I simply use this:-

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

This is best used when you have to search across a listview and have to filter out items. I never go by implementing the search function using the manifest file. The 2 methods do all the job.




回答4:


I was also facing the same problem, then I wrote this code and it solved my problem.

Implement this in your Activity

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

Add this function in the class:

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

Call the function in the 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);
        }

This will totally solve your problem..

Happy Coding!!




回答5:


Briefly:

  1. Add android:launchMode="singleTop" to the searchable activity definition in the AndroidManifest.xml
  2. Implement onNewIntent in the searchable activity and handle the search there.



回答6:


I followed Lachlan's clue of "You can then use the string to reload your activity", and finally worked this out. So please read Lachlan's post first, and then take the following 3 steps "to reload your activity":

  1. Save query string in ApplicationContext.
  2. Finish the new opened search Activity.
  3. Override OnResume, get query string you just saved, and then refresh the list.

Codes in List Activity:

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

MyApp class: (This original idea is from here: Android: How to declare global variables?)

public class MyApp extends Application {

    private String mSearchText;

    public String getSearchText() {
        return mSearchText;
    }

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

Don't forget to add property android:name=".MyApp" to your application in the Manifest file. Good luck!




回答7:


in the manifest file, add:

android:launchMode="singleTop"

To your search activity. Then, let your search activity implement SearchView.OnSuggestionListener finally:

mSearchView.setOnSuggestListener(this)

this way you can handle the suggestion click event with out creating a new instance of your search activity.




回答8:


It doesn't bring up a new activity if the SearchView.OnSuggestionListener on the searchView is set, and the overridden methods return true (overriding the default behavior). You can do that in the onCreateOptionsMenu() implementation, like this:

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

No need to force the activity to singleTop or other hacks.




回答9:


Just add

<application>

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

   <!-- All your activities, service, etc. -->

</application>

in your android_manifest.xml file where #Activity_Name is the name of the activity that handles the search.



来源:https://stackoverflow.com/questions/5094222/android-return-search-query-to-current-activity

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!