編輯:Android開發實例
這節課主要講述怎樣利用設備已安裝的其他照相應用程序來拍攝照片。
例如您想要實現一個氣象服務的APP,用來把全球的天氣圖片收集在一起,整合這些圖片只是您應用程序的一部分工作,但是您又不想編寫太復雜的代碼來自己控制相機的拍照,幸好,大多數Android設備已至少安裝有一個拍照程序,本課程就教您怎麼樣利用設備自帶的拍照應用來拍攝這些圖片。
如果您的應用的基本功能就是拍照,需要在Android Market 中進行可見性限制,只有擁有攝像頭的設備才能浏覽和下載您的應用程序,那麼您需要在manifest 文件的< uses-feature > tag中加入權限限制。
<manifest ... > <uses-feature android:name="android.hardware.camera" /> ... </manifest ... >
如果您的應用在設備沒有相機的情況下仍能正常工作,那麼可以在該tag中加入android:required=”false”。設定以後,所有的設備不管有沒有攝像頭都可以在Android Market 上面浏覽和下載您的應用。但是,您需要自己在運行時檢測設備是否有攝像頭,調用方法hasSystemFeature(PackageManager.FEATURE_CAMERA)即可,如果相機不可用,那麼您就需要禁用應用中與拍照有關的功能模塊。
在Andriod系統中,如果您的應用要委托其他的應用幫忙完成一些工作,可以使用Intent,把期望完成的任務和參數列表設置到Intent中,然後通過系統廣播出去,最後當其他應用完成工作的時候,您的應用可以收到一個反饋信息,在回調函數中就可以取得任務處理結果。調用相機程序進行拍照,過程與上面描述的類似,有三個關注點,定義拍照的 Intent,啟動其他相機應用Activity,處理拍照後的照片數據。
示例代碼,啟動拍照應用
private void dispatchTakePictureIntent(int actionCode) { Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); startActivityForResult(takePictureIntent, actionCode); }
恭喜您,通過如上的代碼就可以給您的應用加入使用設備內置應用拍照的功能,當然,如果恰巧設備中沒有安裝任何的拍照應用,那麼您的應用就有可能出錯,一個好的解決辦法是,在調用上面的代碼前首先檢查設備中是否有內置拍照應用,示例代碼如下:
public static boolean isIntentAvailable(Context context, String action) { final PackageManager packageManager = context.getPackageManager(); final Intent intent = new Intent(action); List<ResolveInfo> list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); return list.size() > 0; }
如果您的應用不僅僅是通過設備內置的拍照應用拍攝照片,還需要對照片進行進一步的變換處理,那麼您需要獲得原始照片數據,拍照應用會將編碼後的相片數據(small Bitmap )放到Intent的“data”鍵值中,然後通過回調onactivityresult()返回,如下示例代碼將返回後的照片數據顯示到 ImageView中。
private void handleSmallCameraPhoto(Intent intent) { Bundle extras = intent.getExtras(); mImageBitmap = (Bitmap) extras.get("data"); mImageView.setImageBitmap(mImageBitmap); }
注意:從Intent的“data”鍵值中取得的縮略圖數據適合作為圖標icon,如果要處理大的圖片數據,您還要做更多的工作。
如果您在指定拍照Intent的時候設置了照片的存儲路徑,那麼拍照應用就會把拍攝的照片以文件的形式保存到該路徑中,路徑要求是絕對路徑(如(存儲器名SD卡)/(路徑名)/(文件名))。
這裡有一個獲取照片路徑的簡單辦法,僅限於Android 2.2 (API level 8) 及以上。
storageDir = new File( Environment.getExternalStoragePublicDirectory( Environment.DIRECTORY_PICTURES ), getAlbumName() );
在早期的Android版本中,您必須手動指定照片的目錄
storageDir = new File ( Environment.getExternalStorageDirectory() + PICTURES_DIR + getAlbumName() );
注意:PICTURES_DIR 實際上就是 Pictures/,external/shared storage(外部/共享存儲設備) 上共享照片的標准目錄。
如上文所述,拍攝的照片會存放在一個標准的圖片目錄中,您要做的是解決圖片的命名沖突,或許您還會設置一個成員變量來保存,以便後續引用該圖片,示例如下:
private File createImageFile() throws IOException { // Create an image file name String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss").format(new Date()); String imageFileName = JPEG_FILE_PREFIX + timeStamp + "_"; File image = File.createTempFile( imageFileName, JPEG_FILE_SUFFIX, getAlbumDir() ); mCurrentPhotoPath = image.getAbsolutePath(); return image; }
一旦您選定了圖片的存儲路徑,那麼在啟動拍照應用的時候就可以通過設置Intent來傳遞給它。
File f = createImageFile(); takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(f));
通過拍照應用,您可以知道拍攝的照片具體存放在系統的什麼位置,因為這是您在Intent中指定的路徑,若想讓其他的應用也可以知道該照片的存在,那麼最好的辦法便是利於系統的媒體管理(system’s Media Provider)。
示例代碼展示了如何調用系統的媒體管理模塊(system’s media scanner),將您的照片添加到媒體數據庫(Media Provider’s database)中,這樣系統的Gallery APP和其他的APP就能訪問該照片了。
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); }
在有限的內存設備上面處理全尺寸的大圖片是一個需要關注的問題。如果您發現只顯示了幾張圖片後就內存溢出了,您可以動態地調整堆容量,把圖片縮放到界面需要展示的ImageView大小,然後映射到一個內存的JPEG數組中。 代碼示例展示了如何使用這一技術。
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); }
參考文摘:
http://developer.android.com/training/camera/photobasics.html
原文:http://blog.zhourunsheng.com/2012/01/android-%e7%9b%b8%e7%89%87%e7%ae%a1%e7%90%86%e4%b8%93%e9%a2%98%e4%b9%8b%e6%8b%8d%e7%85%a7%e5%8a%9f%e8%83%bd/ | 潤物無聲
在Android中,可以有多種方式來實現網絡編程: 創建URL,並使用URLConnection/HttpURLConnection 使用HttpClient使用
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩
登錄應用程序的屏幕,詢問憑據登錄到一些特定的應用。可能需要登錄到Facebook,微博等本章介紹了,如何創建一個登錄界面,以及如何管理安全問題和錯誤嘗試。首先,必須定義兩