android实现前置后置摄像头相互切换
首先自定义一个继承自SurfaceView并且实现了SurfaceHolder.Callback接口的组件:
public class CameraView extends SurfaceView implements Callback {
private SurfaceHolder surfaceHolder;
private Camera mCamera;
public CameraView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public void init(Camera camera){
surfaceHolder = getHolder();
surfaceHolder.addCallback(this);
mCamera = camera;
}
/**
* 初始化SurfaceView时调用一次,另外更改surface或者onpause->onresume时调用
*/
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
if(holder.getSurface() == null || mCamera == null){
return;
}
mCamera.stopPreview();
try {
mCamera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
}
@Override
public void surfaceCreated(SurfaceHolder holder) {
if(mCamera == null){
return;
}
try {
mCamera.setPreviewDisplay(surfaceHolder);
} catch (IOException e) {
e.printStackTrace();
}
mCamera.startPreview();
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
// TODO Auto-generated method stub
}
}
检查设备是否有摄像头:
private boolean checkCamera(){
return MainActivity.this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
标记前置,后置摄像头,以及当前打开的摄像头,并且首先默认打开前置摄像头,监听Button的click事件,切换摄像头:
public class MainActivity extends Activity {
private Button button;
private Camera camera;
private CameraView cameraView;
private static final int FRONT = 1;//前置摄像头标记
private static final int BACK = 2;//后置摄像头标记
private int currentCameraType = -1;//当前打开的摄像头标记
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(!checkCamera()){
MainActivity.this.finish();
}
try {
camera = openCamera(FRONT);
} catch (Exception e) {
e.printStackTrace();
}
button = (Button)findViewById(R.id.button);
button.setOnClickListener(new Button.OnClickListener() {
@Override
public void onClick(View v) {
try {
changeCamera();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
cameraView = (CameraView)findViewById(R.id.cameraview);
cameraView.init(camera);
}
/**
* @return 摄像头是否存在
*/
private boolean checkCamera(){
return MainActivity.this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA);
}
@SuppressLint("NewApi")
private Camera openCamera(int type){
int frontIndex =-1;
int backIndex = -1;
int cameraCount = Camera.getNumberOfCameras();
CameraInfo info = new CameraInfo();
for(int cameraIndex = 0; cameraIndex<cameraCount; cameraIndex++){
Camera.getCameraInfo(cameraIndex, info);
if(info.facing == CameraInfo.CAMERA_FACING_FRONT){
frontIndex = cameraIndex;
}else if(info.facing == CameraInfo.CAMERA_FACING_BACK){
backIndex = cameraIndex;
}
}
currentCameraType = type;
if(type == FRONT && frontIndex != -1){
return Camera.open(frontIndex);
}else if(type == BACK && backIndex != -1){
return Camera.open(backIndex);
}
return null;
}
private void changeCamera() throws IOException{
camera.stopPreview();
camera.release();
if(currentCameraType == FRONT){
camera = openCamera(BACK);
}else if(currentCameraType == BACK){
camera = openCamera(FRONT);
}
camera.setPreviewDisplay(cameraView.getHolder());
camera.startPreview();
}
}
布局文件:
<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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" > <Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/switchcamera" /> <com.example.cameratest.CameraView
android:id="@+id/cameraview"
android:layout_below="@id/button"
android:layout_width="fill_parent"
android:layout_height="fill_parent"/>
</RelativeLayout>
当然,首先得申明权限跟软硬件环境:
<uses-permission android:name="android.permission.CAMERA"/>
<uses-feature android:name="android.hardware.camera"/>
最好把activity的screenOrientation设置为landscape,不然显示的方向不对。
如果有可以优化的地方,望各位大侠指导,谢谢。
android实现前置后置摄像头相互切换的更多相关文章
- win 10 禁用后置摄像头
2.双摄像头电脑,甄别时默认开启的是后置摄像头,识别不到人脸. (1)更换设备参加甄别: (2)自行调整:停用电脑后置摄像头,停用后甄别时会默认调取前置摄像头: 以下操作适用于Windows surf ...
- spring 切面 前置后置通知 环绕通知demo
环绕通知: <?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http:// ...
- AOP 环绕通知 集成了前置 后置 返回通知等功能
AOP 环绕通知 集成了前置 后置 返回通知等功能
- uwp之拍照(使用后置摄像头)
参考:wp8.1之拍照(获取焦点,使用后置摄像头) uwp开启摄像头要借助CaptureElement呈现来自捕获设备(如照相机或网络摄像机)的流.今天讲讲如何打开摄像头,获取焦点,以及拍照.废话不多 ...
- wp8.1之拍照(获取焦点,使用后置摄像头)
wp8.1 没有像wp8一样直接用启动器开启摄像头,他要开启摄像头要借助CaptureElement呈现来自捕获设备(如照相机或网络摄像机)的流.今天讲讲如何打开摄像头,获取焦点,以及拍照.废话不多说 ...
- pytest_前置后置
今天总结下pytest,pytest简直就是python自动化中的高富帅,各种操作,哈哈 这次总结主要涉及到了以下几点: 1.unittest中的setUp.tearDown.setUpClass.t ...
- Spring Bean前置后置处理器的使用
Spirng中BeanPostProcessor和InstantiationAwareBeanPostProcessorAdapter两个接口都可以实现对bean前置后置处理的效果,那这次先讲解一下B ...
- unittest的前置后置,pytest的fixture和共享机制conftest.py
Unittest setUp/tearDown setUp当中得到的变量,用self.xxx = value传递给测试用例 setUpClass/tearDownClass setupClass当中得 ...
- C: printf参数执行顺序与前置后置自增自减的影响
起源: 今天在了解副作用side-effect的过程中,看到了下面的网页,把我带到了由printf引起的一系列问题,纠结了一整天,勉强弄懂. 第一个代码没什么好解释的.而第二个printf(" ...
随机推荐
- C,通信,多线程,数据库小练习——在线电子词典第一版
#ifndef FILE_H #define FILE_H #include<stdio.h> #include<sys/types.h> #include<sys/so ...
- StackOverflow之旅<1>------{去掉烦人的"!=null"判断}
问题 为了避免空指针调用,我们经常会看到这样的语句 if (someobject != null) { someobject.doCalc(); } 最终,项目中会存在大量判空代码,多么丑陋繁冗!如何 ...
- 交叉验证(Cross Validation)方法思想简介
以下简称交叉验证(Cross Validation)为CV.CV是用来验证分类器的性能一种统计分析方法,基本思想是把在某种意义下将原始数据(dataset)进行分组,一部分做为训练集(train ...
- VC-基础-WebBrowser控件中弹出新网页窗口
用webbrowser控件浏览网页时,常弹出新的网页窗口,若不做任何控制的话,会在默认浏览器(一般是IE)中打开,这样就在新的窗口打开了,原程序就很难控制了,且存在webbrowser控件和IE的se ...
- GB MB KB B 关系
1KB=1024Bytes=2的10次方Bytes 1MB=1024KB=2的20次方Bytes 1GB=1024MB=2的30次方Bytes 1TB=1024GB=2的40次方Bytes
- 定位设备--llseek实现
/** 如果llseek实现lseek和llseek系统调用,如果未定义llseek方法, 内核默认修改file结构体中的f_pos成员来实现定位,如果是操作一个 设备,则需提供自己的llseek方法 ...
- c 语言技巧
位运算 & 位逻辑与 | 位逻辑或 ^ 位逻辑异或 - 位逻辑反 >> 右移 << 左移 通过对数据本身的01编码进行处理,速度稍微快于普通运算符 如,10 / 2 = ...
- 6- vue django restful framework 打造生鲜超市 -完成商品列表页(下)
Vue+Django REST framework实战 搭建一个前后端分离的生鲜超市网站 Django rtf 完成 商品列表页下 drf中的request和response drf对于django的 ...
- flock文件锁
linux中的定时任务crontab会定时执行一些脚本,但是脚本的时间往往无法控制,当脚本的执行时间过长,可能会导致上一次任务的脚本还没执行完,下一次任务的脚本又开始执行的问题.这种情况下会出现一些并 ...
- eclipse中使用git上传项目
eclipse中使用git上传项目 先需要上传到本地仓库 先找到此选项打钩 再如下 再添加的属性则可以自动填充邮箱和密码 之后 右键选择import 点击找到git 选中 下一步 如果没有找到git ...