亚洲免费在线-亚洲免费在线播放-亚洲免费在线观看-亚洲免费在线观看视频-亚洲免费在线看-亚洲免费在线视频

【Android Developers Training】 48. 輕松拍攝

系統 2609 0

注:本文翻譯自Google官方的Android Developers Training文檔,譯者技術一般,由于喜愛安卓而產生了翻譯的念頭,純屬個人興趣愛好。

原文鏈接: http://developer.android.com/training/camera/photobasics.html


這節課將展示如何使用已經存在的相機應用拍攝相機。

假設你現在在實現一個基于人群的氣象服務,它構建一個全球的氣象地圖,通過將運行了你的應用色設備所拍攝的天空照片拼接起來來實現這個氣象地圖。整合照片只是你的應用的一小部分。你希望通過最簡單地方式拍攝照片,而不是需要重新構造一個相機。大多數Android設備其實已經至少有了一個相機應用。在這節課中,你將學習如何利用它來為您拍攝一個照片。


一). 請求相機權限

如果你的應用中一個重要的函數會拍攝照片,同時限制只有那些擁有相機的設備可以在Google Play上下載。為了聲明你的應用依賴于一個相機,在你的清單文件中放置一個 <uses-feature> 標簽:

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

                  android:required
      
      
        ="true"
      
      
        />
      
      
        

    ...


      
      
        </
      
      
        manifest
      
      
        >
      
    

如果你的應用使用,但并不依賴一個相機來執行功能,那么將“ android:required ”設置為“ false ”。這樣的話,那么Google Play將會允許沒有相機的設備下載你的應用。那么接下來就是你的責任在運行時如果調用了需要用相機的函數時, 通過調用 hasSystemFeature(PackageManager.FEATURE_CAMERA) 檢查是否可以獲取相機。如果相機無法獲取,那么你就應該禁止你的相關功能特性。


二). 使用相機應用拍攝照片

在Android中向其它應用分發意圖是通過激活一個描述你的意圖的 Intent 。這一過程分為三步: Intent 自身,調用外部 Activity ,當焦點回到你的activity中處理圖像數據的一些代碼。

下面的代碼是構造一個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的組件。執行這個檢查時很重要的因為如果你調用了 startActivityForResult() 并使用一個沒有一個應用可以處理的 intent ,你的應用將會崩潰。所以只要結果不是 null,那么使用這個intent是安全的。


三). 獲取縮略圖

如果簡單地獲取照片不是你的應用的終極目標,那么你可能希望從相機應用收回圖像并做一些事情。

Android相機應用在 onActivityResult() 中傳遞的 Intent 內,將照片編碼并作為一個小的位圖( Bitmap )在“ extras ”,在鍵“ 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);

    }

}
      
    

Note:

這個來自“ data ”的縮略圖用作圖標hi非常好的,但是如果用作更大的圖片就不行了。處理全尺寸的圖片需要更多操作。


四). 保存全尺寸照片

如果你提供了一個存儲文件的地方,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 字段來表明該權限聲明只對低版本有效:

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

                     android:maxSdkVersion
      
      
        ="18"
      
      
        />
      
      
        

    ...


      
      
        </
      
      
        manifest
      
      
        >
      
    

Note:

你存儲在由 getExternalFilesDir() 所提供的目錄內的文件,將會在用戶刪除你的應用時一起被刪除。

一旦你決定了文件存儲的目錄,你需要創建一個不容易重名的文件名。你可能也希望在成員變量中存儲路徑名,以備今后使用。這里是一個方法的例子,它通過時間戳為一個新照片返回一個唯一的文件名:

      
        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
      
       in 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
      
      
        ) {

            takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT,

                    Uri.fromFile(photoFile));

            startActivityForResult(takePictureIntent, REQUEST_TAKE_PHOTO);

        }

    }

}
      
    

五). 將照片添加至圖庫:

當你通過一個intent創建了一個照片,你應該知道照片放置在哪里,因為你指定了它需要存儲在哪里。對其他任何應用來說,可能最簡單的讓你照片可訪問的方法就是讓它可被系統的媒體提供程序( Media Provider )可被訪問。

Note:

如果你把文件存儲在了由 getExternalFilesDir() 提供的路徑,那么此時媒體掃描器

下面的方法證明了如何激活系統的媒體掃描器將你的照片添加至照片提供程序的數據庫,使它對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);

}
      
    

六). 解碼縮放圖像

管理多個全尺寸圖像對于有限的存儲空間來說是很復雜的。如果你發現你的應用在顯示了幾幅圖片后就用盡了存儲,那么你可以通過將JPEG延展到一個記憶數組里面,它將圖片縮放至目標View的尺寸,這樣可以大幅減小使用的動態堆內存。下面的代碼展示了這一技術:

      
        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 Developers Training】 48. 輕松拍攝照片


更多文章、技術交流、商務合作、聯系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!??!

發表我的評論
最新評論 總共0條評論
主站蜘蛛池模板: 欧美刺激午夜性久久久久久久 | 亚洲欧美日本国产综合在线 | 亚洲国产综合自在线另类 | 一区二区三区不卡免费视频97 | 狠狠色丁香久久综合五月 | 亚洲欧美一区二区三区麻豆 | sihu永久在线播放地址 | 黄页网址大全免费观看美女 | 国产精品久久久久久久久免费观看 | 日本免费人成黄页网观看视频 | 久久亚洲精品中文字幕第一区 | 亚洲欧洲视频 | 天天舔天天射 | 成人a毛片免费全部播放 | 日本免费不卡在线一区二区三区 | 精品成人免费一区二区在线播放 | 曰本亚洲欧洲色a在线 | 精品一区二区三区在线视频 | 在线观看国产欧美 | 婷婷久久综合 | 国产欧美亚洲三区久在线观看 | 久久不射网 | 午夜毛片在线观看 | 天天操天天射天天爽 | 国产亚洲欧美另类久久久 | 色婷婷精品 | 国产日产欧美精品一区二区三区 | 日本高清视频www夜色资源 | 日本在线精品视频 | 亚洲产在线精品第一站不卡 | 亚洲国产成人久久99精品 | 亚洲精品成人 | 国产精品98福利小视频 | 日韩欧美中文在线 | 91免费国产高清观看 | 奇米777在线观看 | 久久国产大片 | 国产成人不卡亚洲精品91 | 久久99精品一级毛片 | 国产观看精品一区二区三区 | 成人午夜在线 |