0

我一直在写一个简单的闪光灯应用程序,它有一个开/关切换按钮。应用程序启动,我点击“开”按钮,闪光灯一直亮着,直到我点击“关”按钮,但如果我再次点击“开”按钮,闪光灯不亮,我不能找出原因。

这是一个简单的应用程序,代码如下:

package com.redcricket.flashlife;

import java.io.IOException;
import java.util.Collection;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.os.Bundle;
import android.util.Log;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.widget.CompoundButton;
import android.widget.Toast;
import android.widget.ToggleButton;

public class FlashlightActivity extends Activity implements
            SurfaceHolder.Callback {

    private static String TAG = "flashlight";
    private ToggleButton toggleButton1;
    boolean cameraOpened;
    private boolean hasSurface;
    static Camera cam = null;

    @Override
    public void onPause() {
            Log.i(TAG, "[32] onPause()");
            super.onPause();
            if (cam != null) {
                    Log.i("flashlight", "[35] onPause() cam not null. Calling stopPreview and release cam. Setting cam to null.");
                    cam.stopPreview();
                    cam.release();
                    cam = null;
            }
    }

    public void turnFlashOn() {
            Log.i(TAG, "[42] turnFlashOn()");
            if (cam == null) {
                    cam = Camera.open();
                    Log.i(TAG, "[64] turnFlashOn() cam was null. Camera.open() called");
            }
            if (cam != null) {
                    Log.i(TAG, "[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).");
                    setDesiredCameraParameters(cam);
                    Log.i(TAG, "[69] turnFlashOn() before startPreview");
                    /*
                     * step 6
                     * http://developer.android.com/reference/android/hardware/Camera.html
                     */
                    cam.startPreview();
                    Log.i(TAG,"[75] turnFlashOn() after startPreview");
                    cam.autoFocus(new AutoFocusCallback() {
                            public void onAutoFocus(boolean success, Camera camera) {
                                    if (success) {
                                            Log.i(TAG,
                                                            "[80] turnFlashOn() onAutoFocus success = true");
                                    } else {
                                            Log.i(TAG,
                                                            "[83] turnFlashOn() onAutoFocus success = false");
                                    }
                            }
                    });
                    //Log.i(TAG,"[69] turnFlashOn() after cam.autoFocus TAKEPIC");
                    //cam.takePicture(null, null, null, null);
            }
    }

    void setDesiredCameraParameters(Camera camera) {
            Camera.Parameters parameters = camera.getParameters();
            Log.i("flashlight",
                            "[77] FlashlightActivity.java setDestiredVcmaeria paramers");
            if (parameters == null) {
                    Log.w(TAG,
                                    "Device error: no camera parameters are available. Proceeding without configuration.");
                    return;
            }

            Log.i(TAG, "[84] Initial camera parameters: " + parameters.flatten());

            // SharedPreferences prefs =
            // PreferenceManager.getDefaultSharedPreferences(context);

            initializeTorch(parameters);
            camera.setParameters(parameters);
    }

    private void initializeTorch(Camera.Parameters parameters) {
            Log.i(TAG, "[95] initializeTorch()");
            doSetTorch(parameters);
    }

    private void doSetTorch(Camera.Parameters parameters) {
            Log.i(TAG, "[100] dosetTorch()");
            String flashMode;

            flashMode = findSettableValue(parameters.getSupportedFlashModes(),
                            Camera.Parameters.FLASH_MODE_TORCH);
            Log.i(TAG, "[104] doSetTorch() flashmode is " + flashMode);
            // ,
            // Camera.Parameters.FLASH_MODE_ON,
            // Camera.Parameters.FOCUS_MODE_INFINITY);
            if (flashMode != null) {
                    Log.i(TAG, "[109] openDriver() called parameters.setFlashMode( " + flashMode + ")");
                    parameters.setFlashMode(flashMode);
            }

    }

    private static String findSettableValue(Collection<String> supportedValues,
                    String... desiredValues) {
            Log.i(TAG, "[117] findSettableValue() Supported values: " + supportedValues);
            String result = null;
            if (supportedValues != null) {
                    for (String desiredValue : desiredValues) {
                            if (supportedValues.contains(desiredValue)) {
                                    result = desiredValue;
                                    Log.i("flashlight", "[123] findSettableValue() result set to : " + desiredValue);
                                    break;
                            }
                    }
            }
            Log.i("flashlight", "[128] findSettableValue() Settable value: " + result);
            return result;
    }

    public void turnFlashOff() {
            Log.i("flashlight", "[133] turnFlashOff()");
            if (cam != null) {
                    Log.i("flashlight", "[135] turnFlashOff() cam is not null.");
                    cam.stopPreview();
                    cam.release();
                    cam = null;
            }
    }

    public void addListenerOnButton() {
            Log.i("flashlight", "[143] addListenerOnButton()");
            toggleButton1 = (ToggleButton) findViewById(R.id.toggleButton1);
            toggleButton1.setOnCheckedChangeListener(
                            new CompoundButton.OnCheckedChangeListener() {
                                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
                                            Log.i("flashlight", "[148] onCheckedChanged() isChecked = " + isChecked);
                                            if (isChecked) {
                                                    turnFlashOn();
                                            } else {
                                                    turnFlashOff();
                                            }
                                    }
                            });
    }

    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
            Log.i(TAG, "[163] onCreate() hasSurface is " + hasSurface );
            super.onCreate(savedInstanceState);
            setContentView(R.layout.main);

            SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
            SurfaceHolder surfaceHolder = surfaceView.getHolder();

            if (hasSurface) {
                    // The activity was paused but not stopped, so the surface still
                    // exists. Therefore
                    // surfaceCreated() won't be called, so init the camera here.
                    Log.i(TAG, "[174] onCreate() calling initCamera() hasSurface is " + hasSurface );
                    initCamera(surfaceHolder);
            } else {
                    Log.i(TAG, "[177] does not have surface, so install callback and wait for surfaceCreated() to init the camera");
                    // Install the callback and wait for surfaceCreated() to init the
                    // camera.
                    surfaceHolder.addCallback(this);
                    surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
            }

            if (this.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH)) {
                    cam = Camera.open();
                    Log.i(TAG, "[202] onCreate(). Camera.open() called");
                    addListenerOnButton();
            } else {
                    Toast.makeText(getApplicationContext(),
                                    "This device does not have flash bulb.\nExitting.", 60)
                                    .show();
            }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
            Log.i(TAG, "[196] surfaceCreated() hasSurface is " + hasSurface );
            if (holder == null) {
                    Log.e(TAG,
                                    "*** WARNING *** surfaceCreated() gave us a null surface!");
            }
            if (!hasSurface) {
                    hasSurface = true;
                    Log.i("flashlight", "[201] surfaceCreated() set hasSurface to true.");
                    initCamera(holder);
            }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
            Log.i("flashlight", "[209] surfaceDestroyed()");
            hasSurface = false;
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
            Log.i("flashlight", "[216] surfaceChanged(holder,format,width,height)");
    }

    @Override
    protected void onDestroy() {
            Log.i("flashlight", "[220] onDestroy()");
            try {
                    cam.stopPreview();
                    cam.setPreviewCallback(null);
                    try {
                            cam.release();
                    } catch (Exception e) {
                    }
                    cam = null;
            } catch (Exception e) {
            }
            super.onDestroy();
    }

    /* new stuff */
    private void initCamera(SurfaceHolder surfaceHolder) {
            Log.i(TAG, "[236] initCamera() trying to call openDriver(holder)");

            try {
                    openDriver(surfaceHolder);
            } catch (Exception e) {
                    e.printStackTrace();
            }
    }

    /**
     * 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 synchronized void openDriver(SurfaceHolder holder)
                    throws IOException {
            Log.i(TAG, "[256] openDriver() top");

            Camera theCamera = cam;
            if (theCamera == null) {
                    Log.i(TAG, "[278] openDriver()");
                    theCamera = Camera.open();
                    Log.i(TAG, "[280] openDriver() Camera.open() called");
                    if (theCamera == null) {
                            Log.i(TAG, "[263] openDriver()");
                            throw new IOException();
                    }
                    cam = theCamera;
            }
            /*
             * do this as per
             * http://developer.android.com/reference/android/hardware/Camera.html
             * step 5
             */
            Log.i(TAG, "[281] openDriver() calling setPreviewDisplay(holder)");
            theCamera.setPreviewDisplay(holder);
    }

    public synchronized boolean isOpen() {
            return cam != null;
    }

    /**
     * Closes the camera driver if still in use.
     */
    public synchronized void closeDriver() {
            Log.i(TAG, "[285] closeDriver()");
            if (cam != null) {
                    cam.release();
                    cam = null;
            }
    }

    /* end new stuff */
}

这是我的评论内联的logcat:

[163] onCreate() hasSurface is false
[177] does not have surface, so install callback and wait for surfaceCreated() to init the camera
[202] onCreate(). Camera.open() called
[143] addListenerOnButton()
[196] surfaceCreated() hasSurface is false
[201] surfaceCreated() set hasSurface to true.
[236] initCamera() trying to call openDriver(holder)
[256] openDriver() top
[281] openDriver() calling setPreviewDisplay(holder)
[216] surfaceChanged(holder,format,width,height)
[148] onCheckedChanged() isChecked = true
[42] turnFlashOn()
[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84] Initial camera parameters: very long line
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue() Supported values: [off, on, auto, torch]
[123] findSettableValue() result set to : torch
[128] findSettableValue() Settable value: torch
[104] doSetTorch() flashmode is torch
[109] openDriver() called parameters.setFlashMode( torch)
[69] turnFlashOn() before startPreview
[75] turnFlashOn() after startPreview
[80] turnFlashOn() onAutoFocus success = true

欢呼!灯亮了!所以我点击关闭按钮。

[148] onCheckedChanged() isChecked = false
[133] turnFlashOff()
[135] turnFlashOff() cam is not null.

欢呼!灯熄灭。所以现在我点击打开按钮。

[148] onCheckedChanged() isChecked = true
[42] turnFlashOn()
[64] turnFlashOn() cam was null. Camera.open() called
[67] turnFlashOn() cam nit null. calling setDesiredCameraParameters(cam).
[77] FlashlightActivity.java setDestiredVcmaeria paramers
[84] Initial camera parameters: very long line
[95] initializeTorch()
[100] dosetTorch()
[117] findSettableValue() Supported values: [off, on, auto, torch]
[123] findSettableValue() result set to : torch
[128] findSettableValue() Settable value: torch
[104] doSetTorch() flashmode is torch
[109] openDriver() called parameters.setFlashMode( torch)
[69] turnFlashOn() before startPreview
[75] turnFlashOn() after startPreview

嘘!无光 :(

[148] onCheckedChanged() isChecked = false
[133] turnFlashOff()
[135] turnFlashOff() cam is not null.
[32] onPause()
[209] surfaceDestroyed()
4

1 回答 1

0

啊! 它现在正在工作。我不得不像这样修改我的 turnFlashOn() 方法:

public void turnFlashOn() {
    Log.i(TAG, "[42] turnFlashOn()");
    if (cam == null) {
            Log.i(TAG, "turnFlashOn() step 1");
            cam = Camera.open();
            Log.i(TAG, "[64] turnFlashOn() cam was null. Camera.open() called");
            /* new stuff */
            SurfaceView surfaceView = (SurfaceView) findViewById(R.id.preview_view);
            SurfaceHolder surfaceHolder = surfaceView.getHolder();
            Log.i(TAG, "[174] turnFlashOn() calling initCamera(surfaceHolder) hasSurface is " + hasSurface );
            initCamera(surfaceHolder);
            /* end new stuff */
    }
于 2013-01-24T08:01:18.333 回答