Transcript Document
Chapter 10
Multimedia Application Development
本投影片(下稱教用資源)僅授權給採用教用資源相關之旗標書籍為教科書之授課老師(下稱老師)專用,老師為教學使用之目的,得摘錄、編輯、重製教用資
源(但使用量不得超過各該教用資源內容之80%)以製作為輔助教學之教學投影片,並於授課時搭配旗標書籍公開播放,但不得為網際網路公開傳輸之遠距教學、
網路教學等之使用;除此之外,老師不得再授權予任何第三人使用,並不得將依此授權所製作之教學投影片之相關著作物移作他用。
著作權所有 © 旗標出版股份有限公司
Widget
Introduction on Widget
Android.widget includes many visual UI
elements and can apply operation interface in
application display
To get acquainted with Android multi-media
application development, we have to start from
widget. So examples in the chapters all focus
on application of android.widget
Introduction on Gallery
Gallery是一個水平的清單,移動清單時,會
將選擇項目放大顯示於中央,範例如圖所示。
About Gallery
Gallery includes some XML attributes and
methods as shown below:
XML Attribute
Methods
Description
android:animationDuration setAnimationDuration(int)
設定當佈局發生改變時,
動畫應多久才會運行(毫秒)
android:gravity
setGravity(int)
設定物件的擺放位置
android:spacing
setSpacing(int)
android:unselectedAlpha
setUnselectedAlpha(float)
設定項目未被選擇時的透明度
Gallery Layout.xml
Layout.xml (res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent">
<ImageSwitcher android:id="@+id/switcher"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<Gallery android:id="@+id/gallery"
android:background="#55000000"
android:layout_width="fill_parent"
android:layout_height="60dp"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:gravity="center_vertical"
android:spacing="16dp"
/>
</RelativeLayout>
Gallery Codes-1
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
mSwitcher = (ImageSwitcher) findViewById(R.id.switcher);
/* 設定ImageSwitcher的Factory進行資源配置 */
mSwitcher.setFactory(this);
/* 設定ImageSwitcher動畫 */
mSwitcher.setInAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_in));
mSwitcher.setOutAnimation(AnimationUtils.loadAnimation(this,
android.R.anim.fade_out));
/* 初始化Gallery */
Gallery g = (Gallery) findViewById(R.id.gallery);
/* 設定Adapter */
g.setAdapter(new ImageAdapter(this));
/* 設定項目選擇監聽器 */
g.setOnItemSelectedListener(this);
}
Gallery Codes-2
public View makeView()
{
ImageView i = new ImageView(this);
/* 設定ImageView屬性 */
i.setBackgroundColor(0xFF000000);
i.setScaleType(ImageView.ScaleType.FIT_CENTER);
i.setLayoutParams(new
ImageSwitcher.LayoutParams(LayoutParams.FILL_PARENT,
LayoutParams.FILL_PARENT));
return i;
}
/* 當項目被選擇到時發生 */
@SuppressWarnings("unchecked")
public void onItemSelected(AdapterView parent, View v, int position, long id)
{
/* 為ImageSwitcher設定圖檔資源 */
mSwitcher.setImageResource(mImageIds[position]);
}
Gallery Codes-3
public View getView(int position, View convertView, ViewGroup parent)
{
ImageView i = new ImageView(mContext);
/* 設定ImageView屬性 */
i.setImageResource(mThumbIds[position]);
i.setAdjustViewBounds(true);
i.setLayoutParams(new Gallery.LayoutParams(
LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT));
return i;
}
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of GalleryEX.java
AnalogClock
AnalogClock is an analog clock component with hour
hand and minute hand .It is shown below:
AnalogClock
Layout.xml (res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<AnalogClock
android:id="@+id/AnalogClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>
</RelativeLayout>
DigitalClock
It is similar to AnalogClock, but it adopts digital
time display (which shows hour/minute/second). It
is shown below:
DigitalClock
Layout.xml (res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android">
<AnalogClock
android:id="@+id/AnalogClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_alignParentTop="true"
/>
<DigitalClock
android:id="@+id/DigitalClock"
android:text="DigitalClock"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:layout_below="@id/AnalogClock"
/>
</RelativeLayout>
Multimedia Application Development
Multimedia Application Development
Android對於多媒體的支援性非常強大,在
SDK中的android.media提供了許多媒體相關
類別可使用,像是一般播放音樂、影片及錄
音…等等功能都可藉由SDK達成,也可自行
搭配元件開發。
其中Android所支援的音訊、圖像、視訊格
式可由下頁圖得知。
Multimedia Application Development
Android Support Formats
AudioManager
在手機應用程式當中,有時候會需要調整手
機音量或轉換手機聲音模式。
如果要開發一個具有音量調整功能的程式,
Android API中的AudioManager提供了許多
相關的方法,可在程式中控制音量大小、切
換聲音模式,範例如下圖所示。
AudioManager
Diagram of the Example :
AudioManager Layout.xml
Layout.xml-1:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/widget33"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
xmlns:android="http://schemas.android.com/apk/res/android"
>
<ImageButton
android:id="@+id/btnDown"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/down"
android:layout_alignLeft="@+id/up"
android:layout_centerHorizontal="true"
/>
<ImageButton
android:id="@+id/btnUp"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/up"
android:layout_toLeftOf="@+id/btnDown"
/>
<ImageButton
android:id="@+id/btnMute"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/mute"
android:layout_alignRight="@+id/btnDown"
android:layout_below="@+id/btnDown"
/>
Layout.xml-2:
<ImageButton
android:id="@+id/btnVibrate"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/vibrate"
android:layout_toRightOf="@+id/btnMute"
android:layout_alignTop="@+id/btnMute"
/>
<ImageButton
android:id="@+id/btnNormal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/normal"
android:layout_alignRight="@+id/btnUp"
android:layout_below="@+id/btnUp"
/>
<ImageView
android:id="@+id/imageStatus"
android:src="@drawable/normal"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="135sp"
android:layout_marginLeft="140sp"
/>
AudioManager Layout.xml
Layout.xml-3:
<TextView
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/barInfo"
android:layout_alignBottom="@+id/ProgressBar"
android:text="音量大小"/>
<TextView
android:layout_above="@+id/barInfo"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:id="@+id/modeInfo"
android:layout_alignBottom="@+id/imageStatus"
android:text="聲音模式"/>
<ProgressBar
android:id="@+id/ProgressBar"
android:layout_width="200px"
android:layout_height="wrap_content"
android:layout_marginTop="200sp"
android:layout_marginLeft="140sp"
style="?android:attr/progressBarStyleHorizontal"
/>
</RelativeLayout>
AudioManager Codes
Codes-1(AudioManagerEX.java):
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* 初始化元件 */
audioManager = (AudioManager)
getSystemService(Context.AUDIO_SERVICE);
btnUp = (ImageButton)findViewById(R.id.btnUp);
btnDown = (ImageButton)findViewById(R.id.btnDown);
btnNormal = (ImageButton)findViewById(R.id.btnNormal);
btnMute = (ImageButton)findViewById(R.id.btnMute);
btnVibrate = (ImageButton)findViewById(R.id.btnVibrate);
volumeBar = (ProgressBar)findViewById(R.id.ProgressBar);
imageStatus = (ImageView)findViewById(R.id.imageStatus);
/* 取得目前手機音量 */
volume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
/* 設定音量條 */
volumeBar.setMax(8);
volumeBar.setProgress(volume);
AudioManager Codes
Codes-2(AudioManagerEX.java) :
/* 透過AudioManager取得目前響鈴模式並進行比對,此處為比對一般模式 */
if( ( mode = audioManager.getRingerMode() ) ==
AudioManager.RINGER_MODE_NORMAL )
{
/* 設定目前手機模式的圖示為響鈴 */
imageStatus.setImageDrawable( getResources().getDrawable(R.drawable.normal) );
}
/* 此處為比對靜音模式 */
else if ( mode == AudioManager.RINGER_MODE_SILENT)
{
/* 設定目前手機模式的圖示為靜音 */
imageStatus.setImageDrawable( getResources().getDrawable(R.drawable.mute) );
}
/* 此處為比對震動模式 */
else if ( mode == AudioManager.RINGER_MODE_VIBRATE)
{
/* 設定目前手機模式的圖示為震動 */
imageStatus.setImageDrawable( getResources().getDrawable(R.drawable.vibrate) );
}
AudioManager Codes
Codes-3(AudioManagerEX.java) :
/* 透過AudioManager.ADJUST_RAISE調大音量 */
audioManager.adjustVolume(AudioManager.ADJUST_RAISE, 0);
volume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
volumeBar.setProgress(volume);
/* 透過AudioManager.ADJUST_LOWER調小音量 */
audioManager.adjustVolume(AudioManager.ADJUST_LOWER, 0);
volume = audioManager.getStreamVolume(AudioManager.STREAM_RING);
volumeBar.setProgress(volume);
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of AudioManagerEX.java
AudioManager
Some constants of AudioManager can be found in
Android SDK. Here we only list the important
constants: AudioManager常數
ADJUST_LOWER
降低響鈴音量
ADJUST_RAISE
增加響鈴音量
ADJUST_SAME
維持目前音量
MODE_CURRENT
目前聲音模式
MODE_IN_CALL
通話中聲音模式
MODE_NORMAL
一般的聲音模式(無響鈴且無通話進來)
MODE_RINGTONE
響鈴聲音模式
STREAM_ALARM
鬧鐘聲音串流
STREAM_MUSIC
音樂播放串流
STREAM_NOTIFICATION
通知音效串流
STREAM_RING
響鈴串流
STREAM_SYSTEM
系統音效串流
STREAM_VOICE_CALL
通話聲音串流
VIBRATE_SETTING_OFF
震動模式關閉
VIBRATE_SETTING_ON
震動模式開啟
MediaRecorder
MediaRecorder原先只支援音訊錄製,不過
在Android 1.5版本以後開始支援視訊錄製功
能,透過MediaRecorder類別的方法可以錄
製視訊並儲存為MPEG4、H.263和H.264編
碼的視訊。
MediaRecorder運作狀態、範例程式如下頁
圖所示:
MediaRecorder
Operation State Chart Diagram:
Diagram of the Example :
MediaRecorder
Layout.xml (res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/white"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<ImageButton
android:id="@+id/btnRecord"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/record"
android:layout_below="@+id/mTextView"
/>
<ImageButton
android:id="@+id/btnStop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/stop"
android:layout_alignTop="@+id/btnRecord"
android:layout_toRightOf="@+id/btnRecord"
/>
<ImageButton
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play"
android:layout_alignTop="@+id/btnRecord"
android:layout_toRightOf="@+id/btnStop"
/>
</RelativeLayout>
MediaRecorder
Codes (MediaRecorder.java):
/* 監聽錄音按鈕 */
btnRecord.setOnClickListener(new View.OnClickListener()
{
public void onClick(View arg0)
{
try
{
/* 檢查目前是否還有錄音資源 */
if (recorder == null)
recorder = new MediaRecorder();
/* 設置輸入為麥克風 */
recorder.setAudioSource(MediaRecorder.AudioSource.MIC);
/* 設置輸出的格式為3gp文件 */
/* 音效編碼採用AMR */
recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
/* 暫存文件路徑,檔名為當前系統時間 */
path = "/sdcard/" + System.currentTimeMillis() + ".3ga";
/* 設定輸出路徑 */
recorder.setOutputFile(path);
/* 準備緩衝 */
recorder.prepare();
/* 開始錄音 */
recorder.start();
/* 將狀態設置為正在錄音 */
state = RECORDING;
handler.sendEmptyMessage(UPDATE);
recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP);
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of MediaRecorderEX.java
AudioTrack
AudioTrack負責為Java應用程式管理與播放
聲音資源,雖然MediaPlayer也可播放聲音,
但AudioTrack可以設置的屬性更多,播放起
來也較好操作。
它運作有兩種模式:static與streaming
– static通常用於處理時間較短且延遲需求高的聲
音。
– straming則用於播放品質較好、檔案較大或需要
緩衝的聲音。程式範例如下頁圖所示。
AudioTrack
Diagram of the Example:
AudioTrack
Layout.xml (res/layout/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:id="@+id/textView"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
/>
<Button
android:id="@+id/btnLeft"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="left"
/>
<Button
android:id="@+id/btnRight"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="right"
/>
</LinearLayout>
AudioTrack
Codes (AudioTrackEX.java):
private void playSound(String strPath, int iChannel)
{
/* 檢查是否有AudioTrack物件未釋放 */
if ( audioTrack != null )
{
/* 釋放資源 */
audioTrack.release();
audioTrack = null;
}
/* 設定Buffer */
int iMinBufSize = AudioTrack.getMinBufferSize(44100,
AudioFormat.CHANNEL_CONFIGURATION_STEREO,
AudioFormat.ENCODING_PCM_16BIT);
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of AudioTrackEX.java
MediaPlayer
MediaPlayer can be used to display
sound/video. The following shows the shift of
the display mode and the example
MediaPlayer
Layout.xml(res/layout/main.xml):
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:background="@drawable/white"
xmlns:android="http://schemas.android.com/apk/res/android">
<TextView
android:id="@+id/mTextView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/hello"
android:layout_alignParentTop="true"
android:layout_alignParentLeft="true"
/>
<ImageButton
android:id="@+id/btnPlay"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/play"
android:layout_below="@+id/mTextView"
/>
<ImageButton
android:id="@+id/btnPause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/pause"
android:layout_alignTop="@+id/btnPlay"
android:layout_toRightOf="@+id/btnPlay"
/>
……
MediaPlayer
Codes (MediaPlayerEX.java):
/* 建立MediaPlayer物件,使用raw中的sample.mp3資源檔案 */
player = MediaPlayer.create(this,R.raw.sample);
/* 監聽播放音樂按鈕 */
btnPlay.setOnClickListener(new ImageButton.OnClickListener()
{
@Override
public void onClick(View v)
{
try
{
/* 檢查是否存在MediaPlayer物件 */
if(player != null)
{
/* 停止播放 */
player.stop();
}
player.prepare();
/* 開始播放 */
player.start();
text.setText("音樂播放中...");
}
catch (Exception e)
{
text.setText("播放發生異常...");
e.printStackTrace();
}
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of MediaPlayer.java
}
});
MediaPlayer
如果想播放記憶卡中的音樂或利用URL下載
音樂來播放可使用下列方法,主要是透過
MediaPlayer.setDataSource() 方法,將URL或
檔案路徑以字串方式傳入。
MediaPlayer player = new MediaPlayer();
player.setDataSource(URL/檔案路徑);
player.prepare();
player.start();
VideoView
另外如果要播放影片的話,則使用Android
內建之VideoView來播放影片,需先準備格
式為*.3gp格式的影片,並將影片置於sdcard
中,指令如圖所示。需要注意的是在模擬器
上是無法正常播放的,模擬器在模擬一些視
音訊方面還是會有一些問題,故範例需於執
行於Hero實機上。
VideoView
Diagram of the the Example:
VideoView
Layout.xml (res/layout/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"
>
<VideoView
android:id="@+id/videoView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</LinearLayout>
VideoView
Codes (VideoViewEX.java):
public class MediaPlayerEX2 extends Activity
{
private VideoView videoView;
private String path;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
/* 初始化VideoView */
videoView = (VideoView) findViewById(R.id.videoView);
/* 設定VideoView屬性*/
path = "/sdcard/oldhouse.3gp";
videoView.setVideoPath(path);
videoView.setMediaController(new MediaController(this));
videoView.requestFocus();
}
}
RingtoneManager
RingtoneManager提供存取鈴聲、通知或其
他類型的音效。
Android預設系統鈴聲儲存於
【/system/media/audio/ringtones/】。
如不使用預設的位置,則可將檔案置於
【/sdcard/music/】中,還可進一步分類為三
種不同用途的資料夾。
RingtoneManager
此後便可透過RingtoneManager,在設定鈴
聲時,以intent.putExtra產生不同的鈴聲選單,
範例如圖所示。
RingtoneManager
Layout.xml (res/layout/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"
>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/Ringtone"
android:text="選擇鈴聲"
/>
</LinearLayout>
RingtoneManager
Codes (RingtoneManagerEX.java):
/* 設定選擇鈴聲Intent */
Intent intent = new Intent(RingtoneManager.ACTION_RINGTONE_PICKER);
/* Intent屬性設定 */
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TYPE, RingtoneManager.TYPE_RINGTONE);
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_TITLE, "設定鈴聲");
if( strPath != null)
{
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, Uri.parse(strPath));
}
else
{
intent.putExtra(RingtoneManager.EXTRA_RINGTONE_EXISTING_URI, (Uri)null);
}
/* 開啟一個活動並等待回傳值 */
startActivityForResult(intent, RINGTONE_PICKED);
Owing to the codes are numerous, please
refer to the reference disc to find the
complete codes of RingtoneManager.java
Q&A