mainActivity如下:
package c.c;
import java.io.IOException;
import java.util.Iterator;
import java.util.List;
import android.app.Activity;
import android.content.ContentResolver;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.RelativeLayout;
/**
*需求描述:
*利用SurfaceView预览,且拍照.
*将拍摄后的图片保存至相册
*
*注意
*1 权限
* <uses-permission android:name="android.permission.CAMERA"/>
*2 屏幕旋转后SurfaceView中预览的图片有90度的旋转
* 解决方式:
* 2.1将屏幕设置为竖屏
* setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
* 2.2设置相机的Orientation
* mCamera.setDisplayOrientation(90);
* 注意:
* 该问题虽然解决了,但是会带来以下的一个问题.
*3 拍照保存的图片可能被旋转90度.
* 解决方式:
* http://blog.csdn.net/walker02/article/details/8211628
* http://www.cnblogs.com/andgoo/archive/2012/08/29/2661896.html
*
* 此Demo中如下解决该问题
*
* 关于以上问题解决的说明:
* 1 相机拍照默认的是横屏的
* 以ME525+为例,默认的是LOGO在左边
* 平常的竖屏LOGO在上边.所以,需要将相机旋转90度.
* 即mCamera.setDisplayOrientation(90);
* 这样才能在横竖屏切换后预览画面正常显示.
* 2 最好不要在代码中设置Activity以什么方式(横/竖屏)显示,比如:
* setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
* 应该写在配置文件中,这样效率更高.
* 3 现在已经把Activity设置为竖屏了.所以onConfigurationChanged()
* 方法已经不能起到期望的作用.
* 但是还需要监听现在屏幕是横屏还是竖屏.所以在此采用了重力感应的
* 方式来实现.应该还有其他更好的办法,待调查.
* 4 小bug:LOGO朝右边的时候,拍出的照片仍然被旋转了
*/
public class MainActivity extends Activity
implements SurfaceHolder.Callback,OnClickListener,Camera.PictureCallback{
private SensorManager mSensorManager;
private AccSensorListener mAccSensorListener=null;
private Sensor mSensor;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Camera mCamera;
private float y=0;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//设置Activity竖屏显示
setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
setContentView(R.layout.main);
init();
}
private void init(){
mSensorManager=(SensorManager) getSystemService(SENSOR_SERVICE);
mSensor=mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
mSensorManager.registerListener
(new AccSensorListener(), mSensor, SensorManager.SENSOR_DELAY_NORMAL);
mAccSensorListener=new AccSensorListener();
mSurfaceView=(SurfaceView) findViewById(R.id.surfaceView);
mSurfaceView.setFocusable(true);
mSurfaceView.setFocusableInTouchMode(true);
mSurfaceView.setClickable(true);
mSurfaceView.setOnClickListener(this);
mSurfaceHolder=mSurfaceView.getHolder();
//设置该SurfaceView是一个"推送"类型的SurfaceView
mSurfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mSurfaceHolder.addCallback(this);
}
@Override
protected void onDestroy() {
super.onDestroy();
//取消重力感应
mSensorManager.unregisterListener(mAccSensorListener);
}
private class AccSensorListener implements SensorEventListener{
public void onSensorChanged(SensorEvent event) {
//System.out.println("xxxxxx event.values[1]="+event.values[1]);
y=event.values[1];
}
public void onAccuracyChanged(Sensor sensor, int accuracy) {
}
}
//2 parameters.getSupportedXXX的到相机支持的一些效果或者模式,比如:
//parameters.getSupportedPictureFormats();
//parameters.getSupportedColorEffects();
//parameters.getSupportedFocusModes();
//parameters.getSupportedWhiteBalance();
public void surfaceCreated(SurfaceHolder holder) {
final int LARGEST_WIDTH=200;
final int LARGEST_HEIGHT=200;
int bestWidth=0;
int bestHeight=0;
mCamera=Camera.open();
Camera.Parameters parameters=mCamera.getParameters();
//操作1 为相机设置某种特效
List<String> colorEffects=parameters.getSupportedColorEffects();
Iterator<String> iterator1=colorEffects.iterator();
while (iterator1.hasNext()) {
String effect = (String) iterator1.next();
if (effect.equals(Camera.Parameters.EFFECT_SOLARIZE)) {
//若支持过度曝光效果,则设置该效果
//parameters.setColorEffect(Camera.Parameters.EFFECT_SOLARIZE);
break;
}
}
//操作2 改变SurfaceView的大小
List<Camera.Size> previewSizes=parameters.getSupportedPreviewSizes();
if (previewSizes.size()>1) {
Iterator<Camera.Size> iterator2=previewSizes.iterator();
while (iterator2.hasNext()) {
Camera.Size size = (Camera.Size) iterator2.next();
if (size.width>bestWidth&&size.width<=LARGEST_WIDTH&&
size.height>bestHeight&&size.height<=LARGEST_HEIGHT) {
bestWidth=size.width;
bestHeight=size.height;
}
}
if (bestWidth!=0&&bestHeight!=0) {
parameters.setPreviewSize(bestWidth, bestHeight);
mSurfaceView.setLayoutParams
(new RelativeLayout.LayoutParams(bestWidth, bestHeight));
}
}
//操作3 当屏幕变化时,旋转角度.否则不对
//因为刚开始时竖屏的
mCamera.setDisplayOrientation(90);
//操作结束
try {
//将摄像头的预览显示设置为mSurfaceHolder
mCamera.setPreviewDisplay(mSurfaceHolder);
} catch (IOException e) {
mCamera.release();
}
//设置输出格式
parameters.setPictureFormat(PixelFormat.JPEG);
//设置摄像头的参数.否则前面的设置无效
mCamera.setParameters(parameters);
//摄像头开始预览
mCamera.startPreview();
}
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
mCamera.startPreview();
}
public void surfaceDestroyed(SurfaceHolder holder) {
mCamera.stopPreview();
mCamera.release();
}
//处理SurfaceView的点击事件
public void onClick(View v) {
mCamera.takePicture(null, null, this);
}
public void onPictureTaken(byte[] data, Camera camera) {
//将图片保存至相册
if (y>0) {
System.out.println("竖屏 竖屏 竖屏 竖屏 竖屏 竖屏 ");
ContentResolver resolver = getContentResolver();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
Matrix matrix=new Matrix();
matrix.setRotate(90);
Bitmap bitmap2=Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
MediaStore.Images.Media.insertImage(resolver, bitmap2, "xxoo", "des");
}else {
System.out.println("横屏 横屏 横屏 横屏 横屏 横屏 ");
ContentResolver resolver = getContentResolver();
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
MediaStore.Images.Media.insertImage(resolver, bitmap, "xxoo", "des");
}
//mSensorManager.unregisterListener(mAccSensorListener);
//拍照后重新开始预览
camera.startPreview();
}
}
main.xml如下:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity" >
<SurfaceView
android:id="@+id/surfaceView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</RelativeLayout>