00001 /* 00002 * Copyright (C) 2012 ZXing authors 00003 * Copyright 2012 Robert Theis 00004 * Copyright 2012 Jaime Navarro Santapau 00005 * 00006 * Licensed under the Apache License, Version 2.0 (the "License"); 00007 * you may not use this file except in compliance with the License. 00008 * You may obtain a copy of the License at 00009 * 00010 * http://www.apache.org/licenses/LICENSE-2.0 00011 * 00012 * Unless required by applicable law or agreed to in writing, software 00013 * distributed under the License is distributed on an "AS IS" BASIS, 00014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00015 * See the License for the specific language governing permissions and 00016 * limitations under the License. 00017 */ 00018 00026 package edu.uoc.ocr.camera; 00027 00028 import android.content.Context; 00029 import android.content.SharedPreferences; 00030 import android.hardware.Camera; 00031 import android.preference.PreferenceManager; 00032 import android.util.Log; 00033 import edu.uoc.ocr.PreferencesActivity; 00034 00035 import java.util.ArrayList; 00036 import java.util.Collection; 00037 import java.util.Timer; 00038 import java.util.TimerTask; 00039 00044 public final class AutoFocusManager implements Camera.AutoFocusCallback { 00045 00046 private static final String TAG = AutoFocusManager.class.getSimpleName(); 00047 00048 private static final long AUTO_FOCUS_INTERVAL_MS = 3500L; 00049 private static final Collection<String> FOCUS_MODES_CALLING_AF; 00050 static { 00051 FOCUS_MODES_CALLING_AF = new ArrayList<String>(2); 00052 FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO); 00053 FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO); 00054 } 00055 00056 private boolean active; 00057 private boolean manual; 00058 private final boolean useAutoFocus; 00059 private final Camera camera; 00060 private final Timer timer; 00061 private TimerTask outstandingTask; 00062 00063 AutoFocusManager(Context context, Camera camera) { 00064 this.camera = camera; 00065 timer = new Timer(true); 00066 SharedPreferences sharedPrefs = PreferenceManager 00067 .getDefaultSharedPreferences(context); 00068 String currentFocusMode = camera.getParameters().getFocusMode(); 00069 useAutoFocus = sharedPrefs.getBoolean( 00070 PreferencesActivity.KEY_AUTO_FOCUS, true) 00071 && FOCUS_MODES_CALLING_AF.contains(currentFocusMode); 00072 Log.i(TAG, "Current focus mode '" + currentFocusMode 00073 + "'; use auto focus? " + useAutoFocus); 00074 manual = false; 00075 checkAndStart(); 00076 } 00077 00078 @Override 00079 public synchronized void onAutoFocus(boolean success, Camera theCamera) { 00080 if (active && !manual) { 00081 outstandingTask = new TimerTask() { 00082 @Override 00083 public void run() { 00084 checkAndStart(); 00085 } 00086 }; 00087 timer.schedule(outstandingTask, AUTO_FOCUS_INTERVAL_MS); 00088 } 00089 manual = false; 00090 } 00091 00092 void checkAndStart() { 00093 if (useAutoFocus) { 00094 active = true; 00095 start(); 00096 } 00097 } 00098 00099 synchronized void start() { 00100 try { 00101 camera.autoFocus(this); 00102 } catch (RuntimeException re) { 00103 // Have heard RuntimeException reported in Android 4.0.x+; continue? 00104 Log.w(TAG, "Unexpected exception while focusing", re); 00105 } 00106 } 00107 00113 synchronized void start(long delay) { 00114 outstandingTask = new TimerTask() { 00115 @Override 00116 public void run() { 00117 manual = true; 00118 start(); 00119 } 00120 }; 00121 timer.schedule(outstandingTask, delay); 00122 } 00123 00124 synchronized void stop() { 00125 if (useAutoFocus) { 00126 camera.cancelAutoFocus(); 00127 } 00128 if (outstandingTask != null) { 00129 outstandingTask.cancel(); 00130 outstandingTask = null; 00131 } 00132 active = false; 00133 manual = false; 00134 } 00135 00136 }