簡體   English   中英

摘要:使用Camera Intent拍攝照片並以正確的方向顯示照片(希望所有設備都可以使用)

[英]Summary: Take a picture utilizing Camera Intent and display the photo with correct orientation (works on hopefully all devices)

這似乎是世界上最簡單的事情:使用默認的相機活動在Android應用中拍照。 但是,StackOverflow和Web上的幾個帖子中都有許多陷阱,例如,Null Intents被傳回,圖片的方向不正確或OutOfMemoryErrors。

我正在尋找一個允許我的解決方案

  1. 通過相機意圖啟動相機活動,
  2. 檢索照片的Uri,和
  3. 檢索照片的正確方向。

而且,我想盡可能避免設備配置(制造商,型號,操作系統版本)的具體實現。 所以我想知道:實現這一目標的最佳方法是什么?

更新:2014年1月2日:我努力避免基於設備制造商實施不同的策略。 不幸的是,我沒有繞過它。 通過數百個帖子並與幾個開發人員交談,沒有人找到適用於所有設備的解決方案,而無需實現設備制造商特定的代碼。

在StackOverflow上發布我的解決方案之后,一些開發人員讓我在github上發布我的代碼。 所以現在就是: github上的AndroidCameraUtil

該代碼已在各種Android API級別> = 8的設備上成功測試。有關完整列表,請參閱github上的自述文件。

CameraIntentHelperActivity提供主要功能,下面還將對其進行更詳細的描述。

調用默認的相機活動:

  • 對於三星和索尼設備 :我通過調用startActivityForResult的方法調用相機活動。 我只設置了常量CAPTURE_IMAGE_ACTIVITY_REQUEST_CODE。 我沒有設置任何其他意圖的額外內容。
  • 對於所有其他設備 :我使用方法調用startActivityForResult調用相機活動,如前所述。 然而,這一次,我另外設置了額外的MediaStore.EXTRA_OUTPUT,並提供了一個URI,我想要存儲圖像。

在這兩種情況下,我都記得相機活動開始的時間。


關於相機活動結果:

  1. Mediastore:首先,我嘗試閱讀從MediaStore中捕獲的照片。 在MediaStore內容上使用mangedQuery,我檢索正在拍攝的最新圖像,以及它的orientation屬性和時間戳。 如果我找到一個圖像並且在調用相機意圖之前沒有拍攝,那就是我正在尋找的圖像。 否則,我會忽略結果並嘗試以下方法之一。
  2. 意圖額外:其次,我嘗試從返回意圖的intent.getData()獲取圖像Uri。 如果這也不成功,我繼續第3步。
  3. 默認照片Uri :如果上述所有步驟都不起作用,我會使用我傳遞給相機活動的圖像Uri。

此時,我檢索了照片Uri及其傳遞給我的UploadPhotoActivity的方向。


圖像處理

請仔細查看我的BitmapHelper類。 它基於該教程中詳細描述的代碼。

此外,如果需要,shrinkBitmap方法還會根據先前提取的方向信息旋轉圖像。


我希望這對你們中的一些人有所幫助。

我用Sony Xperia Go,三星Galaxy SII,三星Galaxy SIII mini和三星Galaxy Y測試了這個代碼,它適用於所有設備!

但是在LG E400(2.3.6)上它沒有用,你在畫廊中得到了雙張圖片。 所以我在void startCameraIntent()中添加了manufacturer.contains(“lge”)並修復了問題。

if(!(manufacturer.contains("samsung")) && !(manufacturer.contains("sony")) && !(manufacturer.contains("lge"))) {
    String filename = System.currentTimeMillis() + ".jpg";
    ContentValues values = new ContentValues();
    values.put(MediaStore.Images.Media.TITLE, filename);
    cameraPicUri = getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
    intent.putExtra(MediaStore.EXTRA_OUTPUT, cameraPicUri);
}

在帶有CM 10.1的Galaxy S3上,我在BitmapHelper中得到一個nullpointer異常:

bm = BitmapFactory.decodeFileDescriptor(fileDescriptor.getFileDescriptor(),null,options);

隨后我的UploadPhotoActivity失敗了:

  try { photo = BitmapHelper.readBitmap(this, cameraPicUri); if (photo != null) { photo = BitmapHelper.shrinkBitmap(photo, 600, rotateXDegrees); thumbnail = BitmapHelper.shrinkBitmap(photo, 100); ImageView imageView = (ImageView) findViewById(R.id.sustainable_action_photo); imageView.setImageBitmap(photo); } else { Log.e(TAG,"IMAGE ERROR 1"); } } catch (Exception e) { Log.e(TAG,"IMAGE ERROR 2"); e.printStackTrace(); } 

在第二個日志(IMAGE ERROR 2)。 經過幾次嘗試,我的相機壞了,我得到了“無法連接相機” - 恐怖。

在nexus 7上測試它,它完美地工作。

編輯:將其縮小到這個:

fileDescriptor = context.getContentResolver()。openAssetFileDescriptor(selectedImage,“r”);

雖然selectedImage包含:

文件:///storage/emulated/0/DCIM/Camera/IMG_20131023_183343.jpg

fileDescriptor返回FileNotFoundException。 我檢查了文件系統,圖像未保存在此位置。 TakePhotoActivity中的cameraPicUri指向不存在的圖像。 我目前正在檢查一切都出錯了。

編輯2:我發現錯誤:由於該設備是三星,並告訴應用程序它是一個三星設備,您的三星特定修復程序已應用。 Cyanogenmod雖然不需要那些修復,但最終代碼中斷了。 一旦你刪除

(manufacturer.contains(“samsung”))&&

有用。 由於這是一個自定義ROM,你當然無法計划。 我試圖找出一種方法來檢測設備是否正在運行cyanogenmod,然后將其包含在您的代碼中。

謝謝你一個漂亮的相機修復!

編輯3: 我修改它以在Galaxy S3上的Cyanogenmod上運行,將代碼更改為: 嗯,現在它有時可以工作,有時它不會。 奇怪。

if(getPackageManager()。hasSystemFeature(“com.cyanogenmod.android”)||(!(manufacturer.contains(“samsung”))&&!(manufacturer.contains(“sony”))&&!(manufacturer.contains(“ LGE“))))

使用Sony Xperia Z5時遇到一些問題。

我添加了這個,它變得更好了。

if (buildType.contains("sony")&& buildDevice.contains("e5823")) {
                setPreDefinedCameraUri = true;}

但是22次中有4次它重新啟動了相機並且重啟了兩次。 由於每次測試我都重新啟動了應用程序。 有沒有辦法繞過這個或我接受這個結果?

問題是,如果相機重新啟動,我可以按兩次后退按鈕並進行操作,圖像就在我的Imageview中並保存

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM