android 圆形弹窗摄像头开发踩坑——源码————未来之窗跨平台操作
一、飘窗刷脸,拍照采用飘窗
刷脸认证安卓接口采用飘窗具有在不干扰用户主要操作的前提下以醒目方式引导用户完成认证,且能灵活定制样式以提升用户体验和认证效率的优点
二、踩坑只有一个扇形
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/popfacebgcard2"
android:layout_width="280dp"
android:layout_height="280dp"
app:cardCornerRadius="280dp"
android:layout_gravity="center"
>
</androidx.cardview.widget.CardView>
</FrameLayout>
三、方形改圆形
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="100dp"
android:layout_height="100dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/popfacebgcard2"
android:layout_width="280dp"
android:layout_height="280dp"
app:cardCornerRadius="280dp"
android:layout_gravity="center"
>
</androidx.cardview.widget.CardView>
</FrameLayout>
app:cardCornerRadius="280dp"
四、通用圆形
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="296dp"
android:layout_height="296dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/popfacebgcard2"
android:layout_width="280dp"
android:layout_height="280dp"
app:cardCornerRadius="280dp"
android:layout_gravity="center"
>
<TextureView
android:id="@+id/textureView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
</androidx.cardview.widget.CardView>
</FrameLayout>
五、加外框
六、圆形外框
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="296dp"
android:layout_height="296dp"
xmlns:app="http://schemas.android.com/apk/res-auto">
<androidx.cardview.widget.CardView
android:id="@+id/popfacebgcard"
android:layout_width="296dp"
android:layout_height="296dp"
app:cardCornerRadius="296dp"
android:background="#0078D7"
>
<androidx.cardview.widget.CardView
android:id="@+id/popfacebgcard2"
android:layout_width="280dp"
android:layout_height="280dp"
app:cardCornerRadius="280dp"
android:layout_gravity="center"
>
<!--
<LinearLayout
android:id="@+id/popfacebg"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:background="@drawable/face_border"
>
-->
<TextureView
android:id="@+id/textureView"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
/>
<TextView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:text="智慧押金">
</TextView>
<!--
</LinearLayout>
-->
</androidx.cardview.widget.CardView>
</androidx.cardview.widget.CardView>
<!--
<View android:id="@+id/circularPopupView"
android:layout_width="match_parent"
android:layout_height="match_parent">
<SurfaceView
android:id="@+id/surfaceViewInPopup"
android:layout_width="match_parent"
android:layout_height="match_parent" />
</View>
-->
</FrameLayout>
七、弹窗
private void showPopup() {
LayoutInflater inflater = (LayoutInflater) getSystemService(Context.LAYOUT_INFLATER_SERVICE);
popupView = inflater.inflate(R.layout.cyberwin_popup_face_layout, null);
Context cyberwincpu=this;
// circularPopupView = popupView.findViewById(R.id.circularPopupView);
// surfaceViewInPopup = popupView.findViewById(R.id.surfaceViewInPopup);
// surfaceHolderInPopup = surfaceViewInPopup.getHolder();
// surfaceHolderInPopup.addCallback(this);
textureView = popupView.findViewById(R.id.textureView);
// LinearLayout popfacebg背景 = popupView.findViewById(R.id.popfacebg);
CardView popfacebg背景2 = popupView.findViewById(R.id.popfacebgcard);
WindowManager.LayoutParams params = new WindowManager.LayoutParams(
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.WRAP_CONTENT,
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
WindowManager.LayoutParams params小窗口 = new WindowManager.LayoutParams(
DensityUtils.dp2px(this, 296),
DensityUtils.dp2px(this, 296),
WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY,
WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
| WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
PixelFormat.TRANSLUCENT);
params小窗口.format = PixelFormat.RGBA_8888;//设置图片格式
params.gravity = Gravity.CENTER;
// 创建圆角背景
// GradientDrawable drawable = new GradientDrawable();
// drawable.setColor(Color.RED); // 设置背景颜色
// drawable.setCornerRadius(100); // 设置圆角半径
/*
if (popupView instanceof LinearLayout) {
((LinearLayout) popupView).setBackground(drawable);
}
*/
// ((LinearLayout) popupView).setBackground(drawable);
// circularPopupView.setBackground(drawable);
/*
// 将圆角背景设置为悬浮窗口的背景
if (popupView instanceof LinearLayout) {
((LinearLayout) popupView).setBackground(drawable);
}
*/
// 当 TextureView 可用时,打开摄像头
// ViewGroup.LayoutParams layoutParams摄像头 = textureView.getLayoutParams();
// ViewGroup.LayoutParams layoutParams摄像头背景 = popfacebg背景2.getLayoutParams();
// 设置宽度为 400 像素
// layoutParams摄像头.width = 350;
// 设置高度为 600 像素
// layoutParams摄像头.height = 350;
// popfacebg背景2.setCardr
// popfacebg背景2.setLayoutParams(layoutParams摄像头背景);
// 设置宽度为 400 像素
// layoutParams摄像头.width = 350;
// 设置高度为 600 像素
// layoutParams摄像头.height = 350;
// 应用新的布局参数
// textureView.setLayoutParams(layoutParams摄像头);
int paddingLeftInPx = DensityUtils.dp2px(this, 8);
// popfacebg背景2.setPadding(paddingLeftInPx, paddingLeftInPx, paddingLeftInPx, paddingLeftInPx);
// popfacebg背景2.setBackgroundColor(Color.parseColor("#0078D7"));
textureView.setSurfaceTextureListener(new TextureView.SurfaceTextureListener() {
@Override
public void onSurfaceTextureAvailable(SurfaceTexture surface, int width, int height) {
// openCamera();
// Snackbar.make(view, "Replace with your own action", Snackbar.LENGTH_LONG)
// .setAction("Action", null)
// .setAnchorView(R.id.fab).show();
Toast.makeText(cyberwincpu,"显示界面",Toast.LENGTH_SHORT);
// drawCircle(textureView);
打开摄像头(textureView);
}
@Override
public void onSurfaceTextureSizeChanged(SurfaceTexture surface, int width, int height) {
}
@Override
public boolean onSurfaceTextureDestroyed(SurfaceTexture surface) {
return false;
}
@Override
public void onSurfaceTextureUpdated(SurfaceTexture surface) {
}
});
windowManager.addView(popupView, params小窗口);
// popupView
// circularPopupView.setOnTouchListener(new View.OnTouchListener() {
// popupView.setOnTouchListener(new View.OnTouchListener() {
// circularPopupView.setOnTouchListener(new View.OnTouchListener() {
popupView.setOnTouchListener(new View.OnTouchListener() {
int initialX, initialY;
int initialTouchX, initialTouchY;
@Override
public boolean onTouch(View v, MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
initialX = params小窗口.x;
initialY = params小窗口.y;
initialTouchX = (int) event.getRawX();
initialTouchY = (int) event.getRawY();
return true;
case MotionEvent.ACTION_UP:
return true;
case MotionEvent.ACTION_MOVE:
params小窗口.x = initialX + (int) (event.getRawX() - initialTouchX);
params小窗口.y = initialY + (int) (event.getRawY() - initialTouchY);
drawCircle(popupView);
windowManager.updateViewLayout(popupView, params小窗口);
return true;
}
return false;
}
});
}
八、摄像头
private android.hardware.Camera camera摄像头;
private void 打开摄像头(TextureView tv) {
try {
int cameraId = 仙盟_冥界_摄像头_寻找前置();
if (cameraId != -1) {
camera摄像头 = android.hardware.Camera.open(cameraId);
}else{
camera摄像头 = android.hardware.Camera.open();
// cameraId=0;
}
android.hardware.Camera.Parameters parameters = camera摄像头.getParameters();
android.hardware.Camera.Size previewSize = parameters.getPreviewSize();
android.hardware.Camera.Size pictureSize = parameters.getPictureSize();
camera摄像头.setDisplayOrientation(90);
//注意顺序
camera摄像头.setParameters(parameters);
camera摄像头.setPreviewTexture(tv.getSurfaceTexture());
camera摄像头.startPreview();
//
// 设置相机的预览方向
// setCameraDisplayOrientation(this, cameraId, camera摄像头);
} catch (Exception e) {
e.printStackTrace();
}
}
private int 仙盟_冥界_摄像头_寻找前置() {
int cameraCount = android.hardware.Camera.getNumberOfCameras();
android.hardware.Camera.CameraInfo cameraInfo = new android.hardware.Camera.CameraInfo();
for (int i = 0; i < cameraCount; i++) {
android.hardware.Camera.getCameraInfo(i, cameraInfo);
if (cameraInfo.facing == android.hardware.Camera.CameraInfo.CAMERA_FACING_FRONT) {
return i;
}
}
return -1;
}
// 设置相机的预览方向
public void setCameraDisplayOrientation(Context context, int cameraId, Camera camera) {
try{
Camera.CameraInfo info = new Camera.CameraInfo();
Camera.getCameraInfo(cameraId, info);
WindowManager windowManager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
int rotation = windowManager.getDefaultDisplay().getRotation();
int degrees = 0;
switch (rotation) {
case android.view.Surface.ROTATION_0:
degrees = 0;
break;
case android.view.Surface.ROTATION_90:
degrees = 90;
break;
case android.view.Surface.ROTATION_180:
degrees = 180;
break;
case android.view.Surface.ROTATION_270:
degrees = 270;
break;
}
int result;
if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
result = (info.orientation + degrees) % 360;
result = (360 - result) % 360; // 前置摄像头需要镜像处理
} else { // 后置摄像头
result = (info.orientation - degrees + 360) % 360;
}
camera.setDisplayOrientation(result);
} catch (Exception e) {
e.printStackTrace();
Toast.makeText(this,"设置相机的预览方向"+e.getMessage(),Toast.LENGTH_SHORT);
}
}
private void releaseCamera() {
if (camera摄像头 != null) {
camera摄像头.stopPreview();
camera摄像头.release();
camera摄像头 = null;
}
}