1/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package com.example.android.apis.app;
18
19import com.example.android.apis.R;
20
21import android.app.Activity;
22import android.app.AlertDialog;
23import android.app.SearchManager;
24import android.os.Bundle;
25import android.provider.SearchRecentSuggestions;
26import android.view.Menu;
27import android.view.MenuItem;
28import android.view.View;
29import android.view.View.OnClickListener;
30import android.widget.AdapterView;
31import android.widget.ArrayAdapter;
32import android.widget.Button;
33import android.widget.EditText;
34import android.widget.Spinner;
35import android.widget.AdapterView.OnItemSelectedListener;
36
37public class SearchInvoke extends Activity
38{
39        // UI elements
40    Button mStartSearch;
41    Spinner mMenuMode;
42    EditText mQueryPrefill;
43    EditText mQueryAppData;
44
45        // Menu mode spinner choices
46        // This list must match the list found in samples/ApiDemos/res/values/arrays.xml
47    final static int MENUMODE_SEARCH_KEY = 0;
48    final static int MENUMODE_MENU_ITEM = 1;
49    final static int MENUMODE_TYPE_TO_SEARCH = 2;
50    final static int MENUMODE_DISABLED = 3;
51
52    /**
53     * Called with the activity is first created.
54     *
55     *  We aren't doing anything special in this implementation, other than
56     *  the usual activity setup code.
57     */
58    @Override
59    public void onCreate(Bundle savedInstanceState) {
60        super.onCreate(savedInstanceState);
61
62        // Inflate our UI from its XML layout description.
63        setContentView(R.layout.search_invoke);
64
65        // Get display items for later interaction
66        mStartSearch = (Button) findViewById(R.id.btn_start_search);
67        mMenuMode = (Spinner) findViewById(R.id.spinner_menu_mode);
68        mQueryPrefill = (EditText) findViewById(R.id.txt_query_prefill);
69        mQueryAppData = (EditText) findViewById(R.id.txt_query_appdata);
70
71        // Populate items
72        ArrayAdapter<CharSequence> adapter = ArrayAdapter.createFromResource(
73                            this, R.array.search_menuModes, android.R.layout.simple_spinner_item);
74        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
75        mMenuMode.setAdapter(adapter);
76
77        // Create listener for the menu mode dropdown.  We use this to demonstrate control
78        // of the default keys handler in every Activity.  More typically, you will simply set
79        // the default key mode in your activity's onCreate() handler.
80        mMenuMode.setOnItemSelectedListener(
81            new OnItemSelectedListener() {
82                public void onItemSelected(
83                        AdapterView<?> parent, View view, int position, long id) {
84                    if (position == MENUMODE_TYPE_TO_SEARCH) {
85                        setDefaultKeyMode(DEFAULT_KEYS_SEARCH_LOCAL);
86                    } else {
87                        setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
88                    }
89                }
90
91                public void onNothingSelected(AdapterView<?> parent) {
92                    setDefaultKeyMode(DEFAULT_KEYS_DISABLE);
93                }
94            });
95
96        // Attach actions to buttons
97        mStartSearch.setOnClickListener(
98            new OnClickListener() {
99                public void onClick(View v) {
100                    onSearchRequested();
101                }
102            });
103    }
104
105    /**
106     * Called when your activity's options menu needs to be updated.
107     */
108    @Override
109    public boolean onPrepareOptionsMenu(Menu menu) {
110        super.onPrepareOptionsMenu(menu);
111        MenuItem item;
112
113            // first, get rid of our menus (if any)
114        menu.removeItem(0);
115        menu.removeItem(1);
116
117            // next, add back item(s) based on current menu mode
118        switch (mMenuMode.getSelectedItemPosition())
119        {
120        case MENUMODE_SEARCH_KEY:
121            item = menu.add( 0, 0, 0, "(Search Key)");
122            break;
123
124        case MENUMODE_MENU_ITEM:
125            item = menu.add( 0, 0, 0, "Search");
126            item.setAlphabeticShortcut(SearchManager.MENU_KEY);
127            break;
128
129        case MENUMODE_TYPE_TO_SEARCH:
130            item = menu.add( 0, 0, 0, "(Type-To-Search)");
131            break;
132
133        case MENUMODE_DISABLED:
134            item = menu.add( 0, 0, 0, "(Disabled)");
135            break;
136        }
137
138        item = menu.add(0, 1, 0, "Clear History");
139        return true;
140    }
141
142    /** Handle the menu item selections */
143    @Override
144    public boolean onOptionsItemSelected(MenuItem item) {
145        switch (item.getItemId()) {
146        case 0:
147            switch (mMenuMode.getSelectedItemPosition()) {
148            case MENUMODE_SEARCH_KEY:
149                new AlertDialog.Builder(this)
150                    .setMessage("To invoke search, dismiss this dialog and press the search key" +
151                                " (F5 on the simulator).")
152                    .setPositiveButton("OK", null)
153                    .show();
154                break;
155
156            case MENUMODE_MENU_ITEM:
157                onSearchRequested();
158                break;
159
160            case MENUMODE_TYPE_TO_SEARCH:
161                new AlertDialog.Builder(this)
162                    .setMessage("To invoke search, dismiss this dialog and start typing.")
163                    .setPositiveButton("OK", null)
164                    .show();
165                break;
166
167            case MENUMODE_DISABLED:
168                new AlertDialog.Builder(this)
169                    .setMessage("You have disabled search.")
170                    .setPositiveButton("OK", null)
171                    .show();
172                break;
173            }
174            break;
175        case 1:
176            clearSearchHistory();
177            break;
178        }
179
180         return super.onOptionsItemSelected(item);
181    }
182
183    /**
184     * This hook is called when the user signals the desire to start a search.
185     *
186     * By overriding this hook we can insert local or context-specific data.
187     *
188     * @return Returns true if search launched, false if activity blocks it
189     */
190    @Override
191    public boolean onSearchRequested() {
192        // If your application absolutely must disable search, do it here.
193        if (mMenuMode.getSelectedItemPosition() == MENUMODE_DISABLED) {
194            return false;
195        }
196
197        // It's possible to prefill the query string before launching the search
198        // UI.  For this demo, we simply copy it from the user input field.
199        // For most applications, you can simply pass null to startSearch() to
200        // open the UI with an empty query string.
201        final String queryPrefill = mQueryPrefill.getText().toString();
202
203        // Next, set up a bundle to send context-specific search data (if any)
204        // The bundle can contain any number of elements, using any number of keys;
205        // For this Api Demo we copy a string from the user input field, and store
206        // it in the bundle as a string with the key "demo_key".
207        // For most applications, you can simply pass null to startSearch().
208        Bundle appDataBundle = null;
209        final String queryAppDataString = mQueryAppData.getText().toString();
210        if (queryAppDataString != null) {
211            appDataBundle = new Bundle();
212            appDataBundle.putString("demo_key", queryAppDataString);
213        }
214
215        // Now call the Activity member function that invokes the Search Manager UI.
216        startSearch(queryPrefill, false, appDataBundle, false);
217
218        // Returning true indicates that we did launch the search, instead of blocking it.
219        return true;
220    }
221
222    /**
223     * Any application that implements search suggestions based on previous actions (such as
224     * recent queries, page/items viewed, etc.) should provide a way for the user to clear the
225     * history.  This gives the user a measure of privacy, if they do not wish for their recent
226     * searches to be replayed by other users of the device (via suggestions).
227     *
228     * This example shows how to clear the search history for apps that use
229     * android.provider.SearchRecentSuggestions.  If you have developed a custom suggestions
230     * provider, you'll need to provide a similar API for clearing history.
231     *
232     * In this sample app we call this method from a "Clear History" menu item.  You could also
233     * implement the UI in your preferences, or any other logical place in your UI.
234     */
235    private void clearSearchHistory() {
236        SearchRecentSuggestions suggestions = new SearchRecentSuggestions(this,
237                SearchSuggestionSampleProvider.AUTHORITY, SearchSuggestionSampleProvider.MODE);
238        suggestions.clearHistory();
239    }
240
241}
242