android studio呼叫攝像頭拍照及具體步驟演示程式碼
阿新 • • 發佈:2019-02-04
演示程式碼的功能,呼叫攝像頭拍照,成功的話則把照片顯示出來。
第一步 定義一個按鈕用於呼叫攝像頭拍照,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"/>