2012-11-12 141 views
2

這是我再次發佈的條形碼掃描儀的源代碼。我編輯了我的代碼。問題是,當我運行應用程序,閃光燈不會自動打開。我在清單文件中添加了權限,但閃光燈未打開。請幫助我,問題在哪裏?我正在使用HTC wIldfire的手機。閃光燈未打開

public final class CameraManager { 

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

private static final int MIN_FRAME_WIDTH = 240; 
private static final int MIN_FRAME_HEIGHT = 240; 
private static final int MAX_FRAME_WIDTH = 480; 
private static final int MAX_FRAME_HEIGHT = 360; 

private static CameraManager cameraManager; 

static final int SDK_INT; // Later we can use Build.VERSION.SDK_INT 
static { 
    int sdkInt; 
    try { 
sdkInt = Integer.parseInt(Build.VERSION.SDK); 
} catch (NumberFormatException nfe) { 
// Just to be safe 
sdkInt = 10000; 
} 
SDK_INT = sdkInt; 
    } 

private final Context context; 
private Camera camera; 
    private Rect framingRect; 
private Rect framingRectInPreview; 
private boolean initialized; 
private boolean previewing; 
    /** 
* Preview frames are delivered here, which we pass on to the registered handler. 
    Make 
sure to 
    * clear the handler so it will only receive one message. 
*/ 
    private final PreviewCallback previewCallback; 
    /** Autofocus callbacks arrive here, and are dispatched to the Handler which 
    requested them. */ 
    private final AutoFocusCallback autoFocusCallback; 

    /** 
    * Initializes this static object with the Context of the calling Activity. 
    * 
    * @param context The Activity which wants to use the camera. 
    */ 
    public static void init(Context context) { 
    if (cameraManager == null) { 
    cameraManager = new CameraManager(context); 
    } 
    } 

     /** 
    * Gets the CameraManager singleton instance. 
    * 
    * @return A reference to the CameraManager singleton. 
    */ 
public static CameraManager get() { 
    return cameraManager; 
    } 

private CameraManager(Context context) { 

this.context = context; 
this.configManager = new CameraConfigurationManager(context); 

// Camera.setOneShotPreviewCallback() has a race condition in Cupcake, so we use the 
    older 
    // Camera.setPreviewCallback() on 1.5 and earlier. For Donut and later, we need to 
    \  use 
    // the more efficient one shot callback, as the older one can swamp the system and 
    cause it 
// to run out of memory. We can't use SDK_INT because it was introduced in the 
    Donut 
    SDK. 
//useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 
Build.VERSION_CODES.CUPCAKE; 
    useOneShotPreviewCallback = Integer.parseInt(Build.VERSION.SDK) > 3; // 3 = Cupcake 

previewCallback = new PreviewCallback(configManager, useOneShotPreviewCallback); 
autoFocusCallback = new AutoFocusCallback(); 
} 

/** 
* Opens the camera driver and initializes the hardware parameters. 
* 
* @param holder The surface object which the camera will draw preview frames into. 
* @throws IOException Indicates the camera driver failed to open. 
*/ 
public void openDriver(SurfaceHolder holder) throws IOException { 
if (camera == null) { 
camera = Camera.open(); 
if (camera == null) { 
throw new IOException(); 
} 
camera.setPreviewDisplay(holder); 

    if (!initialized) { 
    initialized = true; 
    configManager.initFromCameraParameters(camera); 
    } 
configManager.setDesiredCameraParameters(camera); 

    PreferenceManager.getDefaultSharedPreferences(context); 
//ÊÇ·ñʹÓÃÇ°µÆ 

//  if (prefs.getBoolean(PreferencesActivity.KEY_FRONT_LIGHT, false)) { 
    //  FlashlightManager.enableFlashlight(); 
    //  } 
    FlashlightManager.enableFlashlight(); 
    } 
} 

/** 
* Closes the camera driver if still in use. 
    */ 
    public void closeDriver() { 
    if (camera != null) { 
FlashlightManager.disableFlashlight(); 
camera.release(); 
camera = null; 
} 
} 

    /** 
    * Asks the camera hardware to begin drawing preview frames to the screen. 
    */ 
public void startPreview() { 
    if (camera != null && !previewing) { 
camera.startPreview(); 
previewing = true; 
    } 
    } 

/** 
    * Tells the camera to stop drawing preview frames. 
    */ 
    public void stopPreview() { 
    if (camera != null && previewing) { 
if (!useOneShotPreviewCallback) { 
camera.setPreviewCallback(null); 
} 
camera.stopPreview(); 
previewCallback.setHandler(null, 0); 
autoFocusCallback.setHandler(null, 0); 
previewing = false; 
} 
    } 

/** 
* A single preview frame will be returned to the handler supplied. The data will 
arrive as byte[] 
* in the message.obj field, with width and height encoded as message.arg1 and 
message.arg2, 
* respectively. 
* 
* @param handler The handler to send the message to. 
* @param message The what field of the message to be sent. 
*/ 
public void requestPreviewFrame(Handler handler, int message) { 
if (camera != null && previewing) { 
previewCallback.setHandler(handler, message); 
if (useOneShotPreviewCallback) { 
camera.setOneShotPreviewCallback(previewCallback); 
} else { 
    camera.setPreviewCallback(previewCallback); 
} 
} 
} 

/** 
* Asks the camera hardware to perform an autofocus. 
* 
* @param handler The Handler to notify when the autofocus completes. 
* @param message The message to deliver. 
*/ 
    public void requestAutoFocus(Handler handler, int message) { 
    if (camera != null && previewing) { 
autoFocusCallback.setHandler(handler, message); 
    //Log.d(TAG, "Requesting auto-focus callback"); 
camera.autoFocus(autoFocusCallback); 
} 
} 

/** 
* Calculates the framing rect which the UI should draw to show the user where to 
    place the 
* barcode. This target helps with alignment as well as forces the user to hold the 
device 
* far enough away to ensure the image will be in focus. 
* 
* @return The rectangle to draw on screen in window coordinates. 
*/ 
public Rect getFramingRect() { 
Point screenResolution = configManager.getScreenResolution(); 
if (framingRect == null) { 
if (camera == null) { 
    return null; 
} 
int width = screenResolution.x * 3/4; 
if (width < MIN_FRAME_WIDTH) { 
width = MIN_FRAME_WIDTH; 
} else if (width > MAX_FRAME_WIDTH) { 
width = MAX_FRAME_WIDTH; 
} 
    int height = screenResolution.y * 3/4; 
if (height < MIN_FRAME_HEIGHT) { 
height = MIN_FRAME_HEIGHT; 
} else if (height > MAX_FRAME_HEIGHT) { 
height = MAX_FRAME_HEIGHT; 
} 
int leftOffset = (screenResolution.x - width)/2; 
int topOffset = (screenResolution.y - height)/2; 
framingRect = new Rect(leftOffset, topOffset, leftOffset + width, topOffset + 
height); 
Log.d(TAG, "Calculated framing rect: " + framingRect); 
} 
    return framingRect; 
} 

    /** 
    * Like {@link #getFramingRect} but coordinates are in terms of the preview frame, 
* not UI/screen. 
*/ 
public Rect getFramingRectInPreview() { 
if (framingRectInPreview == null) { 
Rect rect = new Rect(getFramingRect()); 
Point cameraResolution = configManager.getCameraResolution(); 
Point screenResolution = configManager.getScreenResolution(); 
rect.left = rect.left * cameraResolution.x/screenResolution.x; 
rect.right = rect.right * cameraResolution.x/screenResolution.x; 
rect.top = rect.top * cameraResolution.y/screenResolution.y; 
rect.bottom = rect.bottom * cameraResolution.y/screenResolution.y; 
framingRectInPreview = rect; 
} 
    return framingRectInPreview; 
    } 










final class FlashlightManager { 

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

    private static final Object iHardwareService; 
private static final Method setFlashEnabledMethod; 
static { 
iHardwareService = getHardwareService(); 
    setFlashEnabledMethod = getSetFlashEnabledMethod(iHardwareService); 
if (iHardwareService == null) { 
Log.v(TAG, "This device does supports control of a flashlight"); 
    } else { 
Log.v(TAG, "This device does not support control of a flashlight"); 
} 
} 

    private FlashlightManager() { 
    } 

private static Object getHardwareService() { 
Class<?> serviceManagerClass = maybeForName("android.os.ServiceManager"); 
    if (serviceManagerClass == null) { 
return null; 
    } 

Method getServiceMethod = maybeGetMethod(serviceManagerClass, "getService", 
String.class); 
if (getServiceMethod == null) { 
return null; 
    } 

Object hardwareService = invoke(getServiceMethod, null, "hardware"); 
if (hardwareService == null) { 
return null; 
} 

Class<?> iHardwareServiceStubClass = maybeForName("android.os.IHardwareService$Stub"); 
if (iHardwareServiceStubClass == null) { 
return null; 
} 

Method asInterfaceMethod = maybeGetMethod(iHardwareServiceStubClass, "asInterface", 
IBinder.class); 
if (asInterfaceMethod == null) { 
return null; 
} 

return invoke(asInterfaceMethod, null, hardwareService); 
} 

    private static Method getSetFlashEnabledMethod(Object iHardwareService) { 
    if (iHardwareService == null) { 
return null; 
} 
    Class<?> proxyClass = iHardwareService.getClass(); 
return maybeGetMethod(proxyClass, "setFlashlightEnabled", boolean.class); 
} 

private static Class<?> maybeForName(String name) { 
try { 
return Class.forName(name); 
} catch (ClassNotFoundException cnfe) { 
// OK 
return null; 
} catch (RuntimeException re) { 
Log.w(TAG, "Unexpected error while finding class " + name, re); 
return null; 
} 
} 

private static Method maybeGetMethod(Class<?> clazz, String name, Class<?>... 
argClasses) { 
try { 
return clazz.getMethod(name, argClasses); 
} catch (NoSuchMethodException nsme) { 
// OK 
return null; 
} catch (RuntimeException re) { 
Log.w(TAG, "Unexpected error while finding method " + name, re); 
return null; 
    } 
    } 

private static Object invoke(Method method, Object instance, Object... args) { 
    try { 
return method.invoke(instance, args); 
} catch (IllegalAccessException e) { 
Log.w(TAG, "Unexpected error while invoking " + method, e); 
return null; 
} catch (InvocationTargetException e) { 
Log.w(TAG, "Unexpected error while invoking " + method, e.getCause()); 
return null; 
} catch (RuntimeException re) { 
Log.w(TAG, "Unexpected error while invoking " + method, re); 
return null; 
    } 
} 

static void enableFlashlight() { 
setFlashlight(true); 
} 

static void disableFlashlight() { 
setFlashlight(false); 
} 

private static void setFlashlight(boolean active) { 
    if (iHardwareService != null) { 
    invoke(setFlashEnabledMethod, iHardwareService, active); 
} 
} 

} 

package com.zijunlin.Zxing.Demo.camera; 

import android.content.Context; 
import android.graphics.Point; 
import android.hardware.Camera; 
    import android.os.Build; 
import android.util.Log; 
    import android.view.Display; 
    import android.view.WindowManager; 

import java.util.regex.Pattern; 

    final class CameraConfigurationManager { 

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

private static final int TEN_DESIRED_ZOOM = 27; 
    private static final int DESIRED_SHARPNESS = 30; 

private static final Pattern COMMA_PATTERN = Pattern.compile(","); 

private final Context context; 
private Point screenResolution; 
private Point cameraResolution; 
    private int previewFormat; 
    private String previewFormatString; 

    CameraConfigurationManager(Context context) { 
this.context = context; 
} 

/** 
* Reads, one time, values from the camera that are needed by the app. 
*/ 
void initFromCameraParameters(Camera camera) { 
Camera.Parameters parameters = camera.getParameters(); 
previewFormat = parameters.getPreviewFormat(); 
    previewFormatString = parameters.get("preview-format"); 
Log.d(TAG, "Default preview format: " + previewFormat + '/' + previewFormatString); 
WindowManager manager = (WindowManager) 
context.getSystemService(Context.WINDOW_SERVICE); 
Display display = manager.getDefaultDisplay(); 
screenResolution = new Point(display.getWidth(), display.getHeight()); 
    Log.d(TAG, "Screen resolution: " + screenResolution); 
    cameraResolution = getCameraResolution(parameters, screenResolution); 
Log.d(TAG, "Camera resolution: " + screenResolution); 
    } 

    /** 
* Sets the camera up to take preview images which are used for both preview and 
decoding. 
    * We detect the preview format here so that buildLuminanceSource() can build an 
    appropriate 
* LuminanceSource subclass. In the future we may want to force YUV420SP as it's the 
    smallest, 
    * and the planar Y can be used for barcode scanning without a copy in some cases. 
    */ 
    void setDesiredCameraParameters(Camera camera) { 
    Camera.Parameters parameters = camera.getParameters(); 
    Log.d(TAG, "Setting preview size: " + cameraResolution); 
    parameters.setPreviewSize(cameraResolution.x, cameraResolution.y); 
    setFlash(parameters); 
    setZoom(parameters); 
    //setSharpness(parameters); 
    camera.setParameters(parameters); 
    } 

Point getCameraResolution() { 
return cameraResolution; 
    } 

Point getScreenResolution() { 
return screenResolution; 
} 

int getPreviewFormat() { 
return previewFormat; 
    } 

String getPreviewFormatString() { 
return previewFormatString; 
    } 

    private static Point getCameraResolution(Camera.Parameters parameters, Point 
    screenResolution) { 

    String previewSizeValueString = parameters.get("preview-size-values"); 
    // saw this on Xperia 
    if (previewSizeValueString == null) { 
    previewSizeValueString = parameters.get("preview-size-value"); 
    } 

    Point cameraResolution = null; 

    if (previewSizeValueString != null) { 
Log.d(TAG, "preview-size-values parameter: " + previewSizeValueString); 
    cameraResolution = findBestPreviewSizeValue(previewSizeValueString, 
screenResolution); 
    } 

    if (cameraResolution == null) { 
// Ensure that the camera resolution is a multiple of 8, as the screen may not be. 
    cameraResolution = new Point(
    (screenResolution.x >> 3) << 3, 
    (screenResolution.y >> 3) << 3); 
    } 

    return cameraResolution; 
    } 

    private static Point findBestPreviewSizeValue(CharSequence previewSizeValueString, 
Point screenResolution) { 
int bestX = 0; 
int bestY = 0; 
int diff = Integer.MAX_VALUE; 
    for (String previewSize : COMMA_PATTERN.split(previewSizeValueString)) { 

    previewSize = previewSize.trim(); 
int dimPosition = previewSize.indexOf('x'); 
if (dimPosition < 0) { 
    Log.w(TAG, "Bad preview-size: " + previewSize); 
    continue; 
    } 

    int newX; 
    int newY; 
    try { 
    newX = Integer.parseInt(previewSize.substring(0, dimPosition)); 
newY = Integer.parseInt(previewSize.substring(dimPosition + 1)); 
    } catch (NumberFormatException nfe) { 
Log.w(TAG, "Bad preview-size: " + previewSize); 
continue; 
    } 

    int newDiff = Math.abs(newX - screenResolution.x) + Math.abs(newY - 
    screenResolution.y); 
    if (newDiff == 0) { 
bestX = newX; 
bestY = newY; 
break; 
} else if (newDiff < diff) { 
bestX = newX; 
bestY = newY; 
diff = newDiff; 
    } 

} 

if (bestX > 0 && bestY > 0) { 
    return new Point(bestX, bestY); 
} 
    return null; 
    } 

    private static int findBestMotZoomValue(CharSequence stringValues, int 
    tenDesiredZoom) { 
int tenBestValue = 0; 
for (String stringValue : COMMA_PATTERN.split(stringValues)) { 
stringValue = stringValue.trim(); 
    double value; 
try { 
value = Double.parseDouble(stringValue); 
} catch (NumberFormatException nfe) { 
return tenDesiredZoom; 
} 
    int tenValue = (int) (10.0 * value); 
    if (Math.abs(tenDesiredZoom - value) < Math.abs(tenDesiredZoom - tenBestValue)) { 
    tenBestValue = tenValue; 
    } 
    } 
    return tenBestValue; 
    } 

    private void setFlash(Camera.Parameters parameters) { 
// FIXME: This is a hack to turn the flash off on the Samsung Galaxy. 
// And this is a hack-hack to work around a different value on the Behold II 
// Restrict Behold II check to Cupcake, per Samsung's advice 
//if (Build.MODEL.contains("Behold II") && 
    // CameraManager.SDK_INT == Build.VERSION_CODES.CUPCAKE) { 
if (Build.MODEL.contains("Behold II") && CameraManager.SDK_INT == 3) { // 3 = Cupcake 
parameters.set("flash-value", 1); 
} else { 
parameters.set("flash-value", 2); 
} 
    // This is the standard setting to turn the flash off that all devices should honor. 
parameters.set("flash-mode", "off"); 
    } 

private void setZoom(Camera.Parameters parameters) { 

String zoomSupportedString = parameters.get("zoom-supported"); 
    if (zoomSupportedString != null && !Boolean.parseBoolean(zoomSupportedString)) { 
    return; 
    } 

    int tenDesiredZoom = TEN_DESIRED_ZOOM; 

String maxZoomString = parameters.get("max-zoom"); 
if (maxZoomString != null) { 
try { 
int tenMaxZoom = (int) (10.0 * Double.parseDouble(maxZoomString)); 
if (tenDesiredZoom > tenMaxZoom) { 
    tenDesiredZoom = tenMaxZoom; 
} 
} catch (NumberFormatException nfe) { 
Log.w(TAG, "Bad max-zoom: " + maxZoomString); 
} 
} 

String takingPictureZoomMaxString = parameters.get("taking-picture-zoom-max"); 
    if (takingPictureZoomMaxString != null) { 
try { 
int tenMaxZoom = Integer.parseInt(takingPictureZoomMaxString); 
if (tenDesiredZoom > tenMaxZoom) { 
    tenDesiredZoom = tenMaxZoom; 
} 
} catch (NumberFormatException nfe) { 
Log.w(TAG, "Bad taking-picture-zoom-max: " + takingPictureZoomMaxString); 
    } 
} 

String motZoomValuesString = parameters.get("mot-zoom-values"); 
if (motZoomValuesString != null) { 
tenDesiredZoom = findBestMotZoomValue(motZoomValuesString, tenDesiredZoom); 
} 

String motZoomStepString = parameters.get("mot-zoom-step"); 
if (motZoomStepString != null) { 
    try { 
double motZoomStep = Double.parseDouble(motZoomStepString.trim()); 
int tenZoomStep = (int) (10.0 * motZoomStep); 
if (tenZoomStep > 1) { 
    tenDesiredZoom -= tenDesiredZoom % tenZoomStep; 
    } 
    } catch (NumberFormatException nfe) { 
// continue 
    } 
} 

// Set zoom. This helps encourage the user to pull back. 
// Some devices like the Behold have a zoom parameter 
    if (maxZoomString != null || motZoomValuesString != null) { 
    parameters.set("zoom", String.valueOf(tenDesiredZoom/10.0)); 
} 
    // Most devices, like the Hero, appear to expose this zoom parameter. 
// It takes on values like "27" which appears to mean 2.7x zoom 
    if (takingPictureZoomMaxString != null) { 
parameters.set("taking-picture-zoom", tenDesiredZoom); 
} 
} 

/* 
    private void setSharpness(Camera.Parameters parameters) { 

int desiredSharpness = DESIRED_SHARPNESS; 

String maxSharpnessString = parameters.get("sharpness-max"); 
if (maxSharpnessString != null) { 
    try { 
int maxSharpness = Integer.parseInt(maxSharpnessString); 
    if (desiredSharpness > maxSharpness) { 
    desiredSharpness = maxSharpness; 
    } 
    } catch (NumberFormatException nfe) { 
    Log.w(TAG, "Bad sharpness-max: " + maxSharpnessString); 
} 
    } 

parameters.set("sharpness", desiredSharpness); 
    } 
*/ 
    } 

<uses-permission android:name="android.permission.CAMERA"></uses-permission> 
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses- 
    permission> 
<uses-feature android:name="android.hardware.camera" /> 
<uses-feature android:name="android.hardware.camera.autofocus" /> 
<uses-permission android:name="android.permission.VIBRATE"/> 
<uses-permission android:name="android.permission.FLASHLIGHT"/> 
<uses-permission android:name="android.permission.INTERNET" /> 
+0

你說這是你的代碼,但是這明顯是從zxing的舊版本複製的。 –

+0

肖恩,很明顯OP不是母語,所以你可以給出「我的源代碼」的懷疑的好處(OP可能意味着「我使用的源代碼」?) – ataulm

回答