編輯:關於Android編程
在API21中Google就發布了Camera2類來取代Camera類,那麼這個Camera2類到底改變了那些地方呢,我們來看官方的說法:
Camera2 API
還有部分新功能沒有列出
查看了一下API,發現Camera2相對於Camera類架構都改變了,所以代碼肯定是不通用的了,相比之前的代碼應該算是比較難了一點了。
先來看看camera2包架構示意圖:
Google采用了pipeline(管道)的概念,將Camera Device相機設備和AndroidDevice安卓設備連接起來, Android Device通過管道發送CaptureRequest拍照請求給Camera Device,Camera Device通過管道返回CameraMetadata數據給Android Device,這一切建立在一個叫作CameraCaptureSession的會話中。
下面是camera2包中的主要類:
其中CameraManager是所有相機設備(CameraDevice)的管理者,而每個CameraDevice自己會負責建立CameraCaptureSession以及建立CaptureRequest。CameraCharacteristics是CameraDevice的屬性描述類,在CameraCharacteristics中可以進行相機設備功能的詳細設定(當然了,首先你得確定你的相機設備支持這些功能才行)。
類圖中有著三個重要的callback,其中CameraCaptureSession.CaptureCallback將處理預覽和拍照圖片的工作,需要重點對待。
這些類是如何相互配合的?下面是簡單的流程圖:
順便提一下onCaptureProgressed方法很明顯是在Capture過程中的,也就是在onCaptureCompleted之前,所以,在這之前相對圖像干什麼就看你的了,像美顏等操作就可以在這個方法中實現了。
可以看出Camera2相機使用的邏輯還是比較簡單的,其實就是3個Callback函數的回調,先說一下:setRepeatingRequest和capture方法其實都是向相機設備發送獲取圖像的請求,但是capture就獲取那麼一次,而setRepeatingRequest就是不停的獲取圖像數據,所以呢,使用capture就想拍照一樣,圖像就停在那裡了,但是setRepeatingRequest一直在發送和獲取,所以需要連拍的時候就調用它,然後在onCaptureCompleted中保存圖像就行了。(注意了,圖像的預覽也是用的setRepeatingRequest,只是你不處理數據就行了)
下面貼出代碼,我用的TextureView來顯示圖像:
首先權限不能忘:
布局:
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mThreadHandler = new HandlerThread("CAMERA2");
mThreadHandler.start();
mHandler = new Handler(mThreadHandler.getLooper());
mPreviewView = (TextureView) findViewById(R.id.textureview);
mPreviewView.setSurfaceTextureListener(this);
}
@SuppressWarnings("ResourceType")
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
CameraManager cameraManager = (CameraManager) getSystemService(CAMERA_SERVICE);
try {
String[] CameraIdList = cameraManager.getCameraIdList();
//獲取可用相機設備列表
CameraCharacteristics characteristics = cameraManager.getCameraCharacteristics(CameraIdList[0]);
//在這裡可以通過CameraCharacteristics設置相機的功能,當然必須檢查是否支持
characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL);
//就像這樣
cameraManager.openCamera(CameraIdList[0], mCameraDeviceStateCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {}
private CameraDevice.StateCallback mCameraDeviceStateCallback = new CameraDevice.StateCallback() {
@Override
public void onOpened(CameraDevice camera) {
try {
startPreview(camera);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onDisconnected(CameraDevice camera) {}
@Override
public void onError(CameraDevice camera, int error) {}
};
private void startPreview(CameraDevice camera) throws CameraAccessException {
SurfaceTexture texture = mPreviewView.getSurfaceTexture();
texture.setDefaultBufferSize(mPreviewView.getWidth(), mPreviewView.getHeight());
Surface surface = new Surface(texture);
try {
mPreviewBuilder = camera.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
} catch (CameraAccessException e) {
e.printStackTrace();
}
mPreviewBuilder.addTarget(surface);
camera.createCaptureSession(Arrays.asList(surface), mSessionStateCallback, mHandler);
}
private CameraCaptureSession.StateCallback mSessionStateCallback = new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession session) {
try {
//session.capture(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);
session.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);
} catch (CameraAccessException e) {
e.printStackTrace();
}
}
@Override
public void onConfigureFailed(CameraCaptureSession session) {}
};
private CameraCaptureSession.CaptureCallback mSessionCaptureCallback =
new CameraCaptureSession.CaptureCallback() {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request,
TotalCaptureResult result) {}
@Override
public void onCaptureProgressed(CameraCaptureSession session, CaptureRequest request,
CaptureResult partialResult){}};
}
如需按鍵,就加一個Button,寫上
mSession.setRepeatingRequest(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);
或者
session.capture(mPreviewBuilder.build(), mSessionCaptureCallback, mHandler);就可以了
其實過程還是挺簡單的,主要是邏輯比較簡單,就是不停的Callback,然後在onCaptureCompleted中處理數據就行了。
我們都知道,類似 Activity, Fragment 有 onSaveInstanceState() 回調用來保存狀態。在Fragment裡面,利用onSaveInst
上篇講到了Fragment的基礎應用,現在給大家演示一下Fragment的生命周期是什麼樣子的。關於Fragemnt的基礎應用,請見http://blog.csdn.ne
Android有三個基礎組件Activity,Service和BroadcastReceiver,他們都是依賴Intent來啟動。本文介紹的是Activity的生命周期以
現在開始具體 處理每一個導航頁面的邏輯,首先看第二個導航頁這裡需要實現綁定sim卡序列號的功能,注意添加相應的權限:uses-permission android:nam