Null Pointer Exception - Custom Camera with Flash Light

277 views Asked by At

In my program i want to allow user to capture multiple Images back to back, but once i do tap on Capture button getting Null Pointer Exception (NPE). I have created a Custom Camera.

If i will remove the flash light code from my existing code, then it's working fine for me (yeah then i am able to capture multiple images back to back without facing any NPE), but whenever i use Flash Light code facing NPE

  1. At line number : 324

    mediaFile = new File(mediaStorageDir.getPath() + File.separator
            + "IMG_" + timeStamp + ".jpg");
    
  2. At line number : 301

        pictureFile = getOutputMediaFile();
    
  3. Java Code

    @Override
    public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_camera);
    
        mCamera = getCameraInstance();
    
        mCameraPreview = new PreviewSurface(this, mCamera);
        FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);
        preview.addView(mCameraPreview);
    
    
        Bundle extras = getIntent().getExtras();
        if (extras != null) {
            String value = extras.getString("folder_name");
            Log.d(CameraLauncherActivity.LOG_TAG, "folder_name :: " + value);    
        }
    
    
        Button captureButton = (Button) findViewById(R.id.btnCapture);
        Log.d(CameraLauncherActivity.LOG_TAG, "captureButton :: " + captureButton);
        captureButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                mCamera.takePicture(null, null, mPicture);
                Log.d(CameraLauncherActivity.LOG_TAG, "mCamera.takePicture :: " + mCamera);                                         
            }
        });
    
        Button viewButton = (Button) findViewById(R.id.btnView);
        Log.d(CameraLauncherActivity.LOG_TAG, "SingleAngelActivityButton :: " + viewButton);
        viewButton.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {             
    
                Intent intentNewEvent = new Intent(CameraLauncherActivity.this, UploadActivity.class);
                String event_id = customFolder;
                intentNewEvent.putExtra("event_id", event_id);
                startActivity(intentNewEvent);        
            }
        });
    
        cd = new ConnectionDetector(getApplicationContext());
    
        // Check if Internet present
        if (!cd.isConnectingToInternet()) {
            // Internet Connection is not present
            alert.showAlertDialog(CameraLauncherActivity.this, "Internet Connection Error",
                    "Please connect to working Internet connection", false);
            // stop executing code by return
            return;
        }
    
    
       hasFlash = getApplicationContext().getPackageManager()
                .hasSystemFeature(PackageManager.FEATURE_CAMERA_FLASH);
    
       // Check if Internet present
        if (!hasFlash) {
            // device doesn't support flash
            alert.showAlertDialog(CameraLauncherActivity.this, "Sorry",
                    "your Device doesn't support Flash Light !", false);
            // stop executing code by return
            return;
        }
    
         // displaying button image
       toggleButtonImage();
    
       // flash switch button
        btnSwitch = (ImageButton) findViewById(R.id.btnFlash);
    
        btnSwitch.setOnClickListener(new View.OnClickListener() {
    
            @Override
            public void onClick(View v) {
                if (isFlashOn) {
                    // turn off flash
                    turnOffFlash();
                } else {
                    // turn on flash
                    turnOnFlash();
                }
            }
        });              
    
    // Get event id, angel id
    Intent i = getIntent();
    event_id = i.getStringExtra("event_id");
    angel_id = i.getStringExtra("angel_id");
    
    // calling background thread
    new LoadSingleTrack().execute();
    }
    
     /**
     * Background Async Task to get single angel information
     * */
    class LoadSingleTrack extends AsyncTask<String, String, String> {
    
        /**
         * Before starting background thread Show Progress Dialog
         * */
        @Override
        protected void onPreExecute() {
            super.onPreExecute();
            pDialog = new ProgressDialog(CameraLauncherActivity.this);
            pDialog.setMessage("Initializing Camera...");
            pDialog.setIndeterminate(false);
            pDialog.setCancelable(false);
            pDialog.show();
        }
    
        /**
         * getting angel json and parsing
         * */
        protected String doInBackground(String... args) {
            // Building Parameters
            List<NameValuePair> params = new ArrayList<NameValuePair>();
    
            // post event id, angel id as GET parameters
            params.add(new BasicNameValuePair("event", event_id));
            params.add(new BasicNameValuePair("angel", angel_id));
    
            // getting JSON string from URL
            String json = jsonParser.makeHttpRequest(URL_angel, "GET",
                    params);
    
            // Check your log cat for JSON reponse
            Log.d("Single Track JSON: ", json);
    
            try {
                JSONObject jObj = new JSONObject(json);
                if(jObj != null){
                    angel_name = jObj.getString(TAG_ANGEL);
                    event_name = jObj.getString(TAG_EVENT);
                }           
    
            } catch (JSONException e) {
                e.printStackTrace();
            }
    
            return null;
        }
    
        /**
         * After completing background task Dismiss the progress dialog
         * **/
        protected void onPostExecute(String file_url) {
            // dismiss the dialog after getting angel information
            pDialog.dismiss();
    
            // updating UI from Background Thread
            runOnUiThread(new Runnable() {
                public void run() {
    
                    TextView txt_angel_name = (TextView) findViewById(R.id.angel_title);
                    String timeStamp = new SimpleDateFormat("dd-MM-yyyy").format(new Date());
    
                    txt_angel_name.setText(event_name + " Event_"+ angel_name + "-" + timeStamp);
                    customFolder = txt_angel_name.getText().toString();
    
                    // Change Activity Title with angel title
                    setTitle(angel_name);
    
                    // folder name
                    mediaStorageDir = new File(
                            Environment
                                    .getExternalStoragePublicDirectory(Environment.DIRECTORY_PICTURES),
                                    "/CaptureImages/"+ customFolder + "/");
    
                    if (!mediaStorageDir.exists()) {
                        if (!mediaStorageDir.mkdirs()) {
                            Log.d("App", "failed to create directory");                  
                        }
                    }                   
                }
            });
        }
    }
    

    }

Logcat:-

12-04 23:23:04.610: E/AndroidRuntime(798): FATAL EXCEPTION: main
12-04 23:23:04.610: E/AndroidRuntime(798): java.lang.NullPointerException
12-04 23:23:04.610: E/AndroidRuntime(798):  at com.example.camera.CameraLauncherActivity.getOutputMediaFile(CameraLauncherActivity.java:324)
12-04 23:23:04.610: E/AndroidRuntime(798):  at com.example.camera.CameraLauncherActivity$1.onPictureTaken(CameraLauncherActivity.java:301)
12-04 23:23:04.610: E/AndroidRuntime(798):  at android.hardware.Camera$EventHandler.handleMessage(Camera.java:773)
12-04 23:23:04.610: E/AndroidRuntime(798):  at android.os.Handler.dispatchMessage(Handler.java:99)
12-04 23:23:04.610: E/AndroidRuntime(798):  at android.os.Looper.loop(Looper.java:137)
12-04 23:23:04.610: E/AndroidRuntime(798):  at android.app.ActivityThread.main(ActivityThread.java:5103)
12-04 23:23:04.610: E/AndroidRuntime(798):  at java.lang.reflect.Method.invokeNative(Native Method)
12-04 23:23:04.610: E/AndroidRuntime(798):  at java.lang.reflect.Method.invoke(Method.java:525)
12-04 23:23:04.610: E/AndroidRuntime(798):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:737)
12-04 23:23:04.610: E/AndroidRuntime(798):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:553)
12-04 23:23:04.610: E/AndroidRuntime(798):  at dalvik.system.NativeStart.main(Native Method)
12-04 23:23:07.570: I/Process(798): Sending signal. PID: 798 SIG: 9
1

There are 1 answers

2
Ted Hopp On BEST ANSWER

I can't figure out the exact sequence of execution for various parts of your code, but the only thing on that line that can generate a NPE is that mediaStorageDir is null. Since you initialize mediaStorageDir after an instance of LoadSingleTrack asynchronously executes, I can only assume that it is executing after line 324 executes. Resolve this out-of-order sequencing of code execution and the problem should disappear.

Just as a side note: there is no point in calling runOnUiThread from onPostExecute of an AsyncTask; you are already on the UI thread when onPostExecute is called.