自定义拍照和录像功能。拍完照或录完视频后,弹出另一界面,显示拍的照片或录制的视频:

拍照界面:

界面中的按钮,点击是拍照,长按是摄像,摄像时,按钮周围有圆形进度条显示进度

TakePicActivity.java

package com.haier.uhome.appliance.newVersion.module.messageboard;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class TakePicActivity extends AppCompatActivity {
    private static final String TAG = "TakePicActivity";
    SurfaceView surfaceView;
    SurfaceHolder surfaceHolder;
    RelativeLayout rl_btn;
    @BindView(R.id.fl_content)
    FrameLayout flContent;
    //进度条
    @BindView(R.id.circleProgress)
    CircleProgressView circleProgress;
    @BindView(R.id.iv_turn)
    ImageView ivTurn;
    private Camera camera;
    private Camera.Parameters parameters = null;

Bundle bundle = null; // 声明一个Bundle对象,用来存储数据
    Button takepicture;
    RelativeLayout rl_playPic;
    int w, h;
    protected boolean isPreview;
    private MediaRecorder mMediaRecorder;
    private boolean isRecording = true; // true表示没有录像,点击开始;false表示正在录像,点击暂停
    private File mRecVedioPath;
    private File mRecAudioFile;
    //录制视频时的计时器
    private TextView timer;
    private int hour = 0;
    private int minute = 0;
    private int second = 0;
    private boolean bool;

private Animator animator;
    private boolean isRecordState = false;//是否是视频录制状态
    private int progress;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_pic);
        ButterKnife.bind(this);

takepicture = (Button) findViewById(R.id.takepicture);
        surfaceView = (SurfaceView) this
                .findViewById(R.id.surfaceView);
        rl_btn = (RelativeLayout) this.findViewById(R.id.buttonLayout);
        timer = (TextView) this.findViewById(R.id.show_time);
        // 设置计时器不可见
//        timer.setVisibility(View.GONE);

// 设置缓存路径
        mRecVedioPath = new File(Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/hfdatabase/video/temp/");

if (!mRecVedioPath.exists()) {
            mRecVedioPath.mkdirs();
        }

//圆形进度条设置
        circleProgress.setBgColor(getResources().getColor(R.color.text_white));
        circleProgress.setProgressColor(getResources().getColor(R.color.colorPrimaryDark));
        ViewTreeObserver observerCircle = circleProgress.getViewTreeObserver();
        observerCircle.addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {
            @Override
            public boolean onPreDraw() {
                progress = circleProgress.getmProgress();
                return true;
            }
        });

surfaceView.getHolder()
                .setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        surfaceView.getHolder().setFixedSize(176, 144); //设置Surface分辨率
        surfaceView.getHolder().setKeepScreenOn(true);// 屏幕常亮
        surfaceView.getHolder().addCallback(new SurfaceCallback());//为SurfaceView的句柄添加一个回调函数
        //长按录制
        takepicture.setOnLongClickListener(new View.OnLongClickListener() {
            @Override
            public boolean onLongClick(View v) {
                isRecordState = true;
                if (isRecording) {
                    /*
                     * 点击开始录像
                     */
                    if (isPreview) {
                        camera.stopPreview();
                        camera.release();
                        camera = null;
                    }
                    second = 0;
                    minute = 0;
                    hour = 0;
                    bool = true;
                    if (mMediaRecorder == null)
                        mMediaRecorder = new MediaRecorder();
                    else
                        mMediaRecorder.reset();
                    //拍摄视频时的相机配置
                    if (camera != null) {
                        freeCameraResource();
                    }
                    camera = Camera.open();
                    camera.setDisplayOrientation(90);
                    camera.startPreview();
                    camera.unlock();
                    mMediaRecorder.setCamera(camera);
                    mMediaRecorder.setOnErrorListener(null);
                    mMediaRecorder.setPreviewDisplay(surfaceHolder.getSurface());
                    mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
                    mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
                    mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
                    mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
                    mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
                    mMediaRecorder.setMaxDuration(60 * 1000);
                    mMediaRecorder.setVideoSize(320, 240);
                    mMediaRecorder.setVideoEncodingBitRate(1 * 1024 * 1024);// 设置帧频率,然后就清晰了
//                    mMediaRecorder.setVideoFrameRate(15);
                    mMediaRecorder.setOrientationHint(getPreviewDegree(TakePicActivity.this));// 输出旋转90度,保持竖屏录制
                    try {
                        mRecAudioFile = File.createTempFile("Vedio", ".mp4", mRecVedioPath);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mMediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());

try {
                        mMediaRecorder.prepare();
                        timer.setVisibility(View.VISIBLE);
                        handler.postDelayed(task, 1000);
                        mMediaRecorder.start();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }

showMsg("开始录制");
//                    scalePic.setBackgroundDrawable(iconStop);
                    isRecording = !isRecording;
                    recordAnimater();
                }
                return false;
            }
        });

takepicture.setOnTouchListener(new View.OnTouchListener() {
            @Override
            public boolean onTouch(View v, MotionEvent event) {
                switch (event.getAction()){
                    case MotionEvent.ACTION_UP:
                        Log.d(TAG, "onTouch: takepicture==setOnTouchListener==ACTION_UP");
                        if(isRecordState){
                            if(animator.isRunning()){
                                animator.end();
                            }
                        }
                        break;
                }
                return false;
            }
        });
    }

/*
    * 视频录制时的进度条动画
    * */
    public void recordAnimater() {
        //设置进度条
        startAnimator();
        animator.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {

}

@Override
            public void onAnimationEnd(Animator animation) {
                Log.i("animator", "stop");
                /*
                     * 点击停止
                     */
                try {
                    bool = false;
//                    isRecordState = false;
                    mMediaRecorder.stop();
                    timer.setText(format(hour) + ":" + format(minute) + ":" + format(second));
                    mMediaRecorder.release();
                    mMediaRecorder = null;
                    //录制完成后播放摄像头
                    freeCameraResource();
                    videoRename();
                } catch (Exception e) {
                    e.printStackTrace();
                }

isRecording = !isRecording;
//                    scalePic.setBackgroundDrawable(iconStart);
                showMsg("录制完成,已保存");
//                        Intent backIntent = new Intent();
//                        backIntent.putExtra("path", mrv_wx.mVecordFile.getAbsoluteFile().toString());
//                        setResult(RESULT_OK, backIntent);
//                        finish();
                Intent displayIntent = new Intent(TakePicActivity.this, ShowPicActivity.class);
                bundle = new Bundle();
                bundle.putBoolean("isRecord", isRecordState);
                bundle.putString("video_path", out.getAbsolutePath());
                displayIntent.putExtras(bundle);
                startActivity(displayIntent);
            }

@Override
            public void onAnimationCancel(Animator animation) {

}

@Override
            public void onAnimationRepeat(Animator animation) {

}
        });
    }

@OnClick(R.id.iv_turn)
    public void onClick() {
    }

private final class SurfaceCallback implements SurfaceHolder.Callback {

@Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                if (camera != null) {
                    freeCameraResource();
                }
                camera = Camera.open(); // 打开摄像头
                parameters = camera.getParameters();
                //加这句小米手机会黑屏
//                parameters.setPreviewFrameRate(5); // 每秒5帧
                parameters.setPictureFormat(PixelFormat.JPEG);// 设置照片的输出格式
                parameters.set("jpeg-quality", 85);// 照片质量
                int PreviewWidth = 0;
                int PreviewHeight = 0;
                // 选择合适的预览尺寸
                List<Camera.Size> sizeList = parameters.getSupportedPreviewSizes();
                // 如果sizeList只有一个我们也没有必要做什么了,因为就他一个别无选择
                if (sizeList.size() > 1) {
                    Iterator<Camera.Size> itor = sizeList.iterator();
                    while (itor.hasNext()) {
                        Camera.Size cur = itor.next();
                        if (cur.width >= PreviewWidth
                                && cur.height >= PreviewHeight) {
                            PreviewWidth = cur.width;
                            PreviewHeight = cur.height;
                            break;
                        }
                    }
                }
                parameters.setPreviewSize(PreviewWidth, PreviewHeight); // 获得摄像区域的大小
                parameters.setPictureSize(PreviewWidth, PreviewHeight); // 获得保存图片的大小
//                parameters.setPreviewSize(320, 240); // 设置预览大小
//                parameters.setPictureSize(320,240);
//                    parameters.set("orientation", "portrait");
                camera.setParameters(parameters);
                camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象
                camera.setDisplayOrientation(getPreviewDegree(TakePicActivity.this));
                camera.startPreview(); // 开始预览
                isPreview = true;
//                camera.autoFocus(null);
            } catch (Exception e) {
                e.printStackTrace();
            }
            surfaceHolder = holder;
        }

@Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            surfaceHolder = holder;
            LogUtil.d(TAG,"surfaceChanged======");
            camera.autoFocus(new Camera.AutoFocusCallback() {
                @Override
                public void onAutoFocus(boolean success, Camera camera) {
//                    camera.setOneShotPreviewCallback(null);
                    initCamera(width, height);
                    camera.cancelAutoFocus();//只有加上了这一句,才会自动对焦。
                }
            });

}

@Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            if (camera != null) {
                if (isPreview) {
                    camera.stopPreview();
                    isPreview = false;
                }
                camera.release(); // 释放照相机
                camera = null;
            }
            surfaceHolder = null;
            surfaceView = null;
            mMediaRecorder = null;
        }
    }

// 提供一个静态方法,用于根据手机方向获得相机预览画面旋转的角度
    public static int getPreviewDegree(Activity activity) {
        // 获得手机的方向
        int rotation = activity.getWindowManager().getDefaultDisplay()
                .getRotation();
        int degree = 0;
        // 根据手机的方向计算相机预览画面应该选择的角度
        switch (rotation) {
            case Surface.ROTATION_0:
                degree = 90;
                break;
            case Surface.ROTATION_90:
                degree = 0;
                break;
            case Surface.ROTATION_180:
                degree = 270;
                break;
            case Surface.ROTATION_270:
                degree = 180;
                break;
        }
        return degree;
    }

/**
     * 按钮被点击触发的事件
     *
     * @param v
     */
    public void btnOnclick(View v) {
        if (camera != null) {
            switch (v.getId()) {
                case R.id.takepicture:
                    // 拍照
                    camera.takePicture(null, null, new MyPictureCallback());
                    break;
            }
        }
    }

byte[] picData;

private final class MyPictureCallback implements Camera.PictureCallback {

@Override
        public void onPictureTaken(byte[] data, Camera camera) {
            try {
                bundle = new Bundle();
                bundle.putByteArray("bytes", data);//将图片字节数据保存在bundle中,实现数据交换
                picData = data;
//                saveToSDCard(data);
//                camera.startPreview();//拍完照后,重新开始预览
                if (bundle == null) {
                    Toast.makeText(getApplicationContext(), "请先拍照",
                            Toast.LENGTH_SHORT).show();
                } else {
                    Intent intent = new Intent();
                    intent.setClass(getApplicationContext(), ShowPicActivity.class);
                    bundle.putBoolean("isRecord", isRecordState);
                    intent.putExtras(bundle);
                    startActivity(intent);
                }

} catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

public void initCamera(int width, int height) {
        parameters = camera.getParameters(); // 获取各项参数
        parameters.setPictureFormat(PixelFormat.JPEG); // 设置图片格式
        parameters.setPreviewSize(width, height); // 设置预览大小
//        List<Camera.Size> sizes =parameters.getSupportedPreviewSizes();
//        Camera.Size optimalSize = getOptimalPreviewSize(sizes, 320,240);
//        parameters.setPreviewSize(optimalSize.width, optimalSize.height);
        parameters.setPreviewFrameRate(5);  //设置每秒显示4帧
        parameters.setPictureSize(width, height); // 设置保存的图片尺寸
        parameters.setJpegQuality(80); // 设置照片质量
        parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE);//1连续对焦
        parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
        camera.startPreview();
        camera.cancelAutoFocus();// 2如果要实现连续的自动对焦,这一句必须加上
    }

public boolean onTouchEvent(MotionEvent event) {
        if (event.getAction() == KeyEvent.ACTION_DOWN) {
            if (!isRecordState) {
                camera.autoFocus(new Camera.AutoFocusCallback() {
                    @Override
                    public void onAutoFocus(boolean success, Camera camera) {
                        if (success) {
                            Log.d("TakePicActivity", "success");
                            w = (int) event.getX();
                            h = (int) event.getY();
//                        setLayout(rlFocus,w-50,h-50);
//                        Rect focusRect = calculateTapArea(w,h,100);
                            mHandler.obtainMessage(0).sendToTarget();
                            initCamera(w, h);
                            camera.cancelAutoFocus();//只有加上了这一句,才会自动对焦。
                        }
                    }
                });
            }

}else if(event.getAction() == MotionEvent.ACTION_UP){
            Log.d(TAG, "onTouchEvent: ACTION_UP");
        }
        else if(event.getAction() == MotionEvent.ACTION_MOVE){
            Log.d(TAG, "onTouchEvent: ACTION_MOVE");
        }
        return super.onTouchEvent(event);
    }

/*
     * 覆写返回键监听
     */
    @Override
    public void onBackPressed() {
        if (mMediaRecorder != null) {
            mMediaRecorder.stop();
            mMediaRecorder.release();
            mMediaRecorder = null;
//            videoRename();
        }
        finish();
    }

@Override
    protected void onPause() {
        super.onPause();
        onBackPressed();
    }

View view;
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            switch (msg.what) {
                case 0:
                    flContent.invalidate();
                    view = new MyView(TakePicActivity.this, w, h);
                    flContent.addView(view);
                    mHandler.sendEmptyMessageDelayed(1, 1000);//使选框停留1秒后消失
                    break;
                case 1:
                    flContent.removeView(view);
                    break;
            }
        }
    };

/*
     * 设置控件所在的位置YY,并且不改变宽高,
* XY为绝对位置
*/
    public void setLayout(View view, int x, int y) {
        ViewGroup.MarginLayoutParams margin = new ViewGroup.MarginLayoutParams(view.getLayoutParams());
        margin.setMargins(x, y, x + margin.width, y + margin.height);
        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(margin);
        view.setLayoutParams(layoutParams);
    }

File out;

/*
    * 生成video文件名字
    */
    protected void videoRename() {

String path = Environment.getExternalStorageDirectory()
                .getAbsolutePath() + "/hfdatabase/video/0/";

String fileName = new SimpleDateFormat("yyyyMMddHHmmss")
                .format(new Date()) + ".mp4";

out = new File(path);

if (!out.exists()) {
            out.mkdirs();
        }

out = new File(path, fileName);

if (mRecAudioFile.exists())
            mRecAudioFile.renameTo(out);

}

/*
     * 消息提示
     */
    private Toast toast;

public void showMsg(String arg) {
        if (toast == null) {
            toast = Toast.makeText(this, arg, Toast.LENGTH_SHORT);
        } else {
            toast.cancel();
            toast.setText(arg);
        }

toast.show();
    }

/*
     * 格式化时间
     */
    public String format(int i) {
        String s = i + "";

if (s.length() == 1) {
            s = "0" + s;
        }
        return s;
    }

/*
     * 定时器设置,实现计时
     */
    private Handler handler = new Handler();

private Runnable task = new Runnable() {
        public void run() {
            if (bool) {
                handler.postDelayed(this, 1000);
                second++;
                if (second >= 60) {
                    minute++;
                    second = second % 60;
                }
                if (minute >= 60) {
                    hour++;
                    minute = minute % 60;
                }
                timer.setText(format(hour) + ":" + format(minute) + ":" + format(second));
            }
        }
    };

private void startAnimator() {
        circleProgress.setVisibility(View.VISIBLE);
        animator = ObjectAnimator.ofInt(circleProgress, "progress", progress);
        animator.setDuration(60000);
        animator.setInterpolator(new LinearInterpolator());
        animator.start();
    }

/**
     * 释放摄像头资源
     */
    private void freeCameraResource() {
        if (camera != null) {
            camera.setPreviewCallback(null);
            camera.stopPreview();
            camera.lock();
            camera.release();
            camera = null;
        }
    }

@Override
    protected void onDestroy() {
        super.onDestroy();
        freeCameraResource();
        if(mMediaRecorder != null){
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }

}

显示图片或视频:

ShowPicActivity.java

package com.haier.uhome.appliance.newVersion.module.messageboard;

import butterknife.BindView;
import butterknife.ButterKnife;
import butterknife.OnClick;

public class ShowPicActivity extends AppCompatActivity {
    private final static String ALBUM_PATH = Environment.getExternalStorageDirectory() + "/download_img/";
    private static final String TAG = "ShowPicActivity";
    String imgName;
    ImageView iv_play;
    @BindView(R.id.iv_back2)
    ImageView ivBack2;
    @BindView(R.id.iv_confirm)
    ImageView ivConfirm;
    @BindView(R.id.tv_repeat)
    TextView tvRepeat;
    @BindView(R.id.rl_confirm)
    RelativeLayout rlConfirm;

String videoPath;
    @BindView(R.id.sfv_display)
    SurfaceView sfvDisplay;
    private SurfaceHolder sfh_display2;
    MediaPlayer player;
    boolean isRecord = false;

@Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_show_pic);
        ButterKnife.bind(this);

iv_play = (ImageView) findViewById(R.id.iv_playPic);
        Intent intent = getIntent();
        Bundle data = intent.getExtras();
        if (data.getBoolean("isRecord")) {
            isRecord = true;
            videoPath = data.getString("video_path");
            iv_play.setVisibility(View.GONE);
            sfvDisplay.setVisibility(View.VISIBLE);
            Log.d(TAG, "videoPath=" + videoPath);
            showVideo();
        } else {
            isRecord = false;
            iv_play.setVisibility(View.VISIBLE);
            sfvDisplay.setVisibility(View.GONE);
            setImageBitmap(data.getByteArray("bytes"));
        }

}

/**
     * 将MainActivity传过来的图片显示在界面当中
     *
     * @param bytes
     */
    public void setImageBitmap(byte[] bytes) {
        Bitmap cameraBitmap = byte2Bitmap();
        // 根据拍摄的方向旋转图像(纵向拍摄时要需要将图像选择90度)
        Matrix matrix = new Matrix();
        matrix.setRotate(TakePicActivity.getPreviewDegree(this));

cameraBitmap = Bitmap
                .createBitmap(cameraBitmap, 0, 0, cameraBitmap.getWidth(),
                        cameraBitmap.getHeight(), matrix, true);
        imgName = Calendar.getInstance().getTimeInMillis() + ".jpg";
        saveFile(cameraBitmap, imgName);
        iv_play.setScaleType(ImageView.ScaleType.CENTER_CROP);
        iv_play.setImageBitmap(cameraBitmap);
    }

//保存图片到本地
    public void saveFile(Bitmap bm, String imgName) {
        File dirFile = new File(ALBUM_PATH);
        if (!dirFile.exists()) {
            dirFile.mkdir();
        }

File myFile = new File(ALBUM_PATH + imgName);
        try {
            BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(myFile));
            bm.compress(Bitmap.CompressFormat.JPEG, 80, bos);
            bos.flush();
            bos.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }

}

/**
     * 从Bundle对象中获取数据
     *
     * @return
     */
    public byte[] getImageFormBundle() {
        Intent intent = getIntent();
        Bundle data = intent.getExtras();
        byte[] bytes = data.getByteArray("bytes");
        return bytes;
    }

/**
     * 将字节数组的图形数据转换为Bitmap
     *
     * @return
     */
    private Bitmap byte2Bitmap() {
        byte[] data = getImageFormBundle();
        // 将byte数组转换成Bitmap对象
        Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
        return bitmap;
    }

@OnClick({R.id.iv_back2, R.id.iv_confirm, R.id.tv_repeat})
    public void onClick(View view) {
        switch (view.getId()) {
            case R.id.iv_back2:
                finish();
                break;
            case R.id.iv_confirm:
                Intent i = new Intent(this, MainMessageBoard.class);
                if(isRecord){
                    i.putExtra("toMainPath", videoPath);
                }else{
                    i.putExtra("toMainPath", ALBUM_PATH + imgName);
                }
                i.putExtra("isRecord",isRecord);
                //要启动的activity已经在当前的任务中,那么在该activity之上的activity都会关闭,并且intent会传递给在栈顶的activity

//如果 Activity 已经是运行在 Task 的 top,则该 Activity 将不会再被启动
                i.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP);
                startActivity(i);

break;
            case R.id.tv_repeat:
                finish();
                break;
        }
    }

//显示并播放录制的视频
    public void showVideo(){
        sfh_display2 = sfvDisplay.getHolder();
        sfh_display2.addCallback(new SurfaceHolder.Callback() {
            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                player = new MediaPlayer();
                player.setAudioStreamType(AudioManager.STREAM_MUSIC);
                player.setDisplay(sfh_display2);
                try {
                    player.setDataSource(videoPath);
                    player.prepare();
                    player.start();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }

@Override
            public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

}

@Override
            public void surfaceDestroyed(SurfaceHolder holder) {

}
        });
        sfh_display2.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    }
}

圆形进度条

package com.haier.uhome.appliance.newVersion.module.messageboard.view;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.RectF;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.View;

/**
 * Created by wangchm on 2017/1/23 0023.
 */
public class CircleProgressView extends View {
    private static final String TAG = "CircleProgressView";

private int mMaxProgress = 100;

private int mProgress = 100;

private final int mCircleLineStrokeWidth = 22;

private final int mTxtStrokeWidth = 2;

// 画圆所在的距形区域
    private final RectF mRectF;

private final Paint mPaint;

private final Context mContext;

private String mTxtHint1;

private String mTxtHint2;
    private int bgColor;
    private int progressColor;

public CircleProgressView(Context context, AttributeSet attrs) {
        super(context, attrs);

mContext = context;
        mRectF = new RectF();
        mPaint = new Paint();
    }

@Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        int width = this.getWidth();
        int height = this.getHeight();

if (width != height) {
            int min = Math.min(width, height);
            width = min;
            height = min;
        }

// 设置画笔相关属性
        mPaint.setAntiAlias(true);
//        mPaint.setColor(Color.GRAY);
        mPaint.setColor(bgColor);
        canvas.drawColor(Color.TRANSPARENT);
        mPaint.setStrokeWidth(mCircleLineStrokeWidth);
        mPaint.setStyle(Paint.Style.STROKE);
        // 位置
        mRectF.left = mCircleLineStrokeWidth / 2; // 左上角x
        mRectF.top = mCircleLineStrokeWidth / 2; // 左上角y
        mRectF.right = width - mCircleLineStrokeWidth / 2; // 左下角x
        mRectF.bottom = height - mCircleLineStrokeWidth / 2; // 右下角y

// 绘制圆圈,进度条背景
        canvas.drawArc(mRectF, -90, 360, false, mPaint);
//        mPaint.setColor(Color.RED);
        mPaint.setColor(progressColor);
        canvas.drawArc(mRectF, -90, ((float) mProgress / mMaxProgress) * 360, false, mPaint);

// 绘制进度文案显示
        mPaint.setStrokeWidth(mTxtStrokeWidth);
        String text = mProgress + "%";
        int textHeight = height / 4;
        mPaint.setTextSize(textHeight);
        int textWidth = (int) mPaint.measureText(text, 0, text.length());
        mPaint.setStyle(Paint.Style.FILL);
        canvas.drawText(text, width / 2 - textWidth / 2, height / 2 + textHeight / 2, mPaint);

if (!TextUtils.isEmpty(mTxtHint1)) {
            mPaint.setStrokeWidth(mTxtStrokeWidth);
            text = mTxtHint1;
            textHeight = height / 8;
            mPaint.setTextSize(textHeight);
            mPaint.setColor(Color.rgb(0x99, 0x99, 0x99));
            textWidth = (int) mPaint.measureText(text, 0, text.length());
            mPaint.setStyle(Paint.Style.FILL);
            canvas.drawText(text, width / 2 - textWidth / 2, height / 4 + textHeight / 2, mPaint);
        }

if (!TextUtils.isEmpty(mTxtHint2)) {
            mPaint.setStrokeWidth(mTxtStrokeWidth);
            text = mTxtHint2;
            textHeight = height / 8;
            mPaint.setTextSize(textHeight);
            textWidth = (int) mPaint.measureText(text, 0, text.length());
            mPaint.setStyle(Paint.Style.FILL);
            canvas.drawText(text, width / 2 - textWidth / 2, 3 * height / 4 + textHeight / 2, mPaint);
        }
    }

public int getMaxProgress() {
        return mMaxProgress;
    }

public void setMaxProgress(int maxProgress) {
        this.mMaxProgress = maxProgress;
    }

public void setProgress(int progress) {
        this.mProgress = progress;
        this.invalidate();
    }

public int getmProgress(){
        return mProgress;
    }

public void setProgressNotInUiThread(int progress) {
        this.mProgress = progress;
        this.postInvalidate();
    }

public String getmTxtHint1() {
        return mTxtHint1;
    }

public void setmTxtHint1(String mTxtHint1) {
        this.mTxtHint1 = mTxtHint1;
    }

public String getmTxtHint2() {
        return mTxtHint2;
    }

public void setmTxtHint2(String mTxtHint2) {
        this.mTxtHint2 = mTxtHint2;
    }

public int getBgColor() {
        return bgColor;
    }

public void setBgColor(int bgColor) {
        this.bgColor = bgColor;
    }

public int getProgressColor() {
        return progressColor;
    }

public void setProgressColor(int progressColor) {
        this.progressColor = progressColor;
    }

}

android 自定义拍照录像相关推荐

  1. Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题

    Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题 参考文章: (1)Android 自定义拍照,解决图片旋转,拍照参数设置兼容问题 (2)https://www.cnblogs.com/ ...

  2. Android自定义拍照解决部分手机拍完之后图片不清楚的问题

    昨天同事跟我说了一个bug,让我整了一天,从昨天下午这个时间到今天下午这个时间,哎... 大家都懂的 首先我来说一个bug,我用surfaceView来实现自定义拍照的功能,先来张在genymotio ...

  3. Android自定义拍照上传界面,Android自定义dialog——设置头像(拍照,相册)

    Android自定义dialog--设置头像(拍照,相册) 需求场景:个人信息设置,点击头像,在界面上弹出一个弹框,用户选择"拍照"/"从图库选择",选择照片后 ...

  4. Android自定义拍照小米手机拍照照片模糊的问题

    原文地址 昨天同事跟我说了一个bug,让我整了一天,从昨天下午这个时间到今天下午这个时间,哎... 大家都懂的 首先我来说一个bug,我用surfaceView来实现自定义拍照的功能,先来张在geny ...

  5. android 自定义拍照模糊,Android自定义相机拍照模糊处理

    问题分析:随着用户对于拍照清晰度的需求,android手机对于摄像头也是一升再升,这就导致了作为android开发工程师对于兼容性维护的继续跟进以及问题处理. 针对于自定义相机拍照模糊的问题,经过几天 ...

  6. Android自定义拍照实现

    前言 由于网上大部分自定义相机的实现,都是耦合性比较强的,不方便今后的复用,所以我自己实现了一套自定义相机,方便以后的扩展.自定义相机分为以下3个部分.文末有免费福利哦 相机的预览布局SurfaceV ...

  7. uni-app 自定义相机拍照录像,可设置分辨率、支持横竖屏(ios、android)

    插件市场:uni-app 自定义相机拍照录像,可设置分辨率.支持横竖屏(ios.android)

  8. Android自定义照相机实现 拍照 录像

    文档中的Camera 要使用Camera,首先我们先看一下文档(http://androiddoc.qiniudn.com/reference/android/hardware/Camera.html ...

  9. android 拍照插件,拍照录像,android原生插件

    更新记录 1.0.1(2021-03-31) 拍照录像模式,轻触拍照,长按录像:只录像模式,轻触即可录像 支持录像,设置视频的比特率,最长/最短录制时间等 支持录像时,输出视频第一帧图片 支持自定义图 ...

最新文章

  1. 【C++】log(n)斐波那契数列计算
  2. 多篇顶会看个体因果推断(ITE)的前世今生
  3. C语言分区排序partition sort 算法(附完整源码)
  4. Maven学习笔记(2) --mvn archetype:create 说明
  5. C语言中变量的储存类别
  6. python中pip不是内部或外部命令_‘pip’不被识别为内部或外部命令。
  7. 值不值得入手_看好三阳的小拉力,但不知道值不值得入手?
  8. getBoundingClientRect使用指南
  9. [线程安全问题] 多线程到底可能会带来哪些风险?
  10. Python获取实时的时间
  11. 【深度学习】卷积神经网络(CNN)原理
  12. 华为Eudumon1000配置PORTAL认证
  13. trajan算法(离线做法) LCA详解
  14. 即将到来的交通革命——出行即服务(MaaS)
  15. 2011年好莱坞大片索引
  16. iOS转向Flutter学习日记
  17. 命令启动edge浏览器且全屏
  18. HTML特殊字符编码对照表 —— (二)
  19. 升级Windows10,安装程序无法正常启动无法初始化工作目录
  20. 坑:vuex中的mutations不能使用return获取数据

热门文章

  1. Equalization Loss论文小结(CVPR2020)
  2. TortoiseGit
  3. sql 语句 中的 exits 和 in 关键字
  4. Android 面试题 200 道 :全面解析
  5. 如何做一个小程序口令红包功能
  6. 苹果cms去掉链接index.php,如何去除苹果cms链接中的index.php
  7. [项目管理入门系列] 师傅领进门-------项目运作的一般流程(四)
  8. 感觉犹太人最有名的这十句话也挺有感悟的!不妨你来看看!
  9. CGD全局并发队列和主队列的应用
  10. 【实时PPP】对比CNES的实时数据流与CNT产品之间的差异