Android Tutorial Using standard Android search dialog with Basic4Android

Search is a core feature of Android. You can use a configurable standard search dialog for performing searches in your app. This search dialog can also be used within a Basic4Android App (with some limitations). This tutorial will show you how to use the Android search dialog in Basic4Android.

When the user executes a search from the search dialog, the system creates an Intent and stores the user query in it. The system then starts the activity that you've declared to handle searches (the "searchable activity") and delivers it the intent. To set up your application for this kind of assisted search, you need the following:

- A searchable configuration. This is an XML file with a configuration for the search dialog. Unfortunately we have to use XML here. It is not possible to create a searchable configuration by code.

- A searchable activity: This is a special activity which receives and executes the query. We can use a B4A activity module for this activity but we have to add some additional properties in the Manifest editor to it.

- An Activity which can open the standard Android search dialog. This can be any activity in our app. We again need to add some things in the Manifest editor for this.

The searchable configuration

Lets start with the searchable configuration. The searchable configuration is just a XML file where you can configure the features of the standard Android search dialog like voice search etc.

This is a simple example of a searchable configuration file:

B4X:
<?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_text"
    android:voiceSearchMode="showVoiceSearchButton|launchRecognizer" >
</searchable>

The only mandatory property is android:label. Every other property is optional. As you can see we can not provide the strings directly to the "label" and "hint" properties but we have to use another resource file here for the strings. The third property (voiceSearchMode) enables the voice search if it is installed on your device.

For a complete documentation of the searchable configuration look here.

Save the searchable configuration in Objects/res/xml/searchable.xml folder in your project home and make it READ ONLY!

The string resource file looks like this and should be stored under Objects/res/values/string.xml

B4X:
<?xml version="1.0" encoding="utf-8"?>
<resources>
    <string name="app_name">SearchDialogExample</string>
    <string name="search_text">Search for something...</string>
</resources>

Be sure again to make the file READ ONLY otherwise the IDE will delete it on compile!

If you make any changes to the xml files use "Tools/Clean Project" before compiling.


The searchable activity

Now as we have our searchable configuration ready lets create a new Activity in B4A which will handle the search request. Select Project/Add new module/Activity Module from the Menu and name it "Result".

We have to declare this activity to our "searchable activity" in the manifest file. So add the following to the manifest editor:

B4X:
AddActivityText(Result, <intent-filter>
    <action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
           android:resource="@xml/searchable"/>)

With the android:resource property you specify the searchable configuration xml file we created in the first step.

The activity itself receives the query string in the Intent. So our Activity_Create sub should look something like this:

B4X:
Sub Activity_Create(FirstTime As Boolean)
   searchIntent = Activity.GetStartingIntent
   If searchIntent.Action = "android.intent.action.SEARCH" Then
      Dim SearchString As String
      SearchString = searchIntent.GetExtra("query")
      ToastMessageShow("Search for: " & SearchString, False)
   Else
      ToastMessageShow("No search action!", False)
      Activity.Finish
   End If
End Sub

As you can see, the action of the intent is "android.intent.action.SEARCH" and we can get the query string with GetExtra("query").

What you do with the query string is totally up to the activity. You can search in a database or search some information online or just store it in a process global variable to pass it to the calling activity.


How to open the search dialog

Now we have a configuration for the serach dialog and an activity which can handle a search request. The last step now is to just call/open the search dialog. We do this in the main activity. To mark our main activity so that it is allowed to open the search dialog and to configure which activity to start for the search request we again have to add some configuration in the manifest editor:

B4X:
AddActivityText(Main, <meta-data android:name="android.app.default_searchable"
                   android:value=".result" />)

This enables the search dialog in our main activity. The search dialog is hidden normally and you can activate it with the device search button. If you want to open the search dialog by code you have to use a simple part of code which uses the reflection library:

B4X:
Sub Button1_Click
   Dim ref As Reflector
   ref.Target = ref.GetActivity
   ref.RunPublicmethod("onSearchRequested", Null, Null)
End Sub

Now we are done. See the attachment for a more or less complete example.

In the example the searchable activity is invisible and the query string is just passed back to the main activity with the help of process global variables.

If you have any further questions please ask.

Some remarks:
- you can let the searchable activity initiate a search with itself. If the user initiates the search, Activity_Resume is called and you can get the search Intent with Activity.GetStartingIntent. For an example how to use this see the WorldClock example.
You can simulate this behavior with a transparent searchable activity. See the example.
- It is currently not possible to use suggestions for the search or a search history. Perhaps this will be possible with an additional library but I haven't tried it so far.
 

Attachments

  • SearchExample.zip
    8.1 KB · Views: 1,772
  • screenshot-1330509212682.jpg
    screenshot-1330509212682.jpg
    12.5 KB · Views: 2,128
Last edited:

bluedude

Well-Known Member
Licensed User
Longtime User
Keyboard not hiding when clicking in main activity

Hi,

When I enable the search and then click somewhere in the activity the search dialog hides but the keyboard stays open. Tried to find where I can trigger search dialog closing but it cannot find it.

Any suggestions?
 

airblaster

Active Member
Licensed User
Longtime User
Hi Corwin 42,

great tutorial, thanks!
Just one question that comes to mind: Why is it not possible to use auto suggest and search history without a library?
 

corwin42

Expert
Licensed User
Longtime User
As I remember correctly you need to implement a (quite simple) content provider for this.

Unfortunately I never really used the search feature and so I never tried more advanced things with it.
 

walterf25

Expert
Licensed User
Longtime User
Problem launching on a second activity

Hi all, i was wondering if anyone has came across this issue, i have 3 different activities, i can make this work on the main activity, the searchbox pops us and i can type anything and search for anything, but i'm trying to do the same on the second activity named "Activity2" i basically copied everything just as in the main activity and i get no errors, but i don't see the searchbox pop up, does anyone have any idea why this would be, it doesn't make sense to me, this is my code to get this going.

B4X:
Dim ref As Reflector
   ref.Target = ref.GetActivity
   Log(ref.Target)
   ref.RunPublicmethod("onSearchRequested", Null, Null)

I also have the Result trasnsparent activity, and as i mentioned above this works just fine on the main activity, but why wouldn't it work on a second activity?

:sign0163::sign0163::sign0163::sign0163:
:BangHead:
 

walterf25

Expert
Licensed User
Longtime User
Problem launching on a second activity

Never mind i got it, you just need to add a second line like this with the name of the activity you want to start it from like this

AddActivityText(Activity2, <meta-data android:name="android.app.default_searchable"
android:value=".result" />)

thanks All
 

jalle007

Active Member
Licensed User
Longtime User
Is there a way to search android settings
using this approach ?
you know there are a lot of settings that are hard to remember where they are located. and instead of looking into the menu,
best would be to make it searchable.

you know even windows 7 has search settings functionality :icon_clap:
 

corwin42

Expert
Licensed User
Longtime User
No (or yes?), the standard Android search dialog does nothing other than requesting a search string from the user and starts an activity and gives this search string as a parameter.

What you do with the search string and doing the actual search is part of the application.

So the answer is:

No - This approach will not help you in implementing a setting search feature

Yes - You can use the search dialog to implement a setting search feature by yourself. But the handling of the search dialog (which is explained in this tutorial) is the smallest part of such a feature.
 

spyboy79

New Member
Licensed User
Longtime User
Good morning,
I'm testing the search dialog with provided example on emulator and i9000 but I have this error:


main_button1_click (B4A line: 42)


ref.Target = ref.GetActivity
java.lang.NoSuchFieldError: anywheresoftware.b4a.BA.activityBA


at anywheresoftware.b4a.agraham.reflection.Reflection.GetActivity(Reflection.java:638)
at de.amberhome.searchexample.main._button1_click(main.java:306)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:167)
at anywheresoftware.b4a.BA.raiseEvent2(BA.java:155)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:151)
at anywheresoftware.b4a.objects.ViewWrapper$1.onClick(ViewWrapper.java:59)
at android.view.View.performClick(View.java:4204)
at android.view.View$PerformClick.run(View.java:17355)
at android.os.Handler.handleCallback(Handler.java:725)
at android.os.Handler.dispatchMessage(Handler.java:92)
at android.os.Looper.loop(Looper.java:137)
at android.app.ActivityThread.main(ActivityThread.java:5041)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:511)


at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
at dalvik.system.NativeStart.main(Native Method)
** Activity (main) Resume **

what can it be?
 

Taha

Member
Licensed User
Longtime User
Thanks for great tutorial! Is there any event like "TextChanged" in the search textbox?
 

corwin42

Expert
Licensed User
Longtime User
Thanks for great tutorial! Is there any event like "TextChanged" in the search textbox?

No, unfortunately not.
 

focus330

Member
Licensed User
Longtime User
I'm using the android standard search. Everythink works well except when user exit from search without searching anythink. In this case the caller activity doesn't intercept that search is finished and Activity_Resume in not affected. Then I tried to use Activity_WindowFocusChanged. It works fine but I have many problems in debug mode. Then the question: Is there another way to capture exit from search when user doesn't search anything ?

Thanks.
 
Top