編輯:關於Android編程
問題背景:要讓Camera循環聚焦,聚焦完成後進行拍照,在拍照的數據裡截取出一定區域的數據。在initCamera裡設置聚焦模式:
ListallFocus = myParam.getSupportedFocusModes(); for(String ff:allFocus){ Log.i(tag, ff + ...FOCUS...); } if(allFocus.contains(Camera.Parameters.FLASH_MODE_AUTO)){ myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_AUTO); Focus_Mode = 1; } else if(allFocus.contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)){ myParam.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_PICTURE); // FOCUS_MODE_CONTINUOUS_PICTURE FOCUS_MODE_AUTO Focus_Mode = 2; } myCamera.setParameters(myParam);
class GetPictureThread implements Runnable{ public void run() { // TODO Auto-generated method stub while(!Thread.currentThread().isInterrupted()){ if(myCamera != null && isPreview){ if(Focus_Mode == 1 && (!isFocusing)){ myCamera.autoFocus(mAutoFocusCallback); } else if(Focus_Mode == 2){ myCamera.takePicture(myShutterCallback, null, myJpegCallback); } try { Thread.sleep(3000); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); Thread.currentThread().interrupt(); } } } } }
12-07 18:05:33.227: D/dalvikvm(13589): threadid=11: exiting 12-07 18:05:33.227: W/dalvikvm(13589): threadid=11: thread exiting with uncaught exception (group=0x417669a8) 12-07 18:05:33.230: E/AndroidRuntime(13589): FATAL EXCEPTION: Thread-1177 12-07 18:05:33.230: E/AndroidRuntime(13589): java.lang.RuntimeException: autoFocus failed 12-07 18:05:33.230: E/AndroidRuntime(13589): at android.hardware.Camera.native_autoFocus(Native Method) 12-07 18:05:33.230: E/AndroidRuntime(13589): at android.hardware.Camera.autoFocus(Camera.java:1120) 12-07 18:05:33.230: E/AndroidRuntime(13589): at org.yanzi.rectphoto_wuzhou.RectPhoto$GetPictureThread.run(RectPhoto.java:428) 12-07 18:05:33.230: E/AndroidRuntime(13589): at java.lang.Thread.run(Thread.java:838) 12-07 18:05:33.240: I/Camera(13589): handleMessage: 2
F:.log (12 hits) Line 12829: 12-08 10:14:19.477 D/CameraClient( 142): autoFocus (pid 10314) Line 12831: 12-08 10:14:19.477 D/MtkCam/CamDevice( 142): (599)(Default:0)[CamDevice::autoFocus] + Line 12834: 12-08 10:14:19.477 D/MtkCam/CamAdapter( 142): (599)(Default)[autoFocus] + Line 12861: 12-08 10:14:19.477 D/aaa_hal ( 142): [autoFocus()] Line 12877: 12-08 10:14:19.477 D/MtkCam/CamAdapter( 142): (599)(Default)[autoFocus] - Line 20489: 12-08 10:14:20.677 D/CameraClient( 142): autoFocus (pid 10314) Line 20491: 12-08 10:14:20.677 D/MtkCam/CamDevice( 142): (142)(Default:0)[CamDevice::autoFocus] + Line 20503: 12-08 10:14:20.678 E/MtkCam/CamDevice( 142): (142)(Default:0)[CamDevice::autoFocus] preview is not enabled (autoFocus){#552:mediatek/hardware/camera/device/CamDevice/CamDevice.cpp} Line 20503: 12-08 10:14:20.678 E/MtkCam/CamDevice( 142): (142)(Default:0)[CamDevice::autoFocus] preview is not enabled (autoFocus){#552:mediatek/hardware/camera/device/CamDevice/CamDevice.cpp} Line 20512: 12-08 10:14:20.679 E/AndroidRuntime(10314): java.lang.RuntimeException: autoFocus failed Line 20514: 12-08 10:14:20.679 E/AndroidRuntime(10314): at android.hardware.Camera.native_autoFocus(Native Method) Line 20516: 12-08 10:14:20.679 E/AndroidRuntime(10314): at android.hardware.Camera.autoFocus(Camera.java:1120)可以看到,上面提到preview is not enabled,竟然說preview沒有開啟。可我明明preview已經開啟了,而且我在掃描線程裡設置了判斷if(myCamera != null && isPreview)。參考國外這位大大的帖子http://www.hitziger.net/blog/android-camera-autofocus-failed/ 上面提到auto focus失敗原因是surfaceholder還沒有被創建,換句話camera還沒有開啟預覽就進行自動聚焦了。但其實我的掃描線程啟動已經加了延遲,確保camera預覽已經開啟,姑且信了吧。把線程開啟的地方加到了surfacechanged,因為我的initcamera是在surfacechanged裡面,initcamera的最後就是startPreview。但依然出錯。我加了個延遲在surfacechanged依舊報錯。後來參考又一個人的帖子,在activity的onResume方法裡進行mySurfaceHolder.addCallback(this);確保surfaceview已經創建了再添加回調。這樣干確實嚴謹一點,但依舊報錯。事實上這樣做不是必須的,因為我把GetPictureThread去掉之後,一切ok。我加個button,拍照的時候自動聚焦,如果聚焦成功再觸發takePicture也是ok的。
問題出在哪呢?最後才恍然大悟,問題在拍照的jpegCallback上,代碼如下:
PictureCallback myJpegCallback = new PictureCallback() { public void onPictureTaken(byte[] data, Camera camera) { // TODO Auto-generated method stub Log.i(tag, myJpegCallback:onPictureTaken...); long t1 = System.currentTimeMillis(); if(null != data){ mBitmap = BitmapFactory.decodeByteArray(data, 0, data.length); myCamera.stopPreview(); isPreview = false; } Matrix matrix = new Matrix(); matrix.postRotate((float)90.0); Bitmap rotaBitmap = Bitmap.createBitmap(mBitmap, 0, 0, mBitmap.getWidth(), mBitmap.getHeight(), matrix, false); //Bitmap sizeBitmap = Bitmap.createScaledBitmap(rotaBitmap, 540, 800, true); Bitmap rectBitmap = Bitmap.createBitmap(rotaBitmap, square.left, square.top, square.width(), square.height()); if(null != rectBitmap) { saveThread.setSaveBitmap(rectBitmap); } //ImageUtil.saveJpeg(rotaBitmap); myCamera.startPreview(); isPreview = true; long t2 = System.currentTimeMillis(); Log.i(tag, 本次保存耗時: + (t2 - t1) + 毫秒); } };注意在拍照時,camera首先停止預覽保存完照片後再次開啟預覽。盡管我加了isPreview這個標志,但這個標志位是不起啥作用的。推測,stoppreviw和startpreview的時候,camera在底層是異步處理的。也就是說程序執行到startpreview,isPreview為真了,但這時camera還沒有完全開啟預覽,而掃描線程再次觸發auto focus就會報上面的錯誤。後來我對這個myJpegCallback測了下時間,完全同樣的代碼,在geek手機上是900多毫秒左右,在G700上是1800毫秒左右,將近2秒了,所以掃描周期一定得大於這個時間。後來將掃描周期設為3秒,兩個手機都ok了。但G700上偶發的也還是會報錯,這是因為內存占用太多,手機速度變慢,myJpegCallback回調的周期超過了3秒,重啟下手機就好了。在AutoFocusCallback裡設置標志isFocusing也是必須的。
final AutoFocusCallback mAutoFocusCallback = new AutoFocusCallback() { public void onAutoFocus(boolean success, Camera camera) { // TODO Auto-generated method stub isFocusing = true; if(success){ Log.i(tag, 聚焦成功...); myCamera.takePicture(myShutterCallback, null, myJpegCallback); } else{ Log.i(tag, 聚焦失敗...); } isFocusing = false; } };
輪播圖是很常用的一個效果 核心功能已經實現 沒有什麼特殊需求 自己沒事研究的 所以封裝的不太好 一些地方還比較糙 為想要研究輪播圖的同學提供個參考目前測試圖片為mipma
今天終於考完了!也該來把這篇博客寫完!不能留下空白!上一篇博客主要是介紹這個社交系統的界面和一下功能了!現在我們來看看怎麼實現這些界面或功能的!首先:我們來看看項目 的目
Android多終端適配是我們在實際開發中必然會遇到也必然要解決的問題,解決多終端適配的方法有很多,比如使用百分比布局庫(percent-support-lib)、在re
關於Dagger,在之前的博文(Android 依賴注入:Dagger 實例講解(Demo下載))中已有介紹, 本文說的Dagger 2主要是由Google