多媒体应用开发-控制摄像头拍照

摄像头拍照


从 Android 5.0 开始,Google 引入了一套全新的相机框架 Camera2(android.hardware.camera2)并且废弃了旧的相机框架 Camera1(android.hardware.Camera)

1、Camera1使用

1.1 使用步骤:
  1. 调用Camera.open(),打开相机,默认为后置,可以根据摄像头ID来指定打开前置还是后置
  2. 调用Camera.getParameters ()得到一个Camera.Parameters对象
  3. 使用步骤2得到的Camera.Parameters对象,对拍照参数进行设置
  4. 调用Camera.setPreviewDispaly(SurfaceHolder holder),指定使用哪个SurfaceView来显示预览图片
  5. 调用Camera.startPreview()方法开始预览取景
  6. 调用Camera.takePicture()方法进行拍照
  7. 拍照结束后,调用Camera.stopPreview()结束取景预览,之后再replease()方法释放资
1.2 为什么要使用Camera2

通过 Camera2 提供的高级特性可以构建出更加高质量的相机应用程序。

​ 1.在开启相机之前检查相机信息

​ 2.在不开启预览的情况下拍照

​ 3.一次拍摄多张不同格式和尺寸的图片

​ 4.控制曝光时间

​ 5.连拍

1.3 Camera2的 5点新特性:

(1)支持30帧的高清连拍功能。

(2)支持每帧之间的手动设置。

(3)支持RAW原始图像的拍摄。

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

(5)支持相机其它方面的手动控制,包括噪音消除。

1.4 Camera2架构概述

在这里插入图片描述

Camera2引用了管道的概念,将Camera Device相机设备和Android Device安卓设备连接起来,android Device通过管道发送CaputerRequest拍照请求给Camera Device,Camera Device通过管道返回CameraMetaData数据给Android Device,这一切建立在一个叫做CameraCaptureSession。

1.5 Camera2中比较重要的类及方法

在这里插入图片描述

其中CameraManager是所有相机设备(CameraDevice)的管理者,而每个CameraDevice自己会负责建立CameraCaptureSession以及建立CaptureRequest。

CameraCharacteristics是CameraDevice的属性描述类,在CameraCharacteristics中可以进行相机设备功能的详细设定(当然了,首先你得确定你的相机设备支持这些功能才行)。

类图中有着三个重要的callback,其中CameraCaptureSession.CaptureCallback将处理预览和拍照图片的工作,需要重点对待

2、 Camera2拍照流程图:

在这里插入图片描述

  1. 调用 CameraManager的openCamera(String cameraId, CameraDevice.StateCallback callback, Handler handler) 方法打开指定摄像头。该方法的第一个参数cameraId代表要打开的摄像头ID(摄像头ID(通常0代表后置摄像头,1代表前置摄像头);第二个参数用于监听摄像头的状态;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。

  2. 获取CameraDevice对象
    当摄像头被打开之后,程序即可获取CameraDevice—即根据摄像头ID获取了指定摄像头设备,然后调用CameraDevice的createCaptureSession(List outputs, CameraCaptureSession. StateCallback callback,Handler handler)方法来创建CameraCaptureSession。该方法的第一个参数是一个List集合,封装了所有需要从该摄像头获取图片的Surface,第二个参数用于监听CameraCaptureSession的创建过程;第三个参数代表执行callback的Handler,如果程序希望直接在当前线程中执行callback,则可将handler参数设为null。

  3. 设置设置摄像头模式

不管预览还是拍照,程序都调用CameraDevice的createCaptureRequest(int templateType)方法创建CaptureRequest.Builder,该方法支持TEMPLATE_PREVIEW(预览)、TEMPLATE_RECORD(拍摄视频)、TEMPLATE_STILL_CAPTURE(拍照)等参数。

通过第3步所调用方法返回的CaptureRequest.Builder设置拍照的各种参数,比如对焦模式、曝光模式等。

调用CaptureRequest.Builder的build()方法即可得到CaptureRequest对象,接下来程序可通过CameraCaptureSession的setRepeatingRequest()方法开始预览,或调用capture()方法拍照。

2.1 CameraManager

管理所有的摄像头(CameraDevice)设备的管理者,用于打开和关闭系统摄像头。

获取该实例的方法:

CameraManager manager =(CameraManager)Context.getSystemService(Context.CAMERA_SERVICE);

或者

CameraManager manager =(CameraManager)Context.getSystemService(CameraManager.class);
  • getCameraIdList() :返回当前设备中可用的相机列表, 这个 id 通常都是从 0 开始并依次递增的

  • public CameraCharacteristics getCameraCharacteristics (String cameraId) :根据摄像头id返回该摄像头的相关信息;cameraId,0为后置摄像头、1为前置摄像头

  • public void openCamera(String cameraId,final CameraDevice.StateCallback callback, Handler handler)

  • public void openCamera(String cameraId,Executor executor,final CameraDevice.StateCallback callback)都是打开指定cameraId的相机,只是一个传入Handler,一个传入Executor,是想用线程池来执行Camera中耗时操作

😄 cameraId 是一个标识,标识当前要打开的camera

😆 callback 是一个状态回调,当前camera被打开的时候,这个状态回调会被触发的。

😃 handler 指定回调执行的线程。传 null 时默认使用当前线程的 Looper,我们通常创建一个后台线程来处理。

😚 executor操作线程池

2.2 CameraCharacteristics

描述摄像头的各种特性,其中的属性都是固定的,类似于Camera1中的CamerInfo。通过CameraManager的getCameraCharacteristics(String cameraId)方法来获取

包含一个CameraCharacteristics.Key<T>的内部类,用做相机特性的字段查询使用。常搭配 CameraCharacteristics.get(CameraCharacteristics.Key<T> key)方法使用。

get(Key<T> key):通过制定的key获取相应的相机参数。

常用的key值有:

😉 CameraCharacteristics.LENS_FACING :获取摄像头方向。前置摄像头(LENS_FACING_FRONT)或 后置摄像头(LENS_FACING_BACK)

😃 CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL:获取当前设备支持的相机特性

😃 CameraCharacteristics.SENSOR_ORIENTATION:获取摄像头方向

😃 CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP:获取StreamConfigurationMap,它是管理摄像头支持的所有输出格式和尺寸

😃 CameraCharacteristics.FLASH_INFO_AVAILABLE:是否支持闪光灯

😃 CameraCharacteristics.STATISTICS_INFO_MAX_FACE_COUNT:同时检测到人脸的数量

😃 CameraCharacteristics.STATISTICS_INFO_AVAILABLE_FACE_DETECT_MODES:相机支持的人脸检测模式

2.3 CameraDevice

CameraDevice 代表当前连接的相机设备,可以把它看作为相机设备在 java 代码中的表现,它的职责有以下四个:

  • 根据指定的参数创建 CameraCaptureSession。

  • 根据指定的模板创建 CaptureRequest。

  • 关闭相机设备。

  • 监听相机设备的状态,例如断开连接、开启成功和开启失败等。

熟悉 Camera1 的人可能会说 CameraDevice 就是 Camera1 的 Camera 类,实则不是,Camera 类几乎负责了所有相机的操作,而 CameraDevice 的功能则十分的单一,就是只负责建立相机连接的事务,而更加细化的相机操作则交给了稍后会介绍的CameraCaptureSession。

创建方法:通过 CameraManager 的 openCamera() 方法打开相机,在 CameraDevice.StateCallback 的 onOpened(CameraDevice camera) 方法中可获得 CameraDevice 的实例。

createCaptureRequest(int templateType):创建一个新的拍照请求。参数templateType代表了请求类型,请求类型一共分为六种,分别为:

😁 TEMPLATE_PREVIEW : 创建预览的请求,相机会优先保证高帧率而不是高画质

😁 TEMPLATE_STILL_CAPTURE: 创建一个拍照请求。相机会优先保证高画质而不是高帧率

😁 TEMPLATE_RECORD : 创建一个录像请求。相机会使用标准帧率,并设置录像级别的画质

😁 TEMPLATE_VIDEO_SNAPSHOT : 创建一个录像时拍照的请求。相机会尽可能的保证照片质量的同时不破坏正在录制的视频质量; 高于 LEGACY

😁 TEMPLATE_ZERO_SHUTTER_LAG : 创建一个适用于零快门延迟的请求。在不影响预览帧率的情况下最大化图像质量

😁 TEMPLATE_MANUAL : 创建一个基本捕获请求,这种请求中所有的自动控制都是禁用的(自动曝光,自动白平衡、自动焦点)

硬件支持等级

在 Camera2 中,相机设备支持的硬件等级有LEGACY < LIMITED < FULL < LEVEL_3

  • LEVEL_LEGACY: 向后兼容模式, 如果是此等级, 基本没有额外功能

  • LEVEL_LIMITED: 有最基本的功能, 还支持一些额外的高级功能, 这些高级功能是LEVEL_FULL的子集

  • LEVEL_FULL: 支持对每一帧数据进行控制,还支持高速率的图片拍摄

  • LEVEL_3: 支持YUV后处理和Raw格式图片拍摄, 还支持额外的输出流配置

  • LEVEL_EXTERNAL: API28中加入的, 应该是外接的摄像头, 功能和LIMITED类似

createCaptureSession(List<Surface>outputs,CameraCaptureSession.StateCallback callback,Handler handler)

:创建CaptureSession会话,一个 CameraDevice 一次只能开启一个 CameraCaptureSession,绝大部分的相机操作都是通过向 CameraCaptureSession 提交一个 Capture 请求实现的,例如拍照、连拍、设置闪光灯模式、触摸对焦、显示预览画面等等。第一个参数 outputs 是一个 List 数组,相机会把捕捉到的图片数据传递给该参数中的 Surface 。第二个参数 StateCallback 是创建会话的状态回调。第三个参数描述了 StateCallback 被调用时所在的线程

2.4 CameraDevice.StateCallback
CameraDevice的内部类StateCallback,一个回调对象,用于接收关于相机的更新状态。这些状态更新包括关于设备完成启动的通知(允许CameraDevice的createCaptureSession(List, CameraCaptureSession.StateCallback, Handler)被调用),关于设备断开或闭包,以及意外的设备错误。关于特定的CaptureRequests进程事件是由 CameraCaptureSession.CaptureCallback 提供的

回调方法:

回调方法解释
onClosed(CameraDevice camera)当一个相机设备CameraDevice的close()方法时,这个方法就被调用
onDisconnected(CameraDevice camera)当相机设备不再可用时,这个方法就被调用
onError(CameraDevice camera, int error)当相机设备遇到严重错误时,这种方法就被调用了,错误见上表的常量
onOpened(CameraDevice camera)当相机完成打开操作后,这个方法就被调用

onError 回调方法中相应的错误码

常量解释
ERROR_CAMERA_DEVICE由CameraDevice.StateCallback的onError(CameraDevice, int)报告的错误代码,表明相机设备遇到了一个致命错误
ERROR_CAMERA_DISABLED由CameraDevice.StateCallback的onError(CameraDevice, int)报告的错误代码,这表明由于设备的政策,相机设备无法打开。
ERROR_CAMERA_IN_USE由onError(CameraDevice, int)报告的错误代码,表明摄像机设备已经在使用中了
ERROR_CAMERA_SERVICE由onError(CameraDevice, int)报告的错误代码,表明摄像机服务遇到了一个致命错误。
ERROR_MAX_CAMERAS_IN_USE由onError(CameraDevice, int)报告的错误代码,表明相机设备无法打开,因为有太多其他的开放相机设备。
2.5 CameraRequest和CameraRequest.Builder

​ 当程序调用setRepeatingRequest()方法进行预览时,或调用capture()方法进行拍照时,都需要传入CameraRequest参数。CameraRequest代表了一次捕获请求,用于描述捕获图片的各种参数设置,比如对焦模式、曝光模式……总之,程序需要对照片所做的各种控制,都通过CameraRequest参数进行设置

​ 使用CaptureRequest.Builder实例创建CaptureRequests对象,通过调用CameraDevice的createCaptureRequest(int templateType) 获取CaptureRequest.Builder对象。

2.6 CaptureRequest.Builder(内部类)

典型的建造者模式,是 CaptureRequest 的构建者。

addTarget(Surface outputTarget):给此次请求添加一个Surface对象作为图像的输出目标,CameraDevice返回的数据送到这个target surface中。target surface可以是Surface View,Surface Texture,将返回的数据传递到预览界面中;还可以是MediaRecorder或mageReader,将返回的数据传给这两个类,进行进一步处理,形成视频文件或者图片。

2.7 CaptureRequest.Key(内部类)

用作 CaptureRequest.Builder 的属性字段设置和查询使用

set(Key key, T value):设置指定的参数值。

// 自动对焦
captureRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE)
// 闪光灯
captureRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH)
// 根据摄像头方向对保存的照片进行旋转,使其为"自然方向"
captureRequestBuilder.set(CaptureRequest.JPEG_ORIENTATION, mCameraSensorOrientation)
// 人脸检测模式
captureRequestBuilder.set(CaptureRequest.STATISTICS_FACE_DETECT_MODE, CameraCharacteristics.STATISTICS_FACE_DETECT_MODE_
                          SIMPLE) 
2.8 CameraCaptureSession

当需要拍照、预览等功能时,需要先创建该类的实例,然后通过该实例里的方法进行控制(例如:拍照 capture())

setRepeatingRequest(CaptureRequest request,CaptureCallback listener, Handler handler):根据传入的 CaptureRequest 对象开始一个无限循环的捕捉图像的请求, 一般用于捕获画面输出至预览界面或者录制视频。第二个参数 listener 为捕捉图像的回调,在回调中可以拿到捕捉到的图像信息,通常作为请求的进度监听器

capture( CaptureRequest request,CaptureCallback listener, Handler handler):捕获一次,一般用于拍照;第二个参数为拍照的结果回调

Capture()比setRepeatingRequest ()优先级高,当在setRepeatingRequest 时进行Capture,会先处理Capture,然后继续setRepeatingRequest 。(PS:可以根据平时使用相机时,首先我们看到的预览界面是setRepeatingRequest 显示出来的,当点击拍照时执行Capture,然后又出现预览界面继续实行setRepeatingRequest )。

2.9 CameraCaptureSession.CaptureCallback

CameraCaptureSession的内部类CaptureCallback,一个回调对象,用于跟踪向相机提交CaptureRequest对象的进程。

这个回调是在一个请求触发一个捕获开始时调用的,当捕获完成时调用。可以使用这个类来跟踪各进度。如果出现错误捕获图像则会触发错误方法,而不是完成方法。

重写的七个方法:

方法解释
onCaptureBufferLost(CameraCaptureSession session, CaptureRequest request, Surface target, long frameNumber)如果捕获的单个缓冲区不能发送到它的目标表面,就会调用该方法。
onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result)当一个图像捕捉已经完全完成并且所有的结果元数据都可用时,这个方法就会被调用。
onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure)当相机不能向 CaptureResult 对象提供请求,就会调用
onCaptureProgressed(CameraCaptureSession session, CaptureRequest request, CaptureResult partialResult)当图像捕捉取得部分进展时,就会调用该方法;有些(但不是全部)从图像捕获中得到的结果是可用的。
onCaptureSequenceAborted(CameraCaptureSession session, int sequenceId)这个方法独立于CaptureCallback中的其他方法,当捕获序列在任何CaptureResult或capture失败之前通过这个侦听器返回时。
onCaptureSequenceCompleted(CameraCaptureSession session, int sequenceId, long frameNumber)这个方法独立于CaptureCallback中的其他方法,当捕获序列完成后,通过这个侦听器返回所有的CaptureResult或capture失败。
onCaptureStarted(CameraCaptureSession session, CaptureRequest request, long timestamp, long frameNumber)当摄像机设备开始捕捉请求的输出图像,在图像曝光开始时,或者当摄像机设备开始处理一个重新处理请求的输入图像时,这个方法就被调用了。
2.10 CameraCaptureSession.StateCallback

CameraCaptureSession的内部类StateCallback,一个回调对象,用于接收关于相机捕捉会话状态的更新。 其中只有 onConfigured 和 onConfigureFailed 两个方法是抽象的(必须重写),其余均有空实现。

重写的七个方法:

方法解释
onActive(CameraCaptureSession session)当会话开始主动处理捕获请求时,将调用此方法。
onCaptureQueueEmpty(CameraCaptureSession session)当摄像机设备的输入捕捉队列变为空时,该方法将被调用,并准备接受下一个请求。
onClosed(CameraCaptureSession session)会话关闭触发
onConfigureFailed(CameraCaptureSession session)如果会话不能按照请求配置,则调用此方法。
onConfigured(CameraCaptureSession session)当摄像机设备完成配置时,这个方法就会被调用,会话可以开始处理捕获请求。
onReady(CameraCaptureSession session)每当会话不再需要处理请求时,就会调用此方法。
onSurfacePrepared(CameraCaptureSession session, Surface surface)当输出表的缓冲区预分配完成时,就会调用
2.11 CaptureResult
  • 描述拍照完成后的结果(从图像传感器捕获单个图像的结果子集),包含捕获硬件的配置(传感器sensor,、透镜 lens、闪光灯flash),处理管道pipeline,控制算法和输出缓冲区。处理完 CaptureRequest之后,CaptureResults由CameraDevice类产生

  • CaptureResult的所有字段和CaptureRequest相同

  • CaptureResult 对象也是不可变的。常使用的子类是 TotalCaptureResult。

  • 在CameraCaptureSession.CaptureCallback 类的回调方法 onCaptureProgressed() 和 onCaptureCompleted() 中都可以拿到 CaptureResult 的对象。

2.12 ImageReader

得到一个ImageReader对象的方法为newInstance(int width, int height, int format, int maxImages)。前两个参数是保存图片的宽高,第三个参数为保存图片的格式,也就是reader生产的Image的格式,必须是ImageFormat或PixelFormat中的常量,并不是所有的formats都会被支持,第四个参数代表用户可以同时访问到的最大图片数量

image的data被存储在Image类里面,新的images通过ImageReader的surface发送给ImageReader,类似一个队列,需要通过acquireLatestImage()或者acquireNextImage()方法取出Image。

2.13 TextureView 和SurfaceView

SurfaceView 在自己独立的线程中绘制,不会影响到主线程,内部使用双缓冲机制,画面更流畅。相比于 TextureView,它内存占用低,绘制更及时,耗时也更低,但不支持动画和截图。

由于 SurfaceView 是拥有一个独立的 Surface,不在 View hierachy 体系中,因此不支持动画和截图,而 TextureView 则没有该限制。TextureView 是 Android 4.0 之后引入的,它将内容流直接投影到 View 中,数据流可以来自 App 进程或远端进程。缺点是必须在硬件加速的窗口中使用,且内存和耗电比 SurfaceView 更高,绘制也可能存在 1~3 帧的延迟。

使用TextureView的步骤:

(1)MainActvity要实现TextureView.SurfaceTextureListener接口

(2)创建TextureView,并将MainActvity设置为SurfaceTextureListener,供系统回调MainActvity实现的onSurfaceTextureXXX接口方法

(3)在onSurfaceTextureAvailable回调中拿到SurfaceTexture,并把它设置给camera,作为承载、预览数据流的载体

(4)在onSurfaceTextureDestroyed中关闭预览,释放camera资源,返回true

3 、Camera框架实现录像

  • 预览是将数据展示在SurfaceView或者TextureView上,mMediaRecorder.getSurface();

  • 按照MediaRecorder的相关步骤进行设置

4 、屏幕捕捉

在Android5.0之后开放了新的接口android.media.projection,使用该接口,第三方应用程序无需获取系统root权限也可以直接进行屏幕截图操作了。

由于使用了媒体的映射技术手段,故截取的屏幕并不是真正的设备屏幕,而是截取的通过映射出来的“虚拟屏幕”。

MediaProjection是一个准许APP拥有截取屏幕或者是记录系统音频的能力,可以用来捕捉屏幕,具体来说可以截取当前屏幕和录制屏幕视频。MediaProjection由MediaProjectionManager来管理和获取。

4.1 MediaProjectionManager
  • MediaProjectionManager 是一个系统级的服务,可以通过 getSystemService 来获取实例

Context.getSystemService(Class)方法,参数用MediaProjectionManager.class

Context.getSystemService(String)方法,参数用Context.MEDIA_PROJECTION_SERVICE

例如:

MediaProjectionManager mMediaProjectionManager =

(MediaProjectionManager)getSystemService(Context.MEDIA_PROJECTION_SERVICE);

公有方法

  • Intent createScreenCaptureIntent()

    创建了一个隐式的intent,用来调用系统的录屏程序。通过startActivityForResult来传递这个intent,这个Activity会提示用户是否允许捕捉屏幕。所以可以通过onActivityResult来获取用户操作结果,通过getMediaProjection来取出intent中的数据

  • MediaProjection getMediaProjection (int resultCode, Intent resultData)

    成功获得用户允许后获取MediaProjection对象。如果授权失败,则得到空对象。

4.2 MediaProjection

通过createScreenCaptureIntent()捕获屏幕会话。

VirtualDisplay类代表一个虚拟显示器,需要调用DisplayManager 类的 createVirtualDisplay()方法,将虚拟显示器的内容渲染在一个Surface控件上,当进程终止时虚拟显示器会被自动的释放,并且所有的Window都会被强制移除。当不再使用他时,你应该调用release() 方法来释放资源。

公有方法

  • VirtualDisplay createVirtualDisplay (String name, int width, int height, int dpi, int flags, Surface surface, VirtualDisplay.Callback callback, Handler handler)

创建一个VirtualDisplay用来捕获屏幕内容。

name: VirtualDisplay的名字,永不为空

width: 宽度,单位为像素,必须大于0

height: 高度,单位为像素,必须大于0

dpi: 像素密度,单位为dp,必须大于0

flags:int DisplayManager定义的flag组合,虚拟显示标志,取值是:

💗 VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR允许在没有显示内容的情况下在虚显上显示内容

💗 VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY只显示本镜像的内容

💗 VIRTUAL_DISPLAY_FLAG_PRESENTATION

💗 VIRTUAL_DISPLAY_FLAG_PUBLIC

💗 VIRTUAL_DISPLAY_FLAG_SECURE

surface:Surface virtual display的内容应该被渲染的surface,没有的话为空

⭐️ 显示使用SurfaceView组件

⭐️ 截屏使用ImageReader类,这个类的getSurface()方法获取到surface直接传入MediaProjection.createVirtualDisplay()方法中,此时就可以执行截取。通过ImageReader.acquireLatestImage()方法即可获取当前屏幕的Image,经过简单处理之后即可保存为Bitmap。

⭐️ 录屏需要用到MediaCodec,这个类将原始的屏幕数据编码,在通过MediaMuxer封装成MP4格式保存。MediaCodec.createInputSurface()获取一个surface对象传入MediaProjection.createVirtualDisplay()即可获取屏幕原始多媒体数据,之后读取MediaCodec编码输出数据经过MediaMuxer封装处理MP4即可播放,实现录屏。

callback:VirtualDisplay.Callback virtual display状态变化的回调

handler:Handler callback调用的Handler。如果回调在calling thread的主looper被调用,则为空

void registerCallback (MediaProjection.Callback callback, Handler handler)

注册一个listener接收MediaProjection变化状态的通知。

  • void stop ()停止projection

  • void unregisterCallback (MediaProjection.Callback callback) 取消注册MediaProjection的listener

    4.3 步骤如下:

1、获取MediaProjectionManager

该对象是一个系统服务,可通getSystemService(Context.MEDIA_PROJECTION_SERVICE)获取

2、通过MediaProjectionManager.createScreenCaptureIntent()获取Intent

弹出dialog询问用户是否授权应用捕捉屏幕,同时覆写onActivityResult()获取授权结果。

3、通过startActivityForResult传入Intent, 如果授权成功,在onActivityResult中通过MediaProjectionManager.getMediaProjection(resultCode,data)获取MediaProjection

4、创建ImageReader,构建VirtualDisplay

5、最后就是通过ImageReader截图,就可以从ImageReader里获得Image对象。

6、将Image对象转换成bitmap

MediaProjection漏洞

Android MediaProjection服务被滥用,攻击者可以录音、获取屏幕内容。影响Android5.0之后8.0以前的所有版本,google回应已在8.0版本对漏洞进行了修复。

漏洞描述

Google在Android 5.0中引入了MediaProjection 服务, MediaProjection服务可以让应用开发者获取屏幕内容和记录系统音频。在Android 5.0之前,应用开发者需要应用在 root权限下运行或者用设备的release key对应用进行签名,只有这样才可以使用系统保护的权限来获取屏幕内容。而且,使用 MediaProjection服务时,不需要在 AndroidManifest.xml中声明请求的权限。

安卓应用开发者抵御此类攻击的方式是通过应用的WindowManager开启FLAG_SECURE布局参数。这可以确保应用窗口的内容是安全的,可以防止被截屏或通过其他不安全的方式查看。 FLAG_SECURE参数的设置如下:

public class ApplicationActivity extends AppCompatActivity { 
    
@Override 
    public void onCreate(Bundle savedInstanceState) { 
		super.onCreate(savedInstanceState); 
		getWindow().setFlags(LayoutParams.FLAG_SECURE,LayoutParams.FLAG_SECURE); 

	}

} 
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值