編輯:關於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;
}
};
簡單實現android輪播圖
輪播圖是很常用的一個效果 核心功能已經實現 沒有什麼特殊需求 自己沒事研究的 所以封裝的不太好 一些地方還比較糙 為想要研究輪播圖的同學提供個參考目前測試圖片為mipma
Android社交系統----代碼結構
今天終於考完了!也該來把這篇博客寫完!不能留下空白!上一篇博客主要是介紹這個社交系統的界面和一下功能了!現在我們來看看怎麼實現這些界面或功能的!首先:我們來看看項目 的目
Android項目研發之多分辨率適配
Android多終端適配是我們在實際開發中必然會遇到也必然要解決的問題,解決多終端適配的方法有很多,比如使用百分比布局庫(percent-support-lib)、在re
Android 依賴注入: Dagger 2 實例講解(一)
關於Dagger,在之前的博文(Android 依賴注入:Dagger 實例講解(Demo下載))中已有介紹, 本文說的Dagger 2主要是由Google