Android使用系統(tǒng)相機(jī)進(jìn)行拍照的步驟
前言
我們在日常的開發(fā)中有時(shí)候會遇到需要用到相機(jī)的需求,而相機(jī)也是很常用的東西,例如掃二維碼啊拍照上傳啊等等。這里我不講像qq那樣自定義很強(qiáng)的拍照功能(事實(shí)上我也不會),講個(gè)最簡單的調(diào)用系統(tǒng)相機(jī)拍照并儲存
調(diào)用系統(tǒng)相機(jī)步驟
這里我通過一個(gè)簡單的例子來講這個(gè)內(nèi)容。
我自己寫了一個(gè)demo,布局很簡單:
<Button android:id="@+id/button" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="4dp" android:text="take phone" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintHorizontal_bias="0.281" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <ImageView android:id="@+id/imageView" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_marginTop="29dp" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/button" app:srcCompat="@mipmap/ic_launcher_round" />
就是一個(gè)按鈕點(diǎn)擊彈起相機(jī),然后一個(gè)imageView顯示拍到的照片。
接下來我想一下調(diào)用的整個(gè)過程我們需要做什么:
首先彈起相機(jī)肯定要跳到相機(jī)這個(gè)應(yīng)用,那么就必須通過隱性啟動(dòng)相機(jī)的活動(dòng)。
然后當(dāng)我們返回應(yīng)用的時(shí)候,還要將照片顯示,所以這里就要用到startActivityForResult這個(gè)方法。
其次,我們拍照之后肯定要進(jìn)行儲存的,那么就涉及到文件的操作。
涉及到內(nèi)存的操作就肯定要和權(quán)限打交道,所有還有權(quán)限相關(guān)的內(nèi)容。
最后還有一個(gè)問題就是,相機(jī)拍完照是要儲存照片的,所以我們要給他一個(gè)地址uri,但是可不可以直接把地址當(dāng)成參數(shù)發(fā)過去呢?這里就要用到特殊的內(nèi)容提供器FileProvider。
上面就是調(diào)用相機(jī)要用到的內(nèi)容,雖然用的都很淺,但是都會涉及到。接下來看看具體怎么實(shí)現(xiàn)。看看Activity中的onCreate的代碼:
private Uri imageUri;
private ImageView imageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imageView = findViewById(R.id.imageView);
Button button = findViewById(R.id.button);
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
//創(chuàng)建一個(gè)File對象。getExternalCacheDir()獲取應(yīng)用的緩存目錄,outputImage.jpg是照片名稱
File outputImage = new File(getExternalCacheDir(),"outputImage.jpg");
try{
//創(chuàng)建一個(gè)空文件
outputImage.createNewFile();
}catch (IOException e){
e.printStackTrace();
}
//不同的安卓版本對用不同的獲取Uri的方法
if (Build.VERSION.SDK_INT>=24){
imageUri =FileProvider.getUriForFile(MainActivity.this,"huan",outputImage);
}else{
imageUri = Uri.fromFile(outputImage);
}
//啟動(dòng)相機(jī)的對應(yīng)Activity
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT,imageUri);
startActivityForResult(intent,1);
}
});
我們來看看這里的代碼:前面的代碼很簡單就是控件的初始化。
我們知道照片是要放文件夾得,所以這里要?jiǎng)?chuàng)建一個(gè)File對象,指定文件的路徑以及名字。這里路徑為什么要用getExternalCacheDir()呢?因?yàn)槊總€(gè)應(yīng)用都有對應(yīng)得緩存目錄,訪問這些目錄得時(shí)候不用訪問內(nèi)存權(quán)限,這樣得話就可以省去需求權(quán)限得步驟啦。這個(gè)目錄在/scare/Android/data//cache。
然后我們再創(chuàng)建一個(gè)空的文件夾。這里如果已經(jīng)有照片了的話例如我們第二次拍照的時(shí)候,那么就不會創(chuàng)建新的空文件夾了。直到儲存的時(shí)候才會被替換掉。
然后我們剛才講到,拍到的圖片要在我們的應(yīng)用中展示,那么就必須用到內(nèi)容提供器。這里用到FileProvider來獲取uri,關(guān)于provider我在下文有講到可以
如果是低于4.4版本的安卓就用Uri.fromFile(outputImage);方法可以獲取到uri
再通過隱式啟動(dòng)相機(jī)activity可以打開相機(jī)了。這里系統(tǒng)相機(jī)的action是android.media.action.IMAGE_CAPTURE,相機(jī)儲存路徑的參數(shù)名字是MediaStore.EXTRA_OUTPUT,并把uri傳輸進(jìn)去。
好了這樣就完成了拍照并把照片儲存的步驟了。接下來還差什么?對了,把照片顯示出來?,F(xiàn)在在內(nèi)存中已經(jīng)有這個(gè)照片了,而且uri也知道,所以就很容易了,看代碼:
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
if (requestCode == 1) {
if (resultCode == RESULT_OK)
try {
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
imageView.setImageBitmap(bitmap);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
我們剛才使用startActivityForResult來啟動(dòng)活動(dòng)的,所以就要重寫這個(gè)方法來顯示圖片了。這里首先判斷是哪個(gè)啟動(dòng)命令,然后再判斷是否成功啟動(dòng),再BitmapFactory.decodeStream這個(gè)方法來獲取bitmap,再把bitmap顯示出來就行了。BitmapFactory.decodeStream這個(gè)方法需要一個(gè)流,可以通過getContentResolver().openInputStream這個(gè)方法來開啟一個(gè)流。
到此整個(gè)流程就解決了。
FileProvider
FileProvider是一個(gè)特殊的內(nèi)容提供器,可以把一個(gè)file開頭的uri改成content開頭的,例如:file://uri -> content://uri。那為什么要這么做呢?這里簡單講一下:
這個(gè)是因?yàn)樵贏ndroid 7.0之后,官方禁止直接把一個(gè)真實(shí)路徑的uri傳輸?shù)絼e的應(yīng)用,而我們要把地址送給相機(jī),所以就會出現(xiàn)問題了。詳細(xì)可以查閱這篇博客:Android 7.0 行為變更 通過FileProvider在應(yīng)用間共享文件吧
既然是內(nèi)容提供器那么肯定是要進(jìn)行注冊的:
<provider android:name="android.support.v4.content.FileProvider" android:authorities="huan" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
這里的authorities參數(shù)必須和前面的getUriForFile方法的第二個(gè)參數(shù)保持一致,同個(gè)內(nèi)容提供器的authorities肯定要一樣啦。grantUriPermissions參數(shù)一定要是true,這個(gè)的大概意思就是給他的所有元素授權(quán)可以被訪問,在FileProvider中這個(gè)參數(shù)必須是true(這也是為什么在4.4一下版本的安卓無法使用的原因之一,有興趣可以去了解一下)export這個(gè)參數(shù)表示可不可以給其他的應(yīng)用共享,這里要設(shè)置為false。<meta-data這個(gè)是配置我們可以訪問的文件路徑,@xml/file_paths這個(gè)就是表示什么文件可以被訪問,當(dāng)然要建一個(gè)這個(gè)文件??创a:
<?xml version="1.0" encoding="utf-8"?> <paths xmlns:android="http://schemas.android.com/apk/res/android"> <external-path name="my_image" path="/"/> </paths>
<external-path這個(gè)就是表示可以被訪問的路徑,name是后面映射用到的,可以自己隨便起,我這里用一橫桿表示整個(gè)目錄可以被訪問。
小結(jié)
調(diào)用系統(tǒng)相機(jī)的功能雖然不難,代碼也不多,但是其中的零碎知識很多,零零散散,還是要注意的。特別是關(guān)于低高配的安卓版本問題還是要特別注意一下。
以上就是Android使用系統(tǒng)相機(jī)進(jìn)行拍照的步驟的詳細(xì)內(nèi)容,更多關(guān)于Android 適用系統(tǒng)相機(jī)的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解
這篇文章主要介紹了Android使用OKHttp包處理HTTP相關(guān)操作的基本用法講解,包括操作如何利用OKHttp操作HTTP請求與處理緩存等內(nèi)容,需要的朋友可以參考下2016-07-07
在Android app中實(shí)現(xiàn)九(n)宮格圖片連續(xù)滑動(dòng)效果
這篇文章主要介紹了在Android app中實(shí)現(xiàn)九(n)宮格圖片連續(xù)滑動(dòng)效果的方法,作者舉了鳳凰新聞應(yīng)用的例子,同理功能圖標(biāo)也可以利用這樣的滑動(dòng)效果,需要的朋友可以參考下2016-02-02
Android實(shí)現(xiàn)微信朋友圈圖片和視頻播放
這篇文章主要為大家詳細(xì)介紹了Android實(shí)現(xiàn)微信朋友圈圖片和視頻播放,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-05-05
Android編程開發(fā)之多點(diǎn)觸摸(Multitouch)實(shí)現(xiàn)方法
這篇文章主要介紹了Android編程開發(fā)之多點(diǎn)觸摸(Multitouch)實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Android多點(diǎn)觸摸的相關(guān)實(shí)現(xiàn)步驟與操作技巧,需要的朋友可以參考下2016-08-08
TabLayout+ViewPager實(shí)現(xiàn)切頁的示例代碼
這篇文章主要介紹了TabLayout+ViewPager實(shí)現(xiàn)切頁的示例代碼,可實(shí)現(xiàn)左右滑動(dòng)切換視圖界面和點(diǎn)擊切換,非常具有實(shí)用價(jià)值,需要的朋友可以參考下2019-01-01
Android視頻/音頻緩存框架AndroidVideoCache(Okhttp)詳解
這篇文章主要為大家詳細(xì)介紹了Android視頻、音頻緩存框架AndroidVideoCache,實(shí)現(xiàn)邊下邊播功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-07-07
Kotlin對象的懶加載方式by?lazy?與?lateinit?異同詳解
這篇文章主要為大家介紹了Kotlin對象的懶加載方式by?lazy?與?lateinit?異同詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-10-10
Android中通過view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法
這篇文章主要介紹了Android中通過view方式獲取當(dāng)前Activity的屏幕截圖實(shí)現(xiàn)方法,本文方法相對簡單,容易理解,需要的朋友可以參考下2014-09-09

