Tutorial #63: Implement reverse geocoding in Android

Hi everyone!

Geocoding is nothing but the process of finding the latitude and longitude of a place given its geographical data whereas reverse geocoding involves determining the location such as street address from the geographical co-ordinates. The Android platform provides developers with a Geocoder class to implement the same functionality on mobile devices.

In this tutorial, we will learn how to implement reverse geocoding in Android.

Pre-requisites: Eclipse Indigo, Android SDK (Target Android SDK 4.2)

Step 1: Create new Android project

Open Eclipse IDE and make a new Android application project named AndroidReverseGeocodeDemo. Let the package name be com.example

Step 2: Create Activity class

In case of reverse geocoding, we need to provide the latitude and longitude of a place in order to get the associated textual location. Let’s create a new Activity class called MainActivity and add the following code!

MainActivity.java

package com.example;

import java.io.IOException;
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.view.View;
import android.widget.Button;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {

	private Button myLocation;
	private TextView myAddress;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		myLocation= (Button) findViewById(R.id.location);
		myAddress = (TextView)findViewById(R.id.address);
	
		myLocation.setOnClickListener(new View.OnClickListener() {
			
			@Override
			public void onClick(View v) {
				// TODO Auto-generated method stub
				getMyLocationAddress();
			}
		});
		
	}

	public void getMyLocationAddress() {
		
		Geocoder geocoder= new Geocoder(this, Locale.ENGLISH);
		
		try {
        	  
			  //Place your latitude and longitude
			  List<Address> addresses = geocoder.getFromLocation(37.423247,-122.085469, 1);
        	 
        	  if(addresses != null) {
        	  
        		  Address fetchedAddress = addresses.get(0);
        		  StringBuilder strAddress = new StringBuilder();
        	   
        		  for(int i=0; i<fetchedAddress.getMaxAddressLineIndex(); i++) {
        			  	strAddress.append(fetchedAddress.getAddressLine(i)).append("\n");
        		  }
        	   
        		  myAddress.setText("I am at: " +strAddress.toString());
        	  
        	  }
        	  
        	  else
        		  myAddress.setText("No location found..!");
         
        } 
		catch (IOException e) {
        		 // TODO Auto-generated catch block
        		 e.printStackTrace();
        		 Toast.makeText(getApplicationContext(),"Could not get address..!", Toast.LENGTH_LONG).show();
		}
	}
	
}

activity_main.xml

<RelativeLayout 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"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/title"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/hello_world"/>
    
    <TextView
        android:id="@+id/address"
        android:layout_below="@+id/title"
	    android:layout_width="wrap_content"
        android:layout_height="wrap_content"/>
    
    <Button
        android:id="@+id/location"
        android:text="@string/get_location"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/address"/>

</RelativeLayout>

Step 3: Update Manifest file

You need to add the necessary permissions in the AndroidManifest.xml file as seen below,

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

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

    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <permission android:name="com.example.permission.MAPS_RECEIVE" android:protectionLevel="signature"/>
    <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.example.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>
    </application>

</manifest>

On running the application on your Android device, you should the following screenshots!

reverse_geocode_1

reverse_geocode_2

Source code for this tutorial can be found over here.

It’s time for Droidcon!

It’s about that time of the year again when people passionate about technology come together and participate in one of the coolest events. India’s largest Android conference Droidcon is back with a three day extravaganza including in depth, hands-on sessions on everything about Android.

The event will take place on 28th-30th November 2013 at the MLR Convention Centre, Whitefield, Bangalore. If you are an Android enthusiast, then this would be a great chance to meet eminent developers out there and interact with the best speakers in the country. To know more about the event please visit the official Droidcon India 2013 website.

Grab your tickets soon! Hope to see you there! πŸ™‚

droidcon

Tutorial #62: Using HTML5 in Android

Hello everyone!

HTML5 has been around for quite some time now. It is basically a markup language used for structuring and presenting content for the World Wide Web. One of the interesting features of HTML5 is the fact that this new standard is cross platform and is designed to do almost everything without the use of additional plugins. In HTML5 there is only one !DOCTYPE declaration as follows,

<!DOCTYPE html>

Sample HTML5 document

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Title of the document</title>
</head>

<body>
Content of the document......
</body>
</html>

In this tutorial, we will learn how to create a simple HTML5 web application on Android.

Pre-requisites: Eclipse Indigo, Android SDK (Target SDK 2.3.3)

Step 1: Open Eclipse IDE and create a new Android application project called AndroidWebAppDemo with package name com.example

Step 2: Create HTML5 page

Create a new folder web inside the existing assets folder. Create a new HTML5 page named demo.html as follows,

assets/web/demo.html

<!DOCTYPE HTML>
<html>
<head>
<script src="demo.js" type="text/javascript" />
</head>
<body>

<form name="form1" onSubmit="return showInfo()" autocomplete="on">
  First name:<input type="text" id="fname"><br>
  Last name: <input type="text" id="lname"><br>
  <input type="submit">
</form>

</body>
</html>

Also, add a javascript file (demo.js) to the same folder with the following contents!

assets/web/demo.js

function showInfo()
{
	var str1= document.getElementById('fname').value;
	var str2= document.getElementById('lname').value;
	var res = str1.concat(' '+str2);
	alert('Hi,' +res);
}

Now, let’s add our Java code in the MainActivity class.

/src/MainActivity.java

package com.example;

import android.os.Bundle;
import android.webkit.WebChromeClient;
import android.webkit.WebView;
import android.annotation.SuppressLint;
import android.app.Activity;

@SuppressLint("SetJavaScriptEnabled")
public class MainActivity extends Activity {

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		
		WebView webView = (WebView)findViewById(R.id.WebView1);
		webView.getSettings().setJavaScriptEnabled(true);
		webView.setWebChromeClient(new WebChromeClient());
		webView.loadUrl("file:///android_asset/web/demo.html");
	}
}

activity_main.xml

<RelativeLayout 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"
    tools:context=".MainActivity" >

    <WebView
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:id="@+id/WebView1" />

</RelativeLayout>

Finally, make sure no errors are present. Run the project on an Android device and you should see the following output!

web_app_1

web_app_2

Source code for this tutorial can be found over here.

Reference: WebChromeClient and WebView

Packt announces new book for Android and OpenCV!

If you are working on Android, involved in designing image processing applications then most probably you would come across the use of OpenCV, a popular computer vision and real-time image processing library.

Keeping this is mind, print company Packt Publishing recently announced a new book titled Android Application Programming with OpenCV for those who wish to get an insight on using image processing in Android. The book helps you set up OpenCV and Android from scratch depending upon your work environment and includes easy to learn code samples for capturing, displaying real-time videos and still images.

On the whole, the book is a practical, hands on guide covering the fundamental tasks of computer vision with step-by-step instructions for writing both an application and reusable library classes. To know more, grab a copy of the book from over here. Happy reading! πŸ™‚

Using virtual columns in Oracle

Not too long ago Oracle 11g introduced a new feature called virtual columns. A virtual column as the name implies is an empty column defined by an expression. The value of the column is the result of evaluation of the expression.

Pre-requisites: Oracle database 11g Enterprise Edition

The general syntax for defining a virtual column is,

column_name [datatype] [GENERATED ALWAYS] AS [expression] [VIRTUAL]

Characteristics of virtual columns are as follows,

1. Virtual columns cannot be modified using DML statements (INSERT, UPDATE and DELETE)

2. Virtual columns cannot be created on indexed, clustered or temporary tables.

3. The data present in the virtual column is not stored in the database. Instead it is dynamically evaluated.

4. All columns mentioned as part of the virtual column expression should belong to the same table.

As every coin has two sides, virtual columns too have their own limitations. However, in this post we will learn about creating and using virtual columns in the Oracle database.

Let’s create a new table called product with a virtual column profit as follows,

create table product (prodid number, prodname varchar(20), cost_price number(10,2) , selling_price number(10,2) , profit number(10,2) GENERATED ALWAYS as (selling_price -  cost_price));

SELECT column_name, data_type, data_length, data_default, virtual_column FROM user_tab_cols  WHERE table_name = 'PRODUCT';

virtual_column_1

Try inserting a few records in the product table.

insert into product(prodid,prodname,cost_price,selling_price) values (101,’abc’,500,700);
insert into product(prodid,prodname,cost_price,selling_price) values (102,’def’,600,800);
insert into product(prodid,prodname,cost_price,selling_price) values (103,’ghi’,700,900);
insert into product(prodid,prodname,cost_price,selling_price) values (104,’jkl’,800,1200);

virtual_column_2

Now, if we try inserting/updating the virtual column, we get the following error.

insert_error

update_error

So basically using virtual columns Oracle enables us to store expressions directly in the base tables. One can also implement virtual columns in previous versions of Oracle such as Oracle 10g using the concept of function based indexes as specified over here.

Hope this was helpful. Thanks for reading! πŸ™‚

Implement a draggable marker using Google Maps Android API v2

Hi everyone!

If you have worked on Google Maps before then this post will help you to learn something new. A Marker is basically an icon placed at a particular point on the surface of the map. Any marker includes the following properties,

1. Position

The LatLng value for the marker’s position on the map. You can change this value at any time if you want to move the marker.

2. Title

A text string that’s displayed in an info window when the user taps the marker. You can change this value at any time.

3. Snippet

Additional text that’s displayed below the title. You can change this value at any time.

4. Icon

A bitmap that’s displayed for the marker. If the icon is left unset, a default icon is displayed.

5. Drag Status

If you want to allow the user to drag the marker, set this property to true. You can change this value at any time. The default is false.

6. Visibility

By default, the marker is visible. To make the marker invisible, set this property to false. You can change this value at any time.

Through this post, we will learn how to create a draggable marker using Google Maps Android API v2!

In any of your existing Android projects, create a new Activity class named TestDragMarker and add the following code!

Note: Make sure the Android project you are working on has been configured for using Google Play Services

TestDragMarker.java

package com.example;

import android.os.Bundle;
import android.support.v4.app.FragmentActivity;
import android.util.Log;
import android.widget.Toast;
import com.google.android.gms.maps.GoogleMap;
import com.google.android.gms.maps.CameraUpdateFactory;
import com.google.android.gms.maps.GoogleMap.OnMapClickListener;
import com.google.android.gms.maps.GoogleMap.OnMapLongClickListener;
import com.google.android.gms.maps.GoogleMap.OnMarkerDragListener;
import com.google.android.gms.maps.SupportMapFragment;
import com.google.android.gms.maps.model.CameraPosition;
import com.google.android.gms.maps.model.LatLng;
import com.google.android.gms.maps.model.Marker;
import com.google.android.gms.maps.model.MarkerOptions;

public class TestDragMarker extends FragmentActivity implements OnMapLongClickListener,OnMapClickListener,OnMarkerDragListener {

	private static GoogleMap map;
	
	@Override
	protected void onCreate(Bundle saveInstance) {
			super.onCreate(saveInstance);
			setContentView(R.layout.activity_map);
			
			map = ((SupportMapFragment)getSupportFragmentManager().findFragmentById(R.id.map)).getMap();
			map.setOnMarkerDragListener(this);
			map.setOnMapLongClickListener(this);
			map.setOnMapClickListener(this);
			
			CameraPosition INIT =
			new CameraPosition.Builder()
			.target(new LatLng(19.0222, 72.8666))
			.zoom(17.5F)
			.bearing(300F) // orientation
			.tilt( 50F) // viewing angle
			.build();
			 
			// use map to move camera into position
			map.moveCamera( CameraUpdateFactory.newCameraPosition(INIT) );
			
			//create initial marker
			map.addMarker( new MarkerOptions()
			   .position( new LatLng(19.0216, 72.8646) )
			   .title("Location")
			   .snippet("First Marker")).showInfoWindow();
	}
	 
	
	@Override
	public void onMarkerDrag(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMarkerDragEnd(Marker arg0) {
		// TODO Auto-generated method stub
		LatLng dragPosition = arg0.getPosition();
		double dragLat = dragPosition.latitude;
		double dragLong = dragPosition.longitude;
		Log.i("info", "on drag end :" + dragLat + " dragLong :" + dragLong);
		Toast.makeText(getApplicationContext(), "Marker Dragged..!", Toast.LENGTH_LONG).show();
	}

	@Override
	public void onMarkerDragStart(Marker arg0) {
		// TODO Auto-generated method stub
		
	}

	@Override
	public void onMapClick(LatLng arg0) {
		// TODO Auto-generated method stub
		map.animateCamera(CameraUpdateFactory.newLatLng(arg0));
	}


	@Override
	public void onMapLongClick(LatLng arg0) {
		// TODO Auto-generated method stub
	
		//create new marker when user long clicks
		map.addMarker(new MarkerOptions()
		.position(arg0)
		.draggable(true));
	}	
}

activity_map.xml


<?xml version="1.0" encoding="utf-8"?>

<fragment xmlns:android="http://schemas.android.com/apk/res/android"
          android:id="@+id/map"
          android:layout_width="match_parent"
          android:layout_height="match_parent"
          class="com.google.android.gms.maps.SupportMapFragment"/>

Make sure you have added the necessary permissions for accessing Google Maps in the AndroidManifest.xml file. Save your Activity class and run the project on an Android device. If no errors are present, you should see the following output!

before_dragged

after_dragged

Reference: Google Maps Android API v2

Using ODI 12c’s new mapping designer!

In my previous post, I went through the installation of Oracle Data Integrator 12c on the Windows platform. In earlier versions of ODI, we used Interfaces to load a single target datastore from one or more source datastores. Starting from 12c, the concept of Mappings is introduced.

A mapping comprises of a logical design and at least one physical design. A mapping can have many targets, of any technology and can be arbitrarily complex. One can build reusable mappings and use them in other mappings or other reusable mappings (somewhat similar to yellow interfaces). Let’s understand how mappings work through a simple example!

Pre-requisites: Oracle Data Integrator 12c, Oracle database 10g XE

Step 1: Create database tables

Login to any work schema and create two tables in your Oracle database as follows!

create table mappingsrc(empid int primary key, empname varchar(20));
create table mappingtarget(empid int primary key, empname varchar(20));

Add a few dummy records to the mappingsrc table only.

Step 2: Create mapping

Now, open ODI Studio and in any of your existing projects create a new mapping called test_mapping as follows!

mapping_1

Add the source and the target mappings in the Logical Designer.

mapping_2

mapping_3

Once you have completed the mapping, don’t forget to validate it for any errors!

validate_mapping

Finally, run the mapping and check the status of the operation under the Operator tab.

output_1

output_2

That’s it for this post. Stay tuned for more! πŸ™‚

Installing Oracle Data Integrator 12c!

Hi everyone!

Oracle recently announced the latest version of its data integration products by introducing Oracle Data Integrator 12c and Oracle GoldenGate 12c. It is one of the biggest releases of the company this year and provides features that include improved performance, increased productivity and simplified deployment.

Through this post, we will learn how to install Oracle Data Integrator 12c on Windows. The following are some of the new features added to ODI 12c.

  • Declarative Flow-Based User Interface
  • Reusable Mappings
  • Multiple Target Support
  • Step-by-Step Debugger
  • Runtime Performance Enhancements
  • Oracle GoldenGate Integration Improvements
  • Standalone Agent Management with WebLogic Management Framework
  • Integration with OPSS Enterprise Roles
  • XML Improvements
  • Oracle Warehouse Builder Integration
  • Unique Repository IDs
  • Pre-requisites: Windows XP (32 bit) Service Pack 3

    Step 1: Download Oracle Data Integrator 12c

    Go to the downloads page for Oracle Data Integrator and download version 12c for all platforms (including 64 bit).

    Step 2: Run installer

    Once you have downloaded the software, you need to run the installer to begin the setup process. Follow the below steps for better understanding!

    installation_step_1

    installation_step_2

    installation_step_3

    installation_step_4

    installation_step_5

    This completes the installation. Now open ODI Studio from within the application directory. Further, you can choose to store passwords in Wallet.

    running_odi_1

    running_odi_2

    running_odi_3

    Reference: Oracle blog