android studio呼叫攝像頭拍照及具體步驟演示程式碼

IDEA_TEYU_1112發表於2018-08-14

演示程式碼的功能,呼叫攝像頭拍照,成功的話則把照片顯示出來。

第一步 定義一個按鈕用於呼叫攝像頭拍照,ImageView用於存放顯示拍出的照片。

<Button
        android:id="@+id/take_photo"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="take photo"
        />
    <ImageView
        android:id="@+id/picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"
        />

第二步 開始編寫呼叫攝像頭的具體邏輯

package example.com.test;
//邏輯,先建立檔案,之後把它封裝成uri物件,之後封裝帶intent中,呼叫攝像頭,之後呼叫過後會有一個
//返回結果,成功的話就把它顯示出來
import android.content.Intent;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;

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

public class MainActivity extends AppCompatActivity {
    public static final int TAKE_PHOTO=1;//宣告一個請求碼,用於識別返回的結果
    private ImageView picture;
    private Uri imageUri;
    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() {
            public void onClick(View view) {
                File outputImage=new File(getExternalCacheDir(),"output_image.jpg");
                /*
                建立一個File檔案物件,用於存放攝像頭拍下的圖片,我們把這個圖片命名為output_image.jpg
                並把它存放在應用關聯快取目錄下,呼叫getExternalCacheDir()可以得到這個目錄,為什麼要
                用關聯快取目錄呢?由於android6.0開始,讀寫sd卡列為了危險許可權,使用的時候必須要有許可權,
                應用關聯目錄則可以跳過這一步
                 */
                try//判斷圖片是否存在,存在則刪除在建立,不存在則直接建立
                {
                    if(outputImage.exists())
                    {
                        outputImage.delete();
                    }
                    outputImage.createNewFile();
                }
                catch (IOException e)
                {
                    e.printStackTrace();
                }
                if(Build.VERSION.SDK_INT>=24)
                    //判斷安卓的版本是否高於7.0,高於則呼叫高於的方法,低於則呼叫低於的方法
                    //把檔案轉換成Uri物件
                    /*
                    之所以這樣,是因為android7.0以後直接使用本地真實路徑是不安全的,會丟擲異常。
                    FileProvider是一種特殊的內容提供器,可以對資料進行保護
                     */
                {
                    imageUri= FileProvider.getUriForFile(MainActivity.this,
                            "com.example.cameraalbumtest.fileprovider",outputImage);
                    /*
                    第一個引數:context物件
                    第二個引數:任意唯一的字串
                    第三個引數:檔案物件
                     */

                }
                else {
                    imageUri=Uri.fromFile(outputImage);
                }
                //使用隱示的Intent,系統會找到與它對應的活動,即呼叫攝像頭,並把它儲存
                Intent intent=new intent("android.media.action.IMAGE_CAPTURE");
                intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
                startActivityForResult(intent,TAKE_PHOTO);
                //呼叫會返回結果的開啟方式,返回成功的話,則把它顯示出來
            }
        });
    }
    //處理返回結果的函式,下面是隱示Intent的返回結果的處理方式,具體見以前我所發的intent講解
    protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        switch (requestCode)
        {
            case TAKE_PHOTO:
                if(resultCode==RESULT_OK)
                {
                    try
                    {
                         Bitmap bitmap= BitmapFactory.decodeStream(getContent-
                                Resolver().openInputStream(imageUri));
                         picture.setImageBitmap(bitmap);
                         //將圖片解析成Bitmap物件,並把它顯現出來
                    }
                    catch (FileNotFoundException e)
                    {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }
}

 第三步 剛剛我們提到了內容提供器,所以我們現在內容提供器在manifest.xml中進行註冊,其中android:name的值是固定的,

android:authorities的值必須和FileProvider.getUriForFile的第二個引數是一致的,在這裡面我們還利用了<meta-data來制定uri路徑,並引用一個資源,當然這個資源還未建立,我們在第四步建立它。

<provider
            android:authorities="com.example.cameraalbumtest.fileprovider"
            android:name="android.support.v4.content.FileProvider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/file_paths" />
        </provider>

 第四步 在res目錄下建立一個xml目錄,目錄是directory,之後在這個目錄下,建立一個xml原始檔,修改程式碼如下:

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

</paths>

其中 <external-path用於指定uri共享的,名字可以隨便填,path為空表示可以共享整個sd卡 

第五步 為了相容老版本的安卓系統,我們還是打算新增一條許可權,用於宣告訪問sd卡的許可權。

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

 

相關文章