5.6. 媒体录制
5.6.1 MediaRecorder简介
使用MediaRecorder进行音频和视频的录制。
继承结构:
public class MediaRecorderextends Object
|
MediaRecorder的生命周期:
5.6.2 音频录制
配置:
<?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"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageButton android:id="@+id/record" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/record" /> <ImageButton android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stop" /> </LinearLayout> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="文字提示信息..." /> <ListView android:id="@+id/reclist" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
|
Activity:
package com.makyan.demo; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.Intent; import android.media.MediaRecorder; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageButton; import android.widget.ListView; import android.widget.SimpleAdapter; import android.widget.TextView;
public class MediaRecorderActivity extends Activity { private ImageButton record = null; // 按钮信息 private ImageButton stop = null; // 按钮信息 private TextView info = null; // 提示信息 private MediaRecorder mediaRecorder = null; // MediaRecorder对象 private File recordAudioSaveFile = null; // 文件保存目录路径 private File recordAudioSaveFileDir = null; // 文件保存目录 private String recordAudioSaveFileName = null; // 音频文件保存名称 private SimpleAdapter recordSimpleAdapter = null; // 适配器 private ListView reclist = null; // 定义列表视图 private String recDir = "makyanrec"; // 保存目录 private boolean sdcardExists = false; // 判断SD卡是否存在 private boolean isRecord = false; // 判断是否正在录音 private List<Map<String, Object>> recordFiles = null; // 保存所有的List数据
@Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); super.setContentView(R.layout.activity_media_recorder); // 调用布局管理器 this.record = (ImageButton) super.findViewById(R.id.record); // 查找组件 this.stop = (ImageButton) super.findViewById(R.id.stop); // 查找组件 this.info = (TextView) super.findViewById(R.id.info); // 查找组件 this.reclist = (ListView) super.findViewById(R.id.reclist); // 查找组件
// 判断SD卡是否存在 if (this.sdcardExists = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { this.recordAudioSaveFileDir = new File(Environment .getExternalStorageDirectory().toString() + File.separator + MediaRecorderActivity.this.recDir + File.separator); // 保存录音目录 if (!this.recordAudioSaveFileDir.exists()) { // 父文件夹不存在 this.recordAudioSaveFileDir.mkdirs(); // 创建新的文件夹 } }
// 取得全部的文件列表 this.getRecordFiles(); // 设置单击事件 this.stop.setOnClickListener(new StopOnClickListenerImpl()); // 设置单击事件 this.record.setOnClickListener(new RecordOnClickListenerImpl()); // 暂停钮暂时不可用 this.stop.setEnabled(false); // 设置单击事件 this.reclist.setOnItemClickListener(new OnItemClickListenerImpl()); } private class RecordOnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { // 如果SD卡存在 if (MediaRecorderActivity.this.sdcardExists) { // 文件保存名称 MediaRecorderActivity.this.recordAudioSaveFileName = MediaRecorderActivity.this.recordAudioSaveFileDir .toString() + File.separator + "MAKYANRecord_" + System.currentTimeMillis() + ".3gp"; // 取得音频文件保存路径 MediaRecorderActivity.this.recordAudioSaveFile = new File(MediaRecorderActivity.this.recordAudioSaveFileName); // 实例化MediaRecorder MediaRecorderActivity.this.mediaRecorder = new MediaRecorder(); // 设置录音源为MIC(麦克风) MediaRecorderActivity.this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 定义输出格式 MediaRecorderActivity.this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 定义音频编码 MediaRecorderActivity.this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.DEFAULT); // 定义输出文件 MediaRecorderActivity.this.mediaRecorder.setOutputFile(MediaRecorderActivity.this.recordAudioSaveFileName); try { // 准备录音 MediaRecorderActivity.this.mediaRecorder.prepare(); } catch (Exception e) { e.printStackTrace(); } // 开始录音 MediaRecorderActivity.this.mediaRecorder.start(); // 提示信息 MediaRecorderActivity.this.info.setText("正在录音中..."); // 停止按钮可用 MediaRecorderActivity.this.stop.setEnabled(true); // 录音按钮禁用 MediaRecorderActivity.this.record.setEnabled(false); // 正在录音 MediaRecorderActivity.this.isRecord = true; } } } private class StopOnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { // 已经开始录音,则停止 if (MediaRecorderActivity.this.isRecord) { // 停止录音 MediaRecorderActivity.this.mediaRecorder.stop(); // 释放资源 MediaRecorderActivity.this.mediaRecorder.release(); // 录音按钮启用 MediaRecorderActivity.this.record.setEnabled(true); MediaRecorderActivity.this.info.setText("录音结束,文件路径为:"+ MediaRecorderActivity.this.recordAudioSaveFile);
} // 重新加载列表 MediaRecorderActivity.this.getRecordFiles(); } }
private class OnItemClickListenerImpl implements OnItemClickListener { // 选项单击 @Override public void onItemClick(AdapterView<?> adapter, View view,int position, long id) { // 判断是否是Map实例 if (MediaRecorderActivity.this.recordSimpleAdapter.getItem(position) instanceof Map) { // 取出指定位置的内容 Map<?, ?> map = (Map<?, ?>) MediaRecorderActivity.this.recordSimpleAdapter.getItem(position); // 定义操作的Uri Uri uri = Uri.fromFile(new File( MediaRecorderActivity.this.recordAudioSaveFileDir .toString() + File.separator + map.get("filename"))); // 指定Action Intent intent = new Intent(Intent.ACTION_VIEW); // 增加标记 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); // 设置数据播放的MIME intent.setDataAndType(uri, "audio/mp3"); // 启动Activity MediaRecorderActivity.this.startActivity(intent); } } } // 取得全部录音文件 private void getRecordFiles() { // 实例化List集合 this.recordFiles = new ArrayList<Map<String, Object>>(); System.out.println(this.recordAudioSaveFileDir.listFiles().length); // 如果SD卡存在 if (this.sdcardExists) { // 列出目录中的文件 File files[] = this.recordAudioSaveFileDir.listFiles(); for (int x = 0; x < files.length; x++) { Map<String, Object> fileInfo = new HashMap<String, Object>(); fileInfo.put("filename", files[x].getName()); // 增加显示内容 this.recordFiles.add(fileInfo); // 保存数据 } this.recordSimpleAdapter = new SimpleAdapter(this, this.recordFiles, R.layout.recorderfile, new String[] { "filename" }, new int[] { R.id.filename }); // 实例化适配器 this.reclist.setAdapter(this.recordSimpleAdapter); // 定义列表视图 } } }
|
5.6.3 视频录制
录像程序的开发:
配置权限:
<uses-permission android:name="android.permission.CAMERA"/> <uses-permission android:name="android.permission.RECORD_AUDIO"/> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/> <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/> |
录制视频:
package com.makyan.demo; import java.io.File; import android.app.Activity; import android.content.Intent; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.view.Window; import android.view.WindowManager; import android.widget.ImageButton; import android.widget.TextView; public class MediaViewRecorderActivity extends Activity { private ImageButton record = null; // 按钮信息 private ImageButton stop = null; // 按钮信息 private ImageButton browser = null; // 按钮信息 private TextView info = null; // 提示信息 private MediaRecorder mediaRecorder = null; // MediaRecorder对象 private File recordVideoSaveFile = null; // 文件保存目录路径 private File recordVideoSaveFileDir = null; // 文件保存目录 private String recordVideoSaveFileName = null; // 音频文件保存名称 private String recDir = "makyanvideo"; // 保存目录 private boolean sdcardExists = false; // 判断SD卡是否存在 private boolean isRecord = false; // 判断是否正在录音 private SurfaceView surface = null; // SurfaceView @Override public void onCreate(Bundle savedInstanceState) { onCreate(savedInstanceState); // 不显示标题 requestWindowFeature(Window.FEATURE_NO_TITLE); // 全屏显示 getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN); // 高亮显示 getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); setContentView(R.layout.activity_media_view_recorder);// 调用布局管理器 record = (ImageButton) super.findViewById(R.id.record); // 查找组件 stop = (ImageButton) super.findViewById(R.id.stop); // 查找组件 browser = (ImageButton) super.findViewById(R.id.browser); // 查找组件 info = (TextView) super.findViewById(R.id.info); // 查找组件 surface = (SurfaceView) super.findViewById(R.id.surface) ; // 查找组件 // 设置缓冲类型 surface.getHolder(). // 设置分辨率 surface.getHolder().setFixedSize(350, 500) ; // 判断SD卡是否存在 if (sdcardExists = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { recordVideoSaveFileDir = new File(Environment .getExternalStorageDirectory().toString() + File.separator + recDir + File.separator); // 保存录音目录 if (!recordVideoSaveFileDir.exists()) { // 父文件夹不存在 recordVideoSaveFileDir.mkdirs(); // 创建新的文件夹 } } stop.setOnClickListener(new StopOnClickListenerImpl()); // 设置单击事件 record.setOnClickListener(new RecordOnClickListenerImpl()); // 设置单击事件 browser.setOnClickListener(new BrowserOnClickListenerImpl()); // 设置单击事件 stop.setEnabled(false); // 暂停钮暂时不可用 } private class RecordOnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { // 如果SD卡存在 if (MediaViewRecorderActivity.this.sdcardExists) { // 文件保存名称 MediaViewRecorderActivity.this.recordVideoSaveFileName = MediaViewRecorderActivity.this.recordVideoSaveFileDir .toString() + File.separator + "MAKYANVideo_" + System.currentTimeMillis() + ".3gp"; // 取得音频文件保存路径 MediaViewRecorderActivity.this.recordVideoSaveFile = new File(MediaViewRecorderActivity.this.recordVideoSaveFileName); // 实例化MediaRecorder MediaViewRecorderActivity.this.mediaRecorder = new MediaRecorder(); MediaViewRecorderActivity.this.mediaRecorder.reset() ; // 设置录音源为MIC(麦克风) MediaViewRecorderActivity.this.mediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); // 设置视频源为摄像头 MediaViewRecorderActivity.this.mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA); // 定义输出格式 MediaViewRecorderActivity.this.mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); // 定义视频编码 MediaViewRecorderActivity.this.mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263); // 定义音频编码 MediaViewRecorderActivity.this.mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); // 定义输出文件 MediaViewRecorderActivity.this.mediaRecorder.setOutputFile(MediaViewRecorderActivity.this.recordVideoSaveFileName); // 定义视频大小 MediaViewRecorderActivity.this.mediaRecorder.setVideoSize(320, 240); // 每秒10帧 MediaViewRecorderActivity.this.mediaRecorder.setVideoFrameRate(10); // 定义视频显示 MediaViewRecorderActivity.this.mediaRecorder.setPreviewDisplay(MediaViewRecorderActivity.this.surface.getHolder().getSurface()); try { // 准备录象 MediaViewRecorderActivity.this.mediaRecorder.prepare(); } catch (Exception e) { e.printStackTrace(); } // 开始录象 MediaViewRecorderActivity.this.mediaRecorder.start(); // 提示信息 MediaViewRecorderActivity.this.info.setText("正在录象中..."); // 停止按钮可用 MediaViewRecorderActivity.this.stop.setEnabled(true); // 录象按钮禁用 MediaViewRecorderActivity.this.record.setEnabled(false); // 正在录音 MediaViewRecorderActivity.this.isRecord = true; } } } private class StopOnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { if (MediaViewRecorderActivity.this.isRecord) { // 已经开始录音,则停止 MediaViewRecorderActivity.this.mediaRecorder.stop(); // 停止录音 MediaViewRecorderActivity.this.mediaRecorder.release(); // 释放资源 MediaViewRecorderActivity.this.record.setEnabled(true); // 录音按钮启用 MediaViewRecorderActivity.this.info.setText("录像结束,文件路径为:" + MediaViewRecorderActivity.this.recordVideoSaveFile); } } } private class BrowserOnClickListenerImpl implements OnClickListener { @Override public void onClick(View v) { Intent it = new Intent(MediaViewRecorderActivity.this, BrowserActivity.class); // 指定Intent MediaViewRecorderActivity.this.startActivity(it) ; // 跳转Intent } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if (keyCode == KeyEvent.KEYCODE_BACK) { // 如果是手机上的返回键 this.finish(); // 程序结束 } return false; } } |
视频列表:
package com.makyan.demo; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import android.app.Activity; import android.content.Intent; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.AdapterView; import android.widget.AdapterView.OnItemClickListener; import android.widget.ImageButton; import android.widget.ListView; import android.widget.SimpleAdapter; public class BrowserActivity extends Activity { private ImageButton back = null ; // 定义按钮 private ListView videolist = null; // 定义列表视图 private SimpleAdapter recordSimpleAdapter = null; // 适配器 private List<Map<String, Object>> recordFiles = null; // 保存所有的List数据 private String recDir = "makyanvideo"; // 保存目录 private File recordVideoSaveFileDir = null; // 文件保存目录 private boolean sdcardExists = false; // 判断SD卡是否存在 @Override public void onCreate(Bundle savedInstanceState) { onCreate(savedInstanceState); // 调用布局管理器 setContentView(R.layout.browser); videolist = (ListView) super.findViewById(R.id.videolist); back = (ImageButton) super.findViewById(R.id.back) ; // 判断SD卡是否存在 if (sdcardExists = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) { // 保存录音目录 recordVideoSaveFileDir = new File(Environment .getExternalStorageDirectory().toString() + File.separator + recDir + File.separator); // 父文件夹不存在 if (!recordVideoSaveFileDir.exists()) { // 创建新的文件夹 recordVideoSaveFileDir.mkdirs(); } } // 取得全部的文件列表 getRecordFiles(); // 设置单击事件 videolist.setOnItemClickListener(new OnItemClickListenerImpl()); // 设置单击事件 back.setOnClickListener(new BackOnClickListenerImpl()); } // 取得全部录音文件 private void getRecordFiles() { // 实例化List集合 recordFiles = new ArrayList<Map<String, Object>>(); // 如果SD卡存在 if (sdcardExists) { // 列出目录中的文件 File files[] = recordVideoSaveFileDir.listFiles(); for (int x = 0; x < files.length; x++) { Map<String, Object> fileInfo = new HashMap<String, Object>(); // 增加显示内容 fileInfo.put("filename", files[x].getName()); // 保存数据 recordFiles.add(fileInfo); } recordSimpleAdapter = new SimpleAdapter(this, recordFiles, R.layout.recordfiles, new String[] { "filename" }, new int[] { R.id.filename }); // 实例化适配器 videolist.setAdapter(this.recordSimpleAdapter); // 定义列表视图 } } //点击列表中的项,跳转到播放页面 private class OnItemClickListenerImpl implements OnItemClickListener { // 选项单击 @Override public void onItemClick(AdapterView<?> adapter, View view,int position, long id) { // 判断是否是Map实例 if (BrowserActivity.this.recordSimpleAdapter.getItem(position) instanceof Map) { // 取出指定位置的内容 Map<?, ?> map = (Map<?, ?>) BrowserActivity.this.recordSimpleAdapter.getItem(position); // 指定Intent Intent intent = new Intent(BrowserActivity.this,PlayVideoActivity.class); intent.putExtra("filepath", BrowserActivity.this.recordVideoSaveFileDir.toString() + File.separator + map.get("filename").toString()); // 启动Activity BrowserActivity.this.startActivity(intent); } } } private class BackOnClickListenerImpl implements OnClickListener{ @Override public void onClick(View view) { // 指定Intent Intent it = new Intent(BrowserActivity.this, MediaViewRecorderActivity.class); // 跳转Intent BrowserActivity.this.startActivity(it) ; } } } |
点击视频列表项后,进行播放:
package com.makyan.demo; import android.app.Activity; import android.content.Intent; import android.media.AudioManager; import android.media.MediaPlayer; import android.os.Bundle; import android.view.KeyEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton;
public class PlayVideoActivity extends Activity { private SurfaceView surfaceView = null; private SurfaceHolder surfaceHolder = null; private MediaPlayer media = null; private ImageButton play = null; // 定义按钮 private ImageButton stop = null; // 定义按钮 private ImageButton back = null ; // 定义按钮 private String filepath = null ; // 播放文件路径 @Override protected void onCreate(Bundle savedInstanceState) { onCreate(savedInstanceState); // 设置布局管理器 setContentView(R.layout.play); play = (ImageButton) super.findViewById(R.id.play); stop = (ImageButton) super.findViewById(R.id.stop); back = (ImageButton) super.findViewById(R.id.back); filepath = super.getIntent().getStringExtra("filepath"); surfaceView = (SurfaceView) super.findViewById(R.id.surfaceView); // 设置surfaceHolder的类型 surfaceView.getHolder(). surfaceView = (SurfaceView) super.findViewById(R.id.surfaceView); // 取得SurfaceHolder surfaceHolder = this.surfaceView.getHolder(); // 设置SurfaceView的类型 surfaceHolder. // 创建MediaPlayer对象 media = new MediaPlayer(); // 重置操作 media.reset() ; try { // 设置播放文件的路径 media.setDataSource(filepath); } catch (Exception e) { e.printStackTrace(); } play.setOnClickListener(new PlayOnClickListenerImpl());// 单击事件 stop.setOnClickListener(new StopOnClickListenerImpl());// 单击事件 back.setOnClickListener(new BackOnClickListenerImpl());// 单击事件 }
private class PlayOnClickListenerImpl implements OnClickListener { @Override public void onClick(View arg0) { // 设置音频类型 PlayVideoActivity.this.media.setAudioStreamType(AudioManager.STREAM_MUSIC); // 设置显示的区域 PlayVideoActivity.this.media.setDisplay(PlayVideoActivity.this.surfaceHolder); try { // 预备状态 PlayVideoActivity.this.media.prepare(); // 播放视频 PlayVideoActivity.this.media.start(); } catch (Exception e) { e.printStackTrace(); } } } private class StopOnClickListenerImpl implements OnClickListener { @Override public void onClick(View arg0) { // 停止播放 PlayVideoActivity.this.media.stop(); } } private class BackOnClickListenerImpl implements OnClickListener{ @Override public void onClick(View view) { // 指定Intent Intent it = new Intent(PlayVideoActivity.this,BrowserActivity.class); // 跳转Intent PlayVideoActivity.this.startActivity(it) ; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // 如果是手机上的返回键 if (keyCode == KeyEvent.KEYCODE_BACK) { this.media.stop(); this.media.release(); // 程序结束 this.finish(); } return false; } }
|
录制视频布局:
activity_media_view_recorder.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"> <LinearLayout android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageButton android:id="@+id/record" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/record" /> <ImageButton android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stop" /> <ImageButton android:id="@+id/browser" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/browser" /> </LinearLayout> <TextView android:id="@+id/info" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="文字提示信息..." /> <SurfaceView android:id="@+id/surface" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
|
视频列表布局:browser.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"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <TextView android:id="@+id/info" android:textSize="25px" android:gravity="center" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="视频文件列表" /> <ImageButton android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/back" /> </LinearLayout> <ListView android:id="@+id/videolist" android:layout_width="fill_parent" android:layout_height="wrap_content" /> </LinearLayout>
|
播放视频布局play.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"> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="horizontal" android:layout_width="wrap_content" android:layout_height="wrap_content"> <ImageButton android:id="@+id/play" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/play" /> <ImageButton android:id="@+id/stop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/stop" /> <ImageButton android:id="@+id/back" android:layout_width="wrap_content" android:layout_height="wrap_content" android:src="@drawable/back" /> </LinearLayout> <SurfaceView android:id="@+id/surfaceView" android:layout_width="wrap_content" android:layout_height="wrap_content" /> </LinearLayout>
|
5.7. 多点触控
多点触控指的是可以同时对用户的多个屏幕触摸点进行监听,并进行相应处理的一种操作,在Activity类中卫用户提供了一个onTouchEvent()方法。用户就可以利用此方法完成多点触控,此方法定义如下:
public boolean onTouchEvent(MotionEvent event)(…) |
可以发现在此方法上有个android.view.MotionEvent类的事件对象,实际上用户就可以通过这个事件对象完成对用户多个触摸点的操作监听。
实例:
package com.makyan.demo; import android.app.Activity; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Matrix; import android.graphics.Paint; import android.os.Bundle; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.Window; import android.widget.ImageView; public class MulyPointTouchActivity extends Activity { private static final int SCALEBASIC = 3; // 放大比率的调整倍数 private Bitmap bitmap = null; // 通过Bitmap控制图片 private ImageView img = null; // 定义显示图片 private SurfaceHolder holder = null; // SurfaceHolder对象 private int screenWidth = 0; // 保存屏幕宽度 private int screenHeight = 0; // 保存屏幕高度 private int imageWidth = 0; // 图片宽度 private int imageHeight = 0; // 图片高度 private int imageX = 0; // 保存图片开始的X轴 private int imageY = 0; // 保存图片开始的Y轴 @Override public void onCreate(Bundle savedInstanceState) { onCreate(savedInstanceState); requestWindowFeature(Window.FEATURE_NO_TITLE); // 不显示标题 // 取得屏幕宽度 screenWidth = super.getWindowManager().getDefaultDisplay(). // 取得屏幕高度 screenHeight = super.getWindowManager().getDefaultDisplay(). img = new ImageView(this); // 定义ImageView // 取得Bitmap bitmap = BitmapFactory.decodeResource(super.getResources(),R.drawable.tianxiadiyi); // 图片宽度 imageWidth = bitmap.getWidth(); // 图片高度 imageHeight = bitmap.getHeight(); imageX = (screenWidth - imageWidth) / 2; // 图片开始的X轴 imageY = (screenHeight - imageHeight) / 2; // 图片开始的Y轴 img.setImageBitmap(bitmap); // 显示图片 setContentView(new MySurfaceView(this)); // 使用SurfaceView封装 } // 实现SurfaceView private class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback { public MySurfaceView(Context context) { super(context); // 取得SurfaceHolder MulyPointTouchActivity.this.holder = super.getHolder(); // 加入Callback操作 MulyPointTouchActivity.this.holder.addCallback(this); // 可以接收触摸事件 super.setFocusable(true); } // SurfaceView改变 @Override public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) { } // SurfaceView创建 @Override public void surfaceCreated(SurfaceHolder holder) { // 设置默认显示图片 MulyPointTouchActivity.this.setImage( MulyPointTouchActivity.this.getScale(10, 10) , 350, 500); } // 销毁 @Override public void surfaceDestroyed(SurfaceHolder holder) { } } // 设置图片 private void setImage(float scale, int width, int height) { Canvas canvas = MulyPointTouchActivity.this.holder.lockCanvas(null);// 获取画布 Paint paint = new Paint(); // 填充底色 canvas.drawRect(0, 0, MulyPointTouchActivity.this.screenWidth, MulyPointTouchActivity.this.screenHeight, paint); // 绘制矩形 Matrix matrix = new Matrix(); // 控制图象 matrix.postScale(scale, scale); // 缩放设置 Bitmap target = Bitmap.createBitmap(MulyPointTouchActivity.this.bitmap, 0, 0, width, height, matrix, true); // 创建新图片 this.imageWidth = target.getWidth(); // 取得新图片宽度 this.imageHeight = target.getHeight(); // 取得新图片高度 this.imageX = (this.screenWidth - this.imageWidth) / 2; // 重新计算X坐标 this.imageY = (this.screenHeight - this.imageHeight) / 2; // 重新计算Y坐标 canvas.translate(this.imageX, this.imageY); // 图象平移 canvas.drawBitmap(target, matrix, null); // 重新绘图 MulyPointTouchActivity.this.holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像 } private float getScale(float pointA, float pointB) { // 得到缩放比率 float scale = (pointA / pointB); return scale; } @Override public boolean onTouchEvent(MotionEvent event) { // 触摸时间 int pointCount = event.getPointerCount(); // 取得触控点的数量 if (pointCount == 2) { // 有两个触控点 float pointA = event.getY(0); // 取得第一个触摸的Y坐标 float pointB = event.getY(1); // 取得第二个触摸的Y坐标 if (pointA < pointB) { // 让pointA保存最大点 float temp = pointA; pointA = pointB; pointB = temp; } if (event.getAction() != MotionEvent.ACTION_UP) { // 用户按下 float scale = this.getScale(pointA, pointB) / SCALEBASIC;// 计算缩放量 MulyPointTouchActivity.this.setImage(scale, 350, 500); // 重设图片 } } return true; } } |