2

你能帮我吗。我是 android 开发和这个网站的新手。我对烦人的手电筒示例有一点问题。我试图添加频闪功能。它工作正常。但是如果我在 StrobeLightConfig Activity (第二个活动)上按下后退按钮,当切换按钮打开并频闪工作时,我会遇到异常并且应用程序崩溃。如果我在切换按钮关闭时按下后退按钮,一切正常并且工作正常。我认为这个问题与线程。

只有当led频闪灯工作时才会出现这个问题。对不起,如果这个问题已经存在。我试图在这个网站上找到关于这个问题的信息。

日志猫:

11-19 20:28:53.381: E/AndroidRuntime(21737): FATAL EXCEPTION: main
11-19 20:28:53.381: E/AndroidRuntime(21737): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.eugene.android/com.eugene.android.FlashLightActivity}: java.lang.RuntimeException: Fail to connect to camera service
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2194)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2229)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread.access$600(ActivityThread.java:139)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1261)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.os.Handler.dispatchMessage(Handler.java:99)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.os.Looper.loop(Looper.java:154)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread.main(ActivityThread.java:4944)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at java.lang.reflect.Method.invokeNative(Native Method)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at java.lang.reflect.Method.invoke(Method.java:511)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at dalvik.system.NativeStart.main(Native Method)
11-19 20:28:53.381: E/AndroidRuntime(21737): Caused by: java.lang.RuntimeException: Fail to connect to camera service
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.hardware.Camera.native_setup(Native Method)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.hardware.Camera.<init>(Camera.java:307)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.hardware.Camera.open(Camera.java:283)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at com.eugene.android.FlashLightActivity.onCreate(FlashLightActivity.java:83)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.Activity.performCreate(Activity.java:4524)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1071)
11-19 20:28:53.381: E/AndroidRuntime(21737):    at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2150)
11-19 20:28:53.381: E/AndroidRuntime(21737):    ... 11 more
11-19 20:28:53.391: D/(115): [GECameraParameters::getGPUEffect] enter
11-19 20:28:53.391: D/(115): [GECameraParameters::getGPUEffect] leave. no key GPU-effect
11-19 20:28:53.391: D/(115): [GECameraParameters::getGPUEffectParam] leave. no key GE-param0
11-19 20:28:53.391: D/(115): [GECameraParameters::getGPUEffectParam] leave. no key GE-param1
11-19 20:28:53.391: I/GPUPostEffect(115): int mlabs::GPUPostEffect::setParameters(mlabs::GPUPostEffect::GPUTask*): old effect = -1, new effect = -1.
11-19 20:28:53.391: D/GPUPostEffect(115): setParameters: isGEInit == false: no call to ChooseEffect.
11-19 20:28:53.391: E/EmbeddedLogger(367): App crashed! Process: com.eugene.android
11-19 20:28:53.391: E/EmbeddedLogger(367): App crashed! Package: com.eugene.android v1 (1.0)
11-19 20:28:53.391: E/EmbeddedLogger(367): Application Label: AWESOME Flashlight
11-19 20:28:53.401: W/ActivityManager(367):   Force finishing activity com.eugene.android/.FlashLightActivity
11-19 20:28:53.401: W/ActivityManager(367):   Force finishing activity com.eugene.android/.StrobeLightConfig

手电筒活动:

public class FlashLightActivity extends Activity {
protected static final Parameters params = null;
private boolean isLighOn = false;
protected Camera camera;
protected RelativeLayout relativeLayout;
private android.widget.TextView TextView;   
private android.widget.ImageView ImageView;

public void onStart(){
super.onStart();


}
public void onResume(){
    super.onResume();


    }
public void onPause(){
    super.onPause();

        }



public void onStop() {
    super.onStop();

    if (camera != null) {
        camera.release();
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);

    TextView = (android.widget.TextView) findViewById(R.id.textView1);
    relativeLayout = (RelativeLayout) findViewById(R.id.relativeLayout1);
    ImageView= (android.widget.ImageView) findViewById(R.id.imageView1);

    Context context = this;
    PackageManager pm = context.getPackageManager();

        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
        Log.e("err", "Device has no camera!");
        return;
    }

    camera = Camera.open();

        final Parameters p = camera.getParameters();



    relativeLayout.setOnClickListener(new OnClickListener() {

        @Override
        public void onClick(View arg0) {

            if (isLighOn) {

                relativeLayout.setBackgroundResource(R.drawable.light1);
                TextView.setText(R.string.light_off_text);
                Log.i("info", "torch is turn off!");

                p.setFlashMode(Parameters.FLASH_MODE_OFF);
                camera.setParameters(p);
                camera.stopPreview();
                isLighOn = false;
                //ledControl("lcd-backlight", 30);


            } else {

                Log.i("info", "torch is turn on!");

                p.setFlashMode(Parameters.FLASH_MODE_TORCH);
                TextView.setText(R.string.light_on_text);
                camera.setParameters(p);
                camera.startPreview();
                isLighOn = true;
                relativeLayout.setBackgroundResource(R.drawable.light2);


            }

        }

    });



    ImageView.setOnClickListener(new OnClickListener() {

        @Override


public void onClick(View v)
{
switch (v.getId()) 
{
    case R.id.imageView1:

        Intent intent = new Intent(FlashLightActivity.this, StrobeLightConfig.class);
        startActivity(intent);
       camera.release();
        }


}

});



}
    }

频闪灯配置活动:

public class StrobeLightConfig extends FlashLightActivity {
StrobeRunner runner;
Thread bw;
Dialog dialog;
public final Handler mHandler = new Handler();
public final Runnable mShowToastRunnable = new Runnable() {
    public void run() {
        showMessage();
    }
};

/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    /* dialog = new Dialog(StrobeLightConfig.this);
     dialog.setContentView(R.layout.main1);

     dialog.setTitle("Write Message");
     dialog.setCancelable(true);

     inp = (EditText) dialog.findViewById(R.id.morsetext);
     Button okB = (Button) dialog.findViewById(R.id.ok);
     Button cancelB = (Button) dialog.findViewById(R.id.cancel);*/
    super.onCreate(savedInstanceState);
  setContentView(R.layout.main1);
  camera.release();
    final ToggleButton togglebutton = (ToggleButton) findViewById(R.id.ToggleButton01);

    runner = StrobeRunner.getInstance();
    runner.controller = this;

    if(runner.isRunning)
    {   

    }
    else
    {
        try
        {

            camera = Camera.open();

            if(camera==null)
            {
                togglebutton.setEnabled(false);
                TextView t = (TextView)findViewById(R.id.TextView01);
                t.setText(R.string.nocamera);
                return;
            }

            camera.release();
        }
        catch(RuntimeException ex)
        {
            togglebutton.setEnabled(false);
            TextView t = (TextView)findViewById(R.id.TextView01);
            t.setText(R.string.nocamera);
            Toast.makeText(getApplicationContext(), "Error connecting to camera flash.", Toast.LENGTH_LONG).show();
            return;
        }
    } 


    togglebutton.setOnClickListener(new OnClickListener() {
        public void onClick(View v) {
            // Perform action on clicks
            if (togglebutton.isChecked()) {
                bw = new Thread(runner);
                bw.start();
            } else {
                runner.requestStop = true;
            }
        }
    });

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

        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }

        public void onStartTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }

        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            runner.delay=progress;

        }
    });

    final SeekBar skbaroff = (SeekBar)findViewById(R.id.SeekBar02);
    skbaroff.setOnSeekBarChangeListener(new OnSeekBarChangeListener() {

        public void onStopTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }

        public void onStartTrackingTouch(SeekBar seekBar) {
            // TODO Auto-generated method stub

        }

        public void onProgressChanged(SeekBar seekBar, int progress,
                boolean fromUser) {
            runner.delayoff=progress;

        }
    });


}


public void onPause()
{
     super.onPause();       
    runner.requestStop=true;
    camera.release();

        }



@Override
public void onStop() {
    super.onStop();
    runner.requestStop=true;
    ToggleButton togglebutton = (ToggleButton) findViewById(R.id.ToggleButton01);
    togglebutton.setChecked(false);

}


public void showMessage()
{
    String err = runner.errorMessage;
    runner.errorMessage="";
    if(!err.equals(""))
    {
        Context context = getApplicationContext();
        int duration = Toast.LENGTH_SHORT;

        Toast toast = Toast.makeText(context, err, duration);
        toast.show();
    }

    ToggleButton togglebutton = (ToggleButton) findViewById(R.id.ToggleButton01);
    togglebutton.setChecked(false);
}


public boolean onKeyDown(int keyCode, KeyEvent event) {
    // TODO Auto-generated method stub

    if(keyCode == KeyEvent.KEYCODE_BACK){
            Intent i = new Intent(StrobeLightConfig.this, FlashLightActivity.class);
    startActivity(i);


    }
    return super.onKeyDown(keyCode, event);
}        
}

StrobeRunner 活动:

public class StrobeRunner implements Runnable {
protected StrobeRunner()
{

}

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

private static StrobeRunner instance;


public volatile boolean requestStop = false;
public volatile boolean isRunning = false;
public volatile int delay = 0;
public volatile int delayoff = 500;
public volatile StrobeLightConfig controller;
public volatile String errorMessage = "";




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

    requestStop=false;
    isRunning = true;

    Camera cam = Camera.open();

    Camera.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;
    controller.mHandler.post(controller.mShowToastRunnable);
}



}
4

1 回答 1

0

StrobeLightConfig中,您必须删除onKeyDown方法,您不必覆盖它,因为默认情况下它会将您返回到FlashLightActivity并且在您的情况下,您打开FlashLightActivity然后调用return super.onKeyDown(keyCode, event); 再次返回FlashLightActivity

所以现在如果你想在从StrobeLightConfig返回到 FlashLightActivity 后让闪光灯继续工作,你必须保存你的参数并在你使用StartActivityForResultonActivityresult返回它们时将它们放在FlashLightActivity中,如果你想关闭闪光灯按下后退按钮后,只需删除onKeyDown方法,一切都会好起来的

感谢您的代码,这对我开始学习相机API来说是一个很好的开始

于 2013-09-20T19:00:30.903 回答