最近项目中需要在界面中点击按钮拍照,但不展示预览界面(吐槽:什么鬼需求),本来以为比较简单,但在实现时遇到几个问题,在此记录下
本人的实现思路是将预览界面的大小设置为一个宽高都为1px的界面就可以了
一开始的代码
Camera camera;
private void takePhoto(){
if (camera == null)
camera = Camera.open();
if (camera != null) {
SurfaceView surfaceView = new SurfaceView(this);
//设置预览
try {
camera.setPreviewDisplay(surfaceView.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
camera.startPreview();
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
try {
File file = getFile();
if (file == null) {
return;
}
FileOutputStream fos = new FileOutputStream(file);
fos.write(data);
fos.close();
Log.e("PhotoHandler", "图片保存完成");
} catch (Exception error) {
error.printStackTrace();
}
camera.stopPreview();
}
});
}
}
private String FILE_PATH = Environment
.getExternalStorageDirectory().getAbsolutePath()
+ "/testImage/";
private File getFile() {
File f = new File(FILE_PATH);
if (!f.exists()) {
f.mkdirs();
}
String timeStamp = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
File file;
file = new File(FILE_PATH,
"IMG_" + timeStamp + ".jpg");
try {
if (!file.exists()) {
file.createNewFile();
}
} catch (IOException e) {
e.printStackTrace();
}
return file;
}
报错:Caused by: java.lang.RuntimeException: takePicture failed
百度了下找到解决方法
问题是在相机实例上开始预览后,需要一些时间才能拍照
camera.startPreview();
camera.setOneShotPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
camera.takePicture(null, null, new Camera.PictureCallback() {
@Override
public void onPictureTaken(byte[] data, Camera camera) {
// do something you want with your picture and stop preview
camera.stopPreview();
}
});
将takePicture方法放在setOneShotPreviewCallback回调中解决问题
又遇见问题 调用后没反应,回调中也没走
后来发现是SurfaceView 问题,直接new的话就会有这个问题,在xml文件中声明就没有问题(暂时不知道原因,哪位大佬知道麻烦告知,谢谢)
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#ffffff">
<SurfaceView
android:id="@+id/sview"
android:layout_width="1px"
android:layout_height="1px"/>
<ImageView
android:layout_margin="5dp"
android:id="@+id/button"
android:layout_centerInParent="true"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@mipmap/ic_launcher_round"/>
</RelativeLayout>
Camera camera;
private SurfaceView surfaceview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
surfaceview = findViewById(R.id.sview);
ImageView button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
takePhoto();
}
});
}
private void takePhoto(){
if (camera == null)
camera = Camera.open();
if (camera != null) {
// SurfaceView surfaceView = new SurfaceView(this);
//设置预览
try {
camera.setPreviewDisplay(surfaceview.getHolder());
} catch (IOException e) {
e.printStackTrace();
}
.......
}
}
最终实现需求
网友评论