要在activity里面去接受,然后傳遞給fragment對象,fragment有很多回調調用不到
你的設備有攝像頭嗎?
為了確保市場上的大多數設備都能運行你的程序,必須在項目中做一些檢測,保證使用的設備可以執行你的代碼。
我們可以這么做:
- 在程序的配置清單文件中標明要求使用攝像頭;
- 在代碼中用
PackageManager進行設備功能檢測;
在項目的androidManifest文件中添加使用攝像頭權限
android.hardware.camera
(在一個Fragment中)用PackageManager在代碼中檢測設備是否含有攝像頭,代碼如下:
Context context = getActivity(); PackageManager packageManager = context.getPackageManager(); if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false){ Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT) .show(); return; }
如果有一個或者多個攝像頭怎么辦?
在一些安卓設備上會有前置攝像頭和后置攝像頭,我們可以用PackageManager來對攝像頭進行功能檢測,例如:
context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)
通常我們需要檢測的是攝像頭的這些功能:
- FEATURE_CAMERA_FRONT (檢測是否含有前置攝像頭)
- FEATURE_CAMERA (檢測是否含有后置攝像頭)
- FEATURE_CAMERA_ANY (檢測是否含有任意一個攝像頭)
Fragment和攝像頭Intent組件
用Android Studio打開我們的示例代碼,然后在navigation drawer中選擇“Simple Camera Intent”,你會看到如下畫面:
當你選擇”Take Photo“,外部的拍照程序就會彈出來,然后我們就可以拍照了。拍照的結果會被顯示在主界面上,縮略圖也會顯示在一個小區域里。打開SimpleCameraIntentFragment.java,可以看到下面這個方法(摘錄自Google’s Simple Camera documentation):
/** * Start the camera by dispatching a camera intent. */ protected void dispatchTakePictureIntent() { // Check if there is a camera. Context context = getActivity(); PackageManager packageManager = context.getPackageManager(); if(packageManager.hasSystemFeature(PackageManager.FEATURE_CAMERA) == false){ Toast.makeText(getActivity(), "This device does not have a camera.", Toast.LENGTH_SHORT) .show(); return; } // Camera exists? Then proceed... Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); // Ensure that there's a camera activity to handle the intent CameraActivity activity = (CameraActivity)getActivity(); if (takePictureIntent.resolveActivity(activity.getPackageManager()) != null) { // Create the File where the photo should go. // If you don't do this, you may get a crash in some devices. File photoFile = null; try { photoFile = createImageFile(); } catch (IOException ex) { // Error occurred while creating the File Toast toast = Toast.makeText(activity, "There was a problem saving the photo...", Toast.LENGTH_SHORT); toast.show(); } // Continue only if the File was successfully created if (photoFile != null) { Uri fileUri = Uri.fromFile(photoFile); activity.setCapturedImageURI(fileUri); activity.setCurrentPhotoPath(fileUri.getPath()); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, activity.getCapturedImageURI()); startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO); } } }
這里我對攝像頭的檢測並不完美,因為只是簡單判斷是否有后置攝像頭。如果用戶的設備只有一個前置攝像頭,那這種檢測就沒有什么用了。
下一步我們要從攝像頭中接收圖像數據,然后保存下來。以下就是實現的代碼,重復的部分就不一一貼出來了:
** * The activity returns with the photo. * @param requestCode * @param resultCode * @param data */ * @Override public void onActivityResult(int requestCode, int resultCode, Intent data) { if (requestCode == REQUEST_TAKE_PHOTO && resultCode == Activity.RESULT_OK) { addPhotoToGallery(); CameraActivity activity = (CameraActivity)getActivity(); // Show the full sized image. setFullImageFromFilePath(activity.getCurrentPhotoPath(), mImageView); setFullImageFromFilePath(activity.getCurrentPhotoPath(), mThumbnailImageView); } else { Toast.makeText(getActivity(), "Image Capture Failed", Toast.LENGTH_SHORT) .show(); } }
在Fragment中獲取Activity返回結果
接下來我們關注這幾行代碼:
Uri fileUri = Uri.fromFile(photoFile);
activity.setCapturedImageURI(fileUri);
activity.setCurrentPhotoPath(fileUri.getPath());
我們知道,當選擇使用(由Activity管理的)Fragment時,為了保證所有部件運行正常,需要額外處理一些Fragment限制。在某些設備上(比如三星),你必須把返回結果的圖像數據保存到一個文件中(該文件在使用Intent時需要提供)。但是當程序從照相程序中返回到前台時,這個文件就不可用了,然后程序會莫名崩潰了。
為了防止程序崩潰,我已經寫了一個特別的Activity——“CameraActivity”,可以自動保存和恢復攝像頭的數據文件和Uri數據。當程序的生命周期改變時,我們需要這些數據。
安全地獲取圖片數據
我們來看看CameraActivity,這里就不全部貼出代碼了,但是你可以看到這個Activity會在resume中保存和恢復攝像頭的數據文件和Uri數據。
private final static String CAPTURED_PHOTO_PATH_KEY = "mCurrentPhotoPath"; private final static String CAPTURED_PHOTO_URI_KEY = "mCapturedImageURI"; // Required for camera operations in order to save the image file on resume. private String mCurrentPhotoPath = null; private Uri mCapturedImageURI = null; @Override public void onSaveInstanceState(Bundle savedInstanceState) { if (mCurrentPhotoPath != null) { savedInstanceState.putString(CAPTURED_PHOTO_PATH_KEY, mCurrentPhotoPath); } if (mCapturedImageURI != null) { savedInstanceState.putString(CAPTURED_PHOTO_URI_KEY, mCapturedImageURI.toString()); } super.onSaveInstanceState(savedInstanceState); } @Override protected void onRestoreInstanceState(Bundle savedInstanceState) { if (savedInstanceState.containsKey(CAPTURED_PHOTO_PATH_KEY)) { mCurrentPhotoPath = savedInstanceState.getString(CAPTURED_PHOTO_PATH_KEY); } if (savedInstanceState.containsKey(CAPTURED_PHOTO_URI_KEY)) { mCapturedImageURI = Uri.parse(savedInstanceState.getString(CAPTURED_PHOTO_URI_KEY)); } super.onRestoreInstanceState(savedInstanceState); }
事實上我做的只是對這些需要的信息用Intent進行保存和恢復。這樣,程序就知道該從哪里找到需要引用的文件。加入沒有這些代碼,程序在onResume中會崩潰。
以上這就是關於在Fragment中怎么用攝像頭Intent組件進行拍照的簡單教程,你可以隨意使用以上所提供的源碼進行修改使用。
在安卓Fragment中使用Intent組件拍照
說明: 這篇文章主要介紹了如何在安卓Fragment中使用攝像頭拍照並保存圖像和縮略圖。
這篇文章是我的“Android Studio下用Fragment進行攝像頭開發系列文章五篇”的第一篇,如果你還沒做好准備,可以先看看我的代碼,GitHub:UltimateAndroidCameraGuide。這篇教程中也會詳細對代碼進行說明,主要參考這個文件:SimpleCameraIntentFragment.java。
在開始之前,先花點時間說明一下手機設備的功能和發布App時需要考慮的設備功能檢測問題。
你的設備有攝像頭嗎?
為了確保市場上的大多數設備都能運行你的程序,必須在項目中做一些檢測,保證使用的設備可以執行你的代碼。
我們可以這么做:
- 在程序的配置清單文件中標明要求使用攝像頭;
- 在代碼中用
PackageManager進行設備功能檢測;
在項目的androidManifest文件中要求使用攝像頭,代碼如下:
|
1
2
|
;
html
-
script
:
false
]
&
lt
;
uses
-
feature
android
:
name
=&
quot
;
android
.
hardware
.
camera
&
quot
;
android
:
required
=&
quot
;
true
&
quot
;
/
&
gt
;
|
(在一個Fragment中)用PackageManager在代碼中檢測設備是否含有攝像頭,代碼如下:
|
1
2
3
4
5
6
7
8
9
|
;
html
-
script
:
false
]
Context
context
=
getActivity
(
)
;
PackageManager
packageManager
=
context
.
getPackageManager
(
)
;
if
(
packageManager
.
hasSystemFeature
(
PackageManager
.
FEATURE_CAMERA
)
==
false
)
{
Toast
.
makeText
(
getActivity
(
)
,
"This device does not have a camera."
,
Toast
.
LENGTH_SHORT
)
.
show
(
)
;
return
;
}
|
如果有一個或者多個攝像頭怎么辦?
在一些安卓設備上會有前置攝像頭和后置攝像頭,我們可以用PackageManager來對攝像頭進行功能檢測,例如:
|
1
2
|
;
html
-
script
:
false
]
context
.
getPackageManager
(
)
.
hasSystemFeature
(
PackageManager
.
FEATURE_CAMERA
)
|
通常我們需要檢測的是攝像頭的這些功能:
- FEATURE_CAMERA_FRONT (檢測是否含有前置攝像頭)
- FEATURE_CAMERA (檢測是否含有后置攝像頭)
- FEATURE_CAMERA_ANY (檢測是否含有任意一個攝像頭)
Fragment和攝像頭Intent組件
用Android Studio打開我們的示例代碼,然后在navigation drawer中選擇“Simple Camera Intent”,你會看到如下畫面:
當你選擇”Take Photo“,外部的拍照程序就會彈出來,然后我們就可以拍照了。拍照的結果會被顯示在主界面上,縮略圖也會顯示在一個小區域里。打開SimpleCameraIntentFragment.java,可以看到下面這個方法(摘錄自Google’s Simple Camera documentation):



