0

我正在尝试创建一个包含频闪功能的闪光灯应用程序。我已经成功实现了闪光灯开/关效果,但我遇到了频闪效果问题。每当我尝试创建频闪效果时,应用程序就会崩溃。如果我删除它,它工作正常。

我有一项活动,seekbar顶部是 a,中间是开/关开关。我想要实现的是,如果用户单击开/关按钮,如果seekbar顶部为 0,则闪光灯应打开/关闭。如果用户增加seekbar闪光灯中的值,则应开始相应地频闪,如果用户将值移回 0 手电筒应保持不变。请帮我修复错误。

日志猫

07-23 16:54:12.610: W/dalvikvm(21210): threadid=11: thread exiting with uncaught exception (group=0x40c15a68)
07-23 16:54:12.610: E/AndroidRuntime(21210): FATAL EXCEPTION: Thread-2373
07-23 16:54:12.610: E/AndroidRuntime(21210): java.lang.RuntimeException: Fail to connect to camera service
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.native_setup(Native Method)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.<init>(Camera.java:365)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at android.hardware.Camera.open(Camera.java:340)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at com.shyam.flashlight.StrobeController.run(StrobeController.java:29)
07-23 16:54:12.610: E/AndroidRuntime(21210):    at java.lang.Thread.run(Thread.java:856)

手电筒.java

public class FlashLight extends Activity {

ImageButton btnSwitch;
private Camera camera;
private boolean isFlashOn;
private boolean hasFlash;
Parameters params;
MediaPlayer mp;

StrobeController runner;
Thread bw;

@SuppressWarnings("deprecation")
@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    requestWindowFeature(Window.FEATURE_NO_TITLE);
    setContentView(R.layout.activity_flash_light);

    btnSwitch = (ImageButton) findViewById(R.id.btnSwitch);

    runner = StrobeController.getInstance();

    bw = new Thread(runner);
    bw.start();

    hasFlash = getApplicationContext().getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);

    if (!hasFlash) {
        AlertDialog alert = new AlertDialog.Builder(FlashLight.this).create();
        alert.setTitle("Error");
        alert.setMessage("Sorry, your device doesn't support flash light!");
        alert.setButton("OK", new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                finish();
            }
        });
        alert.show();
        return;
    }

    getCamera();

    toggleButtonImage();

    btnSwitch.setOnClickListener(new View.OnClickListener() {

        @Override
        public void onClick(View v) {
            /*if (isFlashOn) {
                turnOffFlash();
            } else {
                turnOnFlash();
            }*/

            if (isFlashOn) {
                bw = new Thread(runner);
                bw.start();
                isFlashOn = false;
            } else {
                isFlashOn = true;
                runner.requestStop = true;
            }

        }
    });

    final SeekBar skbar = (SeekBar) findViewById(R.id.volume_bar);
    skbar.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        @Override
        public void onStopTrackingTouch(SeekBar seekBar) { }

        @Override
        public void onStartTrackingTouch(SeekBar seekBar) { }

        @Override
        public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
            runner.delay = 101 - progress;
            runner.delayoff = 101 - progress;
        }
    });

}

private void getCamera() {
    if (camera == null) {
        try {
            camera = Camera.open();
            params = camera.getParameters();
        } catch (RuntimeException e) {
            Log.e("Camera Error. Failed to Open. Error: ", e.getMessage());
        }
    }
}

private void turnOnFlash() {
    if (!isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        playSound();

        params = camera.getParameters();
        params.setFlashMode(Parameters.FLASH_MODE_TORCH);
        camera.setParameters(params);
        camera.startPreview();
        isFlashOn = true;

        toggleButtonImage();
    }
}

private void turnOffFlash() {
    if (isFlashOn) {
        if (camera == null || params == null) {
            return;
        }

        playSound();

        params = camera.getParameters();
        params.setFlashMode(Parameters.FLASH_MODE_OFF);
        camera.setParameters(params);
        camera.stopPreview();
        isFlashOn = false;

        toggleButtonImage();
    }
}

private void playSound() {
    if (isFlashOn) {
        mp = MediaPlayer.create(FlashLight.this, R.raw.light_switch_off);
    } else {
        mp = MediaPlayer.create(FlashLight.this, R.raw.light_switch_on);
    }
    mp.setOnCompletionListener(new OnCompletionListener() {

        @Override
        public void onCompletion(MediaPlayer mp) {
            mp.release();
        }
    });
    mp.start();
}

private void toggleButtonImage() {
    if (isFlashOn) {
        btnSwitch.setImageResource(R.drawable.btn_switch_on);
    } else {
        btnSwitch.setImageResource(R.drawable.btn_switch_off);
    }
}

@Override
public void onBackPressed() {
    super.onBackPressed();

    params = camera.getParameters();
    params.setFlashMode(Parameters.FLASH_MODE_OFF);
    camera.setParameters(params);
    camera.stopPreview();
    isFlashOn = false;

    if (camera != null) {
        camera.release();
        camera = null;
    }
    Log.d("Camera", "Back Pressed");
}

}

频闪控制器.java

public class StrobeController implements Runnable {

protected StrobeController() { }

public static StrobeController getInstance() {
    return (instance == null ? instance = new StrobeController() : instance);
}

private static StrobeController instance;
public volatile boolean requestStop = false;
public volatile boolean isRunning = false;
public volatile int delay = 10;
public volatile int delayoff = 500;
public volatile String errorMessage = "";

@Override
public void run() {
    if (isRunning)
        return;

    requestStop = false;
    isRunning = true;

    Camera cam = Camera.open();

    Parameters pon = cam.getParameters(), poff = cam.getParameters();

    pon.setFlashMode(Camera.Parameters.FLASH_MODE_TORCH);
    poff.setFlashMode(Camera.Parameters.FLASH_MODE_OFF);

    while (!requestStop) {
        try {
            cam.setParameters(pon);
            Thread.sleep(delay);
            cam.setParameters(poff);
            Thread.sleep(delayoff);
        } catch (InterruptedException ex) {

        } catch (RuntimeException ex) {
            requestStop = true;
            errorMessage = "Error setting camera flash status. Your device may be unsupported.";
        }
    }

    cam.release();

    isRunning = false;
    requestStop = false;
}

}
4

1 回答 1

1

我注意到第 29 行抛出了异常:

在 com.shyam.flashlight.StrobeController.run(StrobeController.java:29)

是第 29 行Camera cam = Camera.open();吗?

您拥有此处所述的正确权限吗? 另外,您是否要打开空相机?查看 StrobeController 类中的第 29 行。

于 2013-07-23T11:34:41.613 回答