I wrote this small test application to demonstrate the problem, that is the searchable activity is not started when the user presses the search button on the keyboard.
I have been following the developer guides, but from my web search, it turns out that the official developer guide misses some points. From my SO search (which did not help):
Reference 1: Solved by Adding tag in the element in the manifest. I also looked into the manifest of the sample "User Dictionary" (I don't know where can I find the samples online, or I would link to it). This tag is there in the application element.
Reference 2: The "android:label" and "android:hint" in res/xml/searchable.xml must be references to string resources and not hard coded strings. Mine are.
Reference 3: Add a tag with "android:name="android.app.default_searchable" " (and " android:value="<. searchable-activity-name>" ") in the manifest in the Activity from where the search is going to be initiated. Tried this, did not seem to work.
Reference 4: "Your Searchable activity has to do something - and actually display results." Mine does, it receives the intent with the ACTION_SEARCH action, and passes the search query string retrieved from the intent to a method named "performSearch(string)" which displays the string in a textview.
So what am I doing wrong, and what can I do to solve this?
Code: MainActivity.java - Has a single SearchView - the user enters the query and presses the Search button on the keyboard.
public class MainActivity extends ActionBarActivity {
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
}
TestTwoActivity.java
public class TestTwoActivity extends Activity {
TextView tv;
private static final String TAG = TestTwoActivity.class.getSimpleName();
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test_two);
/**
* The following code enables assisted search on the SearchView by calling setSearchableInfo() and passing it our SearchableInfo object.
*/
SearchView searchView = (SearchView) findViewById(R.id.searchActivity_searchView);
// SearchManager => provides access to the system search services.
// Context.getSystemService() => Return the handle to a system-level
// service by name. The class of the returned object varies by the
// requested name.
// Context.SEARCH_SERVICE => Returns a SearchManager for handling search
// Context = Interface to global information about an application environment. This is an abstract class whose implementation is provided by the Android
// system. It allows access to application-specific resources and classes, as well as up-calls for application-level operations such as launching
// activities, broadcasting and receiving intents, etc.
// Activity.getComponentName = Returns a complete component name for this Activity
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
/**
* If the search is executed from another activity, the query is sent to this (searchable) activity in an Intent with ACTION_SEARCH action.
*/
// getIntent() Returns the intent that started this Activity
Intent intent = getIntent();
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
Log.i(TAG, "Search Query Delivered");//check
String searchQuery = intent.getStringExtra(SearchManager.QUERY);
performSearch(searchQuery);
}
}
private void performSearch(String searchQuery) {
//Just for testing purposes, I am simply printing the search query delivered to this searchable activity in a textview.
tv = (TextView) findViewById(R.id.testTwoActivity_textView);
tv.setText(searchQuery);
}
}
res/xml/searchable.xml - The Searchable Configuration
<?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/searchViewHint" >
</searchable>
Manifest File
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tests"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="21" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".TestTwoActivity"
android:label="@string/title_activity_test_two" >
<intent-filter>
<action android:name="android.intent.action.SEARCH"/> <!-- Declares the activity to accept ACTION_SEARCH intent -->
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="@xml/searchable" /> <!-- Specifies the searchable configuration to use -->
</activity>
<!-- Points to searchable activity so the whole app can invoke search. -->
<meta-data android:name="android.app.default_searchable"
android:value=".TestTwoActivity" />
</application>
</manifest>
Layouts:
activity_main.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.tests.MainActivity" >
<android.support.v7.widget.SearchView
android:id="@+id/searchActivity_searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>
activity_test_two.xml
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="${relativePackage}.${activityClass}" >
<android.support.v7.widget.SearchView
android:id="@+id/searchActivity_searchView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id="@+id/testTwoActivity_textView"
android:layout_width="wrap_content"
android:layout_height="wrap_content" />
</LinearLayout>
EDIT 1: it's crazy that I wrote a similar app with the search dilogue instead of the search widget, that works perfectly.
I tried to debug it in Eclipse but debugging stops because the TestTwoActivity
(the searchable activity) simply won't start.
I'm not sure if you've forgotten to add it but your MainActivity
misses setting the searchable info on the SearchView
:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SearchView searchView = (SearchView) findViewById(R.id.searchActivity_searchView);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
}
As a side note:
I've had problems with the default_searchable
meta-tag, when using flavors. It seemed to only work when using the full path (skipping the flavor) to the search activity e.g.:
<meta-data
android:name="android.app.default_searchable"
android:value="com.example.SearchActivity"/>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With