热门标签 | HotTags
当前位置:  开发笔记 > 运维 > 正文

Android开发教程之调用摄像头功能的方法详解

这篇文章主要介绍了Android调用摄像头功能的方法,详细分析了Android调用摄像头功能的权限设置、功能代码与实现步骤,需要的朋友可以参考下

本文实例讲述了Android调用摄像头功能的方法。分享给大家供大家参考,具体如下:

我们要调用摄像头的拍照功能,显然

第一步必须加入调用摄像头硬件的权限,拍完照后我们要将图片保存在SD卡中,必须加入SD卡读写权限,所以第一步,我们应该在Android清单文件中加入以下代码

摄像头权限:



SD卡读写权限:




第二步,要将摄像头捕获的图像实时地显示在手机上

我们是用SurfaceView这个视图组件来实现的,因此在main.xml中加入下列代码



第三步,设置窗口的显示方式

首先获得当前窗口

Window window = getWindow();//得到窗口

接着设置没有标题

requestWindowFeature(Window.FEATURE_NO_TITLE);//没有标题

接着设置全屏

代码如下:
window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//设置全屏

当然,我们在拍照过程中,屏幕必须一致处于高亮状态,因此接着加入下面代码

代码如下:
window.addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);//设置高亮

至此,我们将窗口的显示方式规定死了,然后才能设置窗口上显示的组件(顺序非常重要)

setContentView(R.layout.main);

第四步,设置SurficeView显示控件的属性

找到surficeView

surfaceView = (SurfaceView) findViewById(R.id.surfaceview);

设置它的像素为800x600

surfaceView.getHolder().setFixedSize(800, 480);
//下面设置surfaceView不维护自己的缓冲区,而是等待屏幕的渲染引擎将内容推送到用户面前
surfaceView.getHolder().setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

第五步,就是为surficeView加入回调方法(callBack)

surfaceView.getHolder().addCallback(new SurfaceCallback());

上面的回调类是我们自己定义的,代码如下

private class SurfaceCallback implements SurfaceHolder.Callback{
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
camera = Camera.open();//打开硬件摄像头,这里导包得时候一定要注意是android.hardware.Camera
WindowManager wm = (WindowManager) getSystemService(Context.WINDOW_SERVICE);//得到窗口管理器
Display display = wm.getDefaultDisplay();//得到当前屏幕
Camera.Parameters parameters = camera.getParameters();//得到摄像头的参数
parameters.setPreviewSize(display.getWidth(), display.getHeight());//设置预览照片的大小
parameters.setPreviewFrameRate(3);//设置每秒3帧
parameters.setPictureFormat(PixelFormat.JPEG);//设置照片的格式
parameters.setJpegQuality(85);//设置照片的质量
parameters.setPictureSize(display.getHeight(), display.getWidth());//设置照片的大小,默认是和   屏幕一样大
camera.setParameters(parameters);
camera.setPreviewDisplay(surfaceView.getHolder());//通过SurfaceView显示取景画面
camera.startPreview();//开始预览
isPreview = true;//设置是否预览参数为真
} catch (IOException e) {
Log.e(TAG, e.toString());
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width,
int height) {
// TODO Auto-generated method stub
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if(camera!=null){
if(isPreview){//如果正在预览
camera.stopPreview();
camera.release();
}
}
}
}

第六步,我们必须对按键事件进行监听,如是拍照还是聚焦,代码如下

public boolean onKeyDown(int keyCode, KeyEvent event) {//处理按键事件
if(camera!=null&&event.getRepeatCount()==0)//代表只按了一下
{
switch(keyCode){
case KeyEvent.KEYCODE_BACK://如果是搜索键
   camera.autoFocus(null);//自动对焦
 break;
  case KeyEvent.KEYCODE_DPAD_CENTER://如果是中间键
   camera.takePicture(null, null, new TakePictureCallback());//将拍到的照片给第三个对象中,这里的TakePictureCallback()是自己定义的,在下面的代码中
 break;
}
}
return true;//阻止事件往下传递,否则按搜索键会变成系统默认的
}

private final class TakePictureCallback implements PictureCallback{
public void onPictureTaken(byte[] data, Camera camera) {
try {
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
File file = new File(Environment.getExternalStorageDirectory(),System.currentTimeMillis()+".jpg");
FileOutputStream outputStream = new FileOutputStream(file);
bitmap.compress(CompressFormat.JPEG, 100, outputStream);
outputStream.close();
camera.stopPreview();
camera.startPreview();//处理完数据之后可以预览
} catch (Exception e) {
Log.e(TAG, e.toString());
}
}
}

注意,代码中有两个回调类,一个是SurfaceCallback(),另外一个是TakePictureCallback(),初学者可能一时难以理解,通俗地讲,前者是用来监视surficeView这个暂时存放图片数据的显示控件的,根据它的显示情况调用不同的方法,包括surfaceCreated(),surfaceChanged(),surfaceDestroyed(),也就不难理解为什么会有这三个回调方法了(注意,在surfaceDestroyed()方法中必须释放摄像头,详细代码参见上方)。TakePictureCallback()是为了监视是否拍照而设计的接口,期中也仅有一个方法,camera将拍照得到的数据传入方法,我们便可以对拍照得到的数据进行进一步处理了。

至此,简单的拍照功能介绍完毕!

package cn.camera.rxm;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
import org.apache.commons.logging.Log;
import android.text.format.DateFormat;
import android.util.*;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.hardware.Camera.PictureCallback;
import android.os.Bundle;
import android.os.Environment;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
//import android.widget.Toast;
public class MycamActivity extends Activity {
private Preview mPreview;
private Camera mCamera;
Bitmap CameraBitmap;
SurfaceHolder mHolder;
private static final int OPTION_SNAPSHOT = 0;
private static final int OPTION_STOPCAMERA = 1;
private View viewStart;
  @Override
  public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    LayoutInflater flater = this.getLayoutInflater();
    viewStart = flater.inflate(R.layout.main, null);
    setContentView(viewStart);
    Button btn1 = (Button)findViewById(R.id.button1);
    btn1.setOnClickListener(
    new OnClickListener(){
    public void onClick(View v){
    mPreview = new Preview(getBaseContext());
    setContentView(mPreview);
    };
    }
    );
  }
  public boolean onCreateOptionsMenu(Menu menu){
//
menu.add(0, OPTION_SNAPSHOT, 0, R.string.take);
//
menu.add(0, OPTION_STOPCAMERA, 1, R.string.back);
//
return true;//super.onCreateOptionsMenu(menu);
}
public boolean onOptionsItemSelected(MenuItem item) {
//
int itemId = item.getItemId();
//
switch(itemId){
case OPTION_SNAPSHOT:
//拍摄照片
mCamera.takePicture(null, null, jpegCallback);
try {
Thread.sleep(4000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mCamera.startPreview();
break;
case OPTION_STOPCAMERA:
mPreview = null;
setContentView(viewStart);
break;
}
return true;
}
private PictureCallback jpegCallback = new PictureCallback(){
//
public void onPictureTaken(byte[] data, Camera camera) {
try {
String name = new DateFormat().format("yyyyMMdd_hhmmss",
Calendar.getInstance(Locale.CHINA)) + ".jpg";
FileOutputStream fileout = new FileOutputStream("/mnt/sdcard/sdcard/DCIM/"+ name);
System.out.println(name);
fileout.write(data,0,data.length);
fileout.flush();
fileout.close();
} catch (IOException e) {
// TODO: handle exception
System.out.println(e);
}
}
};
class Preview extends SurfaceView implements SurfaceHolder.Callback
{
Preview(Context context)
{
super(context);
mHolder=getHolder();
mHolder.addCallback(this);
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
}
public void surfaceCreated(SurfaceHolder holder)
{
mCamera=Camera.open();
try
{
mCamera.setPreviewDisplay(holder);
}
catch(IOException exception)
{
mCamera.release();
mCamera=null;
}
}
public void surfaceDestroyed(SurfaceHolder holder)
{
mCamera.stopPreview();
mCamera.release();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int w, int h) {
// TODO Auto-generated method stub
Camera.Parameters parameters=mCamera.getParameters();
parameters.setPictureFormat(PixelFormat.JPEG);
parameters.setPreviewSize(1024, 1024);
mCamera.setParameters(parameters);
mCamera.setDisplayOrientation(90);
mCamera.startPreview();
}
}
}

更多关于Android相关内容感兴趣的读者可查看本站专题:《Android文件操作技巧汇总》、《Android编程开发之SD卡操作方法汇总》、《Android开发入门与进阶教程》、《Android资源操作技巧汇总》、《Android视图View技巧总结》及《Android控件用法总结》

希望本文所述对大家Android程序设计有所帮助。


推荐阅读
  • 在 Android 应用开发中,实现全屏模式和无标题栏设计是提升用户体验的重要手段。本文详细介绍了如何通过 Java 代码实现取消标题栏 `this.requestWindowFeature(Window.FEATURE_NO_TITLE)`,并进一步探讨了全屏模式的多种实现方法和最佳实践,帮助开发者打造更加沉浸式和美观的用户界面。 ... [详细]
  • 在Android开发中,BroadcastReceiver(广播接收器)是一个重要的组件,广泛应用于多种场景。本文将深入解析BroadcastReceiver的工作原理、应用场景及其具体实现方法,帮助开发者更好地理解和使用这一组件。通过实例分析,文章详细探讨了静态广播的注册方式、生命周期管理以及常见问题的解决策略,为开发者提供全面的技术指导。 ... [详细]
  • Java能否直接通过HTTP将字节流绕过HEAP写入SD卡? ... [详细]
  • 在探讨Hibernate框架的高级特性时,缓存机制和懒加载策略是提升数据操作效率的关键要素。缓存策略能够显著减少数据库访问次数,从而提高应用性能,特别是在处理频繁访问的数据时。Hibernate提供了多层次的缓存支持,包括一级缓存和二级缓存,以满足不同场景下的需求。懒加载策略则通过按需加载关联对象,进一步优化了资源利用和响应时间。本文将深入分析这些机制的实现原理及其最佳实践。 ... [详细]
  • 本文探讨了如何有效地构建和优化微信公众平台账号,涵盖了用户信息管理、内容创作与发布、互动策略及数据分析等方面。通过合理设置用户信息字段,如用户名、昵称、密码、真实姓名和性别等,确保账号的安全性和用户体验。同时,文章还介绍了如何利用微信公众平台的各项功能,提升用户参与度和品牌影响力。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 深入解析HTTP网络请求API:从基础到进阶的全面指南
    本文全面解析了HTTP网络请求API,从基础到进阶,详细介绍了Android平台上的两种原生API——HttpUrlConnection和HttpClient。这两种API通过对底层Socket的封装,提供了高效、灵活的网络通信功能。文章不仅涵盖了基本的使用方法,还深入探讨了性能优化、错误处理和安全性等方面的高级主题,帮助开发者更好地理解和应用这些工具。 ... [详细]
  • Docker入门指南:初探容器化技术
    Docker入门指南:初探容器化技术摘要:Docker 是一个使用 Go 语言开发的开源容器平台,旨在实现应用程序的构建、分发和运行的标准化。通过将应用及其依赖打包成轻量级的容器,Docker 能够确保应用在任何环境中都能一致地运行,从而提高开发和部署的效率。本文将详细介绍 Docker 的基本概念、核心功能以及如何快速上手使用这一强大的容器化工具。 ... [详细]
  • 本文探讨了Android系统中支持的图像格式及其在不同版本中的兼容性问题,重点涵盖了存储、HTTP传输、相机功能以及SparseArray的应用。文章详细分析了从Android 10 (API 29) 到Android 11 的存储规范变化,并讨论了这些变化对图像处理的影响。此外,还介绍了如何通过系统升级和代码优化来解决版本兼容性问题,以确保应用程序在不同Android版本中稳定运行。 ... [详细]
  • 这是一道涉及数学计算的问题。假设步行速度为 \(a\),车速为 \(b\),总距离为 \(c\)。Teddy 的步行时间为 \(T_1\),WhereIsHeroFrom 的步行时间为 \(T_2\),总时间为 \(T\)。通过分析不同时间段内的速度变化,可以得出最优的车辆使用策略,以最小化总的旅行时间。具体来说,需要计算在不同情况下步行和乘车的时间分配,以确保整体效率最大化。 ... [详细]
  • 在本地环境中部署了两个不同版本的 Flink 集群,分别为 1.9.1 和 1.9.2。近期在尝试启动 1.9.1 版本的 Flink 任务时,遇到了 TaskExecutor 启动失败的问题。尽管 TaskManager 日志显示正常,但任务仍无法成功启动。经过详细分析,发现该问题是由 Kafka 版本不兼容引起的。通过调整 Kafka 客户端配置并升级相关依赖,最终成功解决了这一故障。 ... [详细]
  • Apache Hadoop HDFS QJournalProtocol 中 getJournalCTime 方法的应用与代码实例分析 ... [详细]
  • CTF竞赛中文件上传技巧与安全绕过方法深入解析
    CTF竞赛中文件上传技巧与安全绕过方法深入解析 ... [详细]
  • 面向切面编程(AOP)是Spring框架的两大核心概念之一,另一个核心概念是控制反转(IoC)。AOP通过在应用程序中分离横切关注点,如日志记录、事务管理和安全性,从而提高代码的模块化和可维护性。本文将深入探讨AOP的核心概念和术语,帮助读者更好地理解和应用这一重要技术。 ... [详细]
  • 虚拟网络连接配置指南旨在详细阐述如何在两台区域边界路由器(ABR)之间,通过一个非骨干区域(即传输区域)建立一条逻辑连接通道。该指南提供了具体的配置步骤和最佳实践,帮助网络管理员高效地实现跨区域的虚拟连接,确保网络的稳定性和可靠性。 ... [详细]
author-avatar
手机用户2502884601
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有