Android realizes calling the mobile phone camera to take pictures and store them as files

Declare permissions

First, you should declare the mobile phone memory read and write permissions in the "AndroidManifest" file:

<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Starting from Android 6.0, some sensitive permissions need to be dynamically applied again in the corresponding Activity. Therefore, we need to apply for permissions again in the Activity we wrote:

if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
    
    
            ActivityCompat.requestPermissions(this, new String[]{
    
    Manifest.permission.WRITE_EXTERNAL_STORAGE}, 0);
            Log.d("进入:", "requestPermissions");
        }
        if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED){
    
    
            ActivityCompat.requestPermissions(this, new String[]{
    
    Manifest.permission.READ_EXTERNAL_STORAGE}, 0);
            Log.d("进入:", "requestPermissions");
        }

The camera button triggers an event`

1. The click event of the camera button is as follows:

mBtnUpload.setOnClickListener(new View.OnClickListener() {
    
    
            @Override
            public void onClick(View v) {
    
    
                //点击事件:进行拍照
                Intent intent=new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                File photoFile=createImgFile();
                photoUri= Uri.fromFile(photoFile);
                intent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
                startActivityForResult(intent,1);

            }
        });

2. The function of the above "createImgFile()" function is to customize the picture name and obtain the file of the picture. The specific code is as follows:

/**
     * 自定义图片名,获取照片的file
     */
    private File createImgFile(){
    
    
        //确定文件名
        String fileName="img_"+new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date())+".jpg";
        File dir;
        if(Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)){
    
    
            dir=Environment.getExternalStorageDirectory();
        }else{
    
    
            dir=getExternalFilesDir(Environment.DIRECTORY_PICTURES);
        }
        File tempFile=new File(dir,fileName);
        try{
    
    
            if(tempFile.exists()){
    
    
                tempFile.delete();
            }
            tempFile.createNewFile();
        }catch (IOException e){
    
    
            e.printStackTrace();
        }
        //获取文件路径
        photoPath = tempFile.getAbsolutePath();
        return tempFile;
    }

3. Since the above code uses the "startActivityForResult()" method, the "onActivityResult()" function will be called after the photo is taken. We rewrite this function (to implement photo storage, add to album):

protected void onActivityResult(int requestCode, int resultCode, Intent data) {
    
    
        super.onActivityResult(requestCode, resultCode, data);
        if(resultCode==RESULT_OK){
    
    
            switch (requestCode){
    
    
                case 1:
                    setImageBitmap();
                    galleryAddPic();
                    break;
                case 2:
                    //data中自带有返回的uri
                    photoUri=data.getData();
                    //获取照片路径
                    String[] filePathColumn={
    
    MediaStore.Audio.Media.DATA};
                    Cursor cursor=getContentResolver().query(photoUri,filePathColumn,null,null,null);
                    cursor.moveToFirst();
                    photoPath=cursor.getString(cursor.getColumnIndex(filePathColumn[0]));
                    cursor.close();
                    //有了照片路径,之后就是压缩图片,和之前没有什么区别
                    setImageBitmap();
                    break;
            }
        }
    }

Note: The "case 2" statement block here is used to select photos from the mobile phone's local photo album. Since the code is similar, no demonstration will be given.
4. The function of the "setImageBitmap()" function is to compress the picture we just took and display it in the "ImageView" control we declared. The specific code is as follows:

/**
     * 压缩图片
     */
    private void setImageBitmap(){
    
    
        Log.d("Record", "进入压缩图片");
        //获取imageview的宽和高
        int targetWidth=photoImageView.getWidth();
        int targetHeight=photoImageView.getHeight();

        //根据图片路径,获取bitmap的宽和高
        BitmapFactory.Options options=new BitmapFactory.Options();
        options.inJustDecodeBounds=true;
        BitmapFactory.decodeFile(photoPath,options);
        int photoWidth=options.outWidth;
        int photoHeight=options.outHeight;
        Log.d("Record", "获取长和高:"+ photoHeight + "Width:" + photoWidth);

        //获取缩放比例
        int inSampleSize=1;
        if(photoWidth>targetWidth||photoHeight>targetHeight){
    
    
            int widthRatio=Math.round((float)photoWidth/targetWidth);
            int heightRatio=Math.round((float)photoHeight/targetHeight);
            inSampleSize=Math.min(widthRatio,heightRatio);
            Log.d("Record", "进入缩放比例");
        }

        //使用现在的options获取Bitmap
        options.inSampleSize=inSampleSize;
        options.inJustDecodeBounds=false;
        Bitmap bitmap=BitmapFactory.decodeFile(photoPath,options);
        photoImageView.setImageBitmap(bitmap);
        //调用转换函数,将ImageView文件转换为String类型数据,以便传输到云端
        String bitmapToString = putImageToShare(getApplicationContext(), photoImageView);
        mTvChange.setText(bitmapToString);
        //调用上传函数,将String类型数据传送到服务器
        UploadImage(getApplicationContext(), bitmapToString);
        Log.d("Record", "ToString:" + bitmapToString);
        Log.d("Record", "获取Bitmap");
    }

Among them, the "putImageToShare()" and "UploadImage()" methods are used to convert the image into String data and upload the data to the server. If you do not need to implement the function of uploading photos to the server, you can delete these two lines of code. If you need to implement the upload function, you can read this article:
The Android platform realizes the transfer of pictures to the server and reproduces them in the server folder (client program + server program)

5. The function of the "galleryAddPic()" function is to add the pictures we just The captured photos are added to the mobile phone album, the specific code is as follows:

//将图片添加进手机相册
    private void galleryAddPic(){
    
    
        Intent mediaScanIntent=new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
        mediaScanIntent.setData(photoUri);
        this.sendBroadcast(mediaScanIntent);
    }

postscript

Record some pitfalls stepped on during the programming process:
1. In Android 10, additional operations are required to read and write mobile phone memory permissions:
add statements in the "AndroidManifest" file:

android:requestLegacyExternalStorage="true"

Otherwise, the ImageView control cannot display our pictures.
2. In Android 10, when the above code is executed, calling the camera will crash. The solution is as follows:
add the statement in the corresponding Activity:

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
    
    
            StrictMode.VmPolicy.Builder builder = new StrictMode.VmPolicy.Builder();
            StrictMode.setVmPolicy( builder.build() );
        }

Reference article:

https://blog.csdn.net/happy_fsyy/article/details/51986444
—————————————————————————————
Finally, post my personal public No.: Search "Chaqian" on WeChat or scan the image below. Usually, some programming-related articles will be updated, and everyone is welcome to pay attention~
tea move

Guess you like

Origin blog.csdn.net/weixin_46269688/article/details/111307338