-1

I am trying to make a simple flashlight app that works on all Android devices, including the Nexus 5 (which requires that I implement the SurfaceView).

But my app keeps crashing anytime I run it. What are my doing wrong?

My full code is below:

public class MainActivity extends Activity implements Callback {

    //flag to detect flash is on or off
    private boolean isLighOn = false;
    private Camera camera;
    private Button button;
    private Parameters p;
    private SurfaceHolder mHolder;
    @Override

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

        SurfaceView preview = (SurfaceView)findViewById(R.id.PREVIEW);
            SurfaceHolder mHolder = preview.getHolder();
            mHolder.addCallback(this);
    }

    @Override
    protected void onStop() {
        super.onStop();

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

    @Override   
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        Context context = this;
        PackageManager pm = context.getPackageManager();

        // if device support camera?
        if (!pm.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
            Log.e("err", "Device has no camera!");
            return;
        }
        camera = Camera.open();
        final Parameters p = camera.getParameters();

        final ToggleButton tb = (ToggleButton) findViewById(R.id.toggle);
        final ImageView image = (ImageView) findViewById(R.id.photo);
        tb.setText(null);
        tb.setTextOn(null);
        tb.setTextOff(null);
        tb.setBackgroundResource(R.drawable.check);

        tb.setOnClickListener(new View.OnClickListener() {          
            @Override
            public void onClick(View v) {
                if (tb.isChecked()) {
                    image.setImageResource(R.drawable.b);   
                    turnOffFlash();
                } else {
                    image.setImageResource(R.drawable.a);                       
                }                   
            }
        });
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        // Inflate the menu; this adds items to the action bar if it is present.
        getMenuInflater().inflate(R.menu.main, menu);
        return true;
    }

    private void turnOnFlash(){
        Log.i("info", "torch is turn on!");

        p.setFlashMode(Parameters.FLASH_MODE_TORCH);

        camera.setParameters(p);
        camera.startPreview();
        isLighOn = true;
    }

    private void turnOffFlash(){
        Log.i("info", "torch is turn off!");

        p.setFlashMode(Parameters.FLASH_MODE_OFF);
        camera.setParameters(p);
        camera.stopPreview();
        isLighOn = false;
    }           

    @Override
    public void surfaceChanged(SurfaceHolder holder,int format,int width,int height)   {

    }

    @Override
    public void surfaceCreated(SurfaceHolder holder){
        mHolder = holder;
        try {
            Log.i("SurfaceHolder", "setting preview");
            camera.setPreviewDisplay(mHolder);  
        } catch (IOException e){
            e.printStackTrace();
        }
    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder){
        Log.i("SurfaceHolder", "stopping preview");
        camera.stopPreview();
        mHolder = null;
    }
}

The code in my layout XML file is posted below

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="fill_parent"
    android:layout_height="fill_parent"
    android:gravity="center_horizontal" >

    <ImageView
        android:id="@+id/photo"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent"
        android:src="@drawable/b"
        android:scaleType="centerCrop"
        android:contentDescription="@string/happy" />

    <ToggleButton
        android:id="@+id/toggle"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentBottom="true"
        android:layout_centerHorizontal="true"
        android:layout_margin="10dp"
        android:layout_marginBottom="17dp"
        android:background="@drawable/check"
        android:focusable="false"
        android:focusableInTouchMode="false" />

    <SurfaceView
        android:id="@+id/PREVIEW"
        android:layout_width="1dp"
        android:layout_height="1dp" />

</RelativeLayout>

Here is my Logcat

  07-24 03:09:14.433: V/Provider/Settings(16560): invalidate [system]: current 64 !=   cached 0
   07-24 03:09:14.436: V/Provider/Settings(16560): from db cache, name =   sound_effects_enabled , value = 0
   07-24 03:09:14.437: I/info(16560): torch is turn off!
  07-24 03:09:14.437: D/AndroidRuntime(16560): Shutting down VM
  07-24 03:09:14.437: W/dalvikvm(16560): threadid=1: thread exiting with uncaught  exception (group=0x4112d9a8)
  07-24 03:09:14.441: E/AndroidRuntime(16560): FATAL EXCEPTION: main
   07-24 03:09:14.441: E/AndroidRuntime(16560): java.lang.NullPointerException
    07-24 03:09:14.441: E/AndroidRuntime(16560):    at       com.example.torch.MainActivity.turnOffFlash(MainActivity.java:103)
   07-24 03:09:14.441: E/AndroidRuntime(16560):     at        com.example.torch.MainActivity.access$0(MainActivity.java:100)
07-24 03:09:14.441: E/AndroidRuntime(16560):    at    com.example.torch.MainActivity$1.onClick(MainActivity.java:76)
  07-24 03:09:14.441: E/AndroidRuntime(16560):  at  android.view.View.performClick(View.java:4211)
07-24 03:09:14.441: E/AndroidRuntime(16560):    at  android.widget.CompoundButton.performClick(CompoundButton.java:100)
07-24 03:09:14.441: E/AndroidRuntime(16560):    at android.view.View$PerformClick.run(View.java:17446)
  07-24 03:09:14.441: E/AndroidRuntime(16560):  at android.os.Handler.handleCallback(Handler.java:725)
 07-24 03:09:14.441: E/AndroidRuntime(16560):   at android.os.Handler.dispatchMessage(Handler.java:92)
 07-24 03:09:14.441: E/AndroidRuntime(16560):   at android.os.Looper.loop(Looper.java:153)
 07-24 03:09:14.441: E/AndroidRuntime(16560):   at android.app.ActivityThread.main(ActivityThread.java:5297)
   07-24 03:09:14.441: E/AndroidRuntime(16560):     at java.lang.reflect.Method.invokeNative(Native Method)
 07-24 03:09:14.441: E/AndroidRuntime(16560):   at java.lang.reflect.Method.invoke(Method.java:511)
  07-24 03:09:14.441: E/AndroidRuntime(16560):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:833)
  07-24 03:09:14.441: E/AndroidRuntime(16560):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:600)
  07-24 03:09:14.441: E/AndroidRuntime(16560):  at dalvik.system.NativeStart.main(Native Method)
Donnie Ibiyemi
  • 971
  • 3
  • 15
  • 26
  • Since the app crashes, post your LogCat as guided from above link. – Andrew T. Jul 24 '14 at 02:21
  • @Andrew T. i just posted the Logcat – Donnie Ibiyemi Jul 24 '14 at 02:31
  • 1
    It's because of this `final Parameters p = camera.getParameters();` in your onCreate(). You declare a variable `p` at the top, but never initialize it. You are only initializing the one you declare inside of onCreate. When you use `p.setFlashMode(Parameters.FLASH_MODE_OFF);` p is null; – takendarkk Jul 24 '14 at 02:34

1 Answers1

1

The line causing the problem is

p.setFlashMode(Parameters.FLASH_MODE_OFF);

at this point p is null. You may think you have initialized it with

final Parameters p = camera.getParameters();

in your onCreate() method, but this is incorrect. This p is declared and initialized inside your onCreate() so that is the only place it is available.

private Parameters p;

The above p is the one your app is using in the line p.setFlashMode(Parameters.FLASH_MODE_OFF);.

To correct this just change

final Parameters p = camera.getParameters();

to

p = camera.getParameters();

If you really need it to be final you can add that keyword to your line up top

private Parameters p;
takendarkk
  • 3,347
  • 8
  • 25
  • 37
  • Ok the errors are gone. But for some weird reason the flashlight is not turning on and off on the actual device – Donnie Ibiyemi Jul 24 '14 at 02:47
  • I'm not very familiar with Android related hardware so I probably won't be able to help you with that. Apologies. – takendarkk Jul 24 '14 at 02:49
  • Sure thing. Thank you for actually upvoting/accepting an answer that helped you out. Many times people get the help they need and then just leave. – takendarkk Jul 24 '14 at 02:52