0

我在 Android 上使用 Mezzofanti OSR 开源,但我被卡住了。当我在应用程序中按下相机按钮时,应用程序突然崩溃。这是 CameraManeger.java 代码:

package com.itwizard.mezzofanti;

import java.io.IOException;
import android.content.Context;
import android.content.Intent;
import android.graphics.Point;
import android.graphics.Rect;
import android.hardware.Camera;
import android.net.Uri;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.Display;
import android.view.SurfaceHolder;
import android.view.WindowManager;

final class CameraManager {
private static final String TAG = "MLOG: CameraManager.java: ";

private static byte m_cImgDivisor = 2; // given the limited memory space, we
                                        // cannot allocate memory for all
                                        // the image
                                        // thus we lower a bit the
                                        // resolution by a factor of 2/4

private static CameraManager m_CameraManager; // the camera manager itself
private Camera m_Camera; // the camera
private final Context m_Context; // screen context
private Point m_ptScreenResolution; // the screen resolution
private Rect m_FramingRect; // the framing rectangle
private boolean m_bInitialized; // is the driver initialized
private boolean m_bPreviewing; // is camera in preview mode
private Handler m_ParentMessageHandler; // the parent's message handler
private SurfaceHolder m_ParentSurfaceHolder = null; // the parent's surface
                                                    // holder

/**
 * called when jpeg-image ready, just send to the parent handler the whole
 * image to be processed
 */
Camera.PictureCallback m_PictureCallbackJPG = new Camera.PictureCallback() {
    public void onPictureTaken(byte[] data, Camera c) {

    Log.i(TAG, "pcjpg - started");
    Mezzofanti.CompareTime(TAG + "just started picture callback");
    if (data == null) {
    Log.i(TAG, "data is null");
    } else {
    Message message = m_ParentMessageHandler.obtainMessage(
                R.id.cameramanager_requestpicture, data);
    message.sendToTarget();
    m_ParentMessageHandler = null;
    Log.i(TAG, "pcjpg - finish");
    m_Camera.startPreview();
    Mezzofanti.CompareTime(TAG + "just sent picture to handler");
        }

    }
      };

/**
 * save the parent handler, in order to process the image-request
 */
public void RequestPicture(Handler handler) {
    if (m_Camera != null && m_bPreviewing) {
        m_ParentMessageHandler = handler;
    }
}

/**
 * called on autofocus
 */
private Camera.AutoFocusCallback m_AutoFocusCallback = new Camera.AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
if (success) {
Log.v(TAG, " Focus succeded.");
m_ParentMessageHandler
                    .sendEmptyMessage(R.id.cameramanager_focus_succeded);
} else {
Log.v(TAG, " Focus failed.");
m_ParentMessageHandler
                    .sendEmptyMessage(R.id.cameramanager_focus_failed);
        }
    }
};

/**
 * Save the parent message handler.
 * 
 * @param handler
 *            parent message handler
 */
public void RequestCameraFocus(Handler handler) {
    if (m_Camera != null && m_bPreviewing)
        m_ParentMessageHandler = handler;
}

/**
 * Allocate the camera manager
 */
public static void Initialize(Context context) {
    if (m_CameraManager == null) {
        m_CameraManager = new CameraManager(context);
    }
}

/**
 * set the local image divisor
 */
public static void SetImgDivisor(int imgDivisor) {
if (imgDivisor != 1 && imgDivisor != 2 && imgDivisor != 4)
m_cImgDivisor = (byte) 2;
else
m_cImgDivisor = (byte) imgDivisor;
}

/**
 * Retrieve the private camera manager
 */
public static CameraManager get() {
    return m_CameraManager;
}

/**
 * constructor
 */
private CameraManager(Context context) {
m_Context = context;
GetScreenResolution();
m_Camera = null;
m_bInitialized = false;
m_bPreviewing = false;
}

/**
 * set the parent surface holder
 */
public void SetSurfaceHolder(SurfaceHolder holder) {
m_ParentSurfaceHolder = holder;
}

/**
 * open the camera driver, using the saved parent-surface-holder
 * 
 * @return a boolean variable indicating if the open-driver procedure
 *         succeeded
 */
public boolean OpenDriver() {
if (m_ParentSurfaceHolder == null)
return false;


if (m_Camera == null) {
m_Camera = Camera.open();
try {
m_Camera.setPreviewDisplay(m_ParentSurfaceHolder);
} catch (IOException e) {
Log.v(TAG, e.toString());
return false;
}

if (!m_bInitialized) {
m_bInitialized = true;
GetScreenResolution();
}

SetCameraParameters();
}
return true;
}

/**
 * open camera driver using a parameter surface-holder
 * 
 * @return a boolean variable indicating if the open-driver procedure
 *         succeeded
 */
public void OpenDriver(SurfaceHolder holder) {
if (m_Camera == null) {
m_Camera = Camera.open();
try {
m_Camera.setPreviewDisplay(holder);
} catch (IOException e) {
m_Camera.release();
m_Camera = null;
Log.v(TAG, e.toString());
}

if (!m_bInitialized) {
m_bInitialized = true;
GetScreenResolution();
}

SetCameraParameters();

    }
}

/**
 * close the camera driver
 */
public void CloseDriver() {
if (m_Camera != null) {
m_Camera.release();
m_Camera = null;
m_ParentSurfaceHolder = null;
}
}

/**
 * start camera preview mode
 */
public void StartPreview() {
if (m_Camera != null && !m_bPreviewing) {
m_Camera.startPreview();
m_bPreviewing = true;
}
}

/**
 * stop camera preview mode
 */
public void StopPreview() {
if (m_Camera != null && m_bPreviewing) {
m_Camera.setPreviewCallback(null);
m_Camera.stopPreview();
m_bPreviewing = false;
    }
}

/**
 * set the camera auto-focus callback
 */
public void RequestAutoFocus() {
if (m_Camera != null && m_bPreviewing) {
m_Camera.autoFocus(m_AutoFocusCallback);
}
}

/**
 * Calculates the framing rect which the UI should draw to show the user
 * where to place the text. The actual captured image should be a bit larger
 * than indicated because they might frame the shot too tightly. 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(boolean linemode) {
int border = 10;
if (linemode)
m_FramingRect = new Rect(m_ptScreenResolution.x / 4,
m_ptScreenResolution.y / 2 - 20,
m_ptScreenResolution.x * 3 / 4,
m_ptScreenResolution.y / 2 + 20);
else
m_FramingRect = new Rect(border, border, m_ptScreenResolution.x
                - border, m_ptScreenResolution.y - border - 30);

return m_FramingRect;
}

/**
 * take a picture, and set the jpg callback
 */
public void GetPicture() {
    m_Camera.takePicture(null, null, m_PictureCallbackJPG);
}

/**
 * Sets the camera up to take preview images which are used for both preview
 * and decoding.
 */
public void SetCameraParameters() {
if (m_ptScreenResolution == null)
        return;
Camera.Parameters parameters = m_Camera.getParameters();
parameters.setPreviewSize(m_ptScreenResolution.x,
            m_ptScreenResolution.y);
parameters.setPictureSize(2048 / m_cImgDivisor, 1536 / m_cImgDivisor);
m_Camera.setParameters(parameters);
Log.v(TAG, parameters.flatten());
}

/**
 * @return the screen resolution
 */
private Point GetScreenResolution() {
if (m_ptScreenResolution == null) {
WindowManager manager = (WindowManager) m_Context
                .getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
m_ptScreenResolution = new Point(display.getWidth(),
display.getHeight());
}
return m_ptScreenResolution;
}

}

这是日志猫:

10-09 20:19:23.551: V/MLOG: Mezzofonti.java:(11728): Call startCamera.
10-09 20:19:23.576: V/MLOG: Mezzofonti.java:(11728): InitCamera: start
10-09 20:19:23.576: V/MLOG: Mezzofonti.java:(11728): InitCamera: OpenDriver
10-09 20:19:23.806: V/MLOG: CameraManager.java:(11728): preferred-preview-size-for-video=640x480;zoom=0;max-num-detected-faces-hw=0;zoom-supported=true;whitebalance=auto;scene-mode=auto;jpeg-quality=100;preview-format-values=yuv420sp,yuv420p,yuv422i-yuyv,yuv422sp,rgb565;jpeg-thumbnail-quality=100;preview-format=yuv420sp;video-size-values=720x480,176x144,320x240,352x288,640x480,1280x720,1920x1080;preview-size=800x480;focal-length=4.030000;flash-mode-values=off,auto,on,torch;preview-frame-rate-values=30,25,20,15,10,7;preview-frame-rate=30;focus-mode-values=auto,infinity,macro,fixed,facedetect,continuous-video;jpeg-thumbnail-width=320;video-size=720x480;scene-mode-values=auto,portrait,landscape,night,beach,snow,sunset,fireworks,sports,party,candlelight,dusk-dawn,fall-color,back-light,text;preview-fps-range-values=(7000,30000);jpeg-thumbnail-size-values=320x240,400x240,0x0;zoom-ratios=100,102,104,109,111,113,119,121,124,131,134,138,146,150,155,159,165,170,182,189,200,213,222,232,243,255,283,300,319,364,400;preview-size-values=640x480,720x480,800x480,800x450,352x288,320x240,176x144;picture-size-values=3264x2448,3264x1968,2048x1536,2048x1232,800x480,640x480;preview-fps-range=7000,30000;auto-whitebalance-lock=false;min-exposure-compensation=-4;max-num-focus-areas=1;vertical-view-angle=47.1;horizontal-view-angle=60.5;jpeg-thumbnail-height=240;smooth-zoom-supported=false;focus-mode=auto;video-frame-format=yuv420sp;max-num-detected-faces-sw=3;picture-format-values=jpeg;max-exposure-compensation=4;focus-areas=(0,0,0,0,0);exposure-compensation=0;exposure-compensation-step=0.5;flash-mode=off;auto-exposure-lock=false;effect-values=none,mono,negative,sepia,aqua;picture-size=1024x768;max-zoom=30;effect=none;whitebalance-values=auto,incandescent,fluorescent,daylight,cloudy-daylight;picture-format=jpeg;focus-distances=0.15,1.20,Infinity
10-09 20:19:23.811: V/MLOG: Mezzofonti.java:(11728): InitCamera: StartPreview
10-09 20:19:24.116: V/MLOG: Mezzofonti.java:(11728): InitCamera: end
10-09 20:19:24.121: V/MLOG: Mezzofonti.java:(11728): InitCamera: start
10-09 20:19:24.121: V/MLOG: Mezzofonti.java:(11728): InitCamera: OpenDriver
10-09 20:19:24.121: V/MLOG: Mezzofonti.java:(11728): InitCamera: StartPreview
10-09 20:19:24.121: V/MLOG: Mezzofonti.java:(11728): InitCamera: end
10-09 20:19:32.771: V/MLOG: Mezzofonti.java:(11728): CameraButton OnClick
10-09 20:19:32.771: D/AndroidRuntime(11728): Shutting down VM
10-09 20:19:32.771: W/dalvikvm(11728): threadid=1: thread exiting with uncaught exception (group=0x40c5f1f8)
10-09 20:19:32.781: E/AndroidRuntime(11728): FATAL EXCEPTION: main
10-09 20:19:32.781: E/AndroidRuntime(11728): java.lang.NullPointerException
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.itwizard.mezzofanti.Mezzofanti.RequestCameraFocus(Mezzofanti.java:544)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.itwizard.mezzofanti.Mezzofanti.access$22(Mezzofanti.java:542)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.itwizard.mezzofanti.Mezzofanti$4.onClick(Mezzofanti.java:177)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.view.View.performClick(View.java:3591)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.view.View$PerformClick.run(View.java:14263)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.os.Handler.handleCallback(Handler.java:605)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.os.Handler.dispatchMessage(Handler.java:92)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.os.Looper.loop(Looper.java:137)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at android.app.ActivityThread.main(ActivityThread.java:4507)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at java.lang.reflect.Method.invokeNative(Native Method)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at java.lang.reflect.Method.invoke(Method.java:511)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:790)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:557)
10-09 20:19:32.781: E/AndroidRuntime(11728):    at dalvik.system.NativeStart.main(Native Method)
10-09 20:22:25.481: D/dalvikvm(11728): GC_CONCURRENT freed 82K, 3% free 10105K/10311K, paused 7ms+8ms
10-09 20:22:28.836: I/Process(11728): Sending signal. PID: 11728 SIG: 9
4

2 回答 2

1

您正在使用的变量尚未在RequestCameraFocus()方法中 Mezzofanti.java 文件的第 577 行初始化。这就是您收到 NullPointerException 的原因。logcat 中的这两行说明了一切:

10-09 20:19:32.781: E/AndroidRuntime(11728): java.lang.NullPointerException
10-09 20:19:32.781: E/AndroidRuntime(11728):    at com.itwizard.mezzofanti.Mezzofanti.RequestCameraFocus(Mezzofanti.java:544)

请检查该行并查看是否所有变量都已初始化。如果您需要更多帮助,请发布该文件的代码。

于 2012-10-10T06:24:10.133 回答
0

检查您是否在清单中授予了相机权限

<uses-permission android:name="android.permission.CAMERA" />
  <uses-feature android:name="android.hardware.camera" />
于 2012-10-10T06:17:17.147 回答