Saturday, 8 August 2009

Exercise: Menu and Dialog

In this article, option menu and dialog will be added to Android Application.
The project files can be downloaded here.

Create a new Android Application with the following setting:
Project name: AndroidMenu
Application name: Android Menu
Package name: com.example.androidMenu
Create Activity: AndroidMenuActivity
Min SDK Version: 2


Use the technique described in the article, Tips and Tricks in using Eclipse: Override a method from a base class, to insert methods onCreateOptionsMenu and onOptionsItemSelected.

Right click on the Source Code Editor and invoke Source > Override/Implement Methods.

Find and select onCreateOptionsMenu and onOptionsItemSelected, select the insertion position, and click OK.

The selected methods will be inserted with dummy code, the need files, android.view.Menu and android.view.MenuItem, will be imported also.

We have to add string constane in the string.xml file.
Modify R.string in res>values>string.xml, add the items:
<string name="app_about">About Me</string>
<string name="str_exit">Exit</string>
<string name="app_about_message">Android Menu</string>
<string name="str_ok">OK</string>
<string name="app_exit">Exit</string>
<string name="app_exit_message">Exit?</string>
<string name="str_no">No</string>

Modify onCreateOptionsMenu(Menu menu), onOptionsItemSelected(MenuItem item) and implement openOptionsDialog() and exitOptionsDialog().


@Override
public boolean onCreateOptionsMenu(Menu menu) {
// TODO Auto-generated method stub
menu.add(0, 0, 0, R.string.app_about);
menu.add(0, 1, 1, R.string.str_exit);
return super.onCreateOptionsMenu(menu);
}



@Override
public boolean onOptionsItemSelected(MenuItem item) {
// TODO Auto-generated method stub
super.onOptionsItemSelected(item);

switch(item.getItemId())
{
case 0:
openOptionsDialog();
break;
case 1:
exitOptionsDialog();
break;
}
return true;
}



private void openOptionsDialog()
{
new AlertDialog.Builder(this)
.setTitle(R.string.app_about)
.setMessage(R.string.app_about_message)
.setPositiveButton(R.string.str_ok,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialoginterface, int i)
{
}
})
.show();
}



private void exitOptionsDialog()
{
new AlertDialog.Builder(this)
.setTitle(R.string.app_exit)
.setMessage(R.string.app_exit_message)
.setNegativeButton(R.string.str_no,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialoginterface, int i)
{}
})
.setPositiveButton(R.string.str_ok,
new DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialoginterface, int i)
{
finish();
}
})
.show();
}


In order to use AlertDialog, DialogInterface, two more classes have to be imported:

import android.app.AlertDialog;
import android.content.DialogInterface;


Run the application, click the MENU button, two Menu Option, About Me and Exit, will be displayed.
Click About Me will show the About Me dialog
Click Exit will show a Exit dialog asking to confirm exit.


The project files can be downloaded here.

Friday, 7 August 2009

Open Office - Frame Replacement?

Well I haven't posted much this week because I have been working on a new book template for work. In the past we have used FrameMaker to created our guides. But for our next round of updates, we are gonna use Open Office.


So far I have been pretty impressed. I seem to be able to pretty much do everything I did before in Frame. Create master documents, have paragraph and character formats, create Tables of Contents, running headers and footers. You name it. If I have some time, I'll try to post to tips for those out there that would like to create big thick books too!

Wednesday, 5 August 2009

Exercise: Intent & Bundle

In the previous exercise, I implemented one activity with two layout. In this exercise, I implement the same application, with same function and presentation, using two activity, HelloAndroid.java and HelloAndroid_2.java. The activity is switched using Intent, the data is passed using Bundle.

We can keep both layout, main.xml and main2.xml, no change.

We have to re-write HelloAndroid.java to two separated files, HelloAndroid.java and HelloAndroid_2.java.

HelloAndroid.java

package com.example.helloandroid3;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.EditText;
import android.view.View;

public class HelloAndroid extends Activity {

private
Button okButton;
Button cancel1Button;
EditText textName;
EditText textPhonenumberIs;
EditText textEmailIs;
EditText textWebsiteIs;
EditText textAddressIs;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

startLayout1();
}

private Button.OnClickListener okOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
textName = (EditText) findViewById(R.id.whoareyou);
CharSequence textName_value = textName.getText();

textPhonenumberIs = (EditText) findViewById(R.id.phonenumberIs);
CharSequence textPhonenumberIs_value = textPhonenumberIs.getText();

textEmailIs = (EditText) findViewById(R.id.emailIs);
CharSequence textEmailIs_value = textEmailIs.getText();

textWebsiteIs = (EditText) findViewById(R.id.websiteIs);
CharSequence textWebsiteIs_value = textWebsiteIs.getText();

textAddressIs = (EditText) findViewById(R.id.addressIs);
CharSequence textAddressIs_value = textAddressIs.getText();

Intent intent = new Intent();
intent.setClass(HelloAndroid.this, HelloAndroid_2.class);

Bundle bundle = new Bundle();
bundle.putCharSequence("bName", textName_value);
bundle.putCharSequence("bPhonenumber", textPhonenumberIs_value);
bundle.putCharSequence("bEmail", textEmailIs_value);
bundle.putCharSequence("bWebsite", textWebsiteIs_value);
bundle.putCharSequence("bAddress", textAddressIs_value);

intent.putExtras(bundle);

startActivity(intent);
finish();
}
};

private Button.OnClickListener cancelOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
finish();
}
};

private void startLayout1(){
setContentView(R.layout.main);
okButton = (Button) findViewById(R.id.ok);
okButton.setOnClickListener(okOnClickListener);
cancel1Button = (Button) findViewById(R.id.cancel_1);
cancel1Button.setOnClickListener(cancelOnClickListener);
};
}



HelloAndroid_2.java

package com.example.helloandroid3;

import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.view.View;

public class HelloAndroid_2 extends Activity {

private
Button backButton;
Button cancel2Button;
TextView nameField;
TextView phonenumberField;
TextView emailField;
TextView websiteField;
TextView addressField;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

startLayout2();

Bundle bundle = this.getIntent().getExtras();
CharSequence textName_value = bundle.getCharSequence("bName");
nameField = (TextView) findViewById(R.id.name);
nameField.setText("Hello "+textName_value);

CharSequence textPhonenumberIs_value = bundle.getCharSequence("bPhonenumber");
phonenumberField = (TextView) findViewById(R.id.phonenumber);
phonenumberField.setText("Phone Number: "+textPhonenumberIs_value);

CharSequence textEmailIs_value = bundle.getCharSequence("bEmail");
emailField = (TextView) findViewById(R.id.email);
emailField.setText("Email: "+textEmailIs_value);

CharSequence textWebsiteIs_value = bundle.getCharSequence("bWebsite");
websiteField = (TextView) findViewById(R.id.website);
websiteField.setText("Website: "+textWebsiteIs_value);

CharSequence textAddressIs_value = bundle.getCharSequence("bAddress");
addressField = (TextView) findViewById(R.id.address);
addressField.setText("Address: "+textAddressIs_value);
};

private Button.OnClickListener backOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
Intent intent = new Intent();
intent.setClass(HelloAndroid_2.this, HelloAndroid.class);

startActivity(intent);
finish();
}
};

private Button.OnClickListener cancelOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
finish();
}
};

private void startLayout2(){
setContentView(R.layout.main2);
backButton = (Button) findViewById(R.id.back);
backButton.setOnClickListener(backOnClickListener);
cancel2Button = (Button) findViewById(R.id.cancel_2);
cancel2Button.setOnClickListener(cancelOnClickListener);
};
}


Because we have two activity, so we have to modify the file AndroidManifest.xml, to include the additional activity.

AndroidManifest.xml

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.helloandroid3"
android:versionCode="1"
android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name">
<activity android:name=".HelloAndroid"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".HelloAndroid_2"></activity>
</application>
<uses-sdk android:minSdkVersion="2" />
</manifest>


The project files can be downloaded here.

Tuesday, 4 August 2009

Exercise: autoLink and layout change

In this exercise, autoLink Attribute of TextView will be used.

The project can be downloaded here.

autoLink controls whether links such as urls and email addresses are automatically found and converted to clickable links. The default value is "none", disabling this feature.

It must be one or more (separated by '|') of the following constant values: none, web, email, phone, map and all.

Also, in this exercise, TWO layout will be used on ONE activity, the application can switch between them using setContentView() at runtime.

Create a new Android Application fill in the project details with the following values:
  • Project name: HelloAndroid_III
  • Application name: Hello, Android III
  • Package name: com.example.helloandroid3
  • Create Activity: HelloAndroid
  • Min SDK Version: 2
Modify main.xml and create a main2.xml.

main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Who are you?"
/>
<EditText
android:id = "@+id/whoareyou"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Phone number is?"
/>
<EditText
android:id = "@+id/phonenumberIs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="email is?"
/>
<EditText
android:id = "@+id/emailIs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="web Site is?"
/>
<EditText
android:id = "@+id/websiteIs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="address is?"
/>
<EditText
android:id = "@+id/addressIs"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right|bottom"
>
<Button
android:id = "@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK" />
<Button
android:id = "@+id/cancel_1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>



main2.xml


<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:id = "@+id/name"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<TextView
android:id = "@+id/phonenumber"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="phone"
/>
<TextView
android:id = "@+id/email"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="email"
/>
<TextView
android:id = "@+id/website"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="web"
/>
<TextView
android:id = "@+id/address"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:autoLink="map"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right|bottom"
>
<Button
android:id = "@+id/back"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Back" />
<Button
android:id = "@+id/cancel_2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>


Note the attribute android:autoLink ahve been added on TextView.

And modify HelloAndroid.java

package com.example.helloandroid3;

import android.app.Activity;
import android.os.Bundle;
import android.widget.Button;
import android.widget.TextView;
import android.widget.EditText;
import android.view.View;

public class HelloAndroid extends Activity {

private
Button okButton;
Button cancel1Button;
EditText textName;
EditText textPhonenumberIs;
EditText textEmailIs;
EditText textWebsiteIs;
EditText textAddressIs;

Button backButton;
Button cancel2Button;
TextView nameField;
TextView phonenumberField;
TextView emailField;
TextView websiteField;
TextView addressField;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

startLayout1();
}

private Button.OnClickListener okOnClickListener =
new Button.OnClickListener(){
@Override
public void onClick(View v) {
textName = (EditText) findViewById(R.id.whoareyou);
CharSequence textName_value = textName.getText();

textPhonenumberIs =
(EditText) findViewById(R.id.phonenumberIs);
CharSequence textPhonenumberIs_value =
textPhonenumberIs.getText();

textEmailIs = (EditText) findViewById(R.id.emailIs);
CharSequence textEmailIs_value = textEmailIs.getText();

textWebsiteIs = (EditText) findViewById(R.id.websiteIs);
CharSequence textWebsiteIs_value = textWebsiteIs.getText();

textAddressIs = (EditText) findViewById(R.id.addressIs);
CharSequence textAddressIs_value = textAddressIs.getText();

startLayout2();

nameField = (TextView) findViewById(R.id.name);
nameField.setText("Hello "+textName_value);

phonenumberField = (TextView) findViewById(R.id.phonenumber);
phonenumberField.setText("Phone Number: "
+textPhonenumberIs_value);

emailField = (TextView) findViewById(R.id.email);
emailField.setText("Email: "+textEmailIs_value);

websiteField = (TextView) findViewById(R.id.website);
websiteField.setText("Website: "+textWebsiteIs_value);

addressField = (TextView) findViewById(R.id.address);
addressField.setText("Address: "+textAddressIs_value);

}
};

private Button.OnClickListener backOnClickListener =
new Button.OnClickListener(){
@Override
public void onClick(View v) {
startLayout1();
}
};

private Button.OnClickListener cancelOnClickListener =
new Button.OnClickListener(){
@Override
public void onClick(View v) {
finish();
}
};

private void startLayout1(){
setContentView(R.layout.main);
okButton = (Button) findViewById(R.id.ok);
okButton.setOnClickListener(okOnClickListener);
cancel1Button = (Button) findViewById(R.id.cancel_1);
cancel1Button.setOnClickListener(cancelOnClickListener);
};

private void startLayout2(){
setContentView(R.layout.main2);
backButton = (Button) findViewById(R.id.back);
backButton.setOnClickListener(backOnClickListener);
cancel2Button = (Button) findViewById(R.id.cancel_2);
cancel2Button.setOnClickListener(cancelOnClickListener);
};
}




In order to use the autoLink of map function, you have to use a Android Virtual Device (AVD) with target of Google APIs - 1.5. To create a new AVG, refer to the previous article, How to create Android Virtual Device (AVD) in Eclipse.

Run the Android Application and enter the information, then click OK.



The Activity will switch to another layout, if the data entered are match with the expected format, it will be changed to hyper-link. You can click it to involve another default application to handle it.


Phone Number:


Email is not yet supported!


Website:


Address: (It's the address of Google headquarter)


The project can be downloaded here.

How to create Android Virtual Device (AVD) in Eclipse

Android Virtual Device (AVD), can be created inside Eclipse, such that you needn't remember the syntax of the command "android create avd..." in command mode.

Click Run > Run Configurations... from Android Top Menu.


Select Target tape, click AVD Manager.

Your existing Android Virtual Devices will be listed.
To create a new AVD, enter the name, select Target and Skin, click Create AVD.

OK, your new AVD created.

Select the new AVD, click Apply and Run.

Select the expected AVD to be launched for your application.


You can check on the top of your Emulator, the new AVD is selected to be launched.

Sunday, 2 August 2009

Tips and Tricks in using Eclipse: Override a method from a base class

It's a trick to increasing your productivity in using Eclipse to develope Java code, also apply to Android programming. For example, you want to override the method finish(), but you forget the spelling, or you are too laze to type it. Right click on any space on your source code, and invoke Source > Override/Implement Methods.


Select the desired method(s) to be inserted, also you can select the insertion point, click OK.


See, your code have been inserted.


It's a very useful and helpful practice for me.

HelloAndroid with Spinner

In this exercise, I add a Spinner for user to select country where he come from. I will show how to add a Spinner in main.xml, add a array.xml to embed items into Spinner, and how to handle it in HelloAndroid.java.

A view that displays one child at a time and lets the user pick among them. The items in the Spinner come from the Adapter associated with this view.

Environment:
Ubuntu 9.04
Eclipse 3.5 Galileo
Android 1.5 SDK r3

The exercise continuous from the previous article, Change UI elements by changing main.xml. The project can be downloaded here.

Modify main.xml

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Who you are?"
/>
<EditText
android:id = "@+id/message_text"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>

<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Where you come from?"
/>
<Spinner
android:id = "@+id/spinner_countries"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="right|bottom"
>
<Button
android:id = "@+id/ok"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK" />
<Button
android:id = "@+id/cancel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel" />
</LinearLayout>
</LinearLayout>

Download main.xml

Create a file, named array.xml in /HelloAndroid2/res/values/
array.xml

<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Used in Spinner/spinner_2.java -->
<string-array name="countries">
<item>Canada</item>
<item>China</item>
<item>Germany</item>
<item>Japan</item>
<item>Korea</item>
<item>Russia</item>
<item>UK</item>
<item>USA</item>
</string-array>
</resources>

Download array.xml

Finally, modify JavaAndroid.java

package com.example.helloandroid;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Spinner;

public class HelloAndroid extends Activity {

private Spinner spinner_countries;

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Button okButton = (Button) findViewById(R.id.ok);
okButton.setOnClickListener(okOnClickListener);
Button cancelButton = (Button) findViewById(R.id.cancel);
cancelButton.setOnClickListener(cancelOnClickListener);

spinner_countries = (Spinner) findViewById(R.id.spinner_countries);
ArrayAdapter<CharSequence> adapter
= ArrayAdapter.createFromResource(this,
R.array.countries, android.R.layout.simple_spinner_item);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spinner_countries.setAdapter(adapter);
}
private Button.OnClickListener okOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
EditText edit_text = (EditText) findViewById(R.id.message_text);
CharSequence edit_text_value = edit_text.getText();
setTitle("Hello: "+edit_text_value+" from "
+spinner_countries.getItemAtPosition((int) spinner_countries.getSelectedItemId()));
}
};

private Button.OnClickListener cancelOnClickListener = new Button.OnClickListener(){
@Override
public void onClick(View v) {
finish();
}
};
}

Download HelloAndroid.java

Now, you can try to run it on Emulator.

The project can be downloaded here.

Related article:
- Custom Spinner with icon