【Android】设备操作

本文介绍App开发常用的一些设备操作,主要包括如何使用摄像头进行拍照、如何使用麦克风进行录音并结合摄像头进行录像、如何播放录制好的音频和视频、如何使用常见传感器实现业务功能、如何使用定位功能获取位置信息、如何利用短距离通信技术实现物联网等。

摄像头

本节介绍利用摄像头实现相机功能的办法,首先对表面视图SurfaceView的用法进行说明,演示如何运用相机类Camera结合表面视图完成拍照功能(含单拍和连拍)。然后对表面视图的升级版------纹理视图TextureView的用法进行阐述,并演示如何在新版Camera2架构中结合纹理视图完成拍照功能(含单拍和连拍)。最后介绍了与设备操作有关的运行时权限管理。

表面视图SurfaceView

Android的绘图机制是由UI线程在屏幕上绘图,一般情况下不允许其他线程直接做绘图操作。这个机制在处理简单页面时没什么问题,因为普通页面不会频繁且大面积地绘图,但是该机制在处理复杂多变的页面时会产生问题,比如时刻变化着的游戏界面、拍照或录像时不断变换着的预览界面就会导致UI线程资源堵塞,即界面卡死的状况。

表面视图SurfaceView是Android用来解决子线程绘图的特殊视图,拥有独立的绘图表面,即不与其宿主页面共享同一个绘图表面。由于拥有独立的绘图表面,因此表面视图的界面能够在一个独立线程中进行绘制,这个子线程为渲染线程。因为渲染线程不占用主线程资源,所以一方面可以实现复杂而高效的UI刷新,另一方面及时响应用户的输入事件。由于表面视图具备以上特性,因此可用于拍照和录像的预览界面,也可用于游戏的实时界面。

因为表面视图不在UI主线程绘图,无论是onDraw方法还是dispatchDraw方法都没有进行绘图操作,所以表面视图必然要通过其他途径绘图,这个途径便是内部类表面持有者SurfaceHolder外部调用SurfaceView对象的getHolder方法获得SurfaceHolder对象,然后进行预览界面的相关绘图操作。

从表面视图的转动效果可以看到,它与普通视图在处理上的区别主要有以下两点:

(1)表面视图允许开启多个线程同时进行绘图操作,而普通视图只有一个UI线程可以绘图。

(2)表面视图不会自动清空上次的绘图结果,即绘图操作是增量进行的,而普通视图在每次绘图前都会清空上次的绘图结果。

使用Camera拍照

在Android开发中,相机Camera是直接操作摄像头硬件的工具类,包括后置摄像头和前置摄像头,有以下常用方法。

  • getNumberOfCameras:获取本设备的摄像头数目。
  • open:打开摄像头,默认打开后置摄像头。如果有多个摄像头,那么open(0)表示打开后置摄像头,open(1)表示打开前置摄像头。
  • getParameters:获取摄像头的拍照参数,返回Camera.Parameters对象。setParameters:设置摄像头的拍照参数。具体的拍照参数通过调用Camera.Parameters的下列方法进行设置。
  1. setPreviewSize:设置预览界面的尺寸。
  2. setPictureSize:设置保存图片的尺寸。
  3. setPictureFormat:设置图片格式。一般使用ImageFormat.JPEG表示JPG格式。
  4. setFocusMode:设置对焦模式。取值Camera.Parameters.FOCUS_MODE_AUTO只会自动对焦一次,取值FOCUS_MODE_CONTINUOUS_PICTURE则会连续对焦。
  • setPreviewDisplay:设置预览界面的表面持有者,即SurfaceHolder对象。该方法必须在SurfaceHolder.Callback的surfaceCreated方法中调用。
  • startPreview:开始预览。该方法必须在setPreviewDisplay方法之后调用。
  • unlock:录像时需要对摄像头解锁,这样摄像头才能持续录像。该方法必须在startPreview方法之后调用。setDisplayOrientation:设置预览的角度。Android的0度在三点钟的水平位置,而手机屏幕是垂直位置,从水平位置到垂直位置需要旋转90度。
  • autoFocus:设置对焦事件。参数自动对焦接口AutoFocusCallback的onAutoFocus方法在对焦完成时触发,在此提示用户对焦完毕可以拍照了。
  • takePicture:开始拍照,并设置拍照相关事件。第一个参数为快门回调接口ShutterCallback,它的onShutter方法在按下快门时触发,通常可在此播放拍照声音,默认为"咔嚓"一声;第二个参数的PictureCallback表示原始图像的回调接口,通常无须处理直接传null;第三个参数的PictureCallback表示JPG图像的回调接口,压缩后的图像数据可在该接口中的onPictureTaken方法中获得。
  • setZoomChangeListener:设置缩放比例变化事件。缩放变化监听器OnZoomChangeListener的onZoomChange方法在缩放比例发生变化时触发。
  • setPreviewCallback:设置预览回调事件,通常在连拍时调用。预览回调接口PreviewCallback的onPreviewFrame方法在预览图像发生变化时触发。
  • stopPreview:停止预览。
  • lock:录像完毕对摄像头加锁。该方法在stopPreview方法之后调用。
  • release:释放摄像头。因为摄像头不能重复打开,所以每次退出拍照时都要释放摄像头。
纹理视图TextureView

表面视图SurfaceView在一般情况下足够使用了,但是有一些限制。因为表面视图不是通过onDraw方法和dispatchDraw方法进行绘图,所以无法使用View的基本视图方法。例如,各种视图变化方法均无法奏效,包括透明度变化方法setAlpha、平移方法setTranslation、缩放方法setScale、旋转方法setRotation等,甚至连最基础的背景图设置方法setBackground都失效了。

为了解决表面视图的不足之处,Android在4.0之后引入了纹理视图TextureView。与表面视图相比,纹理视图并没有创建一个单独的绘图表面用来绘制,可以像普通视图一样执行变换操作,也可以正常设置背景图。

下面是TextureView的常用方法。

  • lockCanvas:锁定并获取画布。
  • unlockCanvasAndPost:解锁并刷新画布。
  • setSurfaceTextureListener:设置表面纹理的监听器。该方法相当于SurfaceHolder的addCallback方法,用来监控表面纹理的状态变化事件。方法参数为SurfaceTextureListener监听器对象,需重写以下4个方法。
  1. onSurfaceTextureAvailable:在表面纹理可用时触发,可在此进行打开相机等操作。 onSurfaceTextureSizeChanged:在表面纹理尺寸变化时触发。 onSurfaceTextureDestroyed:在表面纹理销毁时触发。
  2. onSurfaceTextureUpdated:在表面纹理更新时触发。
  • isAvailable:判断表面纹理是否可用。
  • getSurfaceTexture:获取表面纹理。
使用Camera 2拍照

如同纹理视图是表面视图的升级版那样,Android在5.0之后推出了Camera的升级版------Camera 2。按照Android的官方说明,Camera 2支持以下5点新特性:

(1)支持每秒30帧的全高清连拍。

(2)支持在每帧之间使用不同的设置。

(3)支持原生格式的图像输出。

(4)支持零延迟快门和电影速拍。

(5)支持相机在其他方面的手动控制,比如设置噪音消除的级别。

Camera2在架构上做了大幅改造,原先的Camera类被拆分为多个管理类,主要有相机管理器CameraManager、相机设备CameraDevice、相机拍照会话CameraCaptureSession、图像读取器ImageReader。

传感器

本节介绍常见传感器的用法与相关应用场景,首先列举Android目前支持的传感器种类,然后对常用传感器分别进行说明,包括加速度传感器的用法和摇一摇的实现、磁场传感器的用法和指南针的实现,以及计步器、感光器、陀螺仪等其他传感器的基本用法。

传感器的种类

传感器Sensor是一系列感应器的总称,是Android设备用来感知周围环境和运动信息的工具。因为具体的感应信息依赖于相关硬件,所以虽然Android定义了众多感应器,但是并非每部手机都能支持这么多感应器,千元以下的低端手机往往只支持加速度等少数感应器。

相关推荐
大白要努力!41 分钟前
Android opencv使用Core.hconcat 进行图像拼接
android·opencv
天空中的野鸟2 小时前
Android音频采集
android·音视频
小白也想学C3 小时前
Android 功耗分析(底层篇)
android·功耗
曙曙学编程3 小时前
初级数据结构——树
android·java·数据结构
闲暇部落5 小时前
‌Kotlin中的?.和!!主要区别
android·开发语言·kotlin
诸神黄昏EX7 小时前
Android 分区相关介绍
android
大白要努力!8 小时前
android 使用SQLiteOpenHelper 如何优化数据库的性能
android·数据库·oracle
Estar.Lee8 小时前
时间操作[取当前北京时间]免费API接口教程
android·网络·后端·网络协议·tcp/ip
Winston Wood8 小时前
Perfetto学习大全
android·性能优化·perfetto
Dnelic-11 小时前
【单元测试】【Android】JUnit 4 和 JUnit 5 的差异记录
android·junit·单元测试·android studio·自学笔记