仿微信录制视频和拍照并发送留言

仿微信小视频录制功能,打开相机后,点击是拍照,长按是录制,录制小于1秒,要提示“录制时间太短”,最大可以录制1分钟的视频,拍完照或录制完视频后,要自动跳转到相片或视频展示页面,点击确认,回到留言板界面,将相片或视频发送到阿里云,然后再发送留言;如果点击“重新拍照”,则返回到相机页面;


activity页面,点击相机按钮:

case R.id.ll_camera:
    //设置权限
    if (!PermissionHelper.checkPermission(mContext, Manifest.permission.CAMERA)) {
        ToastUtils.showShort(mContext, String.format(getString(R.string.permission_help_text), getString(R.string.per_camera)));
        return;
    }
    if (!PermissionHelper.checkPermission(mContext, Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
        ToastUtils.showShort(mContext, String.format(getString(R.string.permission_help_text), getString(R.string.per_storage)));
        return;
    }
    //打开自定义相机
    Intent cameraIntent = new Intent(this, TakePicActivity.class);
    startActivity(cameraIntent);
    break;


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

import android.animation.Animator;
import android.animation.ObjectAnimator;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Point;
import android.hardware.Camera;
import android.media.MediaRecorder;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
import android.os.Message;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.ViewGroup;
import android.view.ViewTreeObserver;
import android.view.animation.LinearInterpolator;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.haier.uhome.appliance.R;
import com.haier.uhome.appliance.newVersion.module.messageboard.util.CameraConfiguration;
import com.haier.uhome.appliance.newVersion.module.messageboard.view.CircleProgressView;
import com.haier.uhome.common.util.LogUtil;
import com.orhanobut.logger.Logger;

import java.io.File;
import java.io.IOException;
import java.util.List;

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

import static com.haier.uhome.appliance.newVersion.module.messageboard.util.CameraConfiguration.getPreviewDegree1;


public class TakePicActivity extends AppCompatActivity implements Camera.PreviewCallback {
    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;
    ImageView iv_takeBack;
    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 String fileName;//视频文件名
    String model = android.os.Build.MODEL;//手机的型号
    private Animator animator;
    private boolean isRecordState = false;//是否是视频录制状态
    private int progress;
    private int cameraPosition = 0;//0代表后置摄像头,1代表前置摄像头
    private static int isScreenConfigChange = 0;//0 代表竖屏 3代表横屏
    private static final int DEFAULT_WIDTH = 1920;
    private static final int DEFAULT_HEIGHT = 1080;
    private Point screenResolution;

    @Override
    public void onConfigurationChanged(Configuration newConfig) {
        super.onConfigurationChanged(newConfig);
        if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
            // land do nothing is ok
            Log.i("info", "landscape"); // 横屏
        } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
            // port do nothing is ok
            Log.i("info", "portrait"); // 竖屏
        }
    }

    @Override
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        initCamera();
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_take_pic);
        ButterKnife.bind(this);
        this.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
        takepicture = (Button) findViewById(R.id.takepicture);
        iv_takeBack = (ImageView) findViewById(R.id.iv_takeBack);
        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(cameraPosition);
                    //  CameraConfiguration.setCameraDisplayOrientation(TakePicActivity.this, cameraPosition, camera);
                    int result = CameraConfiguration.getPreviewDegree1(TakePicActivity.this, cameraPosition);
                    camera.setDisplayOrientation(result);
                    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);
                    if (cameraPosition == 1) {
                        if (isScreenConfigChange == 3) {
                            mMediaRecorder.setOrientationHint(90);
                        } else {
                            mMediaRecorder.setOrientationHint(270);
                        }
                    } else if (cameraPosition == 0) {
                        mMediaRecorder.setOrientationHint(90);
                    }
                    //    mMediaRecorder.setOrientationHint(90);// 输出旋转90度,保持竖屏录制
                    try {
                        mRecAudioFile = File.createTempFile("Vedio", ".mp4", mRecVedioPath);
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    mMediaRecorder.setOutputFile(mRecAudioFile.getAbsolutePath());

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

                    showMsg("开始录制");
//                    scalePic.setBackgroundDrawable(iconStop);
                    isRecording = !isRecording;
                    recordAnimater();
                }
                return true;
            }
        });
        //返回按钮
        iv_takeBack.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                finish();
            }
        });
        takepicture.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Logger.t("click——-——————>").d("点击了");
                parameters = camera.getParameters();
                List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
                int index = getPictureSize(supportedPictureSizes);
                parameters.setPictureSize(supportedPictureSizes.get(index).width, supportedPictureSizes.get(index).height);
                camera.setParameters(parameters);
                camera.takePicture(null, null, new MyPictureCallback());

            }
        });
        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 (second <= 1) {
//                                showMsg("录制时间太短");
                                Toast.makeText(TakePicActivity.this, "录制时间太短", Toast.LENGTH_SHORT).show();
//                                animator.cancel();
                                try {
                                    Thread.sleep(1000);
                                } catch (InterruptedException e) {
                                    e.printStackTrace();
                                }
                                if (animator.isRunning()) {
                                    animator.end();
                                }
//                                mMediaRecorder.setOnErrorListener(null);
//                                mMediaRecorder.setPreviewDisplay(null);
//                                mMediaRecorder.stop();
//                                mMediaRecorder.reset();
                            } else {
                                if (animator.isRunning()) {
                                    animator.end();
                                }
                            }

                        }
                        break;
                }
                return false;
            }
        });
    }

    protected void onResume() {
        super.onResume();
        timer.setText("点击拍照,长按摄像");
        timer.setVisibility(View.VISIBLE);
        circleProgress.setVisibility(View.GONE);
        isRecordState = 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;
                    //录制完成后播放摄像头

                    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();
                if (second > 1) {
                    freeCameraResource();
                    Intent displayIntent = new Intent(TakePicActivity.this, ShowPicActivity.class);
                    bundle = new Bundle();
                    bundle.putBoolean("isRecord", isRecordState);
                    bundle.putString("video_path", out.getAbsolutePath());//视频路径
                    bundle.putString("video_name", fileName);//视频名
                    displayIntent.putExtras(bundle);
                    startActivity(displayIntent);
//                    finish();
                }
                if (mMediaRecorder != null) {
                    freeMediaRecorderResource();
                }
                timer.setText("点击拍照,长按摄像");
                circleProgress.setVisibility(View.GONE);
                isRecordState = false;
                second = 0;
            }

            @Override
            public void onAnimationCancel(Animator animation) {

            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });
    }

    /**
     * 切换前后摄像头
     */
    @OnClick(R.id.iv_turn)
    public void onClick() {
        //切换前后摄像头
        int cameraCount = 0;
        Camera.CameraInfo cameraInfo = new Camera.CameraInfo();
        cameraCount = Camera.getNumberOfCameras();//得到摄像头的个数

        for (int i = 0; i < cameraCount; i++) {
            Camera.getCameraInfo(i, cameraInfo);//得到每一个摄像头的信息
            if (cameraPosition == 0) {
                //现在是后置,变更为前置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    camera.stopPreview();//停掉原来摄像头的预览
                    camera.release();//释放资源
                    camera = null;//取消原来摄像头
                    camera = Camera.open(i);//打开当前选中的摄像头
                    //  camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, cameraPosition));
                    if (model != null) {
                        if (model.equals("MI 5")) {//针对小米五机型的特殊配置
                            if (isScreenConfigChange == 3) {//横屏
                                camera.setDisplayOrientation(0);
                            } else {
                                camera.setDisplayOrientation(270);
                            }

                        } else {
                            camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, cameraPosition));
                        }
                    } else {
                        camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, cameraPosition));
                    }

                    try {
                        camera.setPreviewDisplay(surfaceHolder);//通过surfaceview显示取景画面
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                    camera.startPreview();//开始预览
                    cameraPosition = 1;
                    break;
                }
            } else {
                //现在是前置, 变更为后置
                if (cameraInfo.facing == Camera.CameraInfo.CAMERA_FACING_BACK) {//代表摄像头的方位,CAMERA_FACING_FRONT前置      CAMERA_FACING_BACK后置
                    camera.stopPreview();//停掉原来摄像头的预览
                    camera.release();//释放资源
                    camera = null;//取消原来摄像头
                    camera = Camera.open(i);//打开当前选中的摄像头
                    camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, cameraPosition));
                    try {
                        camera.setPreviewDisplay(surfaceHolder);//通过surfaceview显示取景画面
                    } catch (IOException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
                    camera.startPreview();//开始预览
                    cameraPosition = 0;
                    break;
                }
            }

        }

    }

    @Override
    public void onPreviewFrame(byte[] data, Camera camera) {

    }

    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);// 照片质量
//                List<Camera.Size> supportedPictureSizes = parameters.getSupportedPictureSizes();
//                int index = getPictureSize(supportedPictureSizes);
//                parameters.setPreviewSize(supportedPictureSizes.get(index).width, supportedPictureSizes.get(index).height);
//                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;
//                        }
//                    }
//                }
//                Log.d("size---->", "宽" + PreviewWidth + "高" + PreviewHeight);
//                parameters.setPreviewSize(PreviewWidth, PreviewHeight); // 获得摄像区域的大小
//                parameters.setPictureSize(PreviewWidth, PreviewHeight); // 获得保存图片的大小
                camera.setParameters(parameters);
                camera.setPreviewDisplay(holder); // 设置用于显示拍照影像的SurfaceHolder对象
                camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, cameraPosition));
                camera.startPreview(); // 开始预览
                isPreview = true;
                // 获得手机的方向
                int rotation = TakePicActivity.this.getWindowManager().getDefaultDisplay()
                        .getRotation();
                isScreenConfigChange = rotation;
//                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);
                    Camera.Parameters parameters = camera.getParameters();
                    Camera.Size s = CameraConfiguration.getBestSupportedSize(parameters.getSupportedPreviewSizes(), w, h);
                    initCamera(s.width, s.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;
        }
    }

    private static Point findBestPreviewSizeValue(List<Camera.Size> sizeList, Point screenResolution) {
        int bestX = 0;
        int bestY = 0;
        int size = 0;
        for (int i = 0; i < sizeList.size(); i++) {
            // 如果有符合的分辨率,则直接返回
            if (sizeList.get(i).width == DEFAULT_WIDTH && sizeList.get(i).height == DEFAULT_HEIGHT) {
                Log.d(TAG, "get default preview size!!!");
                return new Point(DEFAULT_WIDTH, DEFAULT_HEIGHT);
            }

            int newX = sizeList.get(i).width;
            int newY = sizeList.get(i).height;
            int newSize = Math.abs(newX * newX) + Math.abs(newY * newY);
            float ratio = (float) newY / (float) newX;
            Log.d(TAG, newX + ":" + newY + ":" + ratio);
            if (newSize >= size && ratio != 0.75) {  // 确保图片是16:9的
                bestX = newX;
                bestY = newY;
                size = newSize;
            } else if (newSize < size) {
                continue;
            }
        }

        if (bestX > 0 && bestY > 0) {
            return new Point(bestX, bestY);
        }
        return null;
    }

    static 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(TakePicActivity.this, ShowPicActivity.class);

                    //  intent.setClass(getApplicationContext(), ShowPicActivity.class);
                    bundle.putBoolean("isRecord", isRecordState);
                    bundle.putInt("isPosition", cameraPosition);
                    bundle.putInt("isScreenConfigChange", isScreenConfigChange);
                    intent.putExtras(bundle);
                    startActivity(intent);
                    if (camera != null) {
                        freeCameraResource();
                    }
                }

            } 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();
        if (mMediaRecorder != null) {
//            mMediaRecorder.stop();
            mMediaRecorder.release();
            mMediaRecorder = null;
//            videoRename();
        }
        handler.removeCallbacks(task);
    }

    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);
                    if (flContent.getChildCount() == 3) {
                        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/";

        fileName = System.currentTimeMillis() + ".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) {
                if (second >= 60) {
                    minute++;
                    second = second % 60;
                }
                if (minute >= 60) {
                    hour++;
                    minute = minute % 60;
                }
                timer.setText(format(hour) + ":" + format(minute) + ":" + format(second));
                second++;
                handler.postDelayed(this, 1000);
            }
        }
    };

    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;
        }
    }

    /**
     * 释放录像资源
     */
    private void freeMediaRecorderResource() {
        if (mMediaRecorder != null) {
            try {
                mMediaRecorder.setOnErrorListener(null);
                mMediaRecorder.setOnInfoListener(null);
                mMediaRecorder.setPreviewDisplay(null);
                mMediaRecorder.stop();
            } catch (Exception e) {
                e.printStackTrace();
            }
            mMediaRecorder.release();
            mMediaRecorder = null;
        }
    }

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

    /**
     * 切记用intent传递图片
     */
    public static byte[] getDatea() {
        byte[] data = picData;
        return data;
    }

    /*获取手机相片的大小*/
    private int getPictureSize(List<Camera.Size> sizes) {
        // 屏幕的宽度
        int screenWidth = getResources().getDisplayMetrics().widthPixels;
        LogUtil.d(TAG, "screenWidth=" + screenWidth);
        int index = -1;


        for (int i = 0; i < sizes.size(); i++) {
            if (screenWidth == sizes.get(i).width) {
                index = i;
            }
        }
        // 当未找到与手机分辨率相等的数值,取列表中间的分辨率
        if (index == -1) {
            index = sizes.size() / 2;
        }


        return index;
    }

    /*初始化camera的数据不管什么情况变成后摄像头*/
    private void initCamera() {
        if (camera != null) {
            camera.stopPreview();//停掉原来摄像头的预览
            camera.release();//释放资源
            camera = null;//取消原来摄像头
        }
        camera = Camera.open(0);//打开当前选中的摄像头
        camera.setDisplayOrientation(getPreviewDegree1(TakePicActivity.this, 0));
        try {
            camera.setPreviewDisplay(surfaceHolder);//通过surfaceview显示取景画面
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        camera.startPreview();//开始预览
        cameraPosition = 0;
    }
}

activity_take_pic.xml
<?xml version="1.0" encoding="utf-8"?>
<FrameLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/fl_content" android:layout_width="match_parent"
    android:layout_height="match_parent">
    <SurfaceView
        android:id="@+id/surfaceView"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <RelativeLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/iv_takeBack"
            android:layout_marginTop="16dp"
            android:layout_marginLeft="@dimen/dp_16"
            android:src="@drawable/msg_camera_back"
            android:layout_width="@dimen/dp_22"
            android:layout_height="@dimen/dp_22" />
        <ImageView
            android:id="@+id/iv_turn"
            android:src="@drawable/camare_change"
            android:layout_alignParentRight="true"
            android:layout_marginTop="16dp"
            android:layout_marginRight="@dimen/dp_16"
            android:layout_width="@dimen/dp_22"
            android:layout_height="@dimen/dp_22" />
    </RelativeLayout>

    <RelativeLayout
        android:id="@+id/buttonLayout"
        android:layout_marginBottom="@dimen/dp_20"
        android:layout_gravity="center_horizontal"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content">
        <TextView
            android:id="@+id/show_time"
            android:text="点击拍照,长按摄像"
            android:layout_centerHorizontal="true"
            android:textColor="@color/white"
            android:layout_marginBottom="@dimen/dp_10"
            android:layout_above="@+id/takepicture"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
        <!-- 拍照按钮 -->
        <Button
            android:id="@+id/takepicture"
            android:layout_width="80dp"
            android:layout_height="80dp"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:background="@drawable/msg_camera_take"
            />
        <com.haier.uhome.appliance.newVersion.module.messageboard.view.CircleProgressView
            android:id="@+id/circleProgress"
            android:visibility="gone"
            android:layout_centerHorizontal="true"
            android:layout_alignParentBottom="true"
            android:layout_width="@dimen/dp_80"
            android:layout_height="@dimen/dp_80" />
    </RelativeLayout>
</FrameLayout>

视频或相片的展示页
ShowPicActivity.java
package com.haier.uhome.appliance.newVersion.module.messageboard;

import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.os.Bundle;
import android.os.Environment;
import android.provider.Settings;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.KeyEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;

import com.haier.uhome.activity.mine.MainMessageBoard;
import com.haier.uhome.appliance.R;
import com.haier.uhome.appliance.newVersion.module.messageboard.util.CameraConfiguration;
import com.orhanobut.logger.Logger;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Calendar;

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;
    private int position;
    private int isScreenConfigChange;
    private String videoName;
    String model = android.os.Build.MODEL;//手机的型号

    @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.get("isPosition") != null) {
            position = (int) data.get("isPosition");
        }
        if (data.get("isScreenConfigChange") != null) {
            isScreenConfigChange = (int) data.get("isScreenConfigChange");
        }
        Logger.t("degree").d("isScreenConfigChange" + isScreenConfigChange);
        Logger.t("position").d(position + "位置");//0代表后置摄像头,1代表前置摄像头
        if (data.getBoolean("isRecord")) {
            isRecord = true;
            videoPath = data.getString("video_path");
            videoName = data.getString("video_name");
            iv_play.setVisibility(View.GONE);
            sfvDisplay.setVisibility(View.VISIBLE);
            Log.d(TAG, "videoPath=" + videoPath);
            showVideo();
        } else {
            int degree = CameraConfiguration.getPreviewDegree1(ShowPicActivity.this,position);
            Logger.t("degree").d("角度" + degree);
            android.view.WindowManager manager = (WindowManager) ShowPicActivity.this.getSystemService(Context.WINDOW_SERVICE);

            int rotation = manager.getDefaultDisplay().getRotation();
            Logger.t("degree").d("角度rotation" + rotation);
            //返回值0表示关闭了重力感应(锁定方向),1表示开启了重力感应(旋转)
            try {
                int a = Settings.System.getInt(getContentResolver(), Settings.System.ACCELEROMETER_ROTATION);
            } catch (Settings.SettingNotFoundException e) {
                e.printStackTrace();
            }
            Logger.t("degree").d("返回值0表示关闭了重力感应(锁定方向),1表示开启了重力感应(旋转)" + rotation);
            isRecord = false;
            iv_play.setVisibility(View.VISIBLE);
            sfvDisplay.setVisibility(View.GONE);
            //    setImageBitmap(data.getByteArray("bytes"));
            Bitmap cameraBitmap;
            if (position == 1) {
                if (isScreenConfigChange == 3) {
                    if (model.equals("MI 5")) {
                        cameraBitmap = rotaingImageView(270);
                    } else {
                        cameraBitmap = rotaingImageView(90);
                    }
                } else {
                    cameraBitmap = rotaingImageView(270);
                }
            } else {
                cameraBitmap = rotaingImageView(90);
            }
            imgName = Calendar.getInstance().getTimeInMillis() + ".jpg";
            saveFile(cameraBitmap, imgName);
            iv_play.setScaleType(ImageView.ScaleType.CENTER_CROP);
            iv_play.setImageBitmap(cameraBitmap);
        }

    }

    /**
     * 旋转图片
     *
     * @param angle
     * @param
     * @return Bitmap
     */
    public Bitmap rotaingImageView(int angle) {
        Bitmap cameraBitmap = byte2Bitmap();
        //旋转图片 动作
        Matrix matrix = new Matrix();
        matrix.postRotate(angle);
        if (position == 1) {
            matrix.postScale(-1, 1);// 镜像水平翻转
        }
        // 创建新的图片
        Bitmap resizedBitmap = Bitmap.createBitmap(cameraBitmap, 0, 0,
                cameraBitmap.getWidth(), cameraBitmap.getHeight(), matrix, true);
        return resizedBitmap;
    }

    /**
     * 将MainActivity传过来的图片显示在界面当中
     *
     * @param bytes
     */
    public void setImageBitmap(byte[] bytes) {

        Bitmap cameraBitmap = byte2Bitmap();
        // 根据拍摄的方向旋转图像(纵向拍摄时要需要将图像选择90度)
        Matrix matrix = new Matrix();
        matrix.setRotate(CameraConfiguration.getPreviewDegree1(this, position));

        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");
        byte[] bytes = TakePicActivity.getDatea();
        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:
                Intent intent = new Intent(ShowPicActivity.this, TakePicActivity.class);
                startActivity(intent);
                finish();
                break;
            case R.id.iv_confirm:
                Intent i = new Intent(this, MainMessageBoard.class);
                if (isRecord) {
                    i.putExtra("toMainPath", videoPath);//视频文件路径
                    i.putExtra("videoname", videoName);//视频文件名
                } else {
                    i.putExtra("toMainPath", ALBUM_PATH + imgName);
                    i.putExtra("takephoto", 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:
                Intent intent1 = new Intent(ShowPicActivity.this, TakePicActivity.class);
                startActivity(intent1);
                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);
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK
                && event.getAction() == KeyEvent.ACTION_DOWN) {
            Intent intent = new Intent(ShowPicActivity.this, TakePicActivity.class);
            startActivity(intent);
            return false;
        }
        return super.onKeyDown(keyCode, event);
    }

}

展示页的xml:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="@color/black"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin"
    tools:context="com.haier.uhome.appliance.newVersion.module.messageboard.ShowPicActivity">
    <ImageView
        android:id="@+id/iv_back2"
        android:src="@drawable/msg_camera_back"
        android:layout_width="22dp"
        android:layout_height="22dp" />
    <ImageView
        android:layout_above="@+id/rl_confirm"
        android:id="@+id/iv_playPic"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:layout_below="@+id/iv_back2"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <SurfaceView
        android:id="@+id/sfv_display"
        android:visibility="gone"
        android:layout_marginTop="20dp"
        android:layout_marginBottom="20dp"
        android:layout_above="@+id/rl_confirm"
        android:layout_width="match_parent"
        android:layout_height="match_parent" />
    <RelativeLayout
        android:id="@+id/rl_confirm"
        android:layout_alignParentBottom="true"
        android:layout_width="match_parent"
        android:layout_height="wrap_content">
        <ImageView
            android:id="@+id/iv_confirm"
            android:layout_centerHorizontal="true"
            android:src="@drawable/msg_camera_confirm"
            android:layout_width="60dp"
            android:layout_height="60dp" />
        <TextView
            android:id="@+id/tv_repeat"
            android:text="重新拍照"
            android:textColor="@color/text_white"
            android:layout_centerVertical="true"
            android:layout_alignParentRight="true"
            android:layout_marginRight="30dp"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content" />
    </RelativeLayout>
</RelativeLayout>
点击展示页的确认按钮,回到留言板界面,发送图片或视频留言:

//从拍照或视频显示页面返回的处理
    protected void onNewIntent(Intent intent) {
        super.onNewIntent(intent);
        camerPath = intent.getStringExtra("toMainPath");
        Log.d(TAG, "camerPath=" + camerPath);
        boolean isRecord = intent.getBooleanExtra("isRecord", false);
        if (!isRecord) {
            fileName = intent.getStringExtra("takephoto");
            msgType = 1;
            isMsg = 0;

            insertMsg();
            if(!deviceMac.equals("Virtual")){
                DialogHelper.showRoundProcessDialog(MainMessageBoard.this,"正在加载中",true);
                sendFileToAliyun("leaveMsg/" + sdf.format(new Date()) + "/" + fileName, camerPath);
            }

//       sendPicMsg();
        } else {//视频
            videoname = intent.getStringExtra("videoname");
            msgType = 3;
            head_img_name = System.currentTimeMillis() + ".jpg";
            MsgUtil.saveFile(MsgUtil.getVideoThumbnail(camerPath), head_img_name);
            thumbnail = MsgUtil.ALBUM_PATH + head_img_name;
            isMsg = 1;//0可以用于发送文字,图片 语音 1:用于发送视频缩略图  2:视频文件

            insertMsg();
            if(!deviceMac.equals("Virtual")){
                DialogHelper.showRoundProcessDialog(MainMessageBoard.this,"正在加载中",true);
                sendFileToAliyun("leaveMsg/" + sdf.format(new Date()) + "/" + head_img_name, thumbnail);
            }

//       sendFileToAliyun("leaveMsg/"+sdf.format(new Date())+"/"+videoname,camerPath);
//       sendVideoMsg();
        }
    }

/**
 * 上传文件到阿里云
 *
 * @param fileName 文件名 时间戳命名
 * @param filaPath 文件路径
 */
public void sendFileToAliyun(String fileName, String filaPath) {
    PutObjectRequest put = new PutObjectRequest(HttpConstant.bucketName, fileName, filaPath);
    OSSCredentialProvider credentialProvider = new OSSPlainTextAKSKCredentialProvider(HttpConstant.accessKeyId, HttpConstant.accessKeySecret);
    OSS oss = new OSSClient(getApplicationContext(), HttpConstant.endpoint, credentialProvider);
    OSSAsyncTask task = oss.asyncPutObject(put, new OSSCompletedCallback<PutObjectRequest, PutObjectResult>() {
        @Override
        public void onSuccess(PutObjectRequest request, PutObjectResult result) {
            Log.d("PutObject", "UploadSuccess");
            if (isMsg == 1) {//0可以用于发送文字,图片 语音 1:用于发送视频缩略图 2:视频文件
                handler.sendEmptyMessage(UPLOAD_VIDEO);
            } else if (isMsg == 2) {//0可以用于发送文字,图片 语音 1:用于发送视频缩略图 2:视频文件
                handler.sendEmptyMessage(UPLOAD_VIDEO_FILE);
            } else if (isMsg == 0) {
                handler.sendEmptyMessage(UPLOAD_File);
            }
        }

        @Override
        public void onFailure(PutObjectRequest request, ClientException clientExcepion, ServiceException serviceException) {
            // 请求异常
            if (clientExcepion != null) {
                // 本地异常如网络异常等
                clientExcepion.printStackTrace();
            }
            if (serviceException != null) {
                // 服务异常
                Log.e("ErrorCode", serviceException.getErrorCode());
                Log.e("RequestId", serviceException.getRequestId());
            }
            if (msgType == 3) {
                isMsg = 1;
            }
        }
    });

}

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Android中实现仿微信朋友圈底部的拍照和拍摄功能,可以通过使用系统自带的相机应用或者自定义相机来进行实现。 首先,可以使用系统自带的相机应用来实现拍照和拍摄的功能。可以通过调用Intent,使用ACTION_IMAGE_CAPTURE和ACTION_VIDEO_CAPTURE来启动相机应用,并通过设置Uri来指定图片或视频的保存路径。在拍摄完成后,可以在onActivityResult()方法中获取拍摄结果进行处理,比如保存图片或视频的Uri,显示预览等。 其次,也可以自定义相机来实现拍照和拍摄的功能。可以通过使用Camera和Camera2 API来实现相机的预览和拍摄功能。首先,需要使用Camera或Camera2 API来启动相机预览,并通过设置SurfaceHolder或SurfaceTexture来显示预览画面。同时,可以监听相机的拍照或拍摄按钮点击事件,在点击时进行拍照或拍摄操作,并通过设置相机的PictureCallback或CaptureCallback来处理拍摄结果。 无论是使用系统相机应用还是自定义相机,还可以添加一些额外的功能来实现更好的用户体验。比如,可以添加美颜滤镜、闪光灯控制、切换前后摄像头等功能。 总而言之,在Android中实现仿微信朋友圈底部的拍照和拍摄功能可以通过使用系统自带相机应用或自定义相机来实现,为用户提供类似微信朋友圈的相机功能,并可以根据需求添加额外的功能来增强用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值