SoundPool(播放小音频),MediaRecorder(录音),视频播放,开启摄像头
2015-09-15 21:23
253 查看
SoundPool
SoundPool是播放一些小的音频文件,这些文件因为比较小所以会将其完全加载到内存中然会再播放, MediaPlayer由于是播放比较大的文件,所以会边加载边播放。 一般在res中新建一个文件夹(raw)必须是这个名称。然会就可以用SoundPool调用这个文件进行播放了。代码如下:
protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); soundpool_button= (Button) findViewById(R.id.soundPool_button); soundpool_stop_button= (Button) findViewById(R.id.soundPool_Stop_button); soundpool_stop_button.setOnClickListener(this); soundpool_button.setOnClickListener(this); id= iniPlay(); } int a; private SoundPool pool=null; @Override public void onClick(View v) { switch (v.getId()){ case R.id.soundPool_button: //public final int play (int soundID, float leftVolume, float rightVolume, int priority, int loop, float rate) //soundID a soundID returned by the load() function // leftVolume left volume value (range = 0.0 to 1.0) // rightVolume right volume value (range = 0.0 to 1.0) //priority stream priority (0 = lowest priority) //loop loop mode (0 = no loop, -1 = loop forever) // rate playback rate (1.0 = normal playback, range 0.5 to 2.0) a= pool.play(id, 1,1,0,-1,1); break; case R.id.soundPool_Stop_button: pool.stop(a); break; } } private int iniPlay() { if(Build.VERSION.SDK_INT>=21){ //SDK在21即以上版本的用法 SoundPool.Builder builder = new SoundPool.Builder(); builder.setMaxStreams(2); AudioAttributes.Builder attrBuilder= new AudioAttributes.Builder(); attrBuilder.setLegacyStreamType(AudioManager.STREAM_MUSIC); builder.setAudioAttributes(attrBuilder.build()); pool= builder.build(); }else { //public SoundPool(int maxStream, int streamType, int srcQuality) // maxStream —— 同时播放的流的最大数量 // streamType —— 流的类型,一般为STREAM_MUSIC(具体在AudioManager类中列出) // srcQuality —— 采样率转化质量,当前无效果,使用0作为默认值 pool=new SoundPool(2, AudioManager.STREAM_MUSIC,0); } int id= pool.load(getApplicationContext(), R.raw.outgoing,1); return id; }
SDK在21之前直接用new SoundPool()去建立pool,21(包括21)之后会先建立一个builder,然后再进行一系列的操作再建立pool,所以在代码中会先判断SDK的版本号,根据不同的版本号进行不同的操作。具体的代码内容注释已经讲的比较清楚了,这里不再赘余。
注意:在load后不可以立刻play,因为load需要时间,所以将两者分开,初始化在oncreat中
MediaRecorder
MediaRecorder既录音也可以录视频,这里先讲录音。首先建立一个MediaRecorder的对象,然后设置音频来源(一般是麦克风)、设置音频的格式(一般是THREE_GPP)、设置编码格式(一般为AMR_NB)、设置生成文件的地址和文件名(注意有‘/’和后缀名)。代码如下:
myRecorder=new MediaRecorder(); //设置声音的来源 myRecorder.setAudioSource(MediaRecorder.AudioSource.MIC); //设置音频的格式 myRecorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); //设置编码格式 myRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); //设置生成文件的地址 myRecorder.setOutputFile(Environment.getExternalStorageDirectory()+"/Music/myRecord.MP3"); try { //准备录音 myRecorder.prepare(); //开始录音 myRecorder.start(); } catch (IOException e) { e.printStackTrace(); }
若想停止调用一下代码进行释放资源:
//停止录音 myRecorder.stop(); myRecorder.reset(); //释放资源 myRecorder.release();
视频播放
VideoView
VideoView播放视频比较简单,VideoView是一个控件,必须在XML中建立,如下:
<VideoView android:id="@+id/video_view" android:layout_width="match_parent" android:layout_height="0dp" android:layout_weight="1" />
在代码中:
myVideoView.setVideoPath(Environment.getExternalStorageDirectory()+"/Movies/pp.mp4"); myVideoView.setMediaController(new MediaController(MyRecorder.this)); myVideoView.start();
上面的代码是播放Movies文件夹下pp.mp4文件。这个控件自动会带播放和停止按钮。
SurfaceView
SurfaceView也可以播放视频,这个控件在播放视频的时候不会受到UI主线程的控制,而是利用MediaPlayer在控件中播放视频。MediaPlayer的对象配置完各个参数后,调用 player.setDisplay(surfaceView.getHolder());就可以在SurfaceView控件中播放视频了。完整的代码如下:if(player==null){ player = new MediaPlayer(); } player.reset(); try { player.setDataSource(Environment.getExternalStorageDirectory()+"/pp.mp4"); player.setAudioStreamType(AudioManager.STREAM_MUSIC); player.setDisplay(surfaceView.getHolder()); player.prepare(); player.setOnPreparedListener(new MediaPlayer.OnPreparedListener() { @Override public void onPrepared(MediaPlayer mp) { mp.start(); } }); } catch (IOException e) { e.printStackTrace(); }
开启摄像头
开启摄像头是在ACtivity中打开系统自带的摄像头应用。代码如下:public void onClick(View v) { Intent intent = new Intent(); //获得摄像头的action,并设置到intent中 intent.setAction(MediaStore.ACTION_IMAGE_CAPTURE); file = new File(Environment.getExternalStorageDirectory(), System.currentTimeMillis()+".jpg"); try { file.createNewFile(); } catch (IOException e) { e.printStackTrace(); } //将生成的照片放到file文件中。 intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file)); //启动摄像头并获得返回值的照片 startActivityForResult(intent, 0x23); } }); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode==0x23){ if(resultCode==RESULT_OK){ //将获取的照片放到ImageView中 imageView.setImageURI(Uri.fromFile(file)); } } }
在上面的代码中有时会因为图片过大而不能显示出来,所以必须对图片进行压缩,代码如下:
private void zipImage(String savePath) { BitmapFactory.Options options = new BitmapFactory.Options(); options.inJustDecodeBounds = true; BitmapFactory.decodeFile(savePath, options); options.inSampleSize = computeInitialSampleSize(options, 480, 480 * 960); options.inJustDecodeBounds = false; Bitmap bitmap = BitmapFactory.decodeFile(savePath, options); try { FileOutputStream fos = new FileOutputStream(savePath); bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos); fos.flush(); fos.close(); } catch (IOException e) { e.printStackTrace(); } bitmap.recycle(); bitmap = null; System.gc(); } public int computeSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { int initialSize = computeInitialSampleSize(options, minSideLength, maxNumOfPixels); int roundedSize; if (initialSize <= 8) { roundedSize = 1; while (roundedSize < initialSize) { roundedSize <<= 1; } } else { roundedSize = (initialSize + 7) / 8 * 8; } return roundedSize; } private int computeInitialSampleSize(BitmapFactory.Options options, int minSideLength, int maxNumOfPixels) { double w = options.outWidth; double h = options.outHeight; int lowerBound = (maxNumOfPixels == -1) ? 1 : (int) Math.ceil(Math .sqrt(w * h / maxNumOfPixels)); int upperBound = (minSideLength == -1) ? 128 : (int) Math.min( Math.floor(w / minSideLength), Math.floor(h / minSideLength)); if (upperBound < lowerBound) { // return the larger one when there is no overlapping zone. return lowerBound; } if ((maxNumOfPixels == -1) && (minSideLength == -1)) { return 1; } else if (minSideLength == -1) { return lowerBound; } else { return upperBound; } }
在onActivityResult方法中调用 zipImage(file.getAbsolutePath());//对图片进行压缩。
//将获取的照片放到ImageView中
imageView.setImageURI(Uri.fromFile(file));
就可以对压缩的图片进行显示了。
在相册中选择图片
在相册中选择图片的代码如下:gallery_button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { Intent intent = new Intent(Intent.ACTION_GET_CONTENT); intent.setType("image/*"); // startActivityForResult(intent,0x24); } });
在onActivityResult中:
case 0x24: Uri uri= data.getData(); String s = getAbsoluteImagePath(uri); zipImage(s);//对图片进行压缩 imageView.setImageURI(uri); break;
getAbsoluteImagePath(uri)为根据uri获得文件的绝对路径的方法。
protected String getAbsoluteImagePath(Uri uri) { // can post image String [] proj={MediaStore.Images.Media.DATA}; Cursor cursor = managedQuery( uri, proj, // Which columns to return null, // WHERE clause; which rows to return (all rows) null, // WHERE clause selection arguments (none) null); // Order-by clause (ascending by name) int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); cursor.moveToFirst(); return cursor.getString(column_index); }
相关文章推荐
- android学习笔记(三)——Activity
- 第一章 核心动画概念
- Qt 学习之路 :视图代理
- 离散对数
- Adb fail to restart! ADB server didn't ACK
- shellcode
- 如何获取当前屏幕显示的viewcontroller
- 用net beans 学 java
- 八皇后问题求解
- 程序集和应用程序域
- 【学习日记】java反射的知识点总结
- csdn博客开通了
- 图像处理
- mac 终端 常用命令
- CF div2 318 B
- 策略模式
- 2015.9.15 包 模块导入相关
- win7 http://localhost不能访问解决方法
- 搭建虚拟机下ubuntu的qt-arm交叉编译工具
- 深入浅出聊优化:从Draw Calls到GC