之前在解析百度離線人臉識別SDK的Demo封裝的結構時,我就說到後面會介紹如何實現在不預覽的情況下獲取攝像頭回調的元素數據,今天我們就來實現一下。下面先給出實現代碼:
package aoto.com.cameranopreviewtest;
import android.content.Context;
import android.graphics.PixelFormat;
import android.hardware.Camera;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Gravity;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.WindowManager;
import java.io.IOException;
/**
* @author why
* @date 2019-7-2 20:45:49
*/
public class MainActivity extends AppCompatActivity {
private Camera mCamera;
private int previewWidth=1;
private int previewHeight=1;
private static final String TAG = "MainActivityWhy";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
}
@Override
protected void onStart() {
super.onStart();
startPreview();
}
private void startPreview() {
SurfaceView dummyView = new SurfaceView(this);
SurfaceHolder holder = dummyView.getHolder();
SurfaceHolder.Callback surfaceHolder = new SurfaceHolder.Callback() {
@Override
public void surfaceCreated(SurfaceHolder surfaceHolder) {
if (mCamera == null) {
mCamera = Camera.open();
}
if (mCamera != null) {
mCamera.setPreviewCallback(new Camera.PreviewCallback() {
@Override
public void onPreviewFrame(byte[] data, Camera camera) {
Log.e(TAG, "數據長度: "+data.length );
}
});
mCamera.startPreview();
}
else {
Log.e(TAG, "未檢測到攝像頭" );
}
}
@Override
public void surfaceChanged(SurfaceHolder surfaceHolder, int i, int i1, int i2) {
}
@Override
public void surfaceDestroyed(SurfaceHolder surfaceHolder) {
}
};
holder.addCallback(surfaceHolder);
holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
WindowManager wm = (WindowManager) this.getSystemService(Context.WINDOW_SERVICE);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(previewWidth, previewHeight,
WindowManager.LayoutParams.TYPE_SYSTEM_ALERT,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE |
WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE,
PixelFormat.TRANSPARENT);
params.gravity = Gravity.TOP | Gravity.RIGHT;
params.alpha = PixelFormat.TRANSPARENT;
params.x = params.y = 10;
wm.addView(dummyView, params);
}
}
很簡單,我們只需要在我們的Activity中調用startPreview()方法即可獲取攝像頭的原始回調數據,當然,這需要建立在以下幾個條件之上:
- 應用需添加如下權限獲取了對應的權限,如果版本大於等於6.0,請添加對應的權限申請,且後面一個權限有的設備需要手動添加
<uses-permission android:name="android.permission.CAMERA"></uses-permission> <uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW"></uses-permission>
- 設備已經連接了可用的攝像頭
在滿足了上面兩個條件之後,基本上就可以實現在“不預覽”的情況下獲取相機回調數據,其實這裏說的不預覽是不正確的,下面在列舉幾個關鍵點:
- 我們在Activity中也可以放一個SurfaceView或者TextureView等賴裝載預覽的視頻,我們可以通過設置View的寬高很小同樣可以達到“不預覽”的效果
- 我們這裏的實現和上面的思路一模一樣,只不過我們通過一個Window彈窗來實現預覽視頻的裝載,這樣就不用始終開着Activity了
- 使用過微信聊天的朋友一定不會陌生,當我們的聊天視頻拖出微信窗口的時候,應用就會需要您手動授予一個權限(允許其運行於其他應用之上),其正是上面介紹的第二個權限。
- 我們可以通過設置上面的預覽寬高就會發現它的效果和微信聊天是一樣的,現在想想微信聊天授予的那個權限還是蠻可怕的,但是通常在運行時都會有一個通知實時提醒你當前這個功能正在使用,想想如果沒有得多可怕。
好了,今天關於相機在“不預覽”的情況下獲取原始的回調數據實現就介紹到這裏了。
注:歡迎掃碼關注