之前在解析百度离线人脸识别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了
- 使用过微信聊天的朋友一定不会陌生,当我们的聊天视频拖出微信窗口的时候,应用就会需要您手动授予一个权限(允许其运行于其他应用之上),其正是上面介绍的第二个权限。
- 我们可以通过设置上面的预览宽高就会发现它的效果和微信聊天是一样的,现在想想微信聊天授予的那个权限还是蛮可怕的,但是通常在运行时都会有一个通知实时提醒你当前这个功能正在使用,想想如果没有得多可怕。
好了,今天关于相机在“不预览”的情况下获取原始的回调数据实现就介绍到这里了。
注:欢迎扫码关注