注意:本文章只适用于技术交流,请你友好交流净化开发环境
思考
- 由于谷歌强制在Android应用开发中编写拍照程序是必需要有图像预览的。这对那些恶意程序比如Android中泛滥的Service在后台偷偷记录手机用户的行为与周边信息。这样的门槛还包括手机厂商自带的相机软件在拍照时必须是有声音,这样要避免一些偷拍的情况;据说oppo find系列及vivo Nex系列可以检测出那些流氓软件这么做了。
步骤
创建一个surfaView对象
preview = new SurfaceView(this); holder = preview.getHolder(); // deprecated setting, but required on Android versions prior to 3.0 holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); holder.addCallback(new SurfaceHolder.Callback() { @Override //The preview must happen at or after this point or takePicture fails public void surfaceCreated(SurfaceHolder holder) { //创建成功以后打开相机 /** * camaraType: Camera.CameraInfo.CAMERA_FACING_FRONT :打开前置摄像头 * camaraType: Camera.CameraInfo.CAMERA_FACING_BACK :打开后置摄像头 */ try { camera = Camera.open(camaraType); try { camera.setPreviewDisplay(holder); } catch (IOException e) { throw new RuntimeException(e); } camera.startPreview(); Log.d(TAG, "Started preview"); camera.takePicture(null, null, pictureCallback); } catch (Exception e) { if (camera != null) camera.release(); throw new RuntimeException(e); } } @Override public void surfaceDestroyed(SurfaceHolder holder) {} @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {} });
- 使用WindowManager增加一个1*1px的悬浮框
wm = (WindowManager)getSystemService(Context.WINDOW_SERVICE);
//设置悬浮框为:1 * 1 :记得用后将其remove否则其他界面得不到交点,并且下拉框会有提示:应用在他应用的上层显示的应用,关于这个设置选项
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
1, 1, //设置成宽:1px , 高:1px
WindowManager.LayoutParams.TYPE_SYSTEM_OVERLAY,0, PixelFormat.UNKNOWN);
/**
* 根据不同的版本设置:TYPE_APPLICATION_OVERLAY 在低于26版本中报错崩溃
* 但是在Android O的系统中,google规定申请android.permission.SYSTEM_ALERT_WINDOW权限的应用需要给悬浮窗口设置如下params.type
*/
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
params.type = WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
}
将SurfaceView添加到WindowManager中
wm.addView(preview, params);
拍照结果的回掉保存(
注意: 上层的1*1px的拍照布局 : 一定要移除,一定要移除,一定要移除,重要的妖怪打三遍---不然切换点击屏幕其他位置手机是获取不到焦点,没有反应的
)/** * 拍照开始后结果的回调 */ private Camera.PictureCallback pictureCallback = new Camera.PictureCallback() { @Override public void onPictureTaken(byte[] data, Camera camera) { Log.d(TAG, "onPictureTaken"); if(null == data){ return; } Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length); camera.stopPreview(); Matrix matrix = new Matrix(); matrix.postRotate((float) 270.0); //旋转拍照结果,可能方向不正确 bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); Log.d(TAG, "original bitmap width: " + bitmap.getWidth() + " height: " + bitmap.getHeight()); Bitmap sizeBitmap = Bitmap.createScaledBitmap(bitmap, bitmap.getWidth()/3, bitmap.getHeight()/3, true); Log.d(TAG,"size bitmap width "+sizeBitmap.getWidth()+" height "+sizeBitmap