Android Fragment中使用Intent組件拍照


要在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)

通常我們需要檢測的是攝像頭的這些功能:

Fragment和攝像頭Intent組件

用Android Studio打開我們的示例代碼,然后在navigation drawer中選擇“Simple Camera Intent”,你會看到如下畫面:

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文件中要求使用攝像頭,代碼如下:

 

 

(在一個Fragment中)用PackageManager在代碼中檢測設備是否含有攝像頭,代碼如下:

 

 

如果有一個或者多個攝像頭怎么辦?

在一些安卓設備上會有前置攝像頭和后置攝像頭,我們可以用PackageManager來對攝像頭進行功能檢測,例如:

 

 

通常我們需要檢測的是攝像頭的這些功能:

Fragment和攝像頭Intent組件

用Android Studio打開我們的示例代碼,然后在navigation drawer中選擇“Simple Camera Intent”,你會看到如下畫面:

camera_intent

當你選擇”Take Photo“,外部的拍照程序就會彈出來,然后我們就可以拍照了。拍照的結果會被顯示在主界面上,縮略圖也會顯示在一個小區域里。打開SimpleCameraIntentFragment.java,可以看到下面這個方法(摘錄自Google’s Simple Camera documentation):


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM