最近开工做项目了,需要前期准备下技术,项目中需要用到Camera的相关技术,偶然在GitHub上发现了这个东西–EasyCamera,使得调用相机的相关操作变得更加简单了。
这样我们先把Github上的文件先clone一下,将zip文件下载下来,然后解压,由于这个项目还是用的Eclipse构建,用Eclipse的用户就可以跳过这一段了。
为了构建方便我们自己新建一个Library的Module,这样走File->New Module到达下面这个页面:
按照图片中选中的点击Next,然后需要给你的Library来一个名字,然后到达这个页面:
选择Add No Activity,然后直接点击Finish即可。这样我们的Library就创建好了。
我想说的是为何这么做?昨天在研究的时候,因为用到了.aar作为EasyCamera的库,并没有找到合适的方法导入.aar文件,导致自己在这个问题上浪费了不少时间,所以还是选择了这样一种方式来引入,方便而且更快捷。
下边就是需要创建我们的工程Module了,在第一张图上点击Phone And Tablet Application的选项,这样一步步创建好就OK了。
然后是在工程中引入我们刚才创建的库,这个不是很麻烦的问题,请参考我的这篇文章Android Studio--引用自己创建的Library
这样基本上万事具备了,我们需要将我们下载的zip文件解压,将下图所示的三个文件拷贝到Library中的java代码位置:
好了这样我们就能正常引用这个EasyCamera的库了。
这时候前期准备工作正式完成。下面我们来写一个相机的实例来感受一下。
首先先附上布局文件activity_main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">
<SurfaceView
android:id="@+id/camera_preview"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:layout_weight="1"
/>
<Button
android:id="@+id/btn_capture"
android:text="Capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
/>
</LinearLayout>
布局文件很简单,不做过多解释,就是一个相机预览和拍照按钮。
然后附上MainActivity.java的代码:
import library.DefaultEasyCamera;
import library.EasyCamera;
import android.content.Context;
import android.hardware.Camera;
import android.os.Environment;
import android.support.v7.app.ActionBarActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends ActionBarActivity {
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private Button capture;
/**
* 判断是否在预览状态
*/
private boolean previewIsRunning = false;
private EasyCamera mEasyCamera;
private EasyCamera.CameraActions mCameraActions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mSurfaceView = (SurfaceView) findViewById(R.id.camera_preview);
capture = (Button) findViewById(R.id.btn_capture);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) {
// 开启后置摄像头
mEasyCamera = DefaultEasyCamera.open(Camera.CameraInfo.CAMERA_FACING_BACK);
// 设置相机翻转角度
// mEasyCamera.setDisplayOrientation(90);
// 正常显示相机预览
WindowManager manager = (WindowManager) MainActivity
.this.getSystemService(Context.WINDOW_SERVICE);
mEasyCamera.alignCameraAndDisplayOrientation(manager);
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if(!previewIsRunning && mEasyCamera != null) {
try {
// 开启预览
mCameraActions = mEasyCamera.startPreview(holder);
} catch (IOException e) {
e.printStackTrace();
}
previewIsRunning = true;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// 停止预览并释放
mEasyCamera.stopPreview();
mEasyCamera = null;
}
});
capture.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
EasyCamera.PictureCallback mPictureCallback = new EasyCamera.PictureCallback(){
@Override
public void onPictureTaken(byte[] data, EasyCamera.CameraActions actions) {
// 停止预览
mEasyCamera.stopPreview();
try {
// 延时1000s,看的更加清楚
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
// 存储图片的操作
FileOutputStream fos = null;
try {
Log.d("TAG",getExternalFilesDir(Environment.DIRECTORY_PICTURES)+File.separator+"abc.jpg");
fos = new FileOutputStream(new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES)
<span style="white-space:pre"> </span>+File.separator+"abc.jpg"));
fos.write(data);
fos.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
// 开启预览
EasyCamera.Callbacks.create().withRestartPreviewAfterCallbacks(true);
try {
mEasyCamera.startPreview(mSurfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
}
};
// 拍摄照片的操作
mCameraActions.takePicture(
EasyCamera.Callbacks.create().withJpegCallback(mPictureCallback));
}
});
}
}
最后的话需要我们把相应的permission加上,但是我们可以把这个权限加载Library中,这样我们的工程就不需要添加了!权限如下:
<uses-permission android:name=”android.permission.CAMERA”/>
<uses-feature android:name=”android.hardware.camera” android:required=”false”/>
好了,这样我们来看一下运行效果,
中间发生了一个小错误,就是在运行时点击中间的home键退出时,再次进入程序发生了崩溃的现象,深入查看代码的时候,是自己释放相机的时候考虑的不够周全,现在对于自己的代码做出这样的修改:
<span style="white-space:pre"> </span>@Override
public void surfaceDestroyed(SurfaceHolder holder) {
Log.d("TAG","surfaceDestroyed停止并释放");
// 停止预览并释放
mEasyCamera.stopPreview();
mEasyCamera.release();
mEasyCamera = null;
mCameraActions = null;
previewIsRunning = false;
}
而且在代码头部mEasyCamera = null,这样修改后,问题就不大了。在修改的过程中,你可能会发现,没有Camera的release的相应代码,这样我们就修改下源代码了。
首先我们在EasyCamera接口中添加release方法,如下:
/**
* 释放相机的方法
*/
void release();
然后在DefaultCamera中来实现这个方法:
@Override
public void release() {
camera.release();
}
这样简单的一修改我们就可以在自己的代码中将相机完美的释放了!
怎么样是不是很简单啊?
这里附上我的源代码下载地址。
参考文章:http://techblog.bozho.net/fixing-the-android-camera-api/ 英文好的朋友可以直接过来读!
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/38945.html