[关闭]
@Tyhj 2018-05-19T09:02:06.000000Z 字数 1857 阅读 1712

Android自定义相机,相机重启和动态调整预览画面

Android


一般拍照调用系统相机就可以了,不过不同系统的相机可能有所差异,有些特殊的设备的系统相机可能根本调不起来或者没有系统相机,又或者拍照的时候不需要用户手动操作,这个时候就需要自定义相机了

最近做一个APP需要频繁的调用相机,类似后台拍照那种,可能在任何时候拍照或者拍视频,还有改变预览画面的大小,使用的是老版的相机API,发现在相机重启的时候容易出问题

画面的预览调整

这里使用一个系统悬浮窗(surfaceView)来预览画面,在service里面调用相机就可以在任何时候拍照了,通过设置和更新悬浮窗的大小可以实现预览画面的显示和隐藏

  1. //创建悬浮窗
  2. CameraService.class
  3. public static WindowManager mWindowManager;
  4. SurfaceView videoFloat;
  5. WindowManager.LayoutParams wmParams;
  6. public int cameraWidth = 1;
  7. public int cameraHeight = 1;
  8. public void createFloatWindow(Context context) {
  9. WindowManager windowManager = getWindowManager(context);
  10. if (videoFloat != null) {
  11. windowManager.removeView(videoFloat);
  12. //windowManager.removeViewImmediate(videoFloat);
  13. }
  14. wmParams = new WindowManager.LayoutParams();
  15. wmParams.type = WindowManager.LayoutParams.TYPE_TOAST;
  16. //设置图片格式,效果为背景透明
  17. wmParams.format = PixelFormat.RGBA_8888;
  18. //设置浮动窗口不可聚焦(实现操作除浮动窗口外的其他可见窗口的操作)
  19. wmParams.flags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL |
  20. WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
  21. //调整悬浮窗显示的停靠位置为左侧置顶
  22. wmParams.gravity = Gravity.LEFT | Gravity.TOP;
  23. wmParams.verticalMargin = 0;
  24. //以屏幕左上角为原点,设置x、y初始值,相对于gravity
  25. wmParams.x = 0;
  26. wmParams.y = 0;
  27. //设置悬浮窗口长宽数据
  28. wmParams.width = cameraWidth;
  29. wmParams.height = cameraHeight;
  30. videoFloat = new SurfaceView(this);
  31. videoFloat.getHolder().setFormat(PixelFormat.TRANSLUCENT);
  32. windowManager.addView(videoFloat, wmParams);
  33. }
  1. //更新悬浮窗大小
  2. private void setWmParams() {
  3. wmParams.width = cameraWidth;
  4. wmParams.height = cameraHeight;
  5. getWindowManager(this).updateViewLayout(videoFloat, wmParams);
  6. }

相机的重启

重启相机的时候需要先关闭相机,然后重新设置预览的surfaceView,再重新开启相机,如果是直接用之前的surfaceView那么相机会出现打不开的情况

然后如果先移除surfaceView,再重新初始化surfaceView,使用这个surfaceView打开相机,类似上面的代码,发现还是不行

但是如果直接重新创建一个surfaceView,添加到悬浮窗,然后使用它打开相机是可以的

问题就出在移除surfaceView这里,windowManager移除view有两种方法,根据上面的名字可以看出,removeViewImmediate是马上移除的意思那另一个可能就不会马上移除窗口,用这种方法然后重新初始化surfaceView再打开相机是没问题的

拍照和录视频同时进行

应该不会冲突,还没有试过

添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注