Wednesday, April 10, 2013

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


No comments: