0

I am using ZXing Barcode Scanner library in my app and I'm experiencing the following bug: camera auto focus works only if the device is plugged to the charger. As soon as I unplug the device, the camera stops continious auto focusing, but once the device is plugged again, auto focusing immidiately resumes (image focuses every 2000 milliseconds). The battery of the test device is fully charged.

It should be noted that the sample code from XZing works properly, but since I am using some part of it in my app, I am experiencing the above-mentioned issue.

Here is the code of AutoFocusManager class:

/*Copyright (C) 2012 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.myapp.utils.barcode.camera;

import android.content.Context;
import android.content.SharedPreferences;
import android.hardware.Camera;
import android.os.AsyncTask;
import android.preference.PreferenceManager;
import android.util.Log;

import java.util.ArrayList;
import java.util.Collection;

import com.myapp.utils.barcode.main.PreferencesActivity;
import com.myapp.utils.barcode.common.executor.AsyncTaskExecInterface;
import com.myapp.utils.barcode.common.executor.AsyncTaskExecManager;

final class AutoFocusManager implements Camera.AutoFocusCallback {

  private static final String TAG = AutoFocusManager.class.getSimpleName();

  private static final long AUTO_FOCUS_INTERVAL_MS = 2000L;
  private static final Collection<String> FOCUS_MODES_CALLING_AF;
  static {
    FOCUS_MODES_CALLING_AF = new ArrayList<String>(2);
    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_AUTO);
    FOCUS_MODES_CALLING_AF.add(Camera.Parameters.FOCUS_MODE_MACRO);
  }

  private boolean active;
  private final boolean useAutoFocus;
  private final Camera camera;
  private AutoFocusTask outstandingTask;
  private final AsyncTaskExecInterface taskExec;

  AutoFocusManager(Context context, Camera camera) {
    this.camera = camera;
    taskExec = new AsyncTaskExecManager().build();
    SharedPreferences sharedPrefs = PreferenceManager.getDefaultSharedPreferences(context);
    String currentFocusMode = camera.getParameters().getFocusMode();
    useAutoFocus =
        sharedPrefs.getBoolean(PreferencesActivity.KEY_AUTO_FOCUS, true) &&
        FOCUS_MODES_CALLING_AF.contains(currentFocusMode);
    Log.i(TAG, "Current focus mode '" + currentFocusMode + "'; use auto focus? " + useAutoFocus);
    start();
  }

  @Override
  public synchronized void onAutoFocus(boolean success, Camera theCamera) {
    if (active) {
      outstandingTask = new AutoFocusTask();
      taskExec.execute(outstandingTask);
    }
  }

  synchronized void start() {
    if (useAutoFocus) {
      active = true;
      try {
        camera.autoFocus(this);
      } catch (RuntimeException re) {
        // Have heard RuntimeException reported in Android 4.0.x+; continue?
        Log.w(TAG, "Unexpected exception while focusing", re);
      }
    }
  }

  synchronized void stop() {
    if (useAutoFocus) {
      try {
        camera.cancelAutoFocus();
      } catch (RuntimeException re) {
        // Have heard RuntimeException reported in Android 4.0.x+; continue?
        Log.w(TAG, "Unexpected exception while cancelling focusing", re);
      }
    }
    if (outstandingTask != null) {
      outstandingTask.cancel(true);
      outstandingTask = null;
    }
    active = false;
  }

  private final class AutoFocusTask extends AsyncTask<Object,Object,Object> {
    @Override
    protected Object doInBackground(Object... voids) {
      try {
        Thread.sleep(AUTO_FOCUS_INTERVAL_MS);
      } catch (InterruptedException e) {
        // continue
      }
      synchronized (AutoFocusManager.this) {
        if (active) {
          start();
        }
      }
      return null;
    }
  }
}

When the device is connected to debugger, the LogCat shows the following:

03-07 23:37:14.624: I/AutoFocusManager(2296): Current focus mode 'auto'; use auto focus? true

Test device is HTC sensation, OS - Cyanogenmod 10 (Android 4.1.2).

Do you have any suggestions what can be the reason of such a behaviour?

Thank you.

Evgeny M
  • 77
  • 1
  • 8
  • if you start with the device unplugged before attempting to scan does it still not autofocus? Or is this only when it starts plugged in, and then gets unplugged while the camera is working? – FoamyGuy Mar 07 '13 at 22:51
  • The auto focus works only if the power cable is plugged in. So, if I start scanning with the device unplugged, focusing doesn't work. When I connect the power cable, it starts working as planned (once per 2 seconds), but it stops as soon as I unplug the cable. The same behaviour is if it starts plugged in. So, is seems that plugging the power supply cable plays a role of trigger here..My suggestion was that the device goes into another state and some options for camera become unavailable..How do you think, is it possible? But on the other hand, the original code works properly.. Thank you. – Evgeny M Mar 07 '13 at 23:10
  • 1
    I have no idea really, I would say your assessment of it seems plausible, Sounds to me like a weird quirk with your specific device and/or ROM – FoamyGuy Mar 08 '13 at 01:09
  • I have just tested it on HTC Desire HD and Samsung Galaxy Note 2 (stock version) and the issue remains.. – Evgeny M Mar 08 '13 at 13:07
  • does behave this way if you use the stock Barcode Scanner appliction as downloaded from the market? – FoamyGuy Mar 08 '13 at 14:10
  • No, that's what surprises me. The app from Google Play works well. The code from ZXing project repo also works well, but the same code integrated in the app I'm working on shows above-described glitch. I have just tried to use WiFi ADB to see what happens if the cable is unplugged. So, the value of autoFocus is true. Now trying to trace it deeper.. – Evgeny M Mar 09 '13 at 11:42
  • It turned out that AsyncTask almost never works if the device is not connected to power supply..Is it possible that something interrupts it? – Evgeny M Mar 09 '13 at 16:41
  • AsyncTask stucks in PreExecute stage. Sometimes, it goes far, but I can't track the event that stops the execution and continues it. – Evgeny M Mar 09 '13 at 17:26
  • You should integrate barcode scanning via intent like the ZXing authors intended then. This is exactly the sort of thing that you are saving yourself from dealing with if you integrated via intents with Barcode Scanner =). This is in fact why the intent model is so awesome, and is built so deeply into the Android framework. – FoamyGuy Mar 09 '13 at 21:37

1 Answers1

0

Similar happened to me too with zxing 2.1

autoFocusThread X: AF fail

on Samsung Galaxy (GT-P6200) with android 4.0.4, and Sonyericcson Xperia Neo / android 4.0.4.

Error did not occur with ZXing 2.0. You can download release 2.0 from here.

Try it, I hope solve your autofocus issue too.

balage
  • 71
  • 1
  • 2