AS2022 simply realizes calling the mobile phone camera to take pictures and display the pictures

Requirement: Call the phone camera by clicking the camera button, and display it on the screen after taking a photo

1. Layout file design

Place a button and an imageView control in the xml file (the picture is placed here)

PS: I personally recommend dragging components directly with constraint layout

code show as below:

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/take_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="拍照"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.498"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.109" />

    <ImageView
        android:id="@+id/picture"
        android:layout_width="0dp"
        android:layout_height="0dp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintEnd_toEndOf="parent"
        app:layout_constraintHorizontal_bias="0.461"
        app:layout_constraintStart_toStartOf="parent"
        app:layout_constraintTop_toTopOf="@+id/guideline2"
        tools:srcCompat="@drawable/baseline_child_care_24" />

    <androidx.constraintlayout.widget.Guideline
        android:id="@+id/guideline2"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal"
        app:layout_constraintGuide_percent="0.5" />
</androidx.constraintlayout.widget.ConstraintLayout>

2. Grant permissions

Since the function we implement is to read and write data in public storage, we must use the "WRITE_EXTERNAL_STORAGE" permission, and we must remove "android:maxSdkVersion="18"".

Authorize in the manifest file

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

3. Use the FIleProvider class

Since our needs need to share data (i.e. photos taken) between our current application and the camera, we need to use the FileProvider class

Configuration process:

First of all , you need to declare AndroidManifest.xmlthrough tags in the file <provider>and configure customandroid:authorities attributes. The code is as follows:

<manifest>
    <application>
        <provider
            android:name="android.support.v4.content.FileProvider"
            android:authorities="my.itgungnir.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
        </provider>
    </application>
</manifest>

If your emulator version is below Android10, use android.support.v4.content.FileProvider

In order to allow other applications to access the files under the current application, we also need to configure which folders can be accessed. This step is also XMLconfigured in the file. We need to create a path configuration file under the project /res/xmlfolder, named it file_paths.xml(the file name can be customized), and the root node in this file is <paths>to configure the folder under this node. An example configuration is as follows:

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="my_images" path="/"/>
</paths>

The path path is set to "/", which means that all folders can be accessed

After configuring each folder, we also need to reference this configuration in the label AndroidManifest.xmlin the file <provider>, so that the configuration can take effect. Use <meta-data>tags to refer to the configuration, the code is as follows:

<provider
            android:authorities="Tom_LZK"
            android:name="androidx.core.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
        <meta-data
            android:name="android.support.FILE_PROVIDER_PATHS"
            android:resource="@xml/file_paths"/>
        </provider>

<meta-data>The attributes in the tags android:nameare fixed values android.support.FILE_PROVIDER_PATHS, and android:resourcethe attributes are references to the configuration files above.

Attach the code of MainActivity:

package com.example.arbitrary;

import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.content.FileProvider;

import java.io.File;
import java.io.IOException;

public class MainActivity extends AppCompatActivity {
    public static final int TAKE_PHOTO = 1;
    private ImageView picture;
    private Uri imageUri;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Button takePhoto = findViewById(R.id.take_photo);
        picture = findViewById(R.id.picture);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {
                //创建File对象,用来存储拍照后的照片
                //getExternalCacheDir()获取此应用缓存数据的位置,在这个位置保存图片
                File outputImage = new File(getExternalCacheDir(), "output_image.jpg");
                try {
                    if (outputImage.exists()) {//如果图片已经存在就删除再重新创建
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                imageUri = FileProvider.getUriForFile(MainActivity.this,
                        "Tom_LZK", outputImage);

                //启动相机
                Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
                startActivityForResult(intent, TAKE_PHOTO);
            }
        });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        if (requestCode == TAKE_PHOTO && resultCode == RESULT_OK) {
                    //显示拍出来的照片
                    Bitmap bitmap = BitmapFactory.decodeFile(getExternalCacheDir()+"//output_image.jpg");
                    picture.setImageBitmap(bitmap);
                }
        }
}

Finish. 

Note: The authorities variable in the getUriForFile method should be consistent with the authorities in the provider

Guess you like

Origin blog.csdn.net/weixin_64089259/article/details/129813180