2013-07-23 55 views
0

我想创建一个包含频闪功能的闪光灯应用程序。我已经成功实现了闪光灯开/关效果,但是我频闪效果遇到了麻烦。每当我尝试创建选通效果时,应用程序都会崩溃。如果我删除它,它工作正常。如何创建闪光灯以及闪光灯效果。需要帮助来解决频闪效应

我有一个活动,顶部有seekbar,中央有开关。我想要实现的是,如果用户点击开/关按钮,如果顶部的seekbar为0,则闪光灯应当开启/关闭。如果用户增加seekbar中的值,则闪光灯应该开始相应地选通并且如果用户将该值移回0,则手电筒应保持不变。请帮我解决这个错误。

LOG CAT

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) 

FlashLight.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"); 
} 

} 

StrobeController.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; 
} 

} 
+0

看看'logcat'的输出,它会告诉你抛出异常的地方,或者发布它在这里输出的内容 – Kerry

+0

@Kerry请参阅编辑。我已经从logcat粘贴输出。 –

回答

1

我注意到日Ë例外是在第29行抛出:

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

是线29 Camera cam = Camera.open();

你有正确的权限描述here? 此外,你是否试图打开一个空的相机?看看StrobeController类中的第29行。

+0

我在清单中添加了以下权限: ' –

+0

Line 29 in' StrobeController'是'Camera cam = Camera.open();' –

+1

我还没有真正使用过相机设备,但是使用谷歌搜索似乎这可能是以前没有释放相机的问题?我会谷歌异常文本和拖网通过各种答案 – Kerry