1 / 45

Chapter 10

Chapter 10. 多媒體程式開發. Widget. Widget 簡介. android.widget 套件包含了許多視覺性的 UI 元素,可用來將操作界面展示在應用程式畫面上。 要熟悉 Android 多媒體程式的開發,必須從 widget 套件著手,因此本章所舉的範例,便是以 android.widget 套件的應用為中心。. Gallery 簡介. Gallery 是一個水平的清單,移動清單時,會將選擇項目放大顯示於中央,範例如圖所示。. Gallery 相關. Gallery 包含了一些 XML 屬性及方法,如下表所示:. Gallery 布局文件.

shalin
Download Presentation

Chapter 10

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Chapter 10 多媒體程式開發

  2. Widget

  3. Widget簡介 android.widget套件包含了許多視覺性的UI元素,可用來將操作界面展示在應用程式畫面上。 要熟悉Android多媒體程式的開發,必須從widget套件著手,因此本章所舉的範例,便是以android.widget套件的應用為中心。

  4. Gallery簡介 Gallery是一個水平的清單,移動清單時,會將選擇項目放大顯示於中央,範例如圖所示。

  5. Gallery相關 Gallery包含了一些XML屬性及方法,如下表所示:

  6. 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>

  7. 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); }

  8. 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]); }

  9. 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; }

  10. AnalogClock AnalogClock是一個類比時鐘元件,具有時針與分針。範例如圖所示。

  11. 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>

  12. DigitalClock 與AnalogClock類似,但是以數位的方式呈現,有時/分/秒,範例如下圖所示。

  13. 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>

  14. 多媒體開發

  15. 多媒體開發 Android對於多媒體的支援性非常強大,在SDK中的android.media提供了許多媒體相關類別可使用,像是一般播放音樂、影片及錄音…等等功能都可藉由SDK達成,也可自行搭配元件開發。 其中Android所支援的音訊、圖像、視訊格式可由下頁圖得知。

  16. 多媒體開發 Android支援格式

  17. AudioManager 在手機應用程式當中,有時候會需要調整手機音量或轉換手機聲音模式。 如果要開發一個具有音量調整功能的程式,Android API中的AudioManager提供了許多相關的方法,可在程式中控制音量大小、切換聲音模式,範例如下圖所示。

  18. AudioManager 程式範例圖:

  19. 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" />

  20. 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>

  21. 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);

  22. 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) ); }

  23. 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);

  24. AudioManager 有關AudioManager中的一些常數可於Android SDK中找到,在此僅列出較為重要之常數。

  25. MediaRecorder MediaRecorder原先只支援音訊錄製,不過在Android 1.5版本以後開始支援視訊錄製功能,透過MediaRecorder類別的方法可以錄製視訊並儲存為MPEG4、H.263和H.264編碼的視訊。 MediaRecorder運作狀態、範例程式如下頁圖所示:

  26. MediaRecorder 運作狀態圖: 範例圖:

  27. 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>

  28. 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);

  29. AudioTrack • AudioTrack負責為Java應用程式管理與播放聲音資源,雖然MediaPlayer也可播放聲音,但AudioTrack可以設置的屬性更多,播放起來也較好操作。 • 它運作有兩種模式:static與streaming • static通常用於處理時間較短且延遲需求高的聲音。 • straming則用於播放品質較好、檔案較大或需要緩衝的聲音。程式範例如下頁圖所示。

  30. AudioTrack 範例圖:

  31. 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>

  32. 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);

  33. MediaPlayer MediaPlayer可用於控制播放聲音/影像,下圖描述播放狀態的轉換及程式範例。

  34. 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" /> ……

  35. 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(); } } });

  36. MediaPlayer MediaPlayer player = new MediaPlayer(); player.setDataSource(URL/檔案路徑); player.prepare(); player.start(); 如果想播放記憶卡中的音樂或利用URL下載音樂來播放可使用下列方法,主要是透過MediaPlayer.setDataSource() 方法,將URL或檔案路徑以字串方式傳入。

  37. VideoView 另外如果要播放影片的話,則使用Android內建之VideoView來播放影片,需先準備格式為*.3gp格式的影片,並將影片置於sdcard中,指令如圖所示。需要注意的是在模擬器上是無法正常播放的,模擬器在模擬一些視音訊方面還是會有一些問題,故範例需於執行於Hero實機上。

  38. VideoView 程式範例圖:

  39. 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>

  40. 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(); } }

  41. RingtoneManager RingtoneManager提供存取鈴聲、通知或其他類型的音效。 Android預設系統鈴聲儲存於【/system/media/audio/ringtones/】。 如不使用預設的位置,則可將檔案置於【/sdcard/music/】中,還可進一步分類為三種不同用途的資料夾。

  42. RingtoneManager 此後便可透過RingtoneManager,在設定鈴聲時,以intent.putExtra產生不同的鈴聲選單,範例如圖所示。

  43. 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>

  44. 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);

  45. Q&A

More Related