450 likes | 728 Views
Chapter 10. 多媒體程式開發. Widget. Widget 簡介. android.widget 套件包含了許多視覺性的 UI 元素,可用來將操作界面展示在應用程式畫面上。 要熟悉 Android 多媒體程式的開發,必須從 widget 套件著手,因此本章所舉的範例,便是以 android.widget 套件的應用為中心。. Gallery 簡介. Gallery 是一個水平的清單,移動清單時,會將選擇項目放大顯示於中央,範例如圖所示。. Gallery 相關. Gallery 包含了一些 XML 屬性及方法,如下表所示:. Gallery 布局文件.
E N D
Chapter 10 多媒體程式開發
Widget簡介 android.widget套件包含了許多視覺性的UI元素,可用來將操作界面展示在應用程式畫面上。 要熟悉Android多媒體程式的開發,必須從widget套件著手,因此本章所舉的範例,便是以android.widget套件的應用為中心。
Gallery簡介 Gallery是一個水平的清單,移動清單時,會將選擇項目放大顯示於中央,範例如圖所示。
Gallery相關 Gallery包含了一些XML屬性及方法,如下表所示:
Gallery布局文件 布局文件(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程式碼-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程式碼-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程式碼-3 由於程式碼過多,完整程式碼請參考光碟中GalleryEX.java 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; }
AnalogClock AnalogClock是一個類比時鐘元件,具有時針與分針。範例如圖所示。
AnalogClock 布局文件(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 與AnalogClock類似,但是以數位的方式呈現,有時/分/秒,範例如下圖所示。
DigitalClock 布局文件(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>
多媒體開發 Android對於多媒體的支援性非常強大,在SDK中的android.media提供了許多媒體相關類別可使用,像是一般播放音樂、影片及錄音…等等功能都可藉由SDK達成,也可自行搭配元件開發。 其中Android所支援的音訊、圖像、視訊格式可由下頁圖得知。
多媒體開發 Android支援格式
AudioManager 在手機應用程式當中,有時候會需要調整手機音量或轉換手機聲音模式。 如果要開發一個具有音量調整功能的程式,Android API中的AudioManager提供了許多相關的方法,可在程式中控制音量大小、切換聲音模式,範例如下圖所示。
AudioManager 程式範例圖:
AudioManager布局文件 布局文件-1: 布局文件-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" /> <?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" />
AudioManager布局文件 布局文件-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程式碼 程式碼-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程式碼 程式碼-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程式碼 程式碼-3(AudioManagerEX.java) : 由於程式碼過多,完整程式碼請參考光碟中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);
AudioManager 有關AudioManager中的一些常數可於Android SDK中找到,在此僅列出較為重要之常數。
MediaRecorder MediaRecorder原先只支援音訊錄製,不過在Android 1.5版本以後開始支援視訊錄製功能,透過MediaRecorder類別的方法可以錄製視訊並儲存為MPEG4、H.263和H.264編碼的視訊。 MediaRecorder運作狀態、範例程式如下頁圖所示:
MediaRecorder 運作狀態圖: 範例圖:
MediaRecorder 布局文件(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 程式碼(MediaRecorder.java): 由於程式碼過多,完整程式碼請參考光碟中MediaRecorderEX.java /* 監聽錄音按鈕 */ btnRecord.setOnClickListener(new View.OnClickListener() { public void onClick(View arg0) { try { /* 檢查目前是否還有錄音資源 */ if (recorder == null) recorder = new MediaRecorder(); /* 設置輸入為麥克風 */ recorder.setAudioSource(MediaRecorder.AudioSource.MIC); /* 設置輸出的格式為3gp文件 */ recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); /* 音效編碼採用AMR */ recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); /* 暫存文件路徑,檔名為當前系統時間 */ path = "/sdcard/" + System.currentTimeMillis() + ".3ga"; /* 設定輸出路徑 */ recorder.setOutputFile(path); /* 準備緩衝 */ recorder.prepare(); /* 開始錄音 */ recorder.start(); /* 將狀態設置為正在錄音 */ state = RECORDING; handler.sendEmptyMessage(UPDATE);
AudioTrack • AudioTrack負責為Java應用程式管理與播放聲音資源,雖然MediaPlayer也可播放聲音,但AudioTrack可以設置的屬性更多,播放起來也較好操作。 • 它運作有兩種模式:static與streaming • static通常用於處理時間較短且延遲需求高的聲音。 • straming則用於播放品質較好、檔案較大或需要緩衝的聲音。程式範例如下頁圖所示。
AudioTrack 範例圖:
AudioTrack 布局文件(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 程式碼(AudioTrackEX.java): 由於程式碼過多,完整程式碼請參考光碟中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);
MediaPlayer MediaPlayer可用於控制播放聲音/影像,下圖描述播放狀態的轉換及程式範例。
MediaPlayer 布局文件(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 程式碼(MediaPlayerEX.java): 由於程式碼過多,完整程式碼請參考光碟中MediaPlayer.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(); } } });
MediaPlayer MediaPlayer player = new MediaPlayer(); player.setDataSource(URL/檔案路徑); player.prepare(); player.start(); 如果想播放記憶卡中的音樂或利用URL下載音樂來播放可使用下列方法,主要是透過MediaPlayer.setDataSource() 方法,將URL或檔案路徑以字串方式傳入。
VideoView 另外如果要播放影片的話,則使用Android內建之VideoView來播放影片,需先準備格式為*.3gp格式的影片,並將影片置於sdcard中,指令如圖所示。需要注意的是在模擬器上是無法正常播放的,模擬器在模擬一些視音訊方面還是會有一些問題,故範例需於執行於Hero實機上。
VideoView 程式範例圖:
VideoView 布局文件(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 程式碼(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 布局文件(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 程式碼(RingtoneManagerEX.java): 由於程式碼過多,完整程式碼請參考光碟中RingtoneManager.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);