升降攝像頭安卓手機剛上市的時候,有些很流行的app剛開啟時,前置攝像頭就升起來了。好像就是出來看一眼然後又收回去。
雖然我們不呼叫拍照功能,只是為了獲取相機的資訊,也是可能讓攝像頭升起來的。
Camera實現
使用android.hardware.Camera
獲取攝像頭支援的預覽尺寸和fps。
先Camera.open
獲取到camera
例項,然後再camera.getParameters()
。
for (int i = 0; i < Camera.getNumberOfCameras(); i++) {
Camera camera = null;
try {
camera = Camera.open(i);
Parameters parameters = camera.getParameters();
supportedSizes = parameters.getSupportedPreviewSizes();
supportedFpsRanges = parameters.getSupportedPreviewFpsRange();
} catch (RuntimeException e) {
Log.e(TAG, "Failed to open, skipping", e);
continue;
} finally {
if (camera != null) {
camera.release();
}
}
}
android.hardware.Camera
:下文簡稱為「camera」或者「camera1」。
上面的程式碼對於可升降攝像頭手機(例如榮耀X10)來說,前置攝像頭會升起來,然後又縮回去。使用者體驗不好。
可以用Camera2來實現,不用開啟攝像頭就能獲取到相關資訊。
Camera2
引入camera2
首先看模組的gradle。本文示例是放在模組裡的。
我們需要引入androidx相關的包。
- compileSdk 31
- androidx.camera:camera-core:1.1.0-beta01
- androidx.camera:camera-camera2:1.1.0-beta01
apply plugin: 'com.android.library'
android {
compileSdk 31
defaultConfig {
minSdkVersion 19
targetSdkVersion 31
versionCode 110
versionName "1.1.0"
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
implementation 'androidx.appcompat:appcompat:1.3.1'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'com.android.support.test:runner:1.0.2'
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
implementation "androidx.camera:camera-core:1.1.0-beta01"
implementation "androidx.camera:camera-camera2:1.1.0-beta01"
}
注意這裡minSdkVersion 19
,後面使用的時候需要判斷一下執行的Android版本
這裡使用的是beta01版的camera2包,可以看出camera2仍在發展中
使用
部分匯入的包的情況
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraCharacteristics;
import android.hardware.camera2.CameraManager;
import android.hardware.camera2.params.StreamConfigurationMap;
import android.os.Build;
用獲取系統服務的方式來獲取CameraManager,這裡要求 API >= 21
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
CameraManager cameraManager = (CameraManager) mContext.getSystemService(Context.CAMERA_SERVICE);
}
Camera2相比於camera1的一大不同是,Camera2不需要呼叫Camera.open
方法,就能去查詢相機的一些配置。
獲取支援的尺寸。android.hardware
包裡的Camera.Size已經不推薦使用了(Deprecated)。Camera2用的是android.util.Size
。
List<android.util.Size> supportedUtilSize = new ArrayList<>();
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("0"); // 0和1
StreamConfigurationMap configs = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP);
supportedUtilSize = Arrays.asList(configs.getOutputSizes(ImageFormat.JPEG));
獲取支援的fps範圍,結果用Range
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics("1"); // 0和1
Range<Integer>[] ranges21 = characteristics.get(CameraCharacteristics.CONTROL_AE_AVAILABLE_TARGET_FPS_RANGES);
注意上面的程式碼需要判斷系統版本
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
// 在這裡面進行操作
}
Range介紹
獲取fps資料時我們用到了Range
package android.util;
public final class Range<T extends Comparable<? super T>> {
它接受的範型要能夠進行比較,即繼承Comparable。前面的程式碼我們用的是Range
package java.lang;
public final class Integer extends Number implements Comparable<Integer>
Range表示範圍。它代表了一個範圍,提供了一些常用的方法。比較類似數學中的集合的概念。
例如:
判斷目標值是否在範圍裡public boolean contains(T value)
判斷傳入的範圍是否在自己的範圍裡面public boolean contains(Range<T> range)
獲取一個範圍內的數值,即限制數值不能超過自己的範圍 public T clamp(T value)
。假設範圍是0到10,傳入12,則返回10,也就是上限。