1. 程式人生 > >Android開發之拍照

Android開發之拍照

1.請求使用相機的許可權

若使用相機是應用的必要功能,想要它在應用Google player裡僅對有相機的裝置的可見。我們可以在清單檔案(Manifest)中新增標籤:

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

如果我們的應用使用相機,但相機並不是應用的正常執行所必不可少的元件,可以將android:required設定為”false”。這樣的話,Google Play 也會允許沒有相機的裝置下載該應用。當然我們有必要在使用相機之前通過呼叫hasSystemFeature(PackageManager.FEATURE_CAMERA)方法來檢查裝置上是否有相機。如果沒有,我們應該禁用和相機相關的功能

2.使用相機應用程式進行拍照

下面的函式通過傳送一個Intent來捕獲照片:

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);
    }
}

注意在呼叫startActivityForResult()方法之前,先呼叫resolveActivity(),這個方法會返回能處理該Intent的第一個Activity(譯註:即檢查有沒有能處理這個Intent的Activity)。執行這個檢查非常重要,因為如果在呼叫startActivityForResult()時,沒有應用能處理你的Intent,應用將會崩潰。所以只要返回結果不為null,使用該Intent就是安全的。

3.獲取縮圖

Android的相機應用會把拍好的照片編碼為縮小的Bitmap,使用extra value的方式新增到返回的Intent當中,並傳送給onActivityResult(),對應的Key為”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);
    }
}

4.儲存全尺寸照片

如果我們提供了一個File物件給Android的相機程式,它會儲存這張全尺寸照片到給定的路徑下。另外,我們必須提供儲存圖片所需要的含有後綴名形式的檔名。

一般而言,使用者使用裝置相機所拍攝的任何照片都應該被存放在裝置的公共外部儲存中,這樣它們就能被所有的應用訪問。將DIRECTORY_PICTURES作為引數,傳遞給getExternalStoragePublicDirectory()方法,可以返回適用於儲存公共圖片的目錄。由於該方法提供的目錄被所有應用共享,因此對該目錄進行讀寫操作分別需要READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE許可權。另外,因為寫許可權隱含了讀許可權,所以如果需要外部儲存的寫許可權,那麼僅僅需要請求一項許可權就可以了:

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

然而,如果希望照片對我們的應用而言是私有的,那麼可以使用getExternalFilesDir()提供的目錄。在Android 4.3及以下版本的系統中,寫這個目錄需要WRITE_EXTERNAL_STORAGE許可權。從Android 4.4開始,該目錄將無法被其他應用訪問,所以該許可權就不再需要了,你可以通過新增maxSdkVersion屬性,宣告只在低版本的Android裝置上請求這個許可權。

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

注意:所有儲存在getExternalFilesDir()提供的目錄中的檔案會在使用者解除安裝你的app後被刪除。

一旦選定了儲存檔案的目錄,我們還需要設計一個保證檔名不會衝突的命名規則。當然我們還可以將路徑儲存在一個成員變數裡以備在將來使用。下面的例子使用日期時間戳作為新照片的檔名:

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 = Environment.getExternalStoragePublicDirectory(
            Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
        imageFileName,  /* prefix */
        ".jpg",         /* suffix */
        storageDir      /* directory */
    );

    // Save a file: path for use with ACTION_VIEW intents
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}

有了上面的方法,我們就可以給新照片建立檔案物件了,現在我們可以像這樣建立並觸發一個Intent:

    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 e) {
                // Error occurred while creating the File
                // ...
            }

            // Continue only if the File was successfully created
            if (photoFile != null) {
                takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
                startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);
            }
        }
    }

5.將照片新增到相簿中

由於我們通過Intent建立了一張照片,因此圖片的儲存位置我們是知道的。對其他人來說,也許檢視我們的照片最簡單的方式是通過系統的Media Provider。

注意:如果將圖片儲存在getExternalFilesDir()提供的目錄中,Media Scanner將無法訪問到我們的檔案,因為它們隸屬於應用的私有資料。

下面的例子演示瞭如何觸發系統的Media Scanner,將我們的照片新增到Media Provider的資料庫中,這樣就可以使得Android相簿程式與其他程式能夠讀取到這些照片。

    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);
    }

6.解碼一幅縮放圖片

在有限的記憶體下,管理許多全尺寸的圖片會很棘手。如果發現應用在展示了少量圖片後消耗了所有記憶體,我們可以通過縮放圖片到目標檢視尺寸,之後再載入到記憶體中的方法,來顯著降低記憶體的使用,下面的例子演示了這個技術:

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

    // Get the dimensions of the bitmap
    BitmapFactory.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 image
    int 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);
}

相關推薦

Android開發拍照

1.請求使用相機的許可權 若使用相機是應用的必要功能,想要它在應用Google player裡僅對有相機的裝置的可見。我們可以在清單檔案(Manifest)中新增標籤: <manifest ... > <uses-featur

Android開發拍照功能實現(附原始碼)

    大家好,這是一個簡單的拍照功能,很簡單的介面,一個顯示影象區域SurfaceView一個“拍照”按鈕。直接上程式碼! 1、CameraDemoActivity.java(主介面) package org.winplus.camera; import java.i

Android開發裁切(拍照+相簿)影象並設定頭像小結

先看效果:                                                   再貼程式碼: 自定義選擇照片底部彈出對話方塊佈局: <?xml version="1.0" encoding="utf-8"?> <Re

Android開發呼叫攝像頭拍照

現在很多應用中都會要求使用者上傳一張圖片來作為頭像,首先我在這接收使用相機拍照和在相簿中選擇圖片。接下來先上效果圖: 接下來看程式碼: 1,佈局檔案: <?xml version="1.0" encoding="utf-8"?> <

Android開發呼叫相機拍照與本地相簿選擇圖片

使用者看到的介面如下,也是我的xml介面: demo中有一個按鈕,點選彈出對話方塊提示使用者選擇:拍照、相簿。如下圖: 點選拍照,會開啟手機相機開始拍照,拍攝完後可以裁剪,如下圖: 這時候你可以直接點選確定,也可

Android開發 選擇相簿圖片或者拍照

在我們的Android開發中肯定都會遇到要選擇本地相簿的圖片或者是用相機進行拍照使用圖片。 簡單的講解一下如何使用,比如我們要上傳頭像時總會使用的。這個步驟一般就是:1.點選頭像然後會彈出一個選單,然後我們選擇是從相簿中選擇圖片還是使用相機拍照;2.選擇照片或

Android開發控制攝像頭拍照

        現在的手機一般都會提供相機功能,有些相機的鏡頭甚至支援1300萬以上畫素,有些甚至支援獨立對焦、光學變焦這些只有單反才有的功能,甚至有些手機直接宣傳可以拍到星星。可以說手機已經變成了專業數碼相機。為了充分利用手機上的相機功能, Android系統提供了Cam

Android開發呼叫相機拍照和呼叫系統相簿

Android應用程式中呼叫相機進行拍照和選擇相簿中的照片是經常會使用到的,那麼我們就來實現以下這個功能。 首先建立一個工程CameraTest,佈局檔案一個ImageView,兩個Button。 <?xml version="1.0" en

Android開發getX,getRawX,getWidth,getTranslationX等的區別

save string hlist getwidth sta 是我 touch 項目 寬度 轉載請註明出處:http://blog.csdn.net/dmk877/article/details/51550031 好久沒寫博客了,最近工作確實挺忙的,剛剛結束了一個

Android 開發Windows環境下Android Studio安裝和使用教程(圖文詳細步驟)

9.png 虛擬機 jdk版本 編寫 clip 開發平臺 集成開發 arc 電腦安裝 鑒於谷歌最新推出的Android Studio備受開發者的推崇,所以也跟著體驗一下。 一、介紹Android Studio Android Studio 是一個Android

Android開發AudioManager(音頻管理器)具體解釋

應該 數量 service eth out 開發 要求 type 路由 AudioManager簡單介紹: AudioManager類提供了訪問音量和振鈴器mode控制。使用Context.getSystemService(Context.AUDIO_SERVICE)

【入門篇】ANDROID開發BUG專講

world 自然 執行 類型 效率 str 積累 全部 href 話說諸葛亮是一個優秀的程序員,每個錦囊都是應對不同的case而編寫的。可是優秀的程序員也敵只是更優秀的bug。六出祈山。七進中原,鞠躬盡瘁,死而後已的諸葛亮僅僅由於有一

android開發merge結合include優化布局

ted com match clas you title example ews 文件的 merge結合include優化android布局,效果不知道。個人感覺使用上也有非常大的局限。只是還是了解一下。記錄下來。 布局文件都要有根節點,但androi

Android開發增量更新

avt exp chm 這一 font ams extern city ron 一、使用場景 apk升級,節省服務器和用戶的流量 二、原理 自從 Android 4.1 開始, Google Play 引入了應用程序的增量更新功能,App使用該升級方式,可節省約2/3

Android開發布局文件裏實現OnClick事件關聯處理方法

intent dsm nbsp ext 關聯 you vertica findview 時間 一般監聽OnClickListener事件,我們都是通過Button button = (Button)findViewById(....); button.se

Android 開發 ---- bootloader (LK)

ttl tab 不同的 opera 指定 isa system void mem LK是什麽 LK 是 Little Kernel 它是 appsbl (Applications ARM Boot Loader)流程代碼 ,little kernel

Android開發藍牙連接打印機

cep sdi tco disable ner gis util receiver count 代碼很簡單,直接一個布局文件和一個activity。需要的朋友可以直接將這兩部分粘貼復制到項目中即可。 Activity部分: package com.anhua.bluet

Android開發新建項目報錯的問題

instr rul txt gin 通過 ini .com org top 通過android studio新建一個空項目。在新建完項目之後,gradle編譯會報錯。 發生問題的原因是build.gradle(Project:TopDialog)中: allproject

Android開發CriminalIntent項目開發(其一)

開發項目 1.0 enc 增加 委派 其他 date 應用 module 前言   這次的開發項目是一個叫做CriminalIntent的應用,該應用可以詳細記錄各種辦公室陋習。這個應用記載的陋習記錄包括標題、日期和圖片,支持在聯系人中查找當事人,通過E-mail、Twit

Android開發旅3:android架構

通過 圖集 例如 sqlit 組件 mil 大小 簡化 .html 引言 通過前面兩篇: Android 開發之旅:環境搭建及HelloWorld Android 開發之旅:HelloWorld項目的目錄結構 我們對android有了個大