美文网首页待集成Android应用开发连载程序员
羊皮书APP(Android版)开发系列(二十五)自动拍照保存照

羊皮书APP(Android版)开发系列(二十五)自动拍照保存照

作者: JeenWang | 来源:发表于2016-05-25 16:38 被阅读438次

    功能描述:学校刷卡终端采用android系统,学生在进出学校时需要刷卡,刷卡同时系统自动拍照并保存照片,而拍照保存照片这个过程学生并不知晓,也就是后台自动拍照。

    实现方式:自动拍照功能使用系统相机Camera即可实现,但是注意:Android 5.0以下版本和Android 5.0及以上版本的实现方式不同,因系统版本为Android 4.4 故采用Android 5.0以下版本的方式实现。

    1. 添加系统权限。
       <uses-permission android:name="android.permission.CAMERA" />
       <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
       <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    
    2. 在布局文件中添加SurfaceView, SurfaceView的width和height均设置为0.1dp,这样用户就不能看见相机了,但是注意一定不能设置为0dp。
    <SurfaceView
            android:id="@+id/texture"
            android:layout_width="0.1dp"
            android:layout_height="0.1dp"
            android:layout_alignParentTop="true" />
    
    3. Activity中初始化Camera,同时实现SurfaceHolder.Callback,Camera.PictureCallback两个接口。
        @Bind(R.id.texture)
        SurfaceView texture;
        private SurfaceHolder surfaceHolder;
        private Camera camera;
        
         private void initCamera() {
            surfaceHolder = texture.getHolder();
    
            surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    
            surfaceHolder.addCallback(this);
    
        }
    
         @Override
        public void onPictureTaken(byte[] data, Camera camera) {
            if (data != null) {
                Bitmap bitmap = Bytes2Bitmap(data);
                saveImageToGallery(getApplicationContext(), bitmap);
            }
    
            camera.startPreview();
        }
        @Override
        public void surfaceCreated(SurfaceHolder holder) {
            // TODO Auto-generated method stub
    
            int cameraNums = Camera.getNumberOfCameras();
            L.e("CAMERA_CONTROLL", cameraNums + "");
            try {
                //我的设备只有一个摄像头,故而直接使用,若为双摄像头,则需要设置使用的是前摄像头还是后摄像头
                camera = Camera.open(0);
    
            } catch (Exception e) {
                L.e("CAMERA_CONTROLL", e.getMessage());
            }
            try {
                camera.setPreviewDisplay(holder);
                Camera.Parameters parameters = camera.getParameters();
                parameters.set("orientation", "portrait");
                camera.setDisplayOrientation(90);
                parameters.setRotation(90);
                camera.setParameters(parameters);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                if (camera != null) {
                    camera.release();
                }
            }
        }
    
        @Override
        public void surfaceDestroyed(SurfaceHolder holder) {
            // TODO Auto-generated method stub
            if (camera != null) {
                camera.stopPreview();
                camera.release();
            }
        }
    
    4. 刷卡事件触发立即拍照。
            camera.takePicture(null, null, StudentAttendanceActivity.this);
    
    
    5. Bytes转Bitmap方法。
    public Bitmap Bytes2Bitmap(byte[] b) {
            L.e("byte length", b.length + "");
            if (b.length != 0) {
                return BitmapFactory.decodeByteArray(b, 0, b.length);
            } else {
                return null;
            }
        }
    
    5. 将拍照的照片命名后保存到系统相册目录下。
        /**
         * 保存图片到本地
         *
         * @param context
         * @param bmp
         */
        public void saveImageToGallery(Context context, Bitmap bmp) {
            // 首先保存图片
            File appDir = new File(Environment.getExternalStorageDirectory(), AppConstants.FILEDIR);
            if (!appDir.exists()) {
                appDir.mkdir();
            }
            String fileName = dateStr + ".jpg";
            File file = new File(appDir, fileName);
            try {
                FileOutputStream fos = new FileOutputStream(file);
                bmp.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.flush();
                fos.close();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }
    
            // 其次把文件插入到系统图库
            try {
                MediaStore.Images.Media.insertImage(context.getContentResolver(),
                        file.getAbsolutePath(), fileName, null);
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            }
        }
    
    
    7. Activity退出后释放资源。
        @Override
        protected void onDestroy() {
            super.onDestroy();
            ButterKnife.unbind(this);
            if (camera!=null) {
                camera.release();
                camera = null;
            }
        }
    
    8. 总结:

    后台自动拍照保存照片功能,主要在于设置SurfaceView的width和height均设置为0.1dp,则假装对用户不可见,然后设置拍照触发事件,在事件中调用camera.takePicture方法即可。至于照片保存及照片处理可根据业务需求来确定,由于系统拍照拍出的照片很大,一般都要进行压缩处理。

    注: 图片压缩工具见我的github项目AndroidUtilsBitmapCompressor.java 。同时AndroidUtils里还有一些其它常用的工具类哦。

    相关文章

      网友评论

      • 罷罷:AppConstants.FILEDIR这个是什么,我的代码里面就这个报错了
        JeenWang:@罷罷 这个是我的常量类,自己写一个就行,或者直接替换成路径字符串都可以的
        罷罷:@JeenWang 它提示cannot resolve symbol"AppConstants",这个是不是要自己去做出来的一个类
        JeenWang:@罷罷 文件保存路径

      本文标题:羊皮书APP(Android版)开发系列(二十五)自动拍照保存照

      本文链接:https://www.haomeiwen.com/subject/bbetdttx.html