protected void getImageFromAlbum() { Intent intent = new Intent(Intent.ACTION_PICK); intent.setType("image/*");//相片类型
Camera.java
经过源码能够发现,输出的图片有2个分支
若是你没有指定Intent里面的Extra参数,它就返回一个序列化(putExtra("data", bitmap))的Bitmap,从理论上来讲,这样的代码写的很烂,属于Magic Number。
若是你指定了Intent里面的Extra参数MediaStore.EXTRA_OUTPUT,拍照后它就直接把bitmap写到了Uri里面了,返回是空
使用范围:得到很小的预览图,用于设置头像等地方。
返回示例:bitmap = data.getExtras().getParcelable("data");java
public final static int REQUEST_IMAGE_CAPTURE = 1; //start Intent intent = new Intent(android.provider.MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(intent, REQUEST_IMAGE_CAPTURE); //receive @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { Log.d(TAG, "canceled or other exception!"); return; } if (requestCode == REQUEST_IMAGE_CAPTURE) { Log.d(TAG, "REQUEST_IMAGE_CAPTURE"); Bitmap bitmap; try { bitmap = data.getExtras().getParcelable("data"); //TODO:do something with bitmap, Do NOT forget call Bitmap.recycler(); mCameraImageview.setImageBitmap(bitmap); } catch (ClassCastException e){ //do something with exceptions e.printStackTrace(); } } }
得到原始的拍照文件
使用范围:用于处理大的图片,好比使用滤镜,上传原始图像等操做,注意Uri不要用data私有目录,不然相机是写不进去的。android
public final static int REQUEST_IMAGE_CAPTURE = 1; Uri outputFileUri; //start @OnClick(R.id.itemSelectCamera) void itemSelectCamera() { File file = FileUtils.createImageFile(); outputFileUri = Uri.fromFile(file); Intent captureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); captureIntent.putExtra(MediaStore.EXTRA_OUTPUT, outputFileUri); startActivityForResult(captureIntent, REQUEST_IMAGE_CAPTURE); } //receive @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode != RESULT_OK) { Log.d(TAG, "canceled or other exception!"); return; } if (requestCode == REQUEST_IMAGE_CAPTURE) { Log.d(TAG, "REQUEST_IMAGE_CAPTURE"); //TODO:Use the Uri Intent intent = new Intent(this, ImageFilterActivity.class); intent.setData(outputFileUri); startActivity(intent); } }
关于文件如何建立,目前我找到的就是这个最稳定了,写到SD卡根目录,data目录(Context.getXXDir())是私有目录,其它程序(好比Camera)是写不进去的app
public class FileUtils { public static File createImageFile() { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = "JPEG_" + timeStamp + "_"; try { File image = File.createTempFile(imageFileName, /* prefix */ ".jpg", /* suffix */ Environment.getExternalStorageDirectory() /* directory */); return image; } catch (IOException e) { //do noting return null; } } }
第一步:在Eclipse中建立一个名为AndroidCamera的Android工程,可参见Helloworld的例子;
第二步:在AndroidManifest.xml中添加使用Camera相关的声明以下:ide
<uses-feature android:name="android.hardware.camera" android:required="false" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
第三步:编写AndroidCameraActivity类,以下:函数
import java.io.File; import java.text.SimpleDateFormat; import java.util.Date; import android.app.Activity; import android.content.Intent; import android.net.Uri; import android.os.Bundle; import android.os.Environment; import android.provider.MediaStore; import android.widget.Toast; public class AndroidCameraActivity extends Activity { private static final int CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE = 200; private Intent intent = null; private Uri fileUri = null; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); intent = new Intent(MediaStore.ACTION_VIDEO_CAPTURE);//create a intent to record video fileUri = getOutputMediaFileUri(); // create a file Uri to save the video // set the video file name intent.putExtra(MediaStore.EXTRA_OUTPUT, fileUri); // set the video quality high intent.putExtra(MediaStore.EXTRA_VIDEO_QUALITY, 1); // start the video capture Intent startActivityForResult(intent, CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if(requestCode == CAPTURE_VIDEO_ACTIVITY_REQUEST_CODE) { if (resultCode == RESULT_OK) { // video captured and saved to fileUri specified in the Intent Toast.makeText(this, "Video saved to:\n" + data.getData(), Toast.LENGTH_LONG).show(); } else if (resultCode == RESULT_CANCELED) { // User cancelled the video capture } } } /** Create a File Uri for saving a video */ private static Uri getOutputMediaFileUri(){ //get the mobile Pictures directory File picDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES); //get the current time String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); File videoFile = new File(picDir.getPath() + File.separator + "VIDEO_"+ timeStamp + ".mp4"); return Uri.fromFile(videoFile); } }
MediaRecorder类详解
手机通常都有麦克风和摄像头,而Android系统就能够利用这些硬件来录制音视频了。
为了增长对录制音视频的支持,Android系统提供了一个MediaRecorder的类。
结构:ui
Java.lang.Object android.media.MediaRecorder
与MediaPlayer类很是类似MediaRecorder也有它本身的状态图。下面是关于MediaRecorder的各个状态的介绍:
Initial:初始状态,当使用new()方法建立一个MediaRecorder对象或者调用了reset()方法时,该MediaRecorder对象处于Initial状态。在设定视频源或者音频源以后将转换为Initialized状态。另外,在除Released状态外的其它状态经过调用reset()方法均可以使MediaRecorder进入该状态。
Initialized:已初始化状态,能够经过在Initial状态调用setAudioSource()或setVideoSource()方法进入该状态。在这个状态能够经过setOutputFormat()方法设置输出格式,此时MediaRecorder转换为DataSourceConfigured状态。另外,经过reset()方法进入Initial状态。
DataSourceConfigured:数据源配置状态,这期间能够设定编码方式、输出文件、屏幕旋转、预览显示等等。能够在Initialized状态经过setOutputFormat()方法进入该状态。另外,能够经过reset()方法回到Initial状态,或者经过prepare()方法到达Prepared状态。
Prepared:就绪状态,在DataSourceConfigured状态经过prepare()方法进入该状态。在这个状态能够经过start()进入录制状态。另外,能够经过reset()方法回到Initialized状态。
Recording:录制状态,能够在Prepared状态经过调用start()方法进入该状态。另外,它能够经过stop()方法或reset()方法回到Initial状态。
Released:释放状态(官方文档给出的词叫作Idle state 空闲状态),能够经过在Initial状态调用release()方法来进入这个状态,这时将会释放全部和MediaRecorder对象绑定的资源。
Error:错误状态,当错误发生的时候进入这个状态,它能够经过reset()方法进入Initial状态。
提示:与MediaPlayer类似使用MediaRecorder录音录像时须要严格遵照状态图说明中的函数调用前后顺序,在不一样的状态调用不一样的函数,不然会出现异常。
实例描述了的建立过程this
MediaRecorder recorder=newMediaRecorder(); recorder.setAudioSource(MediaRecorder.AudioSource.MIC); recorder.setOutputFormat(MediaRecorder.OutputFormat.THREE_GPP); recorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB); recorder.setOutputFile(PATH_NAME); recorder.prepare(); recorder.start(); // Recording is now started ... recorder.stop(); recorder.reset(); // You can reuse the object by going back to setAudioSource() step recorder.release();// Now the object cannot be reused
实践
使用MediaRecorder录制声音的:
1) 建立 MediaRecorder 对象。
2) 调用MediaRecorder对象的setAudioSource()方法设置声音来源,通常传入 MediaRecorder. AudioSource.MIC参数指定录制来自麦克风的声音。
3) 调用MediaRecorder对象的setOutputFormat()设置所录制的音频文件的格式。
4) 调用MediaRecorder 对象的setAudioEncoder()、setAudioEncodingBitRate(intbitRate)、 setAudioSamplingRate(int samplingRate)设置所录制的声音的编码格式、编码位率、采样率等, 这些参数将能够控制所录制的声音的品质、文件的大小。通常来讲,声音品质越好,声音文件越大。
5) 调用MediaRecorder的setOutputFile(Stringpath)方法设置录制的音频文件的保存位置。
6) 调用MediaRecorder的prepare()方法准备录制。
7) 调用MediaRecorder对象的start()方法开始录制。
8) 录制完成,调用MediaRecorder对象的stop()方法中止录制,并调用release()方法释放资源。编码
<span style="font-size:18px;">package com.jph.recordsound; import java.io.File; import org.crazyit.sound.R; import android.app.Activity; import android.media.MediaRecorder; import android.os.Bundle; import android.os.Environment; import android.view.View; import android.view.View.OnClickListener; import android.widget.ImageButton; import android.widget.Toast; public class RecordSound extends Activity implements OnClickListener { // 定义界面上的两个按钮 ImageButton record, stop; // 系统的音频文件 File soundFile; MediaRecorder mRecorder; @Override public void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); // 获取程序界面中的两个按钮 record = (ImageButton) findViewById(R.id.record); stop = (ImageButton) findViewById(R.id.stop); // 为两个按钮的单击事件绑定监听器 record.setOnClickListener(this); stop.setOnClickListener(this); } @Override public void onDestroy() { if (soundFile != null && soundFile.exists()) { // 中止录音 mRecorder.stop(); // 释放资源 mRecorder.release(); mRecorder = null; } super.onDestroy(); } @Override public void onClick(View source) { switch (source.getId()) { // 单击录音按钮 case R.id.record: if (!Environment.getExternalStorageState().equals( android.os.Environment.MEDIA_MOUNTED)) { Toast.makeText(RecordSound.this, "SD卡不存在,请插入SD卡!", Toast.LENGTH_SHORT).show(); return; } try { // 建立保存录音的音频文件 soundFile = new File(Environment .getExternalStorageDirectory().getCanonicalFile() + "/sound.amr"); mRecorder = new MediaRecorder(); // 设置录音的声音来源 mRecorder.setAudioSource(MediaRecorder .AudioSource.MIC); // 设置录制的声音的输出格式(必须在设置声音编码格式以前设置) mRecorder.setOutputFormat(MediaRecorder .OutputFormat.AMR_NB); // 设置声音编码的格式 mRecorder.setAudioEncoder(MediaRecorder .AudioEncoder.AMR_NB); mRecorder.setOutputFile(soundFile.getAbsolutePath()); mRecorder.prepare(); // 开始录音 mRecorder.start(); //① } catch (Exception e) { e.printStackTrace(); } break; // 单击中止按钮 case R.id.stop: if (soundFile != null && soundFile.exists()) { // 中止录音 mRecorder.stop(); //② // 释放资源 mRecorder.release(); //③ mRecorder = null; } break; } } }</span>
结果图
spa