Search address by name with Geocoder, with Search Dialog.

Last exercise demonstrate how to "search address by name with Geocoder".

Search address by name with Geocoder, with Search Dialog.


Modify AndroidManifest.xml.
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidsearchgeocoder"
android:versionCode="1"
android:versionName="1.0" >

<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="17" />

<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.androidsearchgeocoder.MainActivity"
android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEARCH" />
</intent-filter>
<meta-data android:name="android.app.searchable"
android:resource="@xml/searchable" />
</activity>

</application>

</manifest>


/res/xml/searchable.xml
<searchable xmlns:android="http://schemas.android.com/apk/res/android"
android:label="@string/app_name"
android:hint="Search by Name"
>
</searchable>


MainActivity.java
package com.example.androidsearchgeocoder;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import android.location.Address;
import android.location.Geocoder;
import android.os.Bundle;
import android.app.Activity;
import android.app.SearchManager;
import android.content.Intent;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.ListView;
import android.widget.Toast;

public class MainActivity extends Activity {

ListView listResult;

private ArrayAdapter<String> adapter;

Geocoder geocoder;
final static int maxResults = 5;
List<Address> locationList;
List<String> locationNameList;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
listResult = (ListView)findViewById(R.id.resultlist);

handleIntent(getIntent());

geocoder = new Geocoder(this, Locale.ENGLISH);

locationNameList = new ArrayList<String>(); //empty in start
adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, locationNameList);
listResult.setAdapter(adapter);
}

@Override
protected void onNewIntent(Intent intent) {
setIntent(intent);
handleIntent(intent);
}

private void handleIntent(Intent intent) {
if (Intent.ACTION_SEARCH.equals(intent.getAction())) {
String query = intent.getStringExtra(SearchManager.QUERY);
doSearch(query);
}
}

private void doSearch(String query){

try {
locationList = geocoder.getFromLocationName(query, maxResults);

if(locationList == null){
Toast.makeText(getApplicationContext(),
"locationList == null",
Toast.LENGTH_LONG).show();
}else{
if(locationList.isEmpty()){
Toast.makeText(getApplicationContext(),
"locationList is empty",
Toast.LENGTH_LONG).show();
}else{
Toast.makeText(getApplicationContext(),
"number of result: " + locationList.size(),
Toast.LENGTH_LONG).show();

locationNameList.clear();

for(Address i : locationList){
if(i.getFeatureName() == null){
locationNameList.add("unknown");
}else{
locationNameList.add(i.getFeatureName());

}
}

adapter.notifyDataSetChanged();
}
}
} catch (IOException e) {
Toast.makeText(getApplicationContext(),
"network unavailable or any other I/O problem occurs",
Toast.LENGTH_LONG).show();
e.printStackTrace();
}

String result ="Finished - " + query;

//I can't close search dialog, so I call it again to keep it active.
//Otherwise, user see the search dialog opened, but cannot search in seconf time.
onSearchRequested();

}

@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}

@Override
public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) {
case R.id.search:
onSearchRequested();
return true;
default:
return false;
}
}

}


Layout
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<ListView
android:id="@+id/resultlist"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>



download filesDownload the files.

Next:
- Get details of Address returned from Geocoder