繪圖與多媒體

Download Report

Transcript 繪圖與多媒體

第13章 繪圖與多媒體





13-1 顯示圖檔-行動相簿
13-2 音樂播放-音樂播放器
13-3 影片播放-視訊播放器
13-4 聲音處理-錄音程式
13-5 2D繪圖-井字遊戲
13-1 顯示圖檔-行動相簿(說明)
 行動相簿是一個在手持行動裝置瀏覽照片的程式
,筆者準備用來說明如何在Android應用程式顯示
圖檔,在實務上,我們可以將活動、旅遊、人或
寵物照片收集建立成相簿程式,隨時隨地分享照
片給其他人。
 這個範例是使用ListActivity類別建立ListView元件
顯示照片的分類目錄,然後使用Gallery元件導覽
目錄下各照片的縮圖,只需選擇照片縮圖,就可
以在下方ImageView元件顯示較大且清晰的照片。
13-1 顯示圖檔-行動相簿
步驟一:開啟和執行Android專案
 請啟動Eclipse IDE開啟Android專案Ch13_1,內含2
個Java類別檔、一個版面配置檔mygallery.xml、2
個資源檔strings.xml和attrs.xml和一些照片的PNG
格式圖檔,其執行結果如下圖所示:
13-1 顯示圖檔-行動相簿
步驟二:建立照片的圖形資源
 行動相簿的主要目的是顯示
照片,所以我們需要建立照
片的圖形資源,筆者共建立
2種不同解析度的圖檔,如
右圖所示:
13-1 顯示圖檔-行動相簿
步驟三:建立分類目錄的ListActivity類別-1
 行動相簿的分類目錄是使用ListView元件,筆者直
接建立ListActivity類別來顯示目錄,所以沒有使用
版面配置檔main.xml,如下所示:
public class Ch13_1Activity extends ListActivity {
…
}
13-1 顯示圖檔-行動相簿
步驟三:建立分類目錄的ListActivity類別-2
onCreate()方法
 在onCreate()方法使用ArrayList泛型集合物件來建立
ListAdapter結合器物件,如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ArrayList<String> list = new ArrayList<String>();
list.add("2009/07");
list.add("2009/08");
ListAdapter adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_list_item_1, list);
setListAdapter(adapter); // 指定使用的LisatAdapter
}
13-1 顯示圖檔-行動相簿
步驟三:建立分類目錄的ListActivity類別-3
onListItemClick()方法
 在onListItemClick()方法回應使用者的選擇,這是使用整數陣列來儲存
使用者選取目錄的照片清單,如下所示:
@Override
protected void onListItemClick(ListView l, View v, int position,
long id) {
super.onListItemClick(l, v, position, id);
int [] imageIds = null;
switch(position) {
case 0:
imageIds = new int[6];
imageIds[0] = R.drawable.image01;
imageIds[1] = R.drawable.image02;
13-1 顯示圖檔-行動相簿
步驟三:建立分類目錄的ListActivity類別-4
imageIds[2] = R.drawable.image03;
imageIds[3] = R.drawable.image04;
break;
case 1:
imageIds = new int[5];
imageIds[0] = R.drawable.image05;
imageIds[1] = R.drawable.image06;
imageIds[2] = R.drawable.image07;
break;
}
13-1 顯示圖檔-行動相簿
步驟三:建立分類目錄的ListActivity類別-5
 然後建立Intent物件啟動MyGallery活動,並且傳遞
照片資源陣列的附件,如下所示:
Intent intent = new Intent(Ch13_1Activity.this,
MyGallery.class);
intent.putExtra("IMAGEIDS", imageIds);
startActivity(intent);
}
13-1 顯示圖檔-行動相簿
步驟四:相簿的版面配置Gallery元件
 在MyGallery活動的版面配置檔是mygallery.xml,
使用Gallery介面元件瀏覽選取目錄下的所有照片
,它是以橫向水平捲軸方式來顯示照片縮圖,在
之下是ImageView元件,如下所示:
<Gallery android:id="@+id/gallery1"
android:layout_width="fill_parent"
android:layout_height="wrap_content"/>
<ImageView android:id="@+id/image1"
android:layout_width="320px"
android:layout_height="250px"
android:scaleType="fitXY" />
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-1
 行動相簿的照片主要是在MyGallery活動類別顯示
,在類別宣告開頭是成員的ImageView物件變數和
imageIDs[]陣列,如下所示:
public class MyGallery extends Activity {
private ImageView imageview;
private int[] imageIDs = null;
…
}
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-2
onCreate()方法
 在覆寫的onCreate()方法首先取得Intent物件傳入的圖形陣
列imageIDs[],如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.mygallery);
Intent intent = getIntent();
imageIDs = intent.getIntArrayExtra("IMAGEIDS");
imageview = (ImageView)findViewById(R.id.image1);
imageview.setImageResource(imageIDs[0]);
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-3
 程式碼取得ImageView物件後,指定Gallery元件使用的結合器物件,
和建立選取縮圖的事件處理,如下所示:
Gallery gallery = (Gallery)findViewById(R.id.gallery1);
gallery.setAdapter(new ImageAdapter(this));
gallery.setOnItemSelectedListener(
new AdapterView.OnItemSelectedListener() {
public void onItemSelected(AdapterView<?> parent,
View v, int position, long id) {
imageview.setImageResource(
imageIDs[position]);
}
public void onNothingSelected(AdapterView<?> arg0) {
}
});
}
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-4
內層類別ImageAdapter
 ImageAdapter內層類別是繼承BaseAdapter的自訂結合器類別,需要覆
寫getCount()、getItem()、getItemId()和getView()方法,如下所示:
public class ImageAdapter extends BaseAdapter {
private Context context;
private int itemBackground;
public ImageAdapter(Context c) {
context = c;
TypedArray a = obtainStyledAttributes(
R.styleable.Gallery1);
itemBackground = a.getResourceId(R.styleable.
Gallery1_android_galleryItemBackground, 0);
a.recycle();
}
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-5
@Override
public int getCount() {
return imageIDs.length;
}
@Override
public Object getItem(int position) {
return position;
}
@Override
public long getItemId(int position) {
return position;
}
13-1 顯示圖檔-行動相簿
步驟五:建立顯示行動相簿的MyGallery活動-6
@Override
public View getView(int position, View convertView,
ViewGroup parent) {
ImageView imageView = new ImageView(context);
imageView.setImageResource(imageIDs[position]);
imageView.setScaleType(ImageView.ScaleType.FIT_XY);
imageView.setLayoutParams(
new Gallery.LayoutParams(150, 120));
imageView.setBackgroundResource(itemBackground);
return imageView;
}
}
13-1 顯示圖檔-行動相簿
步驟六:在AndroidManifest.xml註冊活動
 MyGallery活動需要在AndroidManifest.xml檔註冊
,如下所示:
<activity android:name=".MyGallery"/>
13-2 音樂播放-音樂播放器(說明)
 Android應用程式可以使用MediaPlayer物件播放音
樂,為了不中斷音樂的播放,專案是建立服務來
播放儲存在SD卡的MP3音樂,即Windows作業系
統範例音樂Kalimba.mp3。
13-2 音樂播放-音樂播放器
步驟一:開啟和執行Android專案
 請啟動Eclipse IDE開啟Android專案Ch13_2,內含2
個Java類別檔的活動與服務和版面配置檔main.xml
。首先需要將MP3音樂檔複製至Android模擬器的
SD卡後執行此專案,其執行結果如下圖所示:
13-2 音樂播放-音樂播放器
步驟二:建立播放器介面的版面配置
<LinearLayout android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button android:id="@+id/start"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="開始/繼續"
android:onClick="start_Click"/>
<Button android:id="@+id/pause"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="暫停"
android:onClick="pause_Click"/>
<Button android:id="@+id/stop"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="停止"
android:onClick="stop_Click"/>
</LinearLayout>
13-2 音樂播放-音樂播放器
步驟三:建立Activity活動類別的事件處理方法-1
 在Ch13_2Activity活動類別的開頭宣告成員的
TextView物件變數,如下所示:
public class Ch13_2Activity extends Activity {
private TextView output;
…
}
13-2 音樂播放-音樂播放器
步驟三:建立Activity活動類別的事件處理方法-2
onCreate()方法
 在覆寫的onCreate()方法顯示播放器介面的版面配
置和取得TextView元件,如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
output = (TextView) findViewById(R.id.output);
}
13-2 音樂播放-音樂播放器
步驟三:建立Activity活動類別的事件處理方法-3
start_Click()事件處理方法
 在start_Click()方法使用Intent物件呼叫
startService()方法來啟動MusicService服務,附件
ISPAUSE是布林值false,表示不是暫停播放,如下
所示:
public void start_Click(View view) {
Intent intent = new Intent(this, MusicService.class);
intent.putExtra("ISPAUSE", false);
startService(intent);
output.setText("音樂播放中...");
}
13-2 音樂播放-音樂播放器
步驟三:建立Activity活動類別的事件處理方法-4
pause_Click()事件處理方法
 在pause_Click()方法也是使用Intent物件呼叫
startService()方法來啟動MusicService服務,如下
所示:
public void pause_Click(View view) {
Intent intent = new Intent(this, MusicService.class);
intent.putExtra("ISPAUSE", true);
startService(intent);
output.setText("音樂暫停中...");
}
13-2 音樂播放-音樂播放器
步驟三:建立Activity活動類別的事件處理方法-5
stop_Click()事件處理方法
 在stop_Click()方法是使用Intent物件呼叫
stopService()方法來停止服務,也就是停止音樂的
播放,如下所示:
public void stop_Click(View view) {
Intent intent = new Intent(this, MusicService.class);
stopService(intent);
output.setText("音樂已經停止播放...");
}
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-1
 播放音樂是在MusicService服務類別,使用
MediaPlayer物件的相關方法來播放音樂。類別是
繼承自Service類別,在開頭宣告成員的
MediaPlayer物件,如下所示:
public class MusicService extends Service {
private MediaPlayer player;
private String musicFile = "/sdcard/Kalimba.mp3";
......
}
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-2
onCreate()方法
 在覆寫onCreate()方法建立MediaPlayer物件,try/catch例外處理使用
setDataSource()方法指定音樂檔案路徑,setOnCompletionListener()方法指定播
放完畢的傾聽者物件,最後呼叫prepare()方法進入準備狀態,如下所示:
@Override
public void onCreate() {
player = new MediaPlayer();
try {
player.setDataSource(musicFile);
player.setOnCompletionListener(listener);
player.prepare(); // 準備
} catch (Exception ex) {
Log.d("Ch13_2", "onCreate: " + ex.getMessage());
}
}
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-3
OnCompletionListener傾聽者物件
 使用匿名內層類別建立OnCompletionListener傾聽者物件,類別需要覆寫
onCompletion()方法,如下所示:
private OnCompletionListener listener =
new OnCompletionListener() {
@Override
public void onCompletion(MediaPlayer nouse) {
try {
player.stop(); // 停止
player.prepare(); // 準備
} catch (Exception ex){
Log.d("Ch13_2", "Listener: " + ex.getMessage());
}
}
};
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-4
onStartCommand()方法
@Override
public int onStartCommand(Intent intent, int flags, int startId) {
Boolean isPause = intent.getBooleanExtra("ISPAUSE", true);
try {
if (isPause == true) {
if (player.isPlaying() == true)
player.pause(); // 暫停
} else {
player.start(); // 播放
}
} catch (Exception ex) {
Log.d("Ch13_2", "onStart(): " + ex.getMessage());
}
return START_STICKY;
}
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-5
onDestroy()方法
 在覆寫的onDestroy()方法是呼叫stop()方法停止音樂播放,
如下所示:
@Override
public void onDestroy() {
try {
player.stop(); // 停止
player.prepare(); // 準備
} catch (Exception ex) {
Log.d("Ch13_2", "onDestroy(): " + ex.getMessage());
}
}
13-2 音樂播放-音樂播放器
步驟四:建立MusicService服務類別播放音樂-6
onBind()抽象方法
 實作的onBind()抽象方法並沒有使用,所以傳回
null,如下所示:
@Override
public IBinder onBind(Intent intent) {
return null;
}
13-2 音樂播放-音樂播放器
步驟五:在AndroidManifest.xml註冊服務
 MusicService服務需要在AndroidManifest.xml檔註
冊,如下所示:
<service android:name=".MusicService"/>
13-3 影片播放-視訊播放器(說明)
 在Android應用程式播放影片也可以使用
MediaPlayer,不過,我們需要建立Surface物件繪
出影片內容,在第16-3節使用相機時,就會使用
此方式來動態顯示從相機硬體取得的預覽串流畫
面。
 另一種比較簡單的方式是使用VideoView元件和
MediaController物件來控制影片播放,換句話說,
我們可以輕鬆在活動類別建立一個視訊播放器程
式。
13-3 影片播放-視訊播放器
步驟一:開啟和執行Android專案
 請啟動Eclipse IDE開啟
Android專案Ch13_3,內含1
個Java類別檔的活動和一個
版面配置檔main.xml。首先
需要將影片檔複製至Android
模擬器的SD卡來播放影片,
其執行結果如右圖所示:
13-3 影片播放-視訊播放器
步驟二:建立版面配置的VideoView元件
 視訊播放器的使用介面是定義在main.xml版面配
置檔,主要就是VideoView元件,如下所示:
<VideoView android:id="@+id/video1"
android:layout_width="320px"
android:layout_height="240px"/>
13-3 影片播放-視訊播放器
步驟三:建立Activity活動類別播放影片-1
 在Ch13_3Activity活動類別的開頭宣告成員的
VideoView物件變數,如下所示:
public class Ch13_3Activity extends Activity {
private VideoView video;
private String videoFile = "sample.3gp";
…
}
13-3 影片播放-視訊播放器
步驟三:建立Activity活動類別播放影片-2
onCreate()方法
 在覆寫的onCreate()方法顯示VideoView元件的版面配置後
,就可以取得VideoView物件和呼叫相關方法來播放影片
,如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
video = (VideoView)findViewById(R.id.video1);
video.setVideoURI(
Uri.parse("file:///sdcard/"+ videoFile));
video.setMediaController(new MediaController(this));
video.start();
}
13-3 影片播放-視訊播放器
步驟三:建立Activity活動類別播放影片-3
onPause()方法
 在覆寫的onPause()方法是呼叫stopPlayback()方法
停止影片的播放,如下所示:
@Override
public void onPause() {
super.onStop();
video.stopPlayback();
}
13-4 聲音處理-錄音程式(說明)
 一般來說,行動裝置的麥克風除了通話外,我們
也可以建立錄音程式,使用麥克風裝置來錄製聲
音,在Android是使用MediaRecorder物件來錄音和
將它存入檔案。
 MediaRecorder物件在使用上只需指定錄音格式和
儲存檔案的路徑,就可以開始進行聲音錄製。
13-4 聲音處理-錄音程式
步驟一:開啟和執行Android專案
 請啟動Eclipse IDE開啟Android專案Ch13_4,內含1
個Java類別檔、一個版面配置檔main.xml。因為
Android模擬器支援錄音部分有些問題,建議使用
實機來測試,其執行結果如下圖所示:
13-4 聲音處理-錄音程式
步驟二:建立錄音程式的版面配置
<TextView android:id="@+id/output"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/hello"/>
<Button android:id="@+id/start"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="開始錄音"
android:onClick="start_Click"
android:enabled="false"/>
<Button android:id="@+id/stop"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="停止錄音"
android:onClick="stop_Click"
android:enabled="false"/>
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-1
 在Ch13_4Activity活動類別的開頭宣告成員的
MediaRecorder、Button、TextView和File物件變數
,如下所示:
public class Ch13_4Activity extends Activity {
private MediaRecorder recorder;
private Button start, stop;
private TextView output;
File path;
…
}
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-2
onCreate()方法
 在覆寫的onCreate()方法建立MediaRecorder物件和錄音檔路徑的File物
件,如下所示:
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
start = (Button) findViewById(R.id.start);
stop = (Button) findViewById(R.id.stop);
output = (TextView) findViewById(R.id.output);
recorder = new MediaRecorder();
path = new File(Environment.
getExternalStorageDirectory(), "myrecord.3gp");
resetRecorder();
}
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-3
onDestroy()方法
 在覆寫的onDestroy()方法呼叫release()方法釋放
MediaRecorder物件的資源,如下所示:
@Override
protected void onDestroy() {
super.onDestroy();
recorder.release();
}
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-4
resetRecorder()方法
 在自訂的resetRecorder()方法重設錄音機的MediaRecorder物件,如下所示:
private void resetRecorder() {
recorder.setAudioSource(
MediaRecorder.AudioSource.MIC);
recorder.setOutputFormat(
MediaRecorder.OutputFormat.THREE_GPP);
recorder.setAudioEncoder(
MediaRecorder.AudioEncoder.DEFAULT);
recorder.setOutputFile(path.getAbsolutePath());
try {
recorder.prepare();
output.setText("錄音程序準備完成....");
start.setEnabled(true);
} catch (Exception ex) {
Log.d("Ch13_4", "resetRecorder: " + ex.getMessage());
}
}
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-5
start_Click()事件處理方法
 在start_Click()方法呼叫MediaRecorder物件的start()方法開始錄音,然
後使用setEnabled()方法設定按鈕狀態是否可用,因為已經開始錄音,
所以將【停止錄音】鈕設為可用,可以按下此按鈕來結束錄音,如下
所示:
public void start_Click(View view) {
output.setText("開始錄音....");
try {
recorder.start();
start.setEnabled(false);
stop.setEnabled(true);
} catch (Exception ex) {
Log.d("Ch13_4", "start_Click " + ex.getMessage());
}
}
13-4 聲音處理-錄音程式
步驟三:建立Activity活動類別的事件處理方法-6
stop_Click()事件處理方法
 在stop_Click()方法呼叫MediaRecorder物件的stop()
方法停止錄音,如下所示:
public void stop_Click(View view) {
output.setText("停止錄音....");
recorder.stop();
start.setEnabled(true);
stop.setEnabled(false);
}
13-4 聲音處理-錄音程式
步驟四:在AndroidManifest.xml新增錄音權限
 錄音程式因為執行錄音和在外部儲存裝置寫入檔
案,所以在AndroidManifest.xml檔需要新增
RECORD_AUDIO和WRITE_EXTERNAL_STORAGE權限
,如下所示:
<uses-permission android:name=
"android.permission.RECORD_AUDIO"/>
<uses-permission android:name=
"android.permission.WRITE_EXTERNAL_STORAGE"/>
13-5 2D繪圖-井字遊戲
 13-5-1 2D繪圖的基礎
 13-5-2 井字遊戲
13-5-1 2D繪圖的基礎-說明
 Android支援2D繪圖,可以在繼承View類別覆寫的
onDraw()方法繪圖,如下所示:
public class Draw2D extends View {
public Draw2D(Context context) {
super(context);
}
@Override
protected void onDraw(Canvas canvas) {
// 在此繪圖
}
}
13-5-1 2D繪圖的基礎-建立畫布
 在繪圖前,我們需要先建立畫筆的Paint物件,如
下所示:
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
 上述setStyle()方法指定畫筆的樣式,然後將整個
Canvas物件填滿白色的背景色彩,如下所示:
paint.setColor(Color.WHITE);
canvas.drawPaint(paint);
13-5-1 2D繪圖的基礎-畫圓
 在畫布畫圓是使用Canvas物件的drawCircle()方法
,首先使用setAntiAlias()方法指定畫筆線條沒有鋸
齒狀,和色彩為紅色,如下所示:
paint.setAntiAlias(true);
paint.setColor(Color.RED);
canvas.drawCircle(80, 30, 25, paint);
13-5-1 2D繪圖的基礎-畫長方形
 畫長方形是使用drawRect(),參數為兩組(x, y),分
別是左上角和右下角座標,畫筆是藍色,如下所
示:
paint.setColor(Color.BLUE);
canvas.drawRect(20, 15, 50, 100, paint);
13-5-1 2D繪圖的基礎-畫出資源圖形
 在畫布上也可以直接繪出圖形資源的圖檔,首先
取得資源的Resources物件,如下所示:
Resources res = this.getResources();
Bitmap bitmap = BitmapFactory.decodeResource(
res, R.drawable.icon);
canvas.drawBitmap(bitmap, 50 ,200 , paint);
13-5-1 2D繪圖的基礎-畫出文字內容
 在畫布上也可以畫出一段文字內容,首先指定畫
筆的色彩、樣式、線條和字型尺寸,如下所示:
paint.setColor(Color.GREEN);
paint.setStyle(Paint.Style.FILL);
paint.setAntiAlias(true);
paint.setTextSize(30);
 上述setTextSize()方法指定字型尺寸,然後呼叫
drawText()方法畫出一段文字內容,如下所示:
canvas.drawText("我的畫布!", 50, 180, paint);
13-5-1 2D繪圖的基礎-畫出旋轉文字
 我們還可以在畫布上繪出一段旋轉文字。首先指定畫筆色
彩、字型尺寸和繪出的字串,如下所示:
paint.setColor(Color.BLACK);
paint.setTextSize(25);
String str = "旋轉的文字!";
canvas.rotate(-45, 200, 200);
paint.setStyle(Paint.Style.FILL);
canvas.drawText(str, 200, 200, paint);
 取消旋轉是呼叫restore()方法,如下所示:
canvas.restore();
13-5-2 井字遊戲-說明
 井字遊戲是2D繪圖的應用,筆者使用2D繪圖方法
來繪出井字形的遊戲板和在指定儲存格繪出O和X
的圖形。
13-5-2 井字遊戲-步驟
 步驟一:開啟和執行Android專案
 步驟二:建立Activity活動執行井字遊戲
 步驟三:建立井字形遊戲板的MainBoard類別
 步驟四:建立邏輯儲存格的CellBoard類別