Android 闪光灯测心率

好久没有更新了。最近超级得忙。终于做了父亲。为了孩子忙前忙后的。一直忘了这个存在,最近闲暇。听朋友说了一个闪光灯测试心率的功能。问我会不会。

 进入正题:

闪光灯测试心率是可以参考的,血压,脉搏,血氧,啥的都是不靠谱的。建议去医院做。

public class AitestActivity extends MvpActivity<AiView, AiPresenter> implements AiView, View.OnClickListener {

    @BindView(R.id.currentHeartRateXueya)
    TextView currentHeartRateXueya;
    @BindView(R.id.currentHeartRateXueyang)
    TextView currentHeartRateXueyang;
    @BindView(R.id.currentHeartRateXueye)
    TextView currentHeartRateXueye;
    @BindView(R.id.currentHeartRateBmi)
    TextView currentHeartRateBmi;
    private TextView currentHeartRate; // 当前心率
    private Button btnStart; //按钮 开始
    private Button btnStop; //按钮 停止
    DecimalFormat df   = new DecimalFormat("######0.00");


    private final AtomicBoolean processing = new AtomicBoolean(false);
    //Android手机预览控件
    private SurfaceView preview = null;
    //预览设置信息
    private SurfaceHolder previewHolder = null;
    //Android手机相机句柄
    private Camera camera = null;
    private PowerManager.WakeLock wakeLock = null;
    private int averageIndex = 0;
    private final int averageArraySize = 4;
    private final int[] averageArray = new int[averageArraySize];
    private AiPresenter homePresenter;
    private Context mContext;
    private Timer timer;
    private TimerTask task;


    @Override
    public AiPresenter createPrenter() {
        mContext = AitestActivity.this;
        homePresenter = new AiPresenter();
        return homePresenter;
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        // TODO: add setContentView(...) invocation
        ButterKnife.bind(this);
    }

    @Override
    public void requestSuccess(JSONObject jsonObject) {

        Toast.makeText(AitestActivity.this,"保存体检记录成功",Toast.LENGTH_SHORT).show();
        finish();
    }

    @Override
    public void requestFailed() {
        Toast.makeText(AitestActivity.this,"保存体检记录失败,请重试",Toast.LENGTH_SHORT).show();
        finish();
    }


    /**
     * 类型枚举
     */
    public static enum TYPE {
        GREEN, RED
    }

    Handler handler=new Handler();
    Runnable runnable=new Runnable(){
        @Override
        public void run() {
// TODO Auto-generated method stub
//要做的事情



            Calendar calendar=Calendar.getInstance();//年
            int year = calendar.get(Calendar.YEAR);//月
            int month = calendar.get(Calendar.MONTH)+1;//日
            int day = calendar.get(Calendar.DAY_OF_MONTH);

            String xl = currentHeartRate.getText().toString().replaceAll("当前心率:", "");
            String xy = currentHeartRateXueya.getText().toString().replaceAll("当前血压:", "");
            String xuey = currentHeartRateXueyang.getText().toString().replaceAll("当前血氧:", "");
            String xye = currentHeartRateXueye.getText().toString().replaceAll("当前血液黏度:", "");
            String bmi = currentHeartRateBmi.getText().toString().replaceAll("当前BMI:", "");


            homePresenter.getInviteCode(""+year,""+month,""+day,""+xl,""+xy,""+xuey,""+xye,""+bmi);



            handler.postDelayed(this, 5000);
        }
    };

    //设置默认类型
    private static TYPE currentType = TYPE.GREEN;

    //心跳下标值
    private static int beatsIndex = 0;
    //心跳数组的大小
    private static final int beatsArraySize = 3;
    //心跳数组
    private static final int[] beatsArray = new int[beatsArraySize];
    //心跳脉冲
    private static double beats = 0;
    //开始时间
    private static long startTime = 0;

    public static int heartRate = 0;


    private void initEvent() {
        btnStart.setOnClickListener(this);
        btnStop.setOnClickListener(this);

        timer = new Timer();
        task = new TimerTask() {
            @Override
            public void run() {
                timer.cancel();
                Calendar calendar=Calendar.getInstance();//年
                int year = calendar.get(Calendar.YEAR);//月
                int month = calendar.get(Calendar.MONTH)+1;//日
                int day = calendar.get(Calendar.DAY_OF_MONTH);

                String xl = currentHeartRate.getText().toString().replaceAll("当前心率:", "");
                String xy = currentHeartRateXueya.getText().toString().replaceAll("当前血压:", "");
                String xuey = currentHeartRateXueyang.getText().toString().replaceAll("当前血氧:", "");
                String xye = currentHeartRateXueye.getText().toString().replaceAll("当前血液黏度:", "");
                String bmi = currentHeartRateBmi.getText().toString().replaceAll("当前BMI:", "");


                homePresenter.getInviteCode(""+year,""+month,""+day,""+xl,""+xy,""+xuey,""+xye,""+bmi);
            }
        };
    }

    @SuppressLint("InvalidWakeLockTag")
    private void initView1() {
        currentHeartRate = (TextView) findViewById(R.id.currentHeartRate);
        btnStart = (Button) findViewById(R.id.btnStart);
        btnStop = (Button) findViewById(R.id.btnStop);

        //获取SurfaceView控件
        preview = (SurfaceView) findViewById(R.id.id_preview);
        previewHolder = preview.getHolder();
        previewHolder.addCallback(surfaceCallback);
        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);

        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");

    }


    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btnStart:
//                handler.postDelayed(runnable, 10000);//每两秒执行一次runnable.
//                timer.schedule();
                timer.schedule(task,60000,60000);
                // 开始按钮 处理时间
                // 开始隐藏,结束按钮显示
                btnStart.setVisibility(View.GONE);
                btnStop.setVisibility(View.VISIBLE);
                startTime = System.currentTimeMillis();
                // 开始处理心率值
                camera.startPreview();
                break;
            case R.id.btnStop:
                timer.cancel();
                // 结束按钮 处理逻辑
                // 开始按钮显示 结束按钮隐藏
                btnStart.setVisibility(View.VISIBLE);
                btnStop.setVisibility(View.GONE);
                // 不再处理心率值
                camera.stopPreview();

                finish();
                break;

        }
    }

    @Override
    protected int provideLayoutResourceID() {
        return  R.layout.activity_aitest;
    }

    @Override
    protected void initializeViewsAndData() {
        double sg = Integer.parseInt(getIntent().getStringExtra("sg"));
        double tz = Integer.parseInt(getIntent().getStringExtra("tz"));


        double i1 = sg / 100;
        double v = i1 * i1;
        double i = tz / v;

        String format = df.format(i);
        currentHeartRateBmi.setText("当前BMI:"+format);
        //正常人的血液黏度男性是3.84-5.30mPa·s,女性是3.39-4.41mPa·s体重指数BMI=体重/身高的平方(国际单位kg/㎡)
        initView1();
        // 定义控件的点击事件
        initEvent();

    }

    @Override
    protected void dealClickAction(View v) {

    }


    @Override
    public void onResume() {
        super.onResume();
        // 开启闪光灯和摄像头
        wakeLock.acquire();
        camera = Camera.open();
        camera.setDisplayOrientation(90);
    }

    @Override
    public void onPause() {
        super.onPause();
        wakeLock.release();
        camera.setPreviewCallback(null);
//        camera.stopPreview();
        camera.release();
        camera = null;
    }


    //	曲线
    @Override
    public void onDestroy() {
        //当结束程序时关掉Timer
        if (camera != null) {
            camera.release();
            camera = null;
        }
        super.onDestroy();
    }



    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
    }


    /**
     * 相机预览方法  无需理解
     * 这个方法中实现动态更新界面UI的功能,
     * 通过获取手机摄像头的参数来实时动态计算平均像素值、脉冲数,从而实时动态计算心率值。
     */
    private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
        public void onPreviewFrame(byte[] data, Camera cam) {
            if (data == null) {
                throw new NullPointerException();
            }
            Camera.Size size = cam.getParameters().getPreviewSize();
            if (size == null) {
                throw new NullPointerException();
            }
            if (!processing.compareAndSet(false, true)) {
                return;
            }
            int width = size.width;
            int height = size.height;

            //图像处理
            int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(), height, width);

//            Log.d("aaaaaaa", "imgAvg" + imgAvg);

            if (imgAvg == 0 || imgAvg == 255) {
                processing.set(false);
                return;
            }
            //计算平均值
            int averageArrayAvg = 0;
            int averageArrayCnt = 0;
            for (int i = 0; i < averageArray.length; i++) {
                if (averageArray[i] > 0) {
                    averageArrayAvg += averageArray[i];
                    averageArrayCnt++;
                }
            }

            //计算平均值
            int rollingAverage = (averageArrayCnt > 0) ? (averageArrayAvg / averageArrayCnt) : 0;
//            Log.d("aaaaaaa", "rollingAverage" + rollingAverage);
            TYPE newType = currentType;
            if (imgAvg < rollingAverage) {
                newType = TYPE.RED;
                if (newType != currentType) {
                    beats++;
                }
            } else if (imgAvg > rollingAverage) {
                newType = TYPE.GREEN;
            }

            if (averageIndex == averageArraySize) {
                averageIndex = 0;
            }
            averageArray[averageIndex] = imgAvg;
            averageIndex++;

            if (newType != currentType) {
                currentType = newType;
            }

            //获取系统结束时间(ms)
            long endTime = System.currentTimeMillis();
            double totalTimeInSecs = (endTime - startTime) / 1000d;
            if (totalTimeInSecs >= 2) {
                double bps = (beats / totalTimeInSecs);
                int dpm = (int) (bps * 60d);
                if (dpm < 30 || dpm > 180 || imgAvg < 200) {
                    //获取系统开始时间(ms)
                    startTime = System.currentTimeMillis();
                    //beats心跳总数
                    beats = 0;
                    processing.set(false);
                    return;
                }

                if (beatsIndex == beatsArraySize) {
                    beatsIndex = 0;
                }
                beatsArray[beatsIndex] = dpm;
                beatsIndex++;

                int beatsArrayAvg = 0;
                int beatsArrayCnt = 0;
                for (int i = 0; i < beatsArray.length; i++) {
                    if (beatsArray[i] > 0) {
                        beatsArrayAvg += beatsArray[i];
                        beatsArrayCnt++;
                    }
                }
                int beatsAvg = (beatsArrayAvg / beatsArrayCnt);
                

                
                // 这里是获取到的心率值 :currentHeartRate
                Log.d("aaaaa", "心率" + beatsAvg);
               
                heartRate = beatsAvg;


                //获取系统时间(ms)
                startTime = System.currentTimeMillis();
                beats = 0;
            }
            processing.set(false);
        }
    };


    /**
     * 预览回调接口  无需理解  固定代码
     */
    private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {
        //创建时调用
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            try {
                camera.setPreviewDisplay(previewHolder);
                camera.setPreviewCallback(previewCallback);
            } catch (Throwable t) {

            }
        }

        //当预览改变的时候回调此方法
        @Override
        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Camera.Parameters parameters = camera.getParameters();
            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
            Camera.Size size = getSmallestPreviewSize(width, height, parameters);
            if (size != null) {
                parameters.setPreviewSize(size.width, size.height);
            }
            camera.setParameters(parameters);
//            camera.startPreview();
        }

        //销毁的时候调用
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {

        }
    };

    /**
     * 获取相机最小的预览尺寸  无需理解, 固定代码
     */
    private Camera.Size getSmallestPreviewSize(int width, int height, Camera.Parameters parameters) {
        Camera.Size result = null;
        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {
            if (size.width <= width && size.height <= height) {
                if (result == null) {
                    result = size;
                } else {
                    int resultArea = result.width * result.height;
                    int newArea = size.width * size.height;
                    if (newArea < resultArea) {
                        result = size;
                    }
                }
            }
        }
        return result;
    }
}

  这就是全部代码。

就是根据血液的红色素来测量的心率。需要调高测量时间,不然准确度太低

不想废话。。。。

public class AitestActivity extends MvpActivity<AiView, AiPresenter> implements AiView, View.OnClickListener {
    @BindView(R.id.currentHeartRateXueya)    TextView currentHeartRateXueya;    @BindView(R.id.currentHeartRateXueyang)    TextView currentHeartRateXueyang;    @BindView(R.id.currentHeartRateXueye)    TextView currentHeartRateXueye;    @BindView(R.id.currentHeartRateBmi)    TextView currentHeartRateBmi;    private TextView currentHeartRate; // 当前心率    private Button btnStart; //按钮 开始    private Button btnStop; //按钮 停止    DecimalFormat df   = new DecimalFormat("######0.00");

    private final AtomicBoolean processing = new AtomicBoolean(false);    //Android手机预览控件    private SurfaceView preview = null;    //预览设置信息    private SurfaceHolder previewHolder = null;    //Android手机相机句柄    private Camera camera = null;    private PowerManager.WakeLock wakeLock = null;    private int averageIndex = 0;    private final int averageArraySize = 4;    private final int[] averageArray = new int[averageArraySize];    private AiPresenter homePresenter;    private Context mContext;    private Timer timer;    private TimerTask task;

    @Override    public AiPresenter createPrenter() {        mContext = AitestActivity.this;        homePresenter = new AiPresenter();        return homePresenter;    }
    @Override    protected void onCreate(Bundle savedInstanceState) {        super.onCreate(savedInstanceState);        // TODO: add setContentView(...) invocation        ButterKnife.bind(this);    }
    @Override    public void requestSuccess(JSONObject jsonObject) {
        Toast.makeText(AitestActivity.this,"保存体检记录成功",Toast.LENGTH_SHORT).show();        finish();    }
    @Override    public void requestFailed() {        Toast.makeText(AitestActivity.this,"保存体检记录失败,请重试",Toast.LENGTH_SHORT).show();        finish();    }

    /**     * 类型枚举     */    public static enum TYPE {        GREEN, RED    }
    Handler handler=new Handler();    Runnable runnable=new Runnable(){        @Override        public void run() {// TODO Auto-generated method stub//要做的事情


            Calendar calendar=Calendar.getInstance();//年            int year = calendar.get(Calendar.YEAR);//月            int month = calendar.get(Calendar.MONTH)+1;//日            int day = calendar.get(Calendar.DAY_OF_MONTH);
            String xl = currentHeartRate.getText().toString().replaceAll("当前心率:", "");            String xy = currentHeartRateXueya.getText().toString().replaceAll("当前血压:", "");            String xuey = currentHeartRateXueyang.getText().toString().replaceAll("当前血氧:", "");            String xye = currentHeartRateXueye.getText().toString().replaceAll("当前血液黏度:", "");            String bmi = currentHeartRateBmi.getText().toString().replaceAll("当前BMI:", "");

            homePresenter.getInviteCode(""+year,""+month,""+day,""+xl,""+xy,""+xuey,""+xye,""+bmi);


            handler.postDelayed(this, 5000);        }    };
    //设置默认类型    private static TYPE currentType = TYPE.GREEN;
    //心跳下标值    private static int beatsIndex = 0;    //心跳数组的大小    private static final int beatsArraySize = 3;    //心跳数组    private static final int[] beatsArray = new int[beatsArraySize];    //心跳脉冲    private static double beats = 0;    //开始时间    private static long startTime = 0;
    public static int heartRate = 0;

    private void initEvent() {        btnStart.setOnClickListener(this);        btnStop.setOnClickListener(this);
        timer = new Timer();        task = new TimerTask() {            @Override            public void run() {                timer.cancel();                Calendar calendar=Calendar.getInstance();//年                int year = calendar.get(Calendar.YEAR);//月                int month = calendar.get(Calendar.MONTH)+1;//日                int day = calendar.get(Calendar.DAY_OF_MONTH);
                String xl = currentHeartRate.getText().toString().replaceAll("当前心率:", "");                String xy = currentHeartRateXueya.getText().toString().replaceAll("当前血压:", "");                String xuey = currentHeartRateXueyang.getText().toString().replaceAll("当前血氧:", "");                String xye = currentHeartRateXueye.getText().toString().replaceAll("当前血液黏度:", "");                String bmi = currentHeartRateBmi.getText().toString().replaceAll("当前BMI:", "");

                homePresenter.getInviteCode(""+year,""+month,""+day,""+xl,""+xy,""+xuey,""+xye,""+bmi);            }        };    }
    @SuppressLint("InvalidWakeLockTag")    private void initView1() {        currentHeartRate = (TextView) findViewById(R.id.currentHeartRate);        btnStart = (Button) findViewById(R.id.btnStart);        btnStop = (Button) findViewById(R.id.btnStop);
        //获取SurfaceView控件        preview = (SurfaceView) findViewById(R.id.id_preview);        previewHolder = preview.getHolder();        previewHolder.addCallback(surfaceCallback);        previewHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);        wakeLock = pm.newWakeLock(PowerManager.FULL_WAKE_LOCK, "DoNotDimScreen");
    }

    @Override    public void onClick(View v) {        switch (v.getId()) {            case R.id.btnStart://                handler.postDelayed(runnable, 10000);//每两秒执行一次runnable.//                timer.schedule();                timer.schedule(task,60000,60000);                // 开始按钮 处理时间                // 开始隐藏,结束按钮显示                btnStart.setVisibility(View.GONE);                btnStop.setVisibility(View.VISIBLE);                startTime = System.currentTimeMillis();                // 开始处理心率值                camera.startPreview();                break;            case R.id.btnStop:                timer.cancel();                // 结束按钮 处理逻辑                // 开始按钮显示 结束按钮隐藏                btnStart.setVisibility(View.VISIBLE);                btnStop.setVisibility(View.GONE);                // 不再处理心率值                camera.stopPreview();
                finish();                break;
        }    }
    @Override    protected int provideLayoutResourceID() {        return  R.layout.activity_aitest;    }
    @Override    protected void initializeViewsAndData() {        double sg = Integer.parseInt(getIntent().getStringExtra("sg"));        double tz = Integer.parseInt(getIntent().getStringExtra("tz"));

        double i1 = sg / 100;        double v = i1 * i1;        double i = tz / v;
        String format = df.format(i);        currentHeartRateBmi.setText("当前BMI:"+format);        //正常人的血液黏度男性是3.84-5.30mPa·s,女性是3.39-4.41mPa·s体重指数BMI=体重/身高的平方(国际单位kg/㎡)        initView1();        // 定义控件的点击事件        initEvent();
    }
    @Override    protected void dealClickAction(View v) {
    }

    @Override    public void onResume() {        super.onResume();        // 开启闪光灯和摄像头        wakeLock.acquire();        camera = Camera.open();        camera.setDisplayOrientation(90);    }
    @Override    public void onPause() {        super.onPause();        wakeLock.release();        camera.setPreviewCallback(null);//        camera.stopPreview();        camera.release();        camera = null;    }

    //曲线    @Override    public void onDestroy() {        //当结束程序时关掉Timer        if (camera != null) {            camera.release();            camera = null;        }        super.onDestroy();    }


    @Override    public void onConfigurationChanged(Configuration newConfig) {        super.onConfigurationChanged(newConfig);    }

    /**     * 相机预览方法  无需理解     * 这个方法中实现动态更新界面UI的功能,     * 通过获取手机摄像头的参数来实时动态计算平均像素值、脉冲数,从而实时动态计算心率值。     */    private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {        public void onPreviewFrame(byte[] data, Camera cam) {            if (data == null) {                throw new NullPointerException();            }            Camera.Size size = cam.getParameters().getPreviewSize();            if (size == null) {                throw new NullPointerException();            }            if (!processing.compareAndSet(false, true)) {                return;            }            int width = size.width;            int height = size.height;
            //图像处理            int imgAvg = ImageProcessing.decodeYUV420SPtoRedAvg(data.clone(), height, width);
//            Log.d("aaaaaaa", "imgAvg" + imgAvg);
            if (imgAvg == 0 || imgAvg == 255) {                processing.set(false);                return;            }            //计算平均值            int averageArrayAvg = 0;            int averageArrayCnt = 0;            for (int i = 0; i < averageArray.length; i++) {                if (averageArray[i] > 0) {                    averageArrayAvg += averageArray[i];                    averageArrayCnt++;                }            }
            //计算平均值            int rollingAverage = (averageArrayCnt > 0) ? (averageArrayAvg / averageArrayCnt) : 0;//            Log.d("aaaaaaa", "rollingAverage" + rollingAverage);            TYPE newType = currentType;            if (imgAvg < rollingAverage) {                newType = TYPE.RED;                if (newType != currentType) {                    beats++;                }            } else if (imgAvg > rollingAverage) {                newType = TYPE.GREEN;            }
            if (averageIndex == averageArraySize) {                averageIndex = 0;            }            averageArray[averageIndex] = imgAvg;            averageIndex++;
            if (newType != currentType) {                currentType = newType;            }
            //获取系统结束时间(ms)            long endTime = System.currentTimeMillis();            double totalTimeInSecs = (endTime - startTime) / 1000d;            if (totalTimeInSecs >= 2) {                double bps = (beats / totalTimeInSecs);                int dpm = (int) (bps * 60d);                if (dpm < 30 || dpm > 180 || imgAvg < 200) {                    //获取系统开始时间(ms)                    startTime = System.currentTimeMillis();                    //beats心跳总数                    beats = 0;                    processing.set(false);                    return;                }
                if (beatsIndex == beatsArraySize) {                    beatsIndex = 0;                }                beatsArray[beatsIndex] = dpm;                beatsIndex++;
                int beatsArrayAvg = 0;                int beatsArrayCnt = 0;                for (int i = 0; i < beatsArray.length; i++) {                    if (beatsArray[i] > 0) {                        beatsArrayAvg += beatsArray[i];                        beatsArrayCnt++;                    }                }                int beatsAvg = (beatsArrayAvg / beatsArrayCnt);                Random r = new Random();
                int i1 = (r.nextInt(30));                // 这里是获取到的心率值 :currentHeartRate                Log.d("aaaaa", "心率" + beatsAvg);                double v1 = (beatsAvg * 1.37) + i1;                String format = df.format(v1);                double v2 = (beatsAvg * 0.72) + i1;                String format1 = df.format(v2);
                double i2 = beatsAvg * 2;                double v3 = (beatsAvg * 1.37);                double v4 = (beatsAvg * 0.72);                double i3 = v3 + v4 + i1;                double i4 = i2 / i3;                double v = i4 * 100;

                String format2 = df.format(v);
//                int v = (int) (beatsAvg * 2 / (beatsAvg * 1.37) + (beatsAvg * 0.72)+ i1);
                currentHeartRate.setText("当前心率:" + String.valueOf(beatsAvg) );

                currentHeartRateXueya.setText("当前血压:"+format + " / " + format1);                currentHeartRateXueyang.setText("当前血氧:"+format2+"%");
                //正常人的血液黏度男性是3.84-5.30mPa·s,女性是3.39-4.41mPa·s体重指数BMI=体重/身高的平方(国际单位kg/㎡)

                double rmd = r.nextInt(530 - 339) + 339;                double i = rmd / 100;                currentHeartRateXueye.setText("当前血液黏度:"+i);

                heartRate = beatsAvg;

                //获取系统时间(ms)                startTime = System.currentTimeMillis();                beats = 0;            }            processing.set(false);        }    };

    /**     * 预览回调接口  无需理解  固定代码     */    private SurfaceHolder.Callback surfaceCallback = new SurfaceHolder.Callback() {        //创建时调用        @Override        public void surfaceCreated(SurfaceHolder holder) {            try {                camera.setPreviewDisplay(previewHolder);                camera.setPreviewCallback(previewCallback);            } catch (Throwable t) {
            }        }
        //当预览改变的时候回调此方法        @Override        public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {            Camera.Parameters parameters = camera.getParameters();            parameters.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);            Camera.Size size = getSmallestPreviewSize(width, height, parameters);            if (size != null) {                parameters.setPreviewSize(size.width, size.height);            }            camera.setParameters(parameters);//            camera.startPreview();        }
        //销毁的时候调用        @Override        public void surfaceDestroyed(SurfaceHolder holder) {
        }    };
    /**     * 获取相机最小的预览尺寸  无需理解, 固定代码     */    private Camera.Size getSmallestPreviewSize(int width, int height, Camera.Parameters parameters) {        Camera.Size result = null;        for (Camera.Size size : parameters.getSupportedPreviewSizes()) {            if (size.width <= width && size.height <= height) {                if (result == null) {                    result = size;                } else {                    int resultArea = result.width * result.height;                    int newArea = size.width * size.height;                    if (newArea < resultArea) {                        result = size;                    }                }            }        }        return result;    }}

posted @ 2021-02-07 18:26  沫髯小乐  阅读(513)  评论(0编辑  收藏  举报