2014年6月10日 星期二

[Android] 照相

官方範例檔:PhotoIntentActivity.zip

一、設定權限

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

如果也要限制有相機的手機才能下載這個 App ,
則改寫成下面這樣:
<manifest ... >
    <uses-feature android:name="android.hardware.camera"
                  android:required="true" />
    ...
</manifest>




二、照相

宣告一個全域變數
private static final int REQUEST_IMAGE_CAPTURE = 1;

1. 將相片存放在預設的地方

加入下面的 function
private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
    }
}
第四行判斷有沒有照相機 App ,
如果有才跳過去。

使用的時候呼叫:
dispatchTakePictureIntent();


2. 將相片存放至特定資料夾

要使用預設以外的空間,要再加上下面的權限
<manifest ...>
    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
                     android:maxSdkVersion="18" />
    ...
</manifest>

加入下面的 functions
private String mCurrentPhotoPath;

private File createImageFile() throws IOException {
    // 設定相片名稱,在這裡是用「JPEG_」加上當下的時間
    // 注意:要設定為不會重複的名稱
    String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date());
    String imageFileName = "JPEG_" + timeStamp + "_";
    // 存放到 Picture 資料夾下屬於這個 App 的公開空間
    File storageDir = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES);
    File image = File.createTempFile(
        imageFileName,  /* 檔名 */
        ".jpg",         /* 副檔名 */
        storageDir      /* 要存放的資料夾 */
    );

    // 把檔案路徑加上「file:」存下來,之後使用 ACTION_VIEW intents 時用
    mCurrentPhotoPath = "file:" + image.getAbsolutePath();
    return image;
}

private void dispatchTakePictureIntent() {
    Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
    // 判斷有沒有照相機 App
    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
        // 用上面那個 function 建立存放相片的檔案
        File photoFile = null;
        try {
            photoFile = createImageFile();
        } catch (IOException ex) {
            // Error occurred while creating the File
            ...
        }
        // 判斷檔案有沒有新建成功
        if (photoFile != null) {
            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(photoFile));
            startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
        }
    }
}

// 上面存完照片到自訂的資料夾,並不會在相簿中顯示
// 所以要做下面這個 function 讓相片顯示在相簿中
// 如果不需要顯示,則可以省略
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);
}

使用的時候呼叫:
dispatchTakePictureIntent();
galleryAddPic();


三、顯示相片或將相片資料拿回處理

加入下面的 function
@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");

        // 下面可以做任何要做的處理,這邊是顯示到一個 ImageView
        mImageView.setImageBitmap(imageBitmap);
    }
}

這邊的 mImageView 是在其他地方已經設置過的 view,
無論是
ImageView mImageView = (ImageView) findViewById(R.id.photo);
或是
ImageView mImageView = new ImageView();
皆可。


沒有留言:

張貼留言