Take photos

這節(jié)課教我們?nèi)绾瓮ㄟ^將工作委托給設(shè)備上的另一個(gè)攝像頭應(yīng)用來拍攝一張照片儡湾。(如果你想構(gòu)建自己的相機(jī)功能,請(qǐng)參見控制相機(jī)。)

如果整合照片只是你應(yīng)用的小部分時(shí),你想要最低成本拍照输钩,而不是重新實(shí)現(xiàn)一個(gè)拍照功能。令人高興的是仲智,大多數(shù)android設(shè)備已經(jīng)安裝了至少一個(gè)攝像頭應(yīng)用程序买乃。在這節(jié)課中,你要學(xué)習(xí)如何讓它為你拍照坎藐。

請(qǐng)求相機(jī)功能


如果拍照是你應(yīng)用程序的一個(gè)基本功能为牍,那么將其在谷歌應(yīng)用市場(chǎng)上的可見性限制是哼绑,有攝像頭的設(shè)備岩馍。為了宣傳您的應(yīng)用程序依賴于有一個(gè)攝像頭,在您的清單文件中放置一個(gè)< uss -feature>標(biāo)記:

<manifest ...>

<uses-feature android:name="android.hardware.camera"android:required="true"/>

</manifest >


如果您的應(yīng)用程序使用抖韩,但不需要攝像頭來運(yùn)行蛀恩,則設(shè)置android:required="false"。通過這樣做茂浮,谷歌Play將允許沒有攝像頭的設(shè)備下載應(yīng)用程序双谆。然后,您有責(zé)任通過調(diào)用hasSystemFeature(packagemanagemanager . feature_camera)檢查相機(jī)在運(yùn)行時(shí)的可用性席揽。如果沒有攝像頭顽馋,你應(yīng)該禁用你的攝像頭功能。


用相機(jī)應(yīng)用拍照


Android中將操作委托給其他應(yīng)用程序的方式是調(diào)用一個(gè)意圖(意圖:用來描述您想要做的事情)幌羞。這個(gè)過程包括三個(gè)部分:意圖本身寸谜、啟動(dòng)外部活動(dòng)的調(diào)用,以及當(dāng)焦點(diǎn)返回到活動(dòng)時(shí)處理圖像數(shù)據(jù)的代碼属桦。

這是一個(gè)調(diào)用捕獲照片意圖的函數(shù)熊痴。

static final int REQUEST_IMAGE_CAPTURE = 1;

private void dispatchTakePictureIntent() {Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

startActivityForResult

(takePictureIntent, REQUEST_IMAGE_CAPTURE);}}

請(qǐng)注意他爸,startActivityForResult()方法受到調(diào)用resolveActivity()條件的保護(hù)(條件限制保護(hù)),該條件返回能夠處理意圖的第一個(gè)活動(dòng)組件果善。執(zhí)行這個(gè)檢查是很重要的诊笤,因?yàn)槿绻{(diào)用startActivityForResult()使用了任何應(yīng)用程序都無法處理的意圖,您的應(yīng)用程序?qū)⒈罎⒔砩隆K灾灰Y(jié)果不是空的讨跟,使用意圖是安全的。


獲取縮略圖


如果拍照這個(gè)簡(jiǎn)單的壯舉并不是你的應(yīng)用野心的頂點(diǎn)鄙煤,那么你可能想要從相機(jī)應(yīng)用中取回照片许赃,然后用它做點(diǎn)什么。

Android Camera應(yīng)用程序?qū)⒄掌幋a為onActivityResult()返回的意圖的Extra信息中的一個(gè)小位圖馆类,對(duì)應(yīng)鍵為“data”混聊。下面的代碼檢索此映像并將其顯示在ImageView中。

@Override

protected void onActivityResult(int requestCode, int resultCode, Intent data) {

? ? if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {

? ? ? ? Bundle extras = data.getExtras();

? ? ? ? Bitmap imageBitmap = (Bitmap) extras.get("data");

? ? ? ? mImageView.setImageBitmap(imageBitmap);

? ? }

}

注意:這個(gè)來自“data”的縮略圖當(dāng)做一個(gè)圖標(biāo)icon可能ok乾巧,但不能再多要求了句喜。處理一個(gè)完整的圖像需要更多的工作。


保存全尺寸照片?


keywords:full-size

如果你給它一個(gè)文件來保存沟于,Android Camera應(yīng)用程序會(huì)保存全屏照片咳胃。你必須提供一個(gè)完全合格的文件名稱,以便相機(jī)應(yīng)用程序保存照片旷太。

通常展懈,用戶用設(shè)備攝像頭拍攝的任何照片都應(yīng)該保存在設(shè)備的公共外部存儲(chǔ)中,以便所有應(yīng)用程序都能訪問這些照片供璧。共享照片的適當(dāng)目錄由getExternalStoragePublicDirectory()提供存崖,并帶有DIRECTORY_PICTURES參數(shù)。由于此方法提供的目錄在所有應(yīng)用程序之間共享睡毒,因此對(duì)其進(jìn)行讀寫需要分別具有READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE權(quán)限来惧。寫入權(quán)限隱式地允許讀取,所以如果您需要寫入外部存儲(chǔ)演顾,那么您只需要請(qǐng)求一個(gè)權(quán)限:

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

但是供搀,如果希望照片只對(duì)應(yīng)用程序私有,可以使用getExternalFilesDir()提供的目錄钠至。在Android 4.3和更低的版本中葛虐,寫入這個(gè)目錄也需要WRITE_EXTERNAL_STORAGE權(quán)限。從Android 4.4開始棉钧,不再需要權(quán)限屿脐,因?yàn)槠渌麘?yīng)用程序無法訪問該目錄,所以您可以通過添加maxSdkVersion屬性,只在Android的較低版本上請(qǐng)求權(quán)限:

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

注意:在用戶卸載應(yīng)用程序時(shí)摄悯,將刪除保存在getExternalFilesDir()或getFilesDir()所提供目錄中的文件赞季。

確定文件的目錄后,需要?jiǎng)?chuàng)建一個(gè)抗沖突的文件名奢驯。您可能還希望將路徑保存到成員變量中以供以后使用申钩。這里有一個(gè)方法的示例解決方案,該方法使用日期-時(shí)間戳為新照片返回唯一的文件名:

String mCurrentPhotoPath;

private File createImageFile() throws IOException {

? ? // Create an image file name

? ? String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());

? ? String imageFileName = "JPEG_" + timeStamp + "_";

? ? File storageDir = getExternalFilesDir(Environment.DIRECTORY_PICTURES);

? ? File image = File.createTempFile(

? ? ? ? imageFileName,? /* prefix */

? ? ? ? ".jpg",? ? ? ? /* suffix */

? ? ? ? storageDir? ? ? /* directory */

? ? );

? ? // Save a file: path for use with ACTION_VIEW intents

? ? mCurrentPhotoPath = image.getAbsolutePath();

? ? return image;

}

使用此方法為照片創(chuàng)建文件瘪阁,您現(xiàn)在可以創(chuàng)建和調(diào)用這樣的意圖:

static final int REQUEST_TAKE_PHOTO = 1;

private void dispatchTakePictureIntent() {

? ? Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

? ? // Ensure that there's a camera activity to handle the intent

? ? if (takePictureIntent.resolveActivity(getPackageManager()) != null) {

? ? ? ? // Create the File where the photo should go

? ? ? ? File photoFile = null;

? ? ? ? try {

? ? ? ? ? ? photoFile = createImageFile();

? ? ? ? } catch (IOException ex) {

? ? ? ? ? ? // Error occurred while creating the File

? ? ? ? ? ? ...

? ? ? ? }

? ? ? ? // Continue only if the File was successfully created

? ? ? ? if (photoFile != null) {

? ? ? ? ? ? Uri photoURI = FileProvider.getUriForFile(this,

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? "com.example.android.fileprovider",

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? photoFile);

? ? ? ? ? ? takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoURI);

? ? ? ? ? ? startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);

? ? ? ? }

? ? }

}

注意:getUriForFile(context ,string,file)會(huì)返回內(nèi)容:// URI,我們使用?getUriForFile時(shí)會(huì)導(dǎo)致異常撒遣。對(duì)于最近針對(duì)Android 7.0 (API級(jí)別24)和更高的應(yīng)用程序,跨包邊界傳遞文件:// / URI會(huì)導(dǎo)致FileUriExposedException管跺。因此义黎,我們現(xiàn)在提供了一種使用FileProvider存儲(chǔ)圖像的更通用的方法。

現(xiàn)在豁跑,您需要配置FileProvider廉涕。在您的應(yīng)用程序清單中,向應(yīng)用程序添加一個(gè)提供者:

<application>

<provider

? ? ? ? android:name="android.support.v4.content.FileProvider"

? ? ? ? android:authorities="com.example.android.fileprovider"

? ? ? ? android:exported="false"

? ? ? ? android:grantUriPermissions="true">

<meta-data

? ? ? ? ? ? android:name="android.support.FILE_PROVIDER_PATHS"

? ? ? ? ? ? android:resource="@xml/file_paths"/>

</provider>

</application>


自定義file_paths指定可訪問文件

路徑組件對(duì)應(yīng)于getExternalFilesDir()在調(diào)用Environment.DIRECTORY_PICTURES時(shí)返回的路徑艇拍。確保您將com.example.package.name替換為應(yīng)用程序的實(shí)際包名狐蜕。此外,還要檢查FileProvider的文檔卸夕,以獲得除external-path之外可以使用的路徑說明符的詳細(xì)描述层释。


將照片添加到一個(gè)畫廊


當(dāng)您通過一個(gè)意圖創(chuàng)建一個(gè)照片時(shí),您應(yīng)該知道您的圖像位于何處快集,因?yàn)槟紫戎付嗽诤翁幈4嫠备帷?duì)于其他人來說,可能讓你的照片可訪問的最簡(jiǎn)單的方法是從系統(tǒng)的媒體提供商(相冊(cè))那里訪問它个初。

注意:如果您將照片保存到getExternalFilesDir()提供的目錄中乖寒,媒體掃描器無法訪問這些文件,因?yàn)樗鼈兪菓?yīng)用程序的私有文件勃黍。

下面的示例方法演示了如何調(diào)用系統(tǒng)的媒體掃描器將照片添加到媒體提供者的數(shù)據(jù)庫中宵统,使其在Android Gallery應(yīng)用程序和其他應(yīng)用程序中可用。

private void galleryAddPic() {

? ? Intent mediaScanIntent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);

? ? File f = new File(mCurrentPhotoPath);

? ? Uri contentUri = Uri.fromFile(f);

? ? mediaScanIntent.setData(contentUri);

? ? this.sendBroadcast(mediaScanIntent);

}

解碼一個(gè)按比例縮小的圖片


在內(nèi)存有限的情況下覆获,管理多個(gè)全尺寸圖像是很困難的。如果您發(fā)現(xiàn)您的應(yīng)用程序在僅僅顯示了幾個(gè)映像之后就耗盡了內(nèi)存瓢省,那么可以通過將JPEG擴(kuò)展到一個(gè)內(nèi)存數(shù)組中弄息,使其與目標(biāo)視圖的大小相匹配,從而大大減少使用的動(dòng)態(tài)堆的數(shù)量勤婚。下面的示例方法演示了這種技術(shù)摹量。

private void setPic() {// Get the dimensions of the Viewint targetW = mImageView.getWidth();int targetH = mImageView.getHeight();

// Get the dimensions of the bitmapBitmapFactory.Options bmOptions = new BitmapFactory.Options();

bmOptions

.inJustDecodeBounds = true;BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);int photoW = bmOptions.outWidth;int photoH = bmOptions.outHeight;

// Determine how much to scale down the imageint scaleFactor = Math.min(photoW/targetW, photoH/targetH);

// Decode the image file into a Bitmap sized to fill the View

bmOptions

.inJustDecodeBounds = false;

bmOptions

.inSampleSize = scaleFactor;

bmOptions

.inPurgeable = true;

Bitmap bitmap = BitmapFactory.decodeFile(mCurrentPhotoPath, bmOptions);

mImageView

.setImageBitmap(bitmap);}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子缨称,更是在濱河造成了極大的恐慌凝果,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,941評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件睦尽,死亡現(xiàn)場(chǎng)離奇詭異器净,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)当凡,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,397評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門山害,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人沿量,你說我怎么就攤上這事浪慌。” “怎么了朴则?”我有些...
    開封第一講書人閱讀 165,345評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵权纤,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我乌妒,道長(zhǎng)妖碉,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,851評(píng)論 1 295
  • 正文 為了忘掉前任芥被,我火速辦了婚禮欧宜,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘拴魄。我一直安慰自己冗茸,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,868評(píng)論 6 392
  • 文/花漫 我一把揭開白布匹中。 她就那樣靜靜地躺著夏漱,像睡著了一般。 火紅的嫁衣襯著肌膚如雪顶捷。 梳的紋絲不亂的頭發(fā)上挂绰,一...
    開封第一講書人閱讀 51,688評(píng)論 1 305
  • 那天,我揣著相機(jī)與錄音服赎,去河邊找鬼葵蒂。 笑死,一個(gè)胖子當(dāng)著我的面吹牛重虑,可吹牛的內(nèi)容都是我干的践付。 我是一名探鬼主播,決...
    沈念sama閱讀 40,414評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼缺厉,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼永高!你這毒婦竟也來了隧土?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,319評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤命爬,失蹤者是張志新(化名)和其女友劉穎曹傀,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體饲宛,經(jīng)...
    沈念sama閱讀 45,775評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡皆愉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,945評(píng)論 3 336
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了落萎。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片亥啦。...
    茶點(diǎn)故事閱讀 40,096評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖练链,靈堂內(nèi)的尸體忽然破棺而出翔脱,到底是詐尸還是另有隱情,我是刑警寧澤媒鼓,帶...
    沈念sama閱讀 35,789評(píng)論 5 346
  • 正文 年R本政府宣布届吁,位于F島的核電站,受9級(jí)特大地震影響绿鸣,放射性物質(zhì)發(fā)生泄漏疚沐。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,437評(píng)論 3 331
  • 文/蒙蒙 一潮模、第九天 我趴在偏房一處隱蔽的房頂上張望亮蛔。 院中可真熱鬧,春花似錦擎厢、人聲如沸究流。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,993評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽芬探。三九已至,卻和暖如春厘惦,著一層夾襖步出監(jiān)牢的瞬間偷仿,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,107評(píng)論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人贞绳。 一個(gè)月前我還...
    沈念sama閱讀 48,308評(píng)論 3 372
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像形入,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子缝左,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,037評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容

  • Android 自定義View的各種姿勢(shì)1 Activity的顯示之ViewRootImpl詳解 Activity...
    passiontim閱讀 172,167評(píng)論 25 707
  • afinalAfinal是一個(gè)android的ioc,orm框架 https://github.com/yangf...
    wgl0419閱讀 6,284評(píng)論 1 9
  • mean to add the formatted="false" attribute?.[ 46% 47325/...
    ProZoom閱讀 2,699評(píng)論 0 3
  • 一 陌沄終是回來了南方,帶著有些滄桑的臉…… 那天是2014年的正月初四渺杉,一同約定去了高中的學(xué)校蛇数。見到陌沄的那刻,...
    大寫的魚閱讀 198評(píng)論 0 0
  • print 'Hello world!'
    SensorFlow閱讀 128評(píng)論 0 0