Pages

Tuesday, May 24, 2011

Android AnalogClock

It's very easy to add a Analog Clock in Android, Just add the code of AnalogClock in main.xml.



AnalogClock is a widget to display an analogic clock with two hands for hours and minutes.

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"
    />
<AnalogClock
    android:id="@+id/myAnalogClock"
    android:layout_width="fill_parent" 
    android:layout_height="wrap_content"
    />

</LinearLayout>

AndroidSpeech: Android can speech!

A new feature, Text-To-Speech (TTS), have been introduced in version 1.6 of the Android platform. Also known as 'speech synthesis', TTS enables Android device to 'speak' text of different languages.

it's a very simple code to make Android speech. It can speech only.

Create a Android Application, with Target platform 1.6 or higher, API Level 4 or selected platform level. Modify the code as following.

AndroidSpeech.java
package com.exercise.AndroidSpeech;

import android.app.Activity;
import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;

public class AndroidSpeech extends Activity implements OnInitListener{

TextToSpeech myTTS;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
     myTTS = new TextToSpeech(this, this);
 }

@Override
public void onInit(int status) {
// TODO Auto-generated method stub

String myText1 = "Hello Android!";
       String myText2 = "I can speech.";
       myTTS.speak(myText1, TextToSpeech.QUEUE_FLUSH, null);
       myTTS.speak(myText2, TextToSpeech.QUEUE_ADD, null);
}

@Override
protected void onDestroy() {
// TODO Auto-generated method stub
super.onDestroy();
myTTS.shutdown();
}
}




For more details of Android Text-To-Speech, refer to:
Android Developers Blog: An introduction to Text-To-Speech in Android: "We've introduced a new feature in version 1.6 of the Android platform: Text-To-Speech (TTS). Also known as 'speech synthesis', TTS enables your Android device to 'speak' text of different languages."

AndroidBrowser, with visible/gone URL bar

Personally, I don't like the UI in the previous exercise, which start another activity to enter URL, and passed back to open the URL. Here, I implement a URL bar, using TableLayout with visibility. It can be set between visible and gone(hide) by click on the "URL bar" option on the Menu. Such that user can enter URL on the same screen of the browser, and hide it if more room for display is wanted.



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"
>
<TableLayout
android:id="@+id/UrlEntry"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:shrinkColumns="0"
android:visibility="gone"
>
<TableRow>
   <EditText
       android:id="@+id/goUrl"
       android:text="http://"
       />
   <Button
       android:id="@+id/goUrlButton"
       android:text="GO"
       />
</TableRow>
</TableLayout>
<WebView android:id="@+id/mybrowser"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>


strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="hello">Hello World, AndroidBrowser!</string>
<string name="app_name">Android Browser</string>
 
 <string name="str_about_message">Android Browser</string>
 
 <string name="str_exit_message">Exit?</string>
 <string name="str_ok">OK</string>
 <string name="str_no">No</string>
 <string name="str_URL">URL:</string>
 
 <string name="str_URLbar">URL bar</string>
 <string name="str_About">About</string>
 <string name="str_Exit">Exit</string>
 <string name="str_Backward"><<</string>
 <string name="str_Reload">Reload</string>
 <string name="str_Forward">>></string>

</resources>


package com.exercise.AndroidBrowser;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TableLayout;

public class AndroidBrowser extends Activity {
 
 final int MENU_VISIBILITY = 0;
 final int MENU_ABOUT = 1;
 final int MENU_EXIT = 2;
 final int MENU_BACKFORD = 3;
 final int MENU_RELOAD = 4;
 final int MENU_FORWARD = 5;

 WebView myBrowser;
 TableLayout myUrlBar;
 EditText gotoUrl;
 Button myUrlButton;
 
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    String myURL = "http://www.google.com";
    myBrowser=(WebView)findViewById(R.id.mybrowser);

    myUrlBar = (TableLayout)findViewById(R.id.UrlEntry);
    gotoUrl = (EditText)findViewById(R.id.goUrl);
    myUrlButton = (Button)findViewById(R.id.goUrlButton);
    myUrlButton.setOnClickListener(myUrlButtonOnClickListener);

    /*By default Javascript is turned off,
     * it can be enabled by this line.
     */
    myBrowser.getSettings().setJavaScriptEnabled(true);
    myBrowser.setWebViewClient(new WebViewClient());

    myBrowser.loadUrl(myURL);
}

 @Override
 public boolean onCreateOptionsMenu(Menu menu) {
  // TODO Auto-generated method stub
  menu.add(0, MENU_VISIBILITY, 0, R.string.str_URLbar);
  menu.add(0, MENU_ABOUT,  0, R.string.str_About);
  menu.add(0, MENU_EXIT,   0, R.string.str_Exit);
  menu.add(0, MENU_BACKFORD,  0, R.string.str_Backward);
  menu.add(0, MENU_RELOAD,  0, R.string.str_Reload);
  menu.add(0, MENU_FORWARD,  0, R.string.str_Forward);
  
  return super.onCreateOptionsMenu(menu);
 }

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

  switch(item.getItemId())
  {
   case MENU_VISIBILITY:
    ToggleGotoVisibility();
    break;
   case MENU_ABOUT:
    openAboutDialog();
    break;
   case MENU_EXIT:
    openExitDialog();
    break;
   case MENU_BACKFORD:
    if(myBrowser.canGoBack())
     myBrowser.goBack();
    break;
   case MENU_RELOAD:
    myBrowser.reload();
    break;
   case MENU_FORWARD:
    if(myBrowser.canGoForward())
     myBrowser.goForward();
    break;
  }
  return true;
 }
 
 void ToggleGotoVisibility()
 {
  if (myUrlBar.getVisibility() == View.GONE)
  {
   myUrlBar.setVisibility(View.VISIBLE);
  }
  else
  {
   myUrlBar.setVisibility(View.GONE);
  }
 }
 
 private void openAboutDialog()
 {
  new AlertDialog.Builder(this)
   .setTitle(R.string.str_About)
   .setMessage(R.string.str_about_message)
   .setPositiveButton(R.string.str_ok,
    new DialogInterface.OnClickListener()
    {
     public void onClick(DialogInterface dialoginterface, int i)
     {}
    })
   .show();
 }
 
 private void openExitDialog()
 {
  new AlertDialog.Builder(this)
   .setTitle(R.string.str_Exit)
   .setMessage(R.string.str_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();
 }
 
 private Button.OnClickListener myUrlButtonOnClickListener
  = new Button.OnClickListener()
 {

  @Override
  public void onClick(View v) {
   // TODO Auto-generated method stub
   myBrowser.loadUrl(gotoUrl.getText().toString());
  }
  
 };
 
}


Remember to delete the files gotopanel.xml and AndroidBrowserGoto.java. And also remove "activity android:name=".AndroidBrowserGoto" from AndroidManifest.xml to resume original.

The whole project can be downloaded here.

AndroidBrowser, with simple navigating functions

It's the second version of the dummy AndroidBrowser; with some improvement, add some navigating functions, such as Goto URL, Forward, Backward and Reload, and also About Me and Exit.



- Enable my own browser to handle our own URL loading

If you run implemented and ran the AndroidBrowser in the previous article, you can note that the control will be passed to Android default Browser when any links is clicked. In order to make the new links is opened by our own browser, setWebViewClient() have to be called after the browser initiated.

myBrowser.setWebViewClient(new WebViewClient());

* Refer to Android's Hello, WebView example, there is another implementation with little bit difference.

- Remove TextView in main.xml to make more room for the browser.

- Override onCreateOptionsMenu() to add menu for various navigating functions

- Override onOptionsItemSelected(), and the corespond methods to handle the actual operation when the navigating functions selected.

- Implement a AndroidBrowserGoto.java class to handle Goto URL entry, it communicate with the main class, AndroidBrowser, by means of Intent and Bundle.

When GOTO menu item selected, control will be passed to AndroidBrowserGoto.java; after user input the URL and click OK, control and the target URL will be passed back to AndroidBrowser.java. So we start AndroidBrowserGoto.java using startActivityForResult(), instead of startActivity(). And also, we have to Override onActivityResult() to handle the returned data.

main.xml, layout used by AndroidBrowser.java
<?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"
 >
<WebView android:id="@+id/mybrowser"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>


gotopanel.xml, layout used by AndroidBrowserGoto.java.
<?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/mybrowser"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Enter the URL:"
/>
<EditText
android:id="@+id/gotourl"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="http://"
/>
<Button
android:id="@+id/gotoButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="OK"
/>
<Button
android:id="@+id/cancelgotoButton"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="CANCEL"
/>
</LinearLayout>


strings.xml
<?xml version="1.0" encoding="utf-8"?>
<resources>
 <string name="hello">Hello World, AndroidBrowser!</string>
 <string name="app_name">Android Browser</string>

<string name="str_about_message">Android Browser</string>

<string name="str_exit_message">Exit?</string>
<string name="str_ok">OK</string>
<string name="str_no">No</string>
<string name="str_URL">URL:</string>

<string name="str_Goto">Go to</string>
<string name="str_About">About</string>
<string name="str_Exit">Exit</string>
<string name="str_Backward"><<</string>
<string name="str_Reload">Reload</string>
<string name="str_Forward">>></string>
</resources>


AndroidBrowser.java
package com.exercise.AndroidBrowser;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.MenuItem;
import android.webkit.WebView;
import android.webkit.WebViewClient;

public class AndroidBrowser extends Activity {

final int MENU_GOTO = 0;
final int MENU_ABOUT = 1;
final int MENU_EXIT = 2;
final int MENU_BACKFORD = 3;
final int MENU_RELOAD = 4;
final int MENU_FORWARD = 5;

WebView myBrowser;

 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
     String myURL = "http://z4android.blogspot.com";
     myBrowser=(WebView)findViewById(R.id.mybrowser);
  
     /*By default Javascript is turned off,
      * it can be enabled by this line.
      */
     myBrowser.getSettings().setJavaScriptEnabled(true);
     myBrowser.setWebViewClient(new WebViewClient());
  
     myBrowser.loadUrl(myURL);
 }

@Override
public boolean onCreateOptionsMenu(Menu menu) {
 // TODO Auto-generated method stub
 menu.add(0, MENU_GOTO,   0, R.string.str_Goto);
 menu.add(0, MENU_ABOUT,  0, R.string.str_About);
 menu.add(0, MENU_EXIT,   0, R.string.str_Exit);
 menu.add(0, MENU_BACKFORD,  0, R.string.str_Backward);
 menu.add(0, MENU_RELOAD,  0, R.string.str_Reload);
 menu.add(0, MENU_FORWARD,  0, R.string.str_Forward);

 return super.onCreateOptionsMenu(menu);
}

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

 switch(item.getItemId())
 {
  case MENU_GOTO:
   openGotoDialog();
   break;
  case MENU_ABOUT:
   openAboutDialog();
   break;
  case MENU_EXIT:
   openExitDialog();
   break;
  case MENU_BACKFORD:
   if(myBrowser.canGoBack())
    myBrowser.goBack();
   break;
  case MENU_RELOAD:
   myBrowser.reload();
   break;
  case MENU_FORWARD:
   if(myBrowser.canGoForward())
    myBrowser.goForward();
   break;
 }
 return true;
}

private void openGotoDialog()
{
 Intent intent = new Intent();
     intent.setClass(AndroidBrowser.this, AndroidBrowserGoto.class);
  
 startActivityForResult(intent, 0);

}

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

private void openExitDialog()
{
 new AlertDialog.Builder(this)
  .setTitle(R.string.str_Exit)
  .setMessage(R.string.str_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();
}

@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {

 // TODO Auto-generated method stub
 super.onActivityResult(requestCode, resultCode, data);
 if (requestCode==0)
 {
  switch (resultCode)
  { case RESULT_OK:
    String gotourl = data.getStringExtra("url");
    myBrowser.loadUrl(gotourl);
    break;
   case RESULT_CANCELED:
    break;
 
  }

 }
}
}


AndroidBrowserGoto.java
package com.exercise.AndroidBrowser;

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

public class AndroidBrowserGoto extends Activity {

Button gotoButton, cancelButton;
EditText gotoURL;

@Override
protected void onCreate(Bundle savedInstanceState) {
 // TODO Auto-generated method stub
 super.onCreate(savedInstanceState);
 setContentView(R.layout.gotopanel);

 gotoURL = (EditText) findViewById(R.id.gotourl);
 gotoButton = (Button) findViewById(R.id.gotoButton);
 gotoButton.setOnClickListener(gotoOnClickListener);
 cancelButton = (Button) findViewById(R.id.cancelgotoButton);
 cancelButton.setOnClickListener(cancelgotoOnClickListener);
}

 private Button.OnClickListener gotoOnClickListener = new Button.OnClickListener(){
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  Intent intent = new Intent();
  Bundle bundle = new Bundle();
 
  //bundle.putString("url", "http://www.google.com/");
  String targetURL = gotoURL.getText().toString();
  bundle.putString("url", targetURL);
  intent.putExtras(bundle);
  setResult(RESULT_OK, intent);
  finish();
 }
  };
  private Button.OnClickListener cancelgotoOnClickListener
              = new Button.OnClickListener(){
 @Override
 public void onClick(View v) {
  // TODO Auto-generated method stub
  setResult(RESULT_CANCELED);
  finish();
 }
   };
}


Finally, add in AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
   package="com.exercise.AndroidBrowser"
   android:versionCode="1"
   android:versionName="1.0">
 <uses-permission android:name="android.permission.INTERNET" />
 <application android:icon="@drawable/icon" android:label="@string/app_name">
     <activity android:name=".AndroidBrowser"
               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=".AndroidBrowserGoto"></activity>

 </application>
 <uses-sdk android:minSdkVersion="3" />

</manifest>

AndroidBrowser, implement a Android Browser using WebView


Webkit, the Android build-in web browser can be embedded in Android Application easily, just include WebView in the layout, main.xml.







Create a New Android Application:
- Project Name: AndroidBrowser
- Application Name: Android Browser
- Package Name: com.exercise.AndroidBrowser
- Create Activity: AndroidBrowser
- Min SDK Version: 3

Modify main.xml to have a WebView:
<?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"
/>
<WebView android:id="@+id/mybrowser" 
   android:layout_width="fill_parent" 
   android:layout_height="fill_parent" 
   />
</LinearLayout>


Modify AndroidBrowser.java
package com.exercise.AndroidBrowser;

import android.app.Activity;
import android.os.Bundle;
import android.webkit.WebView;

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

     String myURL = "http:/z4android.blogspot.com";       
    WebView myBrowser=(WebView)findViewById(R.id.mybrowser);                
    /*By default Javascript is turned off,         
     * it can be enabled by this line.        
     */       
    myBrowser.getSettings().setJavaScriptEnabled(true);                
    myBrowser.loadUrl(myURL);
}
}


You also have make change on AndroidManifest.xml, so your application can access internet:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.exercise.AndroidBrowser"
  android:versionCode="1"
  android:versionName="1.0">
<uses-permission android:name="android.permission.INTERNET" />
<application android:icon="@drawable/icon" android:label="@string/app_name">
    <activity android:name=".AndroidBrowser"
              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>
<uses-sdk android:minSdkVersion="3" />

</manifest>

AndroidInfo to retrieve various system info. for Android Phone

Expend from previous exercises, AndroidInfo is a integrated application to retrieve various Android information, such as OS Version, System Information, CPU Information, Screen Resolution, Memory, Disk Space.













OS: Ubuntu 9.04
Java: Sun JDK 6
Eclipse version: 3.5 Galileo
Android SDK: Android 1.6 SDK r1

Fill in the project details with the following values:

* Project name: AndroidInfo
* Application name: Hello World, AndroidInfo!
* Package name: com.exercise.AndroidInfo
* Create Activity: AndroidInfo
* Min SDK Version: 4 (using Android 1.5 SDK for trial)

It contents one main class to handle the selection of function (AndroidInfo.java), and six class for each function (AndroidInfoOSVersion.java, AndroidInfoSys.java, AndroidInfoCpu.java, AndroidInfoScreen.java, AndroidInfoMemory.java, and AndroidInfoDisk.java).
It can be download here and extract to the folder /AndroidInfo/src/com/exercise/AndroidInfo/

Two layout files, main.xml for AndroidInfo.java, and panel.xml shared by all other classes.
Download here and extract to the folder /AndroidInfo/res/layout/

also remember to include the added classes in AndroidManifest.xml
Download here and replace the original AndroidManifest.xml.

Or, The whole project can be downloaded here.

Read Android CPU info

Android CPU info. can be retrieved by reading of "/proc/cpuinfo". So, it's just a very little bit of modification on Read Android OS version.



Create a new Android Application, with the Activity named AndroidCPUinfoActivity. Modify the main.xml and AndroidCPUinfoActivity.java:

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:gravity="center_horizontal"
 android:text="android-er.blogspot.com"
 android:autoLink="web"
 />
<TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Android CPU Info.:"
 />
<TextView
 android:id="@+id/CPUinfo"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
</LinearLayout>



AndroidCPUinfoActivity.java
package com.exercise.AndroidCPUinfo;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidCPUinfoActivity extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
     TextView CPUinfo = (TextView) findViewById(R.id.CPUinfo);
     CPUinfo.setText(ReadCPUinfo());
  
 }

 private String ReadCPUinfo()
 {
  ProcessBuilder cmd;
  String result="";
  
  try{
   String[] args = {"/system/bin/cat", "/proc/cpuinfo"};
   cmd = new ProcessBuilder(args);
   
   Process process = cmd.start();
   InputStream in = process.getInputStream();
   byte[] re = new byte[1024];
   while(in.read(re) != -1){
    System.out.println(new String(re));
    result = result + new String(re);
   }
   in.close();
  } catch(IOException ex){
   ex.printStackTrace();
  }
  return result;
 }
}

Read Android system info., using System.getProperty

It's another exercise to read Android system information, using system provided method getProperty.



Create a new Android Application, with the Activity named AndroidSYSinfoActivity. Modify the main.xml and AndroidSYSinfoActivity.java:
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:gravity="center_horizontal"
 android:text="android-er.blogspot.com"
 android:autoLink="web"
 />
<TextView
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="Android System:"
 />
<TextView
 android:id="@+id/SYSinfo"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 />
</LinearLayout>



AndroidSYSinfoActivity.java
package com.exercise.AndroidSYSinfo;

import com.exercise.AndroidSYSinfo.R;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

public class AndroidSYSinfoActivity extends Activity {
 /** Called when the activity is first created. */
 @Override
 public void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
     setContentView(R.layout.main);
  
  
     TextView SYSinfo = (TextView) findViewById(R.id.SYSinfo);
     SYSinfo.setText(ReadSYSinfo());
 }

 private static StringBuffer SYSinfoBuffer;

 private String ReadSYSinfo()
 {
  SYSinfoBuffer = new StringBuffer();
  
  getProperty("os.name", "os.name", SYSinfoBuffer);
  getProperty("os.version", "os.version", SYSinfoBuffer);
  
  getProperty("java.vendor.url", "java.vendor.url", SYSinfoBuffer);
  getProperty("java.version", "java.version", SYSinfoBuffer);
  getProperty("java.class.path", "java.class.path", SYSinfoBuffer);
  getProperty("java.class.version", "java.class.version", SYSinfoBuffer);
  getProperty("java.vendor", "java.vendor", SYSinfoBuffer);
  getProperty("java.home", "java.home", SYSinfoBuffer);
  
  getProperty("user.name", "user.name", SYSinfoBuffer);
  getProperty("user.home", "user.home", SYSinfoBuffer);
  getProperty("user.dir", "user.dir", SYSinfoBuffer);
  
  return SYSinfoBuffer.toString();
 }

 private void getProperty(String desc, String property, StringBuffer tBuffer)
 {
  tBuffer.append(desc);
  tBuffer.append(" : ");
  tBuffer.append(System.getProperty(property));
  tBuffer.append("\n");
 }
}

Read Android OS version

In this exercise, read Android OS version, using ProcessBuilder to Creates operating system processes.



Create a operating system processes, "/system/bin/cat", to retrieve "/proc/version".

If your system is running in Linux, you can try to type the command below in Terminal.
$ cat /proc/version



Actually, this exercise perform the same operation.

Create a new Android Application, with the Activity named AndroidOSinfoActivity. Modify the main.xml and AndroidOSinfoActivity.java:
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:gravity="center_horizontal"
android:text="android-er.blogspot.com"
android:autoLink="web"
/>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Android OS:"
/>
<TextView
android:id="@+id/OSinfo"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
</LinearLayout>



AndroidOSinfoActivity.java
package com.exercise.AndroidOSinfo;

import java.io.IOException;
import java.io.InputStream;

import android.app.Activity;
import android.os.Bundle;
import android.widget.TextView;

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

  TextView OSinfo = (TextView) findViewById(R.id.OSinfo);
  OSinfo.setText(ReadOSinfo());

}

private String ReadOSinfo()
{
ProcessBuilder cmd;
String result="";

try{
 String[] args = {"/system/bin/cat", "/proc/version"};
 cmd = new ProcessBuilder(args);

 Process process = cmd.start();
 InputStream in = process.getInputStream();
 byte[] re = new byte[1024];
 while(in.read(re) != -1){
  System.out.println(new String(re));
  result = result + new String(re);
 }
 in.close();
} catch(IOException ex){
 ex.printStackTrace();
}
return result;
}
}

hHelloGallery, get and display the path of selected picture

Further extend from previouse exercise, HelloGallery, read picture files from SD, using File ArrayList, and File type checking for HelloGallery, the path of the selected picture will be displayed using Toast.



It involve little bit modification on onItemClick(AdapterView parent, View v, int position, long id), and also onCreate(Bundle savedInstanceState).


public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);

Gallery g = (Gallery) findViewById(R.id.gallery);

  final List<String> SD = ReadSDCard();
  g.setAdapter(new ImageAdapter(this, SD));
    
  g.setOnItemClickListener(new OnItemClickListener()
 {
      public void onItemClick(AdapterView<?> parent,
           View v, int position, long id) {
         Toast.makeText(HelloGallery.this,
    (CharSequence)SD.get(position),
    Toast.LENGTH_LONG).show();
      }
  });
}

File type checking for HelloGallery

In the previous article, HelloGallery, read picture files from SD, using File ArrayList, the application view all files, no matter what type it is. Here, add a conditional checking for file type, by checking on the extension. Only files with extension jpg, gif and png will be added in the File ArrayList. Such change involve modification of the method ReadSDCard() only.


private List<String> ReadSDCard()
{
List<String> tFileList = new ArrayList<String>();

//It have to be matched with the directory in SDCard
 File f = new File("/sdcard/pictures/");

 File[] files=f.listFiles();

 for(int i=0; i<files.length; i++)
 {
  File file = files[i];

     String curFile=file.getPath();
     String ext=curFile.substring(curFile.lastIndexOf(".")+1, 
       curFile.length()).toLowerCase();
     if(ext.equals("jpg")||ext.equals("gif")||ext.equals("png"))
   tFileList.add(file.getPath());
 }

 return tFileList;
}

HelloGallery, read picture files from SD, using File ArrayList

It extend from previous exercise, HelloGallery, using Gallery Widget, but read files from SD instead of R.drawable.



Firstly, you have to Create an SD Card to existing AVD and Copying Files to a Disk Image.

All the xml files are same as previous, just keep it no change.

Modify the HelloGallery.java:

package com.exercise.HelloGallery;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;

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

    Gallery g = (Gallery) findViewById(R.id.gallery);
    g.setAdapter(new ImageAdapter(this, ReadSDCard()));

    g.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent,
          View v, int position, long id) {
        }
    });
}

private List<String> ReadSDCard()
{
 List<String> tFileList = new ArrayList<String>();

 //It have to be matched with the directory in SDCard
 File f = new File("/sdcard/pictures/");

 File[] files=f.listFiles();

 for(int i=0; i<files.length; i++)
 {
  File file = files[i];
  /*It's assumed that all file in the path
    are in supported type*/
  tFileList.add(file.getPath());
 }

 return tFileList;
}

public class ImageAdapter extends BaseAdapter {
    int mGalleryItemBackground;
    private Context mContext;
    private List<String> FileList;

    public ImageAdapter(Context c, List<String> fList) {
        mContext = c;
        FileList = fList;
        TypedArray a = obtainStyledAttributes(R.styleable.Theme);
        mGalleryItemBackground = a.getResourceId(
          R.styleable.Theme_android_galleryItemBackground,
          0);
        a.recycle();
    }

    public int getCount() {
        return FileList.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView,
      ViewGroup parent) {
        ImageView i = new ImageView(mContext);

        Bitmap bm = BitmapFactory.decodeFile(
          FileList.get(position).toString());
        i.setImageBitmap(bm);
    
        i.setLayoutParams(new Gallery.LayoutParams(150, 100));
        i.setScaleType(ImageView.ScaleType.FIT_XY);
        i.setBackgroundResource(mGalleryItemBackground);
    
        return i;
    }
}
}

Friday, May 20, 2011

Create SD Card in Android Emulator and copy files into, in Eclipse, Emulator and DDMS.

In my previous articles, I described how to Create an SD Card to existing AVD, and Copying Files to a Disk Image in ubuntu host system using text commands in Terminal.

Now, I have another approach using in Eclipse, Emulator and DDMS. May be it's more easy, at least no need to remember the text commands.

Create a new AVD in Eclipse:

- Start Eclipse, click Window on the top menu, and click Android SDK and AVD Manager.

- New a AVD


- Name your new AVD, select Target, type 1000M in SD Card and select skin. Click Create.
note: SD Card must be either a file path or a size such as 128K 0r 64M. type 1000M now to create a SD Card of 1G.

- Select and Start the new AVD.


After the Emulator started, you can close the AVD Manager.

Create folder in SDCard

I can't find any File Manager in Android Emulator. Fortunately, Android Emulator provide a DevTools with Terminal, so you can create a folder using Linux command inside Android Emulator.

- Click the ARROW on the screen to display the available application.

- Click DevTools.


- Scroll down to start Terminal Emulator


- It's the same a terminal in Linux, you can ls to view the current files and folders in your $home.


- Now change into sdcard and create a folder, say pictures.
$cd sdcard
$mkdir pictures

It's the only two line of command in this approach.


Copy files from your host system into Android SDCard

- With the Emulator is running. Now go back to Eclipse, switch to DDMS Perspective

Click the arrow on the menu bar and select DDMS

or

Click Window > Open Perspective > others > to select DDMS

- Select the device in the window on the left, eg. emulator-5554.
(Without select the device, you will fail in copying files into.)

- In DDMS, select File Explorer tag in the window on the right. Expend sdcard folder. Now, you can see the pictures folder in the tree. And also, you can see the Permissions of the folder.


- Select the pictures folder, and click Push a file onto the device .

- Browse to and select the files from your host, to push onto the Android Emulator.

- Further expend the folder pictures, you can see the new file here.

HelloGallery, read picture files from SD, using File ArrayList

It extend from previous exercise, HelloGallery, using Gallery Widget, but read files from SD instead of R.drawable.



Firstly, you have to Create an SD Card to existing AVD and Copying Files to a Disk Image.

All the xml files are same as previous, just keep it no change.

Modify the HelloGallery.java:

package com.exercise.HelloGallery;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.AdapterView.OnItemClickListener;

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

    Gallery g = (Gallery) findViewById(R.id.gallery);
    g.setAdapter(new ImageAdapter(this, ReadSDCard()));

    g.setOnItemClickListener(new OnItemClickListener() {
        public void onItemClick(AdapterView<?> parent,
          View v, int position, long id) {
        }
    });
}

private List<String> ReadSDCard()
{
 List<String> tFileList = new ArrayList<String>();

 //It have to be matched with the directory in SDCard
 File f = new File("/sdcard/pictures/");

 File[] files=f.listFiles();

 for(int i=0; i<files.length; i++)
 {
  File file = files[i];
  /*It's assumed that all file in the path
    are in supported type*/
  tFileList.add(file.getPath());
 }

 return tFileList;
}

public class ImageAdapter extends BaseAdapter {
    int mGalleryItemBackground;
    private Context mContext;
    private List<String> FileList;

    public ImageAdapter(Context c, List<String> fList) {
        mContext = c;
        FileList = fList;
        TypedArray a = obtainStyledAttributes(R.styleable.Theme);
        mGalleryItemBackground = a.getResourceId(
          R.styleable.Theme_android_galleryItemBackground,
          0);
        a.recycle();
    }

    public int getCount() {
        return FileList.size();
    }

    public Object getItem(int position) {
        return position;
    }

    public long getItemId(int position) {
        return position;
    }

    public View getView(int position, View convertView,
      ViewGroup parent) {
        ImageView i = new ImageView(mContext);

        Bitmap bm = BitmapFactory.decodeFile(
          FileList.get(position).toString());
        i.setImageBitmap(bm);
    
        i.setLayoutParams(new Gallery.LayoutParams(150, 100));
        i.setScaleType(ImageView.ScaleType.FIT_XY);
        i.setBackgroundResource(mGalleryItemBackground);
    
        return i;
    }
}
}

Copying Files to a Disk Image

Once you have created the disk image, you can copy files to it prior to loading it in the emulator. To copy files, you can mount the image as a loop device and then copy the files to it, or you can use a utility such as mtools to copy the files directly to the image. The mtools package is available for Linux, Mac, and Windows.

Here, I will mount and copy files to emulator SD Card as a loop device.

In Unix-like operating systems, a loop device, vnd (vnode disk), or lofi (loopback file interface) is a pseudo-device that makes a file accessible as a block device.

Create a directory, named SD in my home.

Type the command in Terminal:
$sudo mount -o loop /home/eric/.android/avd/my_avd_GoogleAPIs_1.5.avd/sdcard.img /home/eric/sd

Where /home/eric/sd is the directory mounted to be accessed.
/home/eric/.android/avd/my_avd_GoogleAPIs_1.5.avd/sdcard.img is the SDCard image created for Android Emulator.

Now, you can create directory, copy files to the emulator's SDCard by SD.

$cd sd
$sudo mkdir pictures
$cd pictures
$sudo cp /home/eric/SDCard_16M.png .
$...

To know more details of the command mount, type
$man mount

Create an SD Card to existing AVD

Here, I want to create an SD Card image to an AVD.

- Firstly, locate the path of your AVD, type the command in Terminal:
$android list avd

- Create a SDCard image, named "sdcard.img" (it's the default name for the emulator to load).
In my case, I want to add 16M SD Card to the /home/eric/.android/avd/my_avd_GoogleAPIs_1.5.avd.

$mksdcard 16M /home/eric/.android/avd/my_avd_GoogleAPIs_1.5.avd/sdcard.img

where /home/eric/.android/avd/my_avd_GoogleAPIs_1.5.avd/ is the path of my avd.



Restart the emulator, click Menu in Android Home screen, then click Settings > SD Card & phone storage. Now, you can see the SD Card here.

With 16M SD Card:


Without SD Card, before adding the SDCard image:

HelloGallery, using Gallery Widget.

Here is a exercise to implement a picture view using Gallery, a view that shows items in a center-locked, horizontally scrolling list.



Basically, this exercise follow the Android Tutorial, Hello Gallery. But in my practice, error is complained in building. I have to create a attrs.xml and modify some code to fix it.

Here is how I fix it to make it work.

Create a Android Application, HelloGallery. Copy some images, in .png format, into res/drawable/ directory. Named image_01..05.png in my case.

Android supports bitmap resource files in a few different formats: png (preferred), jpg (acceptable), gif (discouraged). The bitmap file itself is compiled and referenced by the file name without the extension (so res/drawable/my_picture.png would be referenced as R.drawable.my_picture).

Create res/values/attrs.xml to define Theme_android_galleryItemBackground.
<?xml version="1.0" encoding="utf-8"?>
<resources>
<declare-styleable name="Theme">
<attr name="android:galleryItemBackground" />
</declare-styleable>
</resources>


Modify main.xml to have a Gallery in the screen.
<?xml version="1.0" encoding="utf-8"?>
<Gallery xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/gallery"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>


Finally, modify the HelloGallery.java
package com.exercise.HelloGallery;

import android.app.Activity;
import android.content.Context;
import android.content.res.TypedArray;
import android.os.Bundle;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.BaseAdapter;
import android.widget.Gallery;
import android.widget.ImageView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;

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

   Gallery g = (Gallery) findViewById(R.id.gallery);
   g.setAdapter(new ImageAdapter(this));

   g.setOnItemClickListener(new OnItemClickListener() {
       public void onItemClick(AdapterView<?> parent,
           View v, int position, long id) {
           Toast.makeText(HelloGallery.this, "" + position,
               Toast.LENGTH_SHORT).show();
       }
   });
}

public class ImageAdapter extends BaseAdapter {
   int mGalleryItemBackground;
   private Context mContext;

   private Integer[] mImageIds = {
           R.drawable.image_01,
           R.drawable.image_02,
           R.drawable.image_03,
           R.drawable.image_04,
           R.drawable.image_05
   };

   public ImageAdapter(Context c) {
       mContext = c;
       TypedArray a = obtainStyledAttributes(R.styleable.Theme);
       mGalleryItemBackground = a.getResourceId(
         R.styleable.Theme_android_galleryItemBackground,
                   0);
       a.recycle();
   }

   public int getCount() {
       return mImageIds.length;
   }

   public Object getItem(int position) {
       return position;
   }

   public long getItemId(int position) {
       return position;
   }

   public View getView(int position,
       View convertView, ViewGroup parent) {
       ImageView i = new ImageView(mContext);

       i.setImageResource(mImageIds[position]);
       i.setLayoutParams(new Gallery.LayoutParams(150, 100));
       i.setScaleType(ImageView.ScaleType.FIT_XY);
       i.setBackgroundResource(mGalleryItemBackground);

       return i;
   }
}
}

Exercise: Change background color, by SeekBar



In this exercise, the background color is changed, controlled by SeekBar.

A SeekBar is an extension of ProgressBar that adds a draggable thumb. The user can touch the thumb and drag left or right to set the current progress level or use the arrow keys.

When SeekBarChange, the onProgressChanged() of OnSeekBarChangeListener will be called, and the background of the screen(LinearLayout) will be updated according to the value (SeekBar.getProgress()).

Create a Android Application, SeekColor, with three SeekBar for Red, Green and Blue setting.

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"
android:id="@+id/myScreen"
>
<TextView
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"
/>
<SeekBar
android:id="@+id/mySeekingBar_R"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:max="255"
    android:progress="0"/>
<SeekBar
android:id="@+id/mySeekingBar_G"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:max="255"
    android:progress="0"/>
<SeekBar
android:id="@+id/mySeekingBar_B"
    android:layout_width="fill_parent"
    android:layout_height="wrap_content"
    android:max="255"
    android:progress="0"/>
</LinearLayout>


SeekColorActivity.java
package com.exercise.seekcolor;

import android.app.Activity;
import android.os.Bundle;
import android.widget.LinearLayout;
import android.widget.SeekBar;

public class SeekColorActivity extends Activity {

private int seekR, seekG, seekB;
SeekBar redSeekBar, greenSeekBar, blueSeekBar;
LinearLayout mScreen;

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

    mScreen = (LinearLayout) findViewById(R.id.myScreen);
    redSeekBar = (SeekBar) findViewById(R.id.mySeekingBar_R);
    greenSeekBar = (SeekBar) findViewById(R.id.mySeekingBar_G);
    blueSeekBar = (SeekBar) findViewById(R.id.mySeekingBar_B);
    updateBackground();

    redSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
    greenSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);
    blueSeekBar.setOnSeekBarChangeListener(seekBarChangeListener);

}

private SeekBar.OnSeekBarChangeListener seekBarChangeListener
= new SeekBar.OnSeekBarChangeListener()
{

@Override
public void onProgressChanged(SeekBar seekBar, int progress,
  boolean fromUser) {
// TODO Auto-generated method stub
 updateBackground();
}
@Override
public void onStartTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}

@Override
public void onStopTrackingTouch(SeekBar seekBar) {
// TODO Auto-generated method stub
}
};

private void updateBackground()
{
 seekR = redSeekBar.getProgress();
 seekG = greenSeekBar.getProgress();
 seekB = blueSeekBar.getProgress();
 mScreen.setBackgroundColor(
  0xff000000
  + seekR * 0x10000
  + seekG * 0x100
  + seekB
  );
}
}

Exercise: Load background to ImageButton, in programmatical approach

In addition to "Load background to ImageButton, using XML", Android support programmatic approach also, using setImageResource().

In this exercise, I implement ImageButton.setOnFocusChangeListener() and ImageButton.setOnClickListener() to handle the background image of the ImageButton. The outcome is same as the "Load background to ImageButton, using XML".



Download and save the three image above to res > drawable folder.

Add a ImageButton in 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"
   />
<ImageButton
    android:id="@+id/myImageButton"
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    android:background="@drawable/android"
    />
</LinearLayout>


Modify the source code to implement setOnFocusChangeListener() and setOnClickListener()
package com.exercise.AndroidImageButton;

import android.app.Activity;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.ImageButton;

public class AndroidImageButtonActivity extends Activity {
 
  private ImageButton mImageButton;
 
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
      
    mImageButton = (ImageButton) findViewById(R.id.myImageButton);
      
    mImageButton.setOnFocusChangeListener(
      new OnFocusChangeListener()
       {
   @Override
   public void onFocusChange(View v, boolean hasFocus) {
   // TODO Auto-generated method stub
   if (hasFocus==true)
   {
      mImageButton.setImageResource(R.drawable.androidonfocus);
   }
   else
   {
      mImageButton.setImageResource(R.drawable.android);
   }
 }
     });
      
     mImageButton.setOnClickListener(
       new OnClickListener() {
   @Override
   public void onClick(View v) {
   // TODO Auto-generated method stub
   mImageButton.setImageResource(R.drawable.androidonclick);
 }
     });     
   }
}

Exercise: Load background to ImageButton, using XML

Default of ImageButton:

Button On Focus:

Button On Click:


The backgound of ImageButton can be defined in main.xml, without any works on programming.



Download and save the three image above to res > drawable folder.

Create a loadimagebutton.xml in res > drawable folder.

<?xml version="1.0" encoding="utf-8"?>
<selector
xmlns:android="http://schemas.android.com/apk/res/android">
<item
 android:state_focused="true"
 android:state_pressed="false"
 android:drawable="@drawable/androidonfocus" />
<item
 android:state_focused="true"
 android:state_pressed="true"
 android:drawable="@drawable/androidonclick" />
<item
 android:state_focused="false"
 android:state_pressed="true"
 android:drawable="@drawable/androidonclick" />
<item  
 android:drawable="@drawable/android" />
</selector>


Modify main.xml to involve loadimagebutton

<?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"
/>
<ImageButton
    android:background="@drawable/loadimagebutton"  
    android:layout_width="wrap_content" 
    android:layout_height="wrap_content" 
    />
</LinearLayout>


(To achieve the same out-come using programmatical approach, refer to the next article, Exercise: Load background to ImageButton, in programmatical approach.)

Exercise: style

A style is a set of one or more formatting attributes that you can apply as a unit to single elements in your layout XML file(s). For example, you could define a style that specifies a certain text size and color, then apply it to instances of a certain type of View element.

details>>

Create a dummy Android Application, AndroidStyle. Create style.xml in the folder res > values


<?xml version="1.0" encoding="utf-8"?>
<resources>
 <style name="StyleText1">
     <item name="android:textSize">20sp</item>
     <item name="android:textColor">#EC9200</item>
     <item name="android:gravity">center_horizontal</item>
 
 </style>
 <style name="StyleText2">
     <item name="android:textSize">30sp</item>
     <item name="android:textColor">#990000</item>
     <item name="android:gravity">right</item>
 </style>
 <style name="StyleButton1">
     <item name="android:layout_width">wrap_content</item>
     <item name="android:layout_height">wrap_content</item>
 </style>
 <style name="StyleButton2">
     <item name="android:layout_width">fill_parent</item>
     <item name="android:layout_height">fill_parent</item>
 </style>    
</resources>


Modify main.xml to apply the styles.

<?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
 style="@style/StyleText1"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="It's StyleText1"
 />
<TextView
 style="@style/StyleText2"
 android:layout_width="fill_parent"
 android:layout_height="wrap_content"
 android:text="It's StyleText2"
 />
<Button
 style="@style/StyleButton1"
 android:text="It's StyleButton1"
 />
<Button
 style="@style/StyleButton2"
 android:text="It's StyleButton2"
 /> 
</LinearLayout>


Exercise: Get screen resolution using android.util.DisplayMetrics

android.util.DisplayMetrics is a structure describing general information about a display, such as its size, density, and font scaling.


To use android.util.DisplayMetrics to get resolution:

Create a dummy Android Application, add a TextView in main.xml to display the result.

<TextView
android:id="@+id/strScreenSize"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text=""
/>

Modify the .java file to read DisplayMetrics

package com.exercise.AndroidScreen;

import android.app.Activity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.widget.TextView;

public class AndroidScreenActivity extends Activity {
  /** Called when the activity is first created. */
  @Override
  public void onCreate(Bundle savedInstanceState) {
      super.onCreate(savedInstanceState);
      setContentView(R.layout.main);
   
        DisplayMetrics dm = new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(dm);
        String str_ScreenSize = "The Android Screen is: "
                    + dm.widthPixels
                    + " x "
                    + dm.heightPixels;

        TextView mScreenSize = (TextView) findViewById(R.id.strScreenSize);
        mScreenSize.setText(str_ScreenSize);
  }
}


Exercise: Apply Theme in AndroidManifest.xml

Android provide some predefine themes in the base package, you can change the theme by adding a code in the file AndroidManifest.xml.

Inside Application tag to take effect on whole Application.

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
 package="com.exercise.AndroidTheme"
 android:versionCode="1"
 android:versionName="1.0">
<application android:icon="@drawable/icon" android:label="@string/app_name"
 android:theme="@android:style/Theme.Black"
 >
   <activity android:name=".AndroidThemeActivity"
             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>
<uses-sdk android:minSdkVersion="2" />
</manifest>

Or,
Inside Activity tag to take effect on individual Activity.

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


@android:style/Theme.Black



@android:style/Theme.Light



@android:style/Theme.Translucent

Popular Posts