HTML ONLINE

Wellcome to html!

Thứ Sáu, 28 tháng 12, 2012

Get installed TTS engines, by calling getEngines() method.

Start from Android API level 14, List<TextToSpeech.EngineInfo> getEngines() method was provided to get a list of all installed TTS engines.

To display installed TTS Engines:

display installed TTS Engines


package com.example.androidtexttospeech;

import java.util.ArrayList;
import java.util.List;

import android.os.Bundle;
import android.speech.tts.TextToSpeech;
import android.speech.tts.TextToSpeech.OnInitListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.TextView;
import android.app.Activity;

public class MainActivity extends Activity implements OnInitListener{

TextView tvDefaultTTS;

Spinner spInstalledEngines;
TextToSpeech tts;
List<TextToSpeech.EngineInfo> listInstalledEngines;
List<String> listInstalledEnginesName;
String defaultTTS;

private ArrayAdapter<String> adapter;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
tvDefaultTTS = (TextView)findViewById(R.id.defaulttts);
spInstalledEngines = (Spinner)findViewById(R.id.installedengines);

tts = new TextToSpeech(this, this);
listInstalledEngines = tts.getEngines();
listInstalledEnginesName = new ArrayList<String>();

for(int i = 0; i < listInstalledEngines.size(); i++){
listInstalledEnginesName.add(listInstalledEngines.get(i).label);
}

adapter = new ArrayAdapter<String>(
this, android.R.layout.simple_spinner_item, listInstalledEnginesName);
adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
spInstalledEngines.setAdapter(adapter);

defaultTTS = tts.getDefaultEngine();
tvDefaultTTS.setText("Default TTS Engine: " + defaultTTS);
}

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

}

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

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:text="@string/hello_world" />
<TextView
android:id="@+id/defaulttts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<Spinner
android:id="@+id/installedengines"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>

</LinearLayout>


Next:
- Get features supported by TextToSpeech Engine

Thứ Năm, 27 tháng 12, 2012

Get device's Android ID

Secure.ANDROID_ID is a 64-bit number (as a hex string) that is randomly generated on the device's first boot and should remain constant for the lifetime of the device. (The value may change if a factory reset is performed on the device.)

device's Android ID


package com.example.androidid;

import android.os.Bundle;
import android.provider.Settings.Secure;
import android.app.Activity;
import android.widget.Toast;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

String id = Secure.getString(getContentResolver(), Secure.ANDROID_ID);
Toast.makeText(getApplicationContext(), id, Toast.LENGTH_LONG).show();
}

}


Thứ Năm, 13 tháng 12, 2012

Read raw text file, and display in ScrollView.

This article demonstrate how to read raw text file from /res/raw/ folder, and display the text in a TextView inside ScrollView.

Read raw text file, and display in ScrollView.


Create raw text file at /res/raw/mytext.txt.
Santa Claus Is Coming To Town:

You better watch out
You better not cry
Better not pout
I'm telling you why
Santa Claus is coming to town

He's making a list,
And checking it twice;
Gonna find out Who's naughty and nice.
Santa Claus is coming to town

He sees you when you're sleeping
He knows when you're awake
He knows if you've been bad or good
So be good for goodness sake!

O! You better watch out!
You better not cry.
Better not pout, I'm telling you why.
Santa Claus is coming to town.
Santa Claus is coming to town.


Add a ScrollView with TextView inside, to our layout.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />

<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<TextView
android:id="@+id/mytextview"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</ScrollView>

</LinearLayout>


Main code:
package com.AndroidTextResource;

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

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

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TextView myTextView = (TextView)findViewById(R.id.mytextview);

InputStream inputStream = getResources().openRawResource(R.raw.mytext);
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

String myText = "";
int in;
try {
in = inputStream.read();
while (in != -1)
{
byteArrayOutputStream.write(in);
in = inputStream.read();
}
inputStream.close();

myText = byteArrayOutputStream.toString();
}catch (IOException e) {
e.printStackTrace();
}

myTextView.setText(myText);
}

}



Thứ Năm, 6 tháng 12, 2012

Draw path on SurfaceView's canvas

Example to detect touch events and draw path on SurfaceView's canvas accordingly.

Draw path on SurfaceView's canvas


package com.TestSurefaceView;

import java.util.Random;
import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MainActivity extends Activity {

MySurfaceView mySurfaceView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mySurfaceView = new MySurfaceView(this);
setContentView(mySurfaceView);
}

class MySurfaceView extends SurfaceView{

Path path;

Thread thread = null;
SurfaceHolder surfaceHolder;
volatile boolean running = false;

private Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
Random random;

public MySurfaceView(Context context) {
super(context);
surfaceHolder = getHolder();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(3);
paint.setColor(Color.WHITE);
}

@Override
public boolean onTouchEvent(MotionEvent event) {
if(event.getAction() == MotionEvent.ACTION_DOWN){
path = new Path();
path.moveTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_MOVE){
path.lineTo(event.getX(), event.getY());
}else if(event.getAction() == MotionEvent.ACTION_UP){
path.lineTo(event.getX(), event.getY());
}

if(path != null){
Canvas canvas = surfaceHolder.lockCanvas();
canvas.drawPath(path, paint);
surfaceHolder.unlockCanvasAndPost(canvas);
}

return true;
}
}
}



Related Post:
- Detect multi-touch, on SurfaceView

Thứ Tư, 5 tháng 12, 2012

Capture screen with getDrawingCache() repeatly

In the article "Create custom dialog with dynamic content, updated in onPrepareDialog()", it demonstrate how to capture screen with setDrawingCacheEnabled() and getDrawingCache() methods. Unfortunately, it cannot work as expected! The screen is captured in the first time only. After that, every time call getDrawingCache() return the same first screen.

To solve it call setDrawingCacheEnabled(false) and then setDrawingCacheEnabled(true) to re-load the cache bitmap.

Modify onClick() method of btnCaptureScreen's OnClickListener:
     btnCaptureScreen.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
screen.setDrawingCacheEnabled(false);
screen.setDrawingCacheEnabled(true);
bmScreen = screen.getDrawingCache();
showDialog(ID_SCREENDIALOG);
}});


Capture screen with getDrawingCache() repeatly

Thứ Tư, 28 tháng 11, 2012

Display custom TrueType Font (TTF)

To display text using custom TTF; create /assets/fonts folder and save your ttf files in it. Create custom Typeface using Typeface.createFromAsset() method and apply it on views by calling setTypeface() method.

Display custom TrueType Font (TTF)


package com.example.androidttf;

import android.os.Bundle;
import android.app.Activity;
import android.graphics.Typeface;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

public class MainActivity extends Activity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

TextView testText = (TextView)findViewById(R.id.testtext);
Button testButton = (Button)findViewById(R.id.testbutton);
EditText testEditText = (EditText)findViewById(R.id.testedittext);

Typeface typeface_Abbeyline = Typeface.createFromAsset(getAssets(), "fonts/Abbeyline.ttf");
Typeface typeface_36daysag = Typeface.createFromAsset(getAssets(), "fonts/36daysag.ttf");
Typeface typeface_AtomicClockRadio = Typeface.createFromAsset(getAssets(), "fonts/AtomicClockRadio.ttf");
testText.setTypeface(typeface_Abbeyline);
testButton.setTypeface(typeface_36daysag);
testEditText.setTypeface(typeface_AtomicClockRadio);
}

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world" />
<TextView
android:id="@+id/testtext"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I'm a TextView" />
<Button
android:id="@+id/testbutton"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="I'm a Button" />
<EditText
android:id="@+id/testedittext"
android:layout_width="match_parent"
android:layout_height="wrap_content" />

</LinearLayout>


Thứ Năm, 22 tháng 11, 2012

Monitor battery level

This code monitor battery level by registering our BroadcastReceiver with IntentFilter for Intent.ACTION_BATTERY_CHANGED.

Monitor battery level of Android device


package com.example.androidbattery;

import android.os.Bundle;
import android.app.Activity;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.widget.TextView;

public class MainActivity extends Activity {

TextView batteryStatus;

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
batteryStatus = (TextView)findViewById(R.id.batterystatus);

IntentFilter batteryFilter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
registerReceiver(batteryMonitor, batteryFilter);
}

private BroadcastReceiver batteryMonitor
= new BroadcastReceiver(){

@Override
public void onReceive(Context arg0, Intent arg1) {
int batteryLevel = arg1.getIntExtra("level", 0);
batteryStatus.setText("Battery level = " + String.valueOf(batteryLevel) + "%");
}};

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical">

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

</LinearLayout>


Thứ Năm, 1 tháng 11, 2012

Remove View dynamically using Java code

Last post "Insert ImageView dynamically using Java code", by clicking on buttons. Removing function is added here to remove clicked ImageView from parent ViewGroup.

Remove View dynamically using Java code


Modify the Java code from last post, adding OnClickListener to the ImageViews to remove itself from its parent.
package com.example.androidinsertimages;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

Button addinHorizontalScrollView, addinScrollView;
LinearLayout inHorizontalScrollView, inScrollView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

inHorizontalScrollView = (LinearLayout)findViewById(R.id.inhorizontalscrollview);
inScrollView = (LinearLayout)findViewById(R.id.inscrollview);

addinHorizontalScrollView = (Button)findViewById(R.id.addinhorizontalscrollview);
addinHorizontalScrollView.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
addImageView(inHorizontalScrollView);
}});

addinScrollView = (Button)findViewById(R.id.addinscrollview);
addinScrollView.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
addImageView(inScrollView);
}});

}

private void addImageView(LinearLayout layout){
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.ic_launcher);
layout.addView(imageView);

imageView.setOnClickListener(viewOnClickListener);
}

OnClickListener viewOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
ViewGroup parent = (ViewGroup)v.getParent();
parent.removeView(v);
}
};
}



The layout file refer to last post.


Thứ Hai, 29 tháng 10, 2012

Insert ImageView dynamically using Java code

Here demonstrate how to create and add ImageView in LinearLayout (inside HorizontalScrollView/ScrollView) dynamically using Java code.

Insert ImageView dynamically using Java code


package com.example.androidinsertimages;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;

public class MainActivity extends Activity {

Button addinHorizontalScrollView, addinScrollView;
LinearLayout inHorizontalScrollView, inScrollView;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

inHorizontalScrollView = (LinearLayout)findViewById(R.id.inhorizontalscrollview);
inScrollView = (LinearLayout)findViewById(R.id.inscrollview);

addinHorizontalScrollView = (Button)findViewById(R.id.addinhorizontalscrollview);
addinHorizontalScrollView.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
addImageView(inHorizontalScrollView);
}});

addinScrollView = (Button)findViewById(R.id.addinscrollview);
addinScrollView.setOnClickListener(new OnClickListener(){

@Override
public void onClick(View arg0) {
addImageView(inScrollView);
}});

}

private void addImageView(LinearLayout layout){
ImageView imageView = new ImageView(this);
imageView.setImageResource(R.drawable.ic_launcher);
layout.addView(imageView);
}

}


<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />

<Button
android:id="@+id/addinhorizontalscrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add in HorizontalScrollView"/>
<HorizontalScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/inhorizontalscrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal">
</LinearLayout>
</HorizontalScrollView>

<Button
android:id="@+id/addinscrollview"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Add in ScrollView"/>
<ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content">
<LinearLayout
android:id="@+id/inscrollview"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="vertical">
</LinearLayout>
</ScrollView>

</LinearLayout>


We can also remove the ImageViews using Java code, refer to next post, "Remove View dynamically using Java code".


Thứ Ba, 16 tháng 10, 2012

Get video width and height of MediaPlayer and update SurfaceView LayoutParams accordingly

Last article demonstrate how to Play Youtube 3gp video with MediaPlayer in SurfaceView. It can be noticed that the video is fill in parent view, because "fill_parent" are defined in layout.

To adjust the video fit the Youtube video width and height, we can implement our custom OnVideoSizeChangedListener(), and call myMediaPlayer.getVideoWidth() and myMediaPlayer.getVideoHeight() to get the video width and height. After then, update SurfaceView LayoutParams with correct size accordingly.

MediaPlay with true size

Modify the Java code:
package com.example.androidyoutubeplayer;

import java.io.IOException;

import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.MediaPlayer.OnVideoSizeChangedListener;
import android.os.Bundle;
import android.app.Activity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.TextView;

public class MainActivity extends Activity implements SurfaceHolder.Callback{

MediaPlayer myMediaPlayer;
SurfaceView mySurfaceView;
SurfaceHolder mySurfaceHolder;

Button btnPlay, btnStop;
TextView textVideoSize;
String path3gp = "rtsp://v8.cache6.c.youtube.com/CjYLENy73wIaLQkP0kiLmutogRMYDSANFEIJbXYtZ29vZ2xlSARSBXdhdGNoYKjR78WV1ZH5Tgw=/0/0/0/video.3gp";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getWindow().setFormat(PixelFormat.UNKNOWN);
mySurfaceView = (SurfaceView)findViewById(R.id.mediasurface);
mySurfaceHolder = mySurfaceView.getHolder();
mySurfaceHolder.addCallback(this);
myMediaPlayer = new MediaPlayer();

btnPlay = (Button)findViewById(R.id.play);
btnStop = (Button)findViewById(R.id.stop);

btnPlay.setOnClickListener(playOnClickListener);
btnStop.setOnClickListener(stopOnClickListener);

textVideoSize = (TextView)findViewById(R.id.size);

}

OnClickListener playOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
myMediaPlayer.reset();

myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
myMediaPlayer.setDisplay(mySurfaceHolder);

try {

myMediaPlayer.setOnVideoSizeChangedListener(videoSizeChangedListener);

myMediaPlayer.setDataSource(path3gp);
myMediaPlayer.prepare();

/*
* if you get Video Width and Height after prepare() here, it always return 0, 0!
*/
int videoWidth = myMediaPlayer.getVideoWidth();
int videoHeight = myMediaPlayer.getVideoHeight();
textVideoSize.setText(String.valueOf(videoWidth) + " x " + String.valueOf(videoHeight));

myMediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}};

OnClickListener stopOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
if(myMediaPlayer.isPlaying()){
myMediaPlayer.stop();
}

}};

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

/*
* Get Video Width and Height in OnVideoSizeChangedListener,
* and update SurfaceView LayoutParams accordingly.
*/
OnVideoSizeChangedListener videoSizeChangedListener
= new OnVideoSizeChangedListener(){

@Override
public void onVideoSizeChanged(MediaPlayer arg0, int arg1, int arg2) {
int videoWidth = myMediaPlayer.getVideoWidth();
int videoHeight = myMediaPlayer.getVideoHeight();

textVideoSize.setText(String.valueOf(videoWidth) + " x " + String.valueOf(videoHeight));

mySurfaceView.setLayoutParams(
new LinearLayout.LayoutParams(videoWidth, videoHeight));
}};
}


Modify the layout file to add TextView to show the detected size.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:id="@+id/play"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="PLAY"/>
<Button
android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="STOP"/>
<TextView
android:id="@+id/size"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<SurfaceView
android:id="@+id/mediasurface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>

</LinearLayout>


Modify AndroidManifest.xml to add permission of "android.permission.INTERNET".

Thứ Sáu, 12 tháng 10, 2012

Play Youtube 3gp video with MediaPlayer in SurfaceView

This example show how to play YouTube's 3gp video using MediaPlayer, in a SurfaceView.

Play Youtube 3gp video with MediaPlayer in SurfaceView


Modify layout file, /res/layout/activity_main.xml, to add two control buttons (play and stop), and a SurfaceView to hold the media window.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<Button
android:id="@+id/play"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="PLAY"/>
<Button
android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="STOP"/>
<SurfaceView
android:id="@+id/mediasurface"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>


</LinearLayout>


Modify MainActivity, extends Activity and implements SurfaceHolder.Callback. In the code, path3gp is the path to the Youtube's 3gp video.
package com.example.androidyoutubeplayer;

import java.io.IOException;

import android.graphics.PixelFormat;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.app.Activity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;

public class MainActivity extends Activity implements SurfaceHolder.Callback{

MediaPlayer myMediaPlayer;
SurfaceView mySurfaceView;
SurfaceHolder mySurfaceHolder;

Button btnPlay, btnStop;

String path3gp = "rtsp://v8.cache6.c.youtube.com/CjYLENy73wIaLQkP0kiLmutogRMYDSANFEIJbXYtZ29vZ2xlSARSBXdhdGNoYKjR78WV1ZH5Tgw=/0/0/0/video.3gp";

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

getWindow().setFormat(PixelFormat.UNKNOWN);
mySurfaceView = (SurfaceView)findViewById(R.id.mediasurface);
mySurfaceHolder = mySurfaceView.getHolder();
mySurfaceHolder.addCallback(this);
myMediaPlayer = new MediaPlayer();

btnPlay = (Button)findViewById(R.id.play);
btnStop = (Button)findViewById(R.id.stop);

btnPlay.setOnClickListener(playOnClickListener);
btnStop.setOnClickListener(stopOnClickListener);

}

OnClickListener playOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
myMediaPlayer.reset();

myMediaPlayer.setAudioStreamType(AudioManager.STREAM_MUSIC);
myMediaPlayer.setDisplay(mySurfaceHolder);

try {
myMediaPlayer.setDataSource(path3gp);
myMediaPlayer.prepare();

myMediaPlayer.start();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalStateException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}

}};

OnClickListener stopOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
if(myMediaPlayer.isPlaying()){
myMediaPlayer.stop();
}

}};

@Override
public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {
// TODO Auto-generated method stub

}

@Override
public void surfaceCreated(SurfaceHolder holder) {
// TODO Auto-generated method stub

}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub

}
}


Modify AndroidManifest.xml to add permission of "android.permission.INTERNET".


Related article: Get video width and height of MediaPlayer and update SurfaceView LayoutParams accordingly.

Chủ Nhật, 7 tháng 10, 2012

My traffic drop on Oct !!!

My web site traffic suddenly dropped in Oct, what's wrong!?

My traffic drop on Oct !!!



Play RTTTL (Ring Tone Text Transfer Language) with MediaPlayer

Android platform support various media formats, include mRTTTL (Ring Tone Text Transfer Language).

Ring Tone Text Transfer Language (RTTTL) was developed by Nokia to be used to transfer ringtones to cellphone by Nokia. (source: Wikipedia - Ring Tone Transfer Language).

We are going to play the RTTTL ringtone of "Haunted House" listed in the Wikipedia article as an example.

Play RTTTL (Ring Tone Text Transfer Language) with MediaPlayer

Create /res/raw/hauntedhouse.rtttl file to define ring tone of "Haunted House".
HauntedHouse: d=4,o=5,b=108: 2a4, 2e, 2d#, 2b4, 2a4, 2c, 2d, 2a#4, 2e., e, 1f4, 1a4, 1d#, 2e., d, 2c., b4, 1a4, 1p, 2a4, 2e, 2d#, 2b4, 2a4, 2c, 2d, 2a#4, 2e., e, 1f4, 1a4, 1d#, 2e., d, 2c., b4, 1a4


Modify layout to have buttons to start and stop the ring tone.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical" >

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello_world"
tools:context=".MainActivity" />
<Button
android:id="@+id/start"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Start" />
<Button
android:id="@+id/stop"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Stop" />

</LinearLayout>


The Java code of the activity.
package com.example.androidrtttl;

import android.media.MediaPlayer;
import android.media.MediaPlayer.OnCompletionListener;
import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.Toast;

public class MainActivity extends Activity {

Button buttonStart, buttonStop;
MediaPlayer mediaPlayer;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
buttonStart = (Button)findViewById(R.id.start);
buttonStart.setOnClickListener(buttonStartOnClickListener);
buttonStop = (Button)findViewById(R.id.stop);
buttonStop.setOnClickListener(buttonStopOnClickListener);

}

OnClickListener buttonStartOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
if (mediaPlayer != null){
mediaPlayer.release();
}

mediaPlayer = MediaPlayer.create(getApplicationContext(), R.raw.hauntedhouse);
mediaPlayer.setOnCompletionListener(mediaplayerCompletionListener);
mediaPlayer.start();
}

};

OnClickListener buttonStopOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {
if (mediaPlayer != null){
mediaPlayer.stop();
mediaPlayer.release();
}

}};

OnCompletionListener mediaplayerCompletionListener
= new OnCompletionListener(){

@Override
public void onCompletion(MediaPlayer arg0) {

mediaPlayer.release();

Toast.makeText(getApplicationContext(),
"onCompletion",
Toast.LENGTH_LONG).show();
}};

}


Thứ Sáu, 5 tháng 10, 2012

Save and Restore Instance State

The methods onSaveInstanceState(Bundle outState) and onRestoreInstanceState(Bundle savedInstanceState) are the good place to Save and Restore Instance State.
  • onSaveInstanceState (Bundle outState)

    Called to retrieve per-instance state from an activity before being killed so that the state can be restored in onCreate(Bundle) or onRestoreInstanceState(Bundle) (the Bundle populated by this method will be passed to both).

    This method is called before an activity may be killed so that when it comes back some time in the future it can restore its state. For example, if activity B is launched in front of activity A, and at some point activity A is killed to reclaim resources, activity A will have a chance to save the current state of its user interface via this method so that when the user returns to activity A, the state of the user interface can be restored via onCreate(Bundle) or onRestoreInstanceState(Bundle).

    Do not confuse this method with activity lifecycle callbacks such as onPause(), which is always called when an activity is being placed in the background or on its way to destruction, or onStop() which is called before destruction. One example of when onPause() and onStop() is called and not this method is when a user navigates back from activity B to activity A: there is no need to call onSaveInstanceState(Bundle) on B because that particular instance will never be restored, so the system avoids calling it. An example when onPause() is called and not onSaveInstanceState(Bundle) is when activity B is launched in front of activity A: the system may avoid calling onSaveInstanceState(Bundle) on activity A if it isn't killed during the lifetime of B since the state of the user interface of A will stay intact.

    The default implementation takes care of most of the UI per-instance state for you by calling onSaveInstanceState() on each view in the hierarchy that has an id, and by saving the id of the currently focused view (all of which is restored by the default implementation of onRestoreInstanceState(Bundle)). If you override this method to save additional information not captured by each individual view, you will likely want to call through to the default implementation, otherwise be prepared to save all of the state of each view yourself.

    If called, this method will occur before onStop(). There are no guarantees about whether it will occur before or after onPause().
  • onRestoreInstanceState (Bundle savedInstanceState)

    This method is called after onStart() when the activity is being re-initialized from a previously saved state, given here in savedInstanceState. Most implementations will simply use onCreate(Bundle) to restore their state, but it is sometimes convenient to do it here after all of the initialization has been done or to allow subclasses to decide whether to use your default implementation. The default implementation of this method performs a restore of any view state that had previously been frozen by onSaveInstanceState(Bundle).

    This method is called between onStart() and onPostCreate(Bundle).
Example:
package com.example.androidsavestate;

import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity {
 
 TextView textviewSavedState;
 EditText edittextEditState;

    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        textviewSavedState = (TextView)findViewById(R.id.savedstate);
     edittextEditState = (EditText)findViewById(R.id.editstate);
    }

 @Override
 protected void onRestoreInstanceState(Bundle savedInstanceState) {
  // TODO Auto-generated method stub
  super.onRestoreInstanceState(savedInstanceState);
  
  String stateSaved = savedInstanceState.getString("saved_state");
  
  if(stateSaved == null){
   Toast.makeText(MainActivity.this, 
     "onRestoreInstanceState:\n" +
     "NO state saved!", 
     Toast.LENGTH_LONG).show();
  }else{
   Toast.makeText(MainActivity.this, 
     "onRestoreInstanceState:\n" +
     "saved state = " + stateSaved, 
     Toast.LENGTH_LONG).show();
   textviewSavedState.setText(stateSaved);
   edittextEditState.setText(stateSaved);
  }

 }

 @Override
 protected void onSaveInstanceState(Bundle outState) {
  // TODO Auto-generated method stub
  super.onSaveInstanceState(outState);
  
  String stateToSave = edittextEditState.getText().toString();
  outState.putString("saved_state", stateToSave);
  
  Toast.makeText(MainActivity.this, 
    "onSaveInstanceState:\n" +
    "saved_state = " + stateToSave, 
    Toast.LENGTH_LONG).show();
 }

}


Save and Restore Instance State

Thứ Năm, 4 tháng 10, 2012

Create scaled bitmap using Bitmap.createScaledBitmap() method

To create a scaled bitmap from a source bitmap, we can call the static method Bitmap.createScaledBitmap().
  • public static Bitmap createScaledBitmap (Bitmap src, int dstWidth, int dstHeight, boolean filter)
    Creates a new bitmap, scaled from an existing bitmap, when possible. If the specified width and height are the same as the current width and height of the source btimap, the source bitmap is returned and now new bitmap is created.

    src: The source bitmap.
    dstWidth: The new bitmap's desired width.
    dstHeight: The new bitmap's desired height.
    filter: true if the source should be filtered.

    Returns: The new scaled bitmap or the source bitmap if no scaling is required.

Example to create scaled bitmap with 1/2 width and height:
   Bitmap scaledBitmap =  Bitmap.createScaledBitmap(
srcBitmap,
srcBitmap.getWidth()/2,
srcBitmap.getHeight()/2,
false);


Thứ Bảy, 22 tháng 9, 2012

Get color-int from alpha, red, green, blue components

Android system's android.graphics.Color class provide methods for creating and converting color ints.


Thứ Năm, 20 tháng 9, 2012

Create Spinner from String array

To create Spinner from String array:

Create Spinner from String array


package com.example.androidspinner;

import android.os.Bundle;
import android.app.Activity;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemSelectedListener;
import android.widget.ArrayAdapter;
import android.widget.Spinner;
import android.widget.Toast;

public class MainActivity extends Activity {

Spinner mySpinner;

String[] spinnerArray ={ "One", "Two", "Three", "Four", "Five"};

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

mySpinner = (Spinner)findViewById(R.id.myspinner);

ArrayAdapter<String> myArrayAdapter = new ArrayAdapter<String>(
this,
android.R.layout.simple_spinner_item,
spinnerArray);
myArrayAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item );

mySpinner.setAdapter(myArrayAdapter);

mySpinner.setOnItemSelectedListener(myOnItemSelectedListener);
}

OnItemSelectedListener myOnItemSelectedListener
= new OnItemSelectedListener(){

@Override
public void onItemSelected(AdapterView<?> parent, View view, int position,
long id) {
String selectedItem = (String) parent.getItemAtPosition(position);
Toast.makeText(
getApplicationContext(),
selectedItem,
Toast.LENGTH_LONG)
.show();

}

@Override
public void onNothingSelected(AdapterView<?> arg0) {
// TODO Auto-generated method stub

}};

}


Thứ Hai, 10 tháng 9, 2012

Home Screen Widget step-by-step - Implement OnClick PendingIntent for Widget

It's part of the Home Screen Widgets step-by-step series.

We can cureat PendingIntent, and register it to widget's RemoteViews by setOnClickPendingIntent() method. As a result, when user click on the assigned view in the widgets, the PendingIntent will be trigged and to do something.

In the example, my blog (http://android-coding.blogspot.com/) will be opened once user click on the ID in widgets.

Implement OnClick PendingIntent for Widget


Modify configure activity (ConfigureWidgetActivity.java) and App Widget Provider (WidgetProvider.java) to Prepare PendingIntent for remoteViews OnClickListener.

ConfigureWidgetActivity.java
package com.example.androidhomewidget;

import android.app.Activity;
import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.TextView;

public class ConfigureWidgetActivity extends Activity {

int appWidgetId;
Button configureOkButton;
TextView wId;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.configure_layout);
wId = (TextView)findViewById(R.id.wid);
configureOkButton = (Button)findViewById(R.id.confighreok);
configureOkButton.setOnClickListener(configureOkButtonOnClickListener);

Intent intent = getIntent();
Bundle extras = intent.getExtras();

if (extras != null) {
appWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);

wId.setText("appWidgetId = " + appWidgetId);

}else{
finish();
}

}

OnClickListener configureOkButtonOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());

RemoteViews remoteViews = new RemoteViews(
getApplicationContext().getPackageName(),
R.layout.widget_layout);

remoteViews.setTextViewText(R.id.widget_id, String.valueOf(appWidgetId));
remoteViews.setTextViewText(R.id.widget_status, "Waiting...");

//--- Prepare PendingIntent for remoteViews OnClickListener
String myBlog = "http://android-coding.blogspot.com/";
Uri Uri_myBlog = Uri.parse(myBlog);
Intent clickIntent = new Intent(Intent.ACTION_VIEW, Uri_myBlog);

int pendingRequestCode = 0;
int pendingFlag = 0;
PendingIntent pendingIntent
= PendingIntent.getActivity(
getApplicationContext(),
pendingRequestCode,
clickIntent,
pendingFlag);
remoteViews.setOnClickPendingIntent(R.id.widget_id, pendingIntent);
//--- End of Prepare PendingIntent

appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

Intent intent = new Intent();
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, intent);
finish();

}};

}


WidgetProvider.java
package com.example.androidhomewidget;

import java.text.SimpleDateFormat;
import java.util.Date;

import android.app.PendingIntent;
import android.appwidget.AppWidgetManager;
import android.appwidget.AppWidgetProvider;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.widget.RemoteViews;
import android.widget.Toast;

public class WidgetProvider extends AppWidgetProvider {

@Override
public void onDeleted(Context context, int[] appWidgetIds) {
// TODO Auto-generated method stub
super.onDeleted(context, appWidgetIds);
}

@Override
public void onDisabled(Context context) {
// TODO Auto-generated method stub
super.onDisabled(context);
}

@Override
public void onEnabled(Context context) {
// TODO Auto-generated method stub
super.onEnabled(context);
}

@Override
public void onReceive(Context context, Intent intent) {
// TODO Auto-generated method stub
super.onReceive(context, intent);
}

@Override
public void onUpdate(Context context, AppWidgetManager appWidgetManager,
int[] appWidgetIds) {

for(int i = 0; i < appWidgetIds.length; i++){

int id = appWidgetIds[i];

Toast.makeText(context,
"onUpdate: " + String.valueOf(id),
Toast.LENGTH_LONG).show();

RemoteViews remoteViews = new RemoteViews(context.getPackageName(), R.layout.widget_layout);

remoteViews.setTextViewText(R.id.widget_id, String.valueOf(id));

SimpleDateFormat simpleDateFormat = new SimpleDateFormat("hh:mm:ss");
String now = simpleDateFormat.format(new Date());
remoteViews.setTextViewText(R.id.widget_status, now);

//--- Prepare PendingIntent for remoteViews OnClickListener
String myBlog = "http://android-coding.blogspot.com/";
Uri Uri_myBlog = Uri.parse(myBlog);
Intent clickIntent = new Intent(Intent.ACTION_VIEW, Uri_myBlog);

int pendingRequestCode = 0;
int pendingFlag = 0;
PendingIntent pendingIntent
= PendingIntent.getActivity(
context,
pendingRequestCode,
clickIntent,
pendingFlag);
remoteViews.setOnClickPendingIntent(R.id.widget_id, pendingIntent);
//--- End of Prepare PendingIntent

appWidgetManager.updateAppWidget(id, remoteViews);

super.onUpdate(context, appWidgetManager, appWidgetIds);
}
}

}



Chủ Nhật, 9 tháng 9, 2012

Home Screen Widget step-by-step - custom background shape of Widget

It's part of the Home Screen Widgets step-by-step series.

To custom background shape of Home Screen Widget, we can create custom background shape XML file, then apply it to the widget layout. (Actually it's same as define custom background in normal layouts.)

custom background shape of Widget


Create /res/drawable/round_rect.xml to define custom background shape.
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<stroke
android:width="5dp"
android:color="#000000"/>
<padding
android:left="5dp"
android:top="5dp"
android:right="5dp"
android:bottom="5dp"/>
<corners
android:radius="10dp"/>
</shape>


Modify the widget layout, /res/layout/widget_layout.xml, to apply android:background="@drawable/round_rect".
<?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:background="@drawable/round_rect">
<TextView
android:id="@+id/widget_id"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:background="#F06030"
android:textColor="#101010"
android:textSize="30sp"
android:text="id"/>
<TextView
android:id="@+id/widget_status"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:background="@android:color/background_dark"
android:textColor="@android:color/white"
android:textSize="30sp"
android:text="status"/>
</LinearLayout>



Thứ Ba, 4 tháng 9, 2012

Home Screen Widget step-by-step - resizeable home screen widget

It's part of the Home Screen Widgets step-by-step series.

Start from Android 3.1, API Level 12, support resizeable home screen widget. To specify a Home Screen Widget as resizeable, include android:resizeMode in App widget provider XML, /res/xml/widgetproviderinfo.xml in our example.

<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:minHeight="72dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/widget_layout"
android:configure="com.example.androidhomewidget.ConfigureWidgetActivity"
android:resizeMode="horizontal|vertical">
</appwidget-provider>


Resizeable Home Screen Widget


To resize the widget, touch-hold it to show its resize handles, then drag the horizontal and/or vertical handles to change the size on the layout grid.


Thứ Hai, 3 tháng 9, 2012

Home Screen Widget step-by-step - implement configure activity

It's part of the Home Screen Widgets step-by-step series.

In the previous articles, we have NO android:configure defined in our App widget provider XML, /res/xml/widgetproviderinfo.xml. So, the App Widget Provider will be called when user add our widget. Optionally we can implement our Configure Activity, it will be called at the first time user add the Widget, instead of App Widget Provider. Such that user can do something when he add the widget.

Configure Activity



Modify /res/xml/widgetproviderinfo.xml to add android:configure="com.example.androidhomewidget.ConfigureWidgetActivity".
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="146dp"
android:minHeight="72dp"
android:updatePeriodMillis="1800000"
android:initialLayout="@layout/widget_layout"
android:configure="com.example.androidhomewidget.ConfigureWidgetActivity">
</appwidget-provider>


ConfigureWidgetActivity.java
package com.example.androidhomewidget;

import android.app.Activity;
import android.appwidget.AppWidgetManager;
import android.content.Intent;
import android.os.Bundle;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.RemoteViews;
import android.widget.TextView;

public class ConfigureWidgetActivity extends Activity {

int appWidgetId;
Button configureOkButton;
TextView wId;

@Override
protected void onCreate(Bundle savedInstanceState) {
// TODO Auto-generated method stub
super.onCreate(savedInstanceState);
setContentView(R.layout.configure_layout);
wId = (TextView)findViewById(R.id.wid);
configureOkButton = (Button)findViewById(R.id.confighreok);
configureOkButton.setOnClickListener(configureOkButtonOnClickListener);

Intent intent = getIntent();
Bundle extras = intent.getExtras();

if (extras != null) {
appWidgetId = extras.getInt(
AppWidgetManager.EXTRA_APPWIDGET_ID,
AppWidgetManager.INVALID_APPWIDGET_ID);

wId.setText("appWidgetId = " + appWidgetId);

}else{
finish();
}

}

OnClickListener configureOkButtonOnClickListener
= new OnClickListener(){

@Override
public void onClick(View v) {

AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(getApplicationContext());

RemoteViews remoteViews = new RemoteViews(
getApplicationContext().getPackageName(),
R.layout.widget_layout);

remoteViews.setTextViewText(R.id.widget_id, String.valueOf(appWidgetId));
remoteViews.setTextViewText(R.id.widget_status, "Waiting...");

appWidgetManager.updateAppWidget(appWidgetId, remoteViews);

Intent intent = new Intent();
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
setResult(RESULT_OK, intent);
finish();

}};

}


Create /res/layout/configure_layout.xml to define the layout of the configure activity.
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">

<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Widget Configure Activity" />
<TextView
android:id="@+id/wid"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
<Button
android:id="@+id/confighreok"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="OK" />

</LinearLayout>


Modify AndroidManifest.xml to add <activity> of ConfigureWidgetActivity.java.
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.androidhomewidget"
android:versionCode="1"
android:versionName="1.0" >

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

<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MainActivity"
android:label="@string/title_activity_main" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />

<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

<!-- define Widget Provider Receiver -->
<receiver android:name=".WidgetProvider" >
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_UPDATE" />
</intent-filter>
<meta-data android:name="android.appwidget.provider"
android:resource="@xml/widgetproviderinfo" />
</receiver>

<!-- define Configure Activity -->
<activity android:name=".ConfigureWidgetActivity">
<intent-filter>
<action android:name="android.appwidget.action.APPWIDGET_CONFIGURE" />
</intent-filter>
</activity>

</application>

</manifest>