Android呼叫攝像頭拍照並顯示照片

MagicMHD發表於2018-06-20

1、先寫xml介面程式碼如下:

 

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:orientation="vertical"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <Button
        android:id="@+id/take_photo"
        android:text="拍照"
        android:layout_width="match_parent"
        android:layout_height="wrap_content" />

    <ImageView
        android:id="@+id/picture"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_gravity="center_horizontal"/>
</LinearLayout>

放了兩個控制元件,一個用來拍照,一個用來顯示照片。

2、MainActivity程式碼如下:

 

public class MainActivity extends AppCompatActivity {
    public static final int TAKE_PHOTO=1;
    private ImageView picture;
    private Uri ImageUri;
    private Button takePhoto;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        takePhoto= (Button) findViewById(R.id.take_photo);
        takePhoto.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                //建立File物件,用於儲存拍照後的圖片
                File outputImage=new File(getExternalCacheDir(),"outputImage.jpg");
                try {
                if (outputImage.exists()){
                    outputImage.delete();
                }
                    outputImage.createNewFile();
                } catch (IOException e) {
                    e.printStackTrace();
                }
                if (Build.VERSION.SDK_INT>=24){
                    ImageUri= FileProvider.getUriForFile(MainActivity.this,
                            "com.example.camerralbumtest.fileprovider",outputImage);
                }else {
                    ImageUri=Uri.fromFile(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, Intent data) {
        switch (requestCode){
            case TAKE_PHOTO:
                if (resultCode==RESULT_OK){
                    try {
                        //將拍攝的照片顯示出來
                        Bitmap bitmap= BitmapFactory.decodeStream(getContentResolver().openInputStream(ImageUri));
                        picture.setImageBitmap(bitmap);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                    }
                }
                break;
            default:
                break;
        }
    }
}

        i:先繫結兩個控制元件,

     ii:在拍照的時候,建立了一個File物件outputImage,用於存放攝像頭拍下的照片命名為:output_image.jpg 。getExteralCacheDir是指把照片存放在手機SD卡的應用關聯快取目錄下面。具體路徑是/sdcard/Android/data/<package name>/cache。

      iii:進行判斷,如果outputImage檔案已經存在,則把它刪除,不存在,則建立這樣一個檔案。

      iv:再進行判斷,若手機版本低於Android7.0  ,就呼叫Uri的fromFile()方法將File物件outputImage轉換成Uri物件,這個Uri物件標識著output_iamge.jpg這張真實照片的本地真實路徑;若手機版本高於7.0,也就是sdk大於等於24時,就呼叫FileProvider的getUriForFile()方法將File物件outputImage轉換成一個封裝過的Uri物件,getUriForFile()方法接收3個引數,第一個時上下文,第二個是任意唯一的字串,第三個是是我們建立的File物件outputImage。

      v:啟動相機程式,構建Intent,將intent的動作指定為IMAGE_CAPTURE,再呼叫putExtra方法指定圖片的輸出地址,這裡填入剛剛得到的uri物件。最後呼叫startActivityForResult來啟動活動。

      vi:剛才我們開啟活動使用的是startActivityForResult,因此拍照結束後會有結果返回到onActivityResult()方法中,因此要重寫這個方法。

      vii:若發現拍照成功,就可以呼叫BitmapFactory的decodeStream方法將output_image.jpg這張圖片解析成Bitmap物件,然後把它設定到ImageView中顯示出來。

3、前面提到若手機版本大於7.0時,我們用到了內容提供器FileProvider,因此需要在Manifest檔案中註冊一下,程式碼如下:

 

<provider
    android:authorities="com.example.camerralbumtest.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>

這裡,android:name是固定的,android:authorities屬性的值就是我們之前寫的getUriForFile方法的第二個引數,還需要在<provider>標籤內部使用<meta-data>用來指定Uri的共享路徑,並引用了一個我們建立好的file_path的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 name="my_images" path=""/>

上面這一句就是用來指定Uri共享的,name屬性值隨便填,path屬性的值表示共享的具體路徑,這裡設定為空值表示整個SD卡共享。

4、訪問SD卡是需要許可權的,因此記得在Manifest檔案中加入許可權如下:

 

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

這樣就全部完成啦,快來啟動吧。

 

 

 

相關文章