首页 > 技术文章 > (原创)android中使用相机的两种方式

BlogCommunicator 2015-10-24 00:13 原文

在社交类应用或扫描二维码的场合都需要用到手机上的摄像头

在程序中启用这一硬件主要有两类方法

1.发送intent启动系统自带的摄像应用

此应用的AndroidManifest中的intent-filter如下

<intent-filter>
                <action android:name="android.media.action.VIDEO_CAPTURE" />
                <category android:name="android.intent.category.DEFAULT" />
</intent-filter>

发送intent的代码如下:

     Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");        
        String path ="storage/sdcard1/picture1.jpg";
        File pic =new File(path);
        Uri uri=      Uri.fromFile(pic);
        //设定拍照后照片保存位置
        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri );    
        startActivity(intent);

2.自己调用API,试用Camera对象来完成拍摄保存

代码如下:

    @Override
    protected void onResume() {
        // TODO Auto-generated method stub
        super.onResume();
        surfaceView = (SurfaceView) findViewById(R.id.sv);
        // 获得预览画面的接收类
        SurfaceHolder holder = surfaceView.getHolder();
        // 接收类设置callback -->surface创建的时候开启camera开始预览,退出时关闭
        // 设置数据来源自渲染引擎, 不使用自己的缓冲区.
        holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
        camera = Camera.open();

        holder.addCallback(new Callback() {

            @Override
            public void surfaceDestroyed(SurfaceHolder holder) {
                // TODO Auto-generated method stub
                camera.stopPreview(); // 停止摄像头预览
                camera.release();
            }

            @Override
            public void surfaceCreated(SurfaceHolder holder) {
                // TODO Auto-generated method stub
                // 摄像头的使用
                try {
                    camera.setPreviewDisplay(holder);
                } catch (IOException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }// 设置预览显示
                camera.startPreview();// 开始预览

            }

            @Override
            public void surfaceChanged(SurfaceHolder holder, int format,
                    int width, int height) {
                // TODO Auto-generated method stub

            }
        });
    }

    public void click(View v) {
        shoot();
    }

    public void shoot() {

        camera.takePicture(null, null, new PictureCallback() {

            @Override
            public void onPictureTaken(byte[] data, Camera camera) {
                // TODO Auto-generated method stub
                Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0,
                        data.length);

                FileOutputStream fos = null;
                try {
                    fos = new FileOutputStream("sdcard/pic1.jpg");
                    boolean isSuccess = bitmap.compress(CompressFormat.JPEG,
                            50, fos);
                    if (isSuccess) {
                        Toast.makeText(MainActivity.this, "拍摄和存储成功", 0).show();
                    } else {
                        Toast.makeText(MainActivity.this, "拍摄和存储失败", 0).show();
                    }

                } catch (Exception e) {
                    e.printStackTrace();
                } finally {
                    if (fos != null) {
                        try {
                            fos.close();
                        } catch (IOException e) {
                            // TODO Auto-generated catch block
                            e.printStackTrace();
                        }
                    }
                }
            }
        });
        Intent intent = new Intent();
        intent.setAction(Intent.ACTION_MEDIA_MOUNTED);

        intent.setData(Uri.fromFile(new File("/sdcard")));
        sendBroadcast(intent);

        camera.startPreview();

    }

两种方法的对比

前一种方法需要跳出本程序,而且灵活性较低,但是简单易用,代码较少便于使用和维护.

后一种方法虽然比较复杂,但是可以自己定制拍摄activity的样式以及功能选项,并且在本应用中就可以完成拍摄的功能,用处也很多.

推荐阅读