getSearchableInfo returns NULL - android

After trying ALL of the solutions in stackoverflow about this problem, I decided to ask it here.
I'm trying to implement search bar in my Action bar.
I'm using AppCompatActivity and imported android.support.v7.widget.SearchView.
For the record, I'm using PageManager and TabLayout if it has any releation.
I get java.lang.NullPointerException error in the following line:
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
This is my code:
search bar declration at menu_main.xml:
<item
android:id="#+id/searchPlace"
android:title="#string/search_hint"
android:actionViewClass="android.support.v7.widget.SearchView"
android:showAsAction="always"/>
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" />
AndroidManifest.xml
<application
android:allowBackup="true"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/Theme.AppCompat.Light.NoActionBar" >
<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>
<meta-data
android:name="android.app.default_searchable"
android:value=".searchResultActivity" />
</activity>
<activity
android:name=".Settings"
android:label="#string/title_activity_settings" >
</activity>
<activity
android:name=".searchResultActivity"
android:label="#string/app_name"
android:theme="#style/Theme.AppCompat.Light.NoActionBar">
<!-- to identify this activity as "searchable" -->
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
Search code in my MainActivity.java onCreateOptionsMenu:
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.searchPlace).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
Logcat error:
Process: il.co.test.test, PID: 1642
java.lang.NullPointerException
at il.co.test.test.MainActivity.onCreateOptionsMenu(MainActivity.java:106)
at android.app.Activity.onCreatePanelMenu(Activity.java:2538)
at android.support.v4.app.FragmentActivity.onCreatePanelMenu(FragmentActivity.java:262)
at android.support.v7.internal.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
at android.support.v7.app.AppCompatDelegateImplBase$AppCompatWindowCallbackBase.onCreatePanelMenu(AppCompatDelegateImplBase.java:267)
at android.support.v7.internal.view.WindowCallbackWrapper.onCreatePanelMenu(WindowCallbackWrapper.java:85)
at android.support.v7.internal.app.ToolbarActionBar.populateOptionsMenu(ToolbarActionBar.java:448)
at android.support.v7.internal.app.ToolbarActionBar$1.run(ToolbarActionBar.java:65)
at android.os.Handler.handleCallback(Handler.java:733)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5017)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
UPDATE
I'm not sure, and I don't know how to check it - but I am pretty sure my getActionVIew() returns NULL.
UPDATE 2 - FIXED!
After checking some stackoverflow's about getActionView() null problem,
The 2nd answer at getActionView() of my MenuItem return null fixed my problem.
I had to use namespace app instaed of android.
Really painful!
Hope someone can find my mistake and help me fix it, since I tried many solutions for 6 hours.
Thanks in advance!

Search menu item
<item
android:id="#+id/searchPlace"
android:title="#string/search_hint"
android:actionViewClass="android.support.v7.widget.SearchView"
android:title="#string/search"
app:showAsAction="always|collapseActionView"/>
Activity code
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.your_menu, menu);
SearchView searchView = (SearchView) menu.findItem(R.id.searchPlace).getActionView();
searchView.setOnQueryTextListener(queryTextListener);
return true;
}
private OnQueryTextListener queryTextListener = new OnQueryTextListener()
{
#Override
public boolean onQueryTextSubmit(String query) {
//if you need this
return false;
}
#Override
public boolean onQueryTextChange(String query) {
//your code
return true;
}
};
In this this case you dont need searchable configuration, dont need strokes in manifest, dont need SearchManager and other stuff. Just declare search item in the menu and thats it.

After checking some stackoverflow's about getActionView() null problem,
The 2nd answer at getActionView() of my MenuItem return null fixed my problem.
I had to use namespace app instaed of android.
Really painful!

Related

SearchView needs to be clicked twice to open

I'm following this Android tutorial to implement the Search View. After fixing some issues, I got it to work. However, the search view needs to be clicked twice to open the editText. Any idea of what's going on?
Filter class:
#Override
public boolean onCreateOptionsMenu(Menu menu)
{
getMenuInflater().inflate(R.menu.toolbar_menu_filter, menu);
// Associate searchable configuration with the SearchView
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.menu_item_search).getActionView();
searchView.setSearchableInfo(
searchManager.getSearchableInfo(getComponentName()));
searchView.setQueryHint(getResources().getString(R.string.search_hint));
return super.onCreateOptionsMenu(menu);
}
menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:app="http://schemas.android.com/apk/res-auto"
tools:context=".FilterUI">
<item android:id="#+id/menu_item_search"
android:title="Search"
android:icon="#drawable/ic_search_white"
app:actionViewClass="android.widget.SearchView"
app:showAsAction="ifRoom|collapseActionView"/>
<item android:id="#+id/menu_item_options"
android:icon="#drawable/ic_clear_all_white"
app:showAsAction="ifRoom"
android:title="#string/filter_default"/>
Manifest file
<activity android:name=".Activities.FilterUI"
android:screenOrientation="portrait"
android:configChanges="orientation"
android:windowSoftInputMode="adjustNothing">
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
<activity android:name=".Activities.SearchActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH"/>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Might be too late to answer but, let's get this done. Like I said, it's better to use:
app:actionViewClass="android.support.v7.widget.SearchView"
For more compatibility and etc. But the point is, in new AndroidX, we can't use android.support since we migrate to AndroidX and there will be only:
app:actionViewClass="android.widget.SearchView"
Available. But, let's see what documentation says for the newest APIs (AndroidX) and etc:
Note: This class is included in the support library for compatibility with API level 7 and higher. If you're developing your
app for API level 11 and higher only, you should instead use the
framework android.widget.SearchView class.
So in AndroidX, I have found:
app:actionViewClass="androidx.appcompat.widget.SearchView"
To use but you still can use: android.widget.SearchView.

searchMenuItem.getActionView() returning null

getActionView() is retuning null. What am i doing wrong?
I am extending Activity and using android:minSdkVersion="11" android:targetSdkVersion="19"
<item
android:id="#+id/search"
android:actionViewClass="android.widget.SearchView"
android:icon="#drawable/ic_action_search"
android:showAsAction="collapseActionView|ifRoom"
app:showAsAction="always"
android:title="#string/search"/>
#Override
public boolean onCreateOptionsMenu(Menu menu) {
super.onCreateOptionsMenu(menu);
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu);
searchItem = menu.findItem(R.id.search);
mSearchView = (SearchView) searchItem.getActionView();
mSearchView.setQueryHint("Search");
return true;
}
manifest
<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>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
</activity>
I saw that you have app:showAsAction="always" the app namespace means that you are using Appcompat v7 library ...
Appcompat library has it owns method for menu items as static method in MenuCompat/MenuItemCompat classes (and you should use 'em like instead menu.methodXXX() use MenuCompat.methodXXX(menu) )
Now, to define a actionViewClass(and others attributes added in api newer then 11) in menu you should use the app namespace for this instead android namespace
so android:actionViewClass should become app:actionViewClass
in the code you should use MenuItemCompat.getActionView(searchItem) instead searchItem.getActionView()
remeber to add namespace app in root element of menu xml file like xmlns:app ="http://schemas.android.com/apk/res-auto"
also small hint (as you are using 11 as min sdk your code should works fine but ...) replace android.widget.SearchView to android.support.v7.widget.SearchView as it(standard SearchView) not works in the same way on different API versions from 11 to newest one(also you will get method not found if you use methods added in API > 11 to SearchView on devce with API 11)

Search in android activity

I am new in android and I am working with a search related feature. After read the tutorial I have some questions:
1 Does the SearchableActivity unique in an application?
It seems that 3 steps are required to setup the search feature(from the android developer guide):
1)create the SearchableActivity to receive the search keyword.
2)make the SearchableActivity to accept the ACTION_SEARCH intent
3)specify the searchable configuration to use, in a element.
Then I wonder if all the search related job will be delegated to the SearchableActivity?
And suppose I have two MainActivity and MainActivityTwo, both of them make a SearchView inside the action bar.
The AndroidMinefset.xml:
<activity android:name="com.app.activity.MainActivityTwo" />
<activity android:name="com.app.activity.MainActivity" />
<activity android:name="com.app.activity.SearchableActivity"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
xml/search.xml:
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:hint="#string/search_hint"
android:label="#string/app_name" >
</searchable>
And register the search configuration(serchableInfo) toSerchView:
.MainActivity
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.u_action_menu_map, menu);
MenuItem searchItem = menu.findItem(R.id.action_search);
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView = (SearchView) MenuItemCompat.getActionView(searchItem);
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
return super.onCreateOptionsMenu(menu);
}
This does not work, it seems that there is no serchableInfo bound with the current Activity(MainActivity).
Even I changed to this:
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName("com.app.activity", "SearchableActivity")));
It still cannot find the searchableInfo.
After I add the search related configuration to MainActivity:
<activity android:name="com.app.activity.MainActivityTwo" />
<activity android:name="com.app.activity.SearchableActivity" />
<activity android:name="com.app.activity.MainActivity"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data
android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
This worked. WTF.
I always thought that the Activity provide the Search UI and the Activity handle the input are different, but after my test it seems that they are the same Activity, that't to say the user input are submit to the Activity itself,but why use the **ing intent to transfer the input data?
2 The search submit
The Search dialog have a search submit button at the right of the dialog:
But there is nothing inside the SearchView so how to submit the search in a SearchView:
There should be a search key on your keyboard. It can also be go, return or similar keys that should start the search.

Search activity not being launched when pressing enter

Search activity not being launched when pressing enter.The search view is shown nicely on the action bar. But when i type the search query and press enter
AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.punit.rateit"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="11"
android:targetSdkVersion="17" />
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<activity
android:name="com.punit.rateit.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:theme="#style/Theme.AppCompat.Light"
android:name=".SearchPageActivity">
<meta-data android:name="android.app.default_searchable" android:value=".SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.SearchPage" />
</intent-filter>
</activity>
<activity android:name="com.punit.rateit.SearchResultsActivity" android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable"/>
</intent-filter>
</activity>
</application>
</manifest>
Here is the Menu.xml
<menu xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:com.punit.rateit="http://schemas.android.com/apk/res-auto" >
<!-- Search, should appear as action button -->
<item android:id="#+id/search"
android:icon="#drawable/ic_search"
android:title="#string/action_search"
com.punit.rateit:actionViewClass="android.widget.SearchView"
com.punit.rateit:showAsAction="ifRoom"
/>
</menu>
The activity which shows action bar.
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.menu,menu);
SearchManager searchManager =
(SearchManager) getSystemService(Context.SEARCH_SERVICE);
SearchView searchView =
(SearchView) menu.findItem(R.id.search).getActionView();
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
searchView.setIconifiedByDefault(false);
searchView.setSubmitButtonEnabled (true);
return super.onCreateOptionsMenu(menu);
}
The SearchResult activity which should be the activity called when search submit button is pressed
public class SearchResultsActivity extends Activity {
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.d("search", "search triggered");
setContentView(R.layout.searchpage);
handleIntent(getIntent());
}
#Override
protected void onNewIntent(Intent intent) {
Log.d("search", "search triggered");
setIntent(intent);
handleIntent(intent);
}
private void handleIntent(Intent intent)
{
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
Log.d("search", query);
}
}
#Override
public boolean onSearchRequested() {
Log.d("search", "search triggered");
return false; // don't go ahead and show the search box
}
After a long Research i have Analyse something
searchView.setSearchableInfo( searchManager.getSearchableInfo(new
ComponentName(this,SearchResultsActivity.class)));
Here the activity.class is the name of the searchable activity where you want to pass the search query.
I had the same problem, and my search for an answer took me here, so here is what worked for me...
Make sure your searchables.xml file is in the correct location (i.e,
in your res/xml/ folder) and that the same file does not contain any
errors - otherwise you will find that
(SearchManager)getSystemService(Context.SEARCH_SERVICE).getSearchableInfo(componentName)
will return null, breaking your search functionality.
(Also, ensure you set componentName in the appropriate manner,
because the example shown in the Android guide is for only when you
are making searches and displaying searches in the same Activity.)
...am sharing in the hope it may save someone else a wasted 4 hours! :/
Solved the problem. The tag
was needed to be for application .Removing it from activity and putting it under application did the trick.
Here is the latest application tag in manifest.xml
<application
android:allowBackup="true"
android:icon="#drawable/ic_launcher"
android:label="#string/app_name"
android:theme="#style/AppTheme"
>
<meta-data android:name="android.app.default_searchable" android:value=".SearchResultsActivity"/>
<activity
android:name="com.punit.rateit.MainActivity"
android:label="#string/app_name" >
<meta-data android:name="android.app.default_searchable"
android:value="com.punit.rateit.SearchResultsActivity" />
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
Creating a ComponentName object with the name of the Search Result activity class worked for me. Like this:
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchStoreActivity.class)));
I was not using the strings within searchable.xml.
You MUST set it up that way or you will get null. I had just put in text instead of using #string.
<?xml version="1.0" encoding="utf-8"?>
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="#string/app_label"
android:hint="#string/search_hint" >
</searchable>
I struggled with the problem for a day or two, it's not very clearly mentioned in the documentation.
searchView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
In the above the getComponentName function returns the name of the
current component, which is good if your current component is
handling/showing the search results, but if you have a different
activity then you need to put the component name of that activity for
search view to redirect searches to that activity.
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(this, SearchResultActivity.class)));
Also make sure to have no errors in searchable.xml file in res/xml folder.

android searchable doesn't work

I'm working around with a searchable action bar. And I gotta a problem that the action bar doesn't react with the searchable activity. THAT IS, I enter something in the action bar's searchable textedit then clicked the submit but nothing happened. The debug tracking shows that the code in my searchresultactivity is never executed. So I'm wondering if there's something wrong in searchable configuration. Well this time I think I've explained the problem clearly and I don't expect any negative votes without any words even spits!
I followed the instruction of developer's document beginning with the manifest.xml, the meta-data is added in the searchresult activity:
<application
android:icon="#drawable/ic_launcher"
android:label="#string/app_name" >
<activity
android:name=".GermanDictionaryActivity"
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=".SearchResultsActivity">
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="#xml/searchable" />
</activity>
</application>
then I initialized the searchview with my menu:
#Override
public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.srhbar, menu);
// Get the SearchView and set the searchable configuration
SearchManager searchManager = (SearchManager) getSystemService(Context.SEARCH_SERVICE);
mSrhView = (SearchView) menu.findItem(R.id.search).getActionView();
mSrhView.setSearchableInfo(searchManager.getSearchableInfo(getComponentName()));
mSrhView.setSubmitButtonEnabled(true);
return true;
}
And the searchable item in menu:
<item android:id="#+id/search"
android:title="#string/srh_title"
android:showAsAction="collapseActionView|ifRoom"
android:actionViewClass="android.widget.SearchView" />
Any answer related is appreciated!
I solved the problem by changing this line:
searchView.setSearchableInfo(searchManager.getSearchableInfo(new ComponentName(getApplicationContext(), SearchResultsActivity.class)));

Categories

Resources