In this article we will explain how to use the SearchUnit search
web services from mobile platforms such as Android, iOS and Windows.
The scenario is that SearchUnit has been deployed as part of a web
application on your server, and that it has a searchable index. The goal is to
create an Android search interface (other platforms such as iOS, Blackberry and
Windows would use the same Web Service interface to run searches on the
server).
Please download
this ZIP with the Android project and an MVC server side project exposing a
WCF search service. The MVC project is extremely basic, it just houses the
SearchService.svc file in the Keyoti_SearchEngine_Web_Common folder, which will
handle incoming service calls from the Android client.
Important notes about setup
- The MVC project requires the SearchUnit DLLs to be installed on the machine,
either through the MSI, manually in to the GAC, or by copying them to the
project BIN and referencing them.
- The MVC project uses IIS to host the app. because only IIS can serve to
remote machines (ie IIS Express and the developer webserver do not support this)
- The MVC project must be opened with administrator priviledges, because the
application is hosted by IIS
- A valid license key is required by the search engine, there is a temporary
key set in the web.config, if it has expired please obtain a new one here
- The Android project (AndroidStudio) needs the server machine address to be
set. The SearchActivity.java file includes a field 'serverAddress' which should
be changed to point to the machine running the 'SearchUnit6-ServiceExample' web
application. Remember that even if you use an Anroid emulator, it is running on
a separate machine (albeit Virtual), so localhost will not work.
- After searching in the app, wait for results to show, or look in the
AndroidStudio logcat for any error messages. The index is several pages of
wikipedia, result generating test queries are "wikipedia", "portal" and
"english".
How it works
The Android code for requesting the search display be shown, and the use of
ListView will not be explained here as it is assumed readers are familiar with
Android development already - if not there are many good articles on the net
about search display and ListView.
The interface to the search service is below - it uses JSON to package the
request data, and unbundles the JSON response from the SearchUnit
service. class SearchTask extends AsyncTask {
String serverAddress = "http://192.168.1.103";
String appRoot = "/SearchUnit6-ServiceExample";
private Exception exception;
protected JSONObject doInBackground(String… query) {
JSONObject jo = null;
try {
String SERVICE_URI = serverAddress + appRoot + "/Keyoti_SearchEngine_Web_Common/SearchService.svc";
//Create the service request URL
String urlFinal=SERVICE_URI+"/GetResults";
//Create the service call parameters as a JSON string
String parameter = "{indexDirectory:'~/IndexDirectory',"+
"query:'"+query[0]+"',"+
"resultPage:1,"+
"resultsPerPage:10,"+
"locationName:'All',"+
"contentNames:[],"+
"securityGroupNames:[]," +
"filterCollection:[],"+
"sortBy:null,"+
"language:'',"+
"customDictionaryPath:'',"+
"spellingSuggestionSource:'PresetDictionary'}";
JSONObject holder = new JSONObject(parameter);
StringEntity se = new StringEntity(holder.toString());
//Call the service
HttpPost postMethod = new HttpPost(urlFinal.trim());
postMethod.setEntity(se);
postMethod.setHeader("Accept", "application/json");
postMethod.setHeader("Content-type", "application/json");
HttpClient hc = new DefaultHttpClient();
HttpResponse response = hc.execute(postMethod);
//Obtain the response and log it
Log.i("response", ""+response.toString());
HttpEntity entity = response.getEntity();
final String responseText = EntityUtils.toString(entity);
//Convert the response to a JSON object
jo = new JSONObject(responseText);
Log.i("Output", ""+responseText);
} catch (Exception e) {
Log.d("SearchResultsActivity", e.toString());
exception = e;
}
try {
//The JSON object returned from the server is wrapped in a 'd' object (when using WCF, but not with ASMX)
//Return the content of the 'd' wrapping object, which will be the results container.
if (jo != null)
return (JSONObject) jo.get("d");
} catch (JSONException ex){
Log.d("SearchResultsActivity", ex.toString());
}
return null;
}
//Called automatically after doInBackground finishes, this unpacks the results and displays them
protected void onPostExecute(JSONObject response) {
if(response!=null) {
try {
//Extract the results
JSONArray results = (JSONArray) response.get("Results");
//Add results to an ArrayList
ArrayList resultList = new ArrayList(results.length());
for (int I = 0; I < results.length(); i++) {
resultList.add((JSONObject) results.get(i));
}
//Display the ArrayList of results in the ListView
setListAdapter(new ResultItemsAdapter(SearchActivity.this, android.R.layout.simple_list_item_1, resultList));
} catch (JSONException e) {
Log.d("SearchResultsActivity", e.toString());
}
}
}
}
Going further
The implementation here is simple, but a good foundation. Please express
your interest in this subject to receive further information and to help us
prioritize this feature for future development. We also are very happy to hear
from developers attempting to build out this functionality themselves. |