您当前的位置: 首页 > 慢生活 > 程序人生 网站首页程序人生
android camera2 API初探打開攝像頭(自拍那個攝像頭)
发布时间:2022-03-27 20:16:49编辑:雪饮阅读()
最近想要做一個系列的安卓端的音視頻的實踐,想的比較多,但是都知道安卓端是很麻煩的,特別音視頻這方面。那麽首先這裏我就先從打開自拍那個攝像頭,這裏也就是後置攝像頭后了。
環境:
android studio:
Android Studio Bumblebee | 2021.1.1 Patch 2
Build #AI-211.7628.21.2111.8193401, built on February 17, 2022
Runtime version: 11.0.11+9-b60-7590822 amd64
VM: OpenJDK 64-Bit Server VM by Oracle Corporation
Windows 10 10.0
GC: G1 Young Generation, G1 Old Generation
Memory: 1280M
Cores: 12
Registry: external.system.auto.import.disabled=true
Non-Bundled Plugins: com.intellij.marketplace (211.7628.36), edu.umontreal.hatchery (0.2.1), com.thoughtworks.gauge (211.6693.111)
真機:pixel4a
網絡上大多數文章介紹的都是camera那個api,而安卓官網早都有了camera2的api,那麽這裏我剛入門安卓,還沒有折騰過攝像頭,沒有想到第一次折騰就遇到一個過時的api。。。
而我這裏要適配的最低安卓版本是安卓9.安卓9也是要要求camera2的api(好像是)。
同樣的打開攝像頭是需要用戶授權的,好像是從安卓6開始就要動態授權了。
那麽這裏我沒有做動態授權,我是自己在app哪裏提前授權好攝像頭權限的。
聲明文件
那麽聲明文件AndroidManifest.xml中自然是需要聲名好攝像頭權限的:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapplication">
<uses-permission android:name="android.permission.CAMERA" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.MyApplication">
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
佈局文件
接下來我需要一個SurfaceView用來顯示後置攝像頭打開后的畫面預覽,所以:
activity_main.xml:
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical">
<SurfaceView
android:id="@+id/sv"
android:layout_width="200dp"
android:layout_height="200dp" />
</LinearLayout>
</android.support.constraint.ConstraintLayout>
注意:這裏可能會報錯“Cannot resolve class android.support.constraint.ConstraintLayout”
這個真坑,折騰了我快一天了,沒有搞定,看好多文章縂說紛紜,甚至都有說是官方的一個bug,至今沒有修復的特別好。
但後來發現我不管他,照樣能在真機上面運行不崩潰。
java邏輯文件
在java這邊我僅僅判斷了沒有授權攝像頭權限就return,沒有過多在權限上做處理。
然後剩下的都是盡量精簡了的打開攝像頭的邏輯了(聯係到web端通過JavaScript打開攝像頭的邏輯就那個一兩行就搞定了。。。)
package com.example.myapplication;
import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.graphics.ImageFormat;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCaptureSession;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraDevice;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.CaptureRequest;
import android.media.ImageReader;
import android.os.Handler;
import android.os.HandlerThread;
import android.support.v4.app.ActivityCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.Toast;
import java.util.Arrays;
public class MainActivity extends AppCompatActivity {
private Handler childHandler, mainHandler;
private CameraCaptureSession mCameraCaptureSession;
private ImageReader mImageReader;
private SurfaceView mSurfaceView;
private SurfaceHolder mSurfaceHolder;
private CameraDevice mCameraDevice;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
SurfaceViewInit();
}
public void SurfaceViewInit(){
//視頻流渲染區域
mSurfaceView = (SurfaceView) findViewById(R.id.sv);
mSurfaceHolder = mSurfaceView.getHolder();
mSurfaceHolder.setKeepScreenOn(true);
mSurfaceHolder.addCallback(new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder holder) { //SurfaceView创建
// 初始化Camera
initCamera2();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) { //SurfaceView销毁
// 释放Camera资源
if (null != mCameraDevice) {
mCameraDevice.close();
MainActivity.this.mCameraDevice = null;
}
}
});
}
/**
* 开始预览
*/
private void takePreview() {
try {
// 创建预览需要的CaptureRequest.Builder
final CaptureRequest.Builder previewRequestBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW);
// 将SurfaceView的surface作为CaptureRequest.Builder的目标
previewRequestBuilder.addTarget(mSurfaceHolder.getSurface());
mImageReader = ImageReader.newInstance(1080, 1920, ImageFormat.JPEG,1);
// 创建CameraCaptureSession,该对象负责管理处理预览请求和拍照请求
mCameraDevice.createCaptureSession(Arrays.asList(mSurfaceHolder.getSurface(), mImageReader.getSurface()), new CameraCaptureSession.StateCallback() // ③
{
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
if (null == mCameraDevice) return;
// 当摄像头已经准备好时,开始显示预览
mCameraCaptureSession = cameraCaptureSession;
try {
// 自动对焦
previewRequestBuilder.set(CaptureRequest.CONTROL_AF_MODE, CaptureRequest.CONTROL_AF_MODE_CONTINUOUS_PICTURE);
// 打开闪光灯
previewRequestBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_ON_AUTO_FLASH);
// 显示预览
CaptureRequest previewRequest = previewRequestBuilder.build();
mCameraCaptureSession.setRepeatingRequest(previewRequest, null, childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession cameraCaptureSession) {
Toast.makeText(MainActivity.this, "配置失败", Toast.LENGTH_SHORT).show();
}
}, childHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
/**
* 摄像头创建监听
*/
private CameraDevice.StateCallback stateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {//打开摄像头
mCameraDevice = camera;
//开启预览
takePreview();
}
@Override
public void onDisconnected(CameraDevice camera) {//关闭摄像头
if (null != mCameraDevice) {
mCameraDevice.close();
MainActivity.this.mCameraDevice = null;
}
}
@Override
public void onError(CameraDevice camera, int error) {//发生错误
Toast.makeText(MainActivity.this, "摄像头开启失败", Toast.LENGTH_SHORT).show();
}
};
public void initCamera2(){
CameraManager mCameraManager = (CameraManager) getSystemService(Context.CAMERA_SERVICE);
//攝像頭權限判斷
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED) {
Log.i("沒有獲取到攝像頭權限","");
return;
}
HandlerThread handlerThread = new HandlerThread("Camera2");
handlerThread.start();
childHandler = new Handler(handlerThread.getLooper());
mainHandler = new Handler(getMainLooper());
//前置攝像頭,自拍用
String mCameraID = "" + CameraCharacteristics.LENS_FACING_BACK;
Log.i("攝像機id",mCameraID);
try{
mCameraManager.openCamera(mCameraID,stateCallback,mainHandler);
}
catch (CameraAccessException e) {
e.printStackTrace();
}
}
}
效果
关键字词:camera2,android,攝像頭,自拍
相关文章
- android studio關於gradle的版本更換及distributionUr
- 惊艳的android12 内置的无线调试
- pixel4a第二次破解獲取root權限基於安卓12 android 12
- s5代理socket5代理安卓端如何連接(proxy droid的使用)
- androidStudio(Android Studio Arctic Fox 2020.3.1)
- 利用androidStudio快速实现安卓view的透明
- androidStudio4.1.2小技巧 快速为你的view选择背景颜
- androidStudio4.1.2為c盤減負(優化c盤占用)sdk目錄遷移,
- androidStudio4.1.2關於ndk配置自定義目錄的變遷
- AndroidStudio如何使用(導入).aar包(第三方依賴如何本地