Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

android.hardware.Camera$EventHandler.handleMessage

I am writing a program in which I am taking picture, then want to store picture into sd card and finally trying to resize existing image (and then over writing same with old one).

My code works fine almost on all the devices but facing this issue only on Samsung devices.

When I am capturing image I am not able to store image into SDCard

Logcat:

12-05 18:23:15.407: E/AndroidRuntime(2378): FATAL EXCEPTION: main
12-05 18:23:15.407: E/AndroidRuntime(2378): java.lang.NullPointerException
12-05 18:23:15.407: E/AndroidRuntime(2378):     at android.graphics.Bitmap.createScaledBitmap(Bitmap.java:461)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at com.example.kdh.TakePhotoActivity$1.onPictureTaken(TakePhotoActivity.java:325)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at android.hardware.Camera$EventHandler.handleMessage(Camera.java:789)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at android.os.Handler.dispatchMessage(Handler.java:99)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at android.os.Looper.loop(Looper.java:137)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at android.app.ActivityThread.main(ActivityThread.java:4921)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at java.lang.reflect.Method.invokeNative(Native Method)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at java.lang.reflect.Method.invoke(Method.java:511)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1036)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:803)
12-05 18:23:15.407: E/AndroidRuntime(2378):     at dalvik.system.NativeStart.main(Native Method)

Code:

private void createCamera() {
                // Create an instance of Camera
                mCamera = getCameraInstance();

                // Setting the right parameters in the camera
                Camera.Parameters params = mCamera.getParameters();

                List<Size> allSizes = params.getSupportedPictureSizes();
                Camera.Size size = allSizes.get(0); // get top size
                for (int i = 0; i < allSizes.size(); i++) {
                     if (allSizes.get(i).width > size.width)
                       size = allSizes.get(i);
                 }
                //set max Picture Size
                params.setPictureSize(size.width, size.height);
                params.setPictureFormat(PixelFormat.JPEG);
                params.setJpegQuality(85);
                mCamera.setParameters(params);

                // Create our Preview view and set it as the content of our activity.
                mPreview = new CameraPreview(TakePhotoActivity.this, mCamera);
                FrameLayout preview = (FrameLayout) findViewById(R.id.camera_preview);

                // Calculating the width of the preview so it is proportional.
                float widthFloat = (float) (deviceHeight) * 4 / 3;
                int width = Math.round(widthFloat);

                // Resizing the LinearLayout so we can make a proportional preview. This
                // approach is not 100% perfect because on devices with a really small
                // screen the the image will still be distorted - there is place for
                // improvment.
                RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(width, deviceHeight);
                preview.setLayoutParams(layoutParams);

                // Adding the camera preview after the FrameLayout and before the button
                // as a separated element.
                preview.addView(mPreview, 0);
            }

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

                // Test if there is a camera on the device and if the SD card is
                // mounted.
                if (!checkCameraHardware(this)) {
                    finish();
                } else if (!checkSDCard()) {                    
                    finish();
                }

                // Creating the camera
                createCamera();

                // Register this class as a listener for the accelerometer sensor
                sensorManager.registerListener(this, sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER), SensorManager.SENSOR_DELAY_NORMAL);
            }

            @Override
            protected void onPause() {
                super.onPause();
                // release the camera immediately on pause event
                releaseCamera();

                // removing the inserted view - so when we come back to the app we
                // won't have the views on top of each other.

                preview.removeViewAt(0);
            }

            private void releaseCamera() {
                if (mCamera != null) {
                    mCamera.stopPreview();
                    mCamera.setPreviewCallback(null);
                    mCamera.release(); // release the camera for other applications
                    mCamera = null;
                }
            }

            /** Check if this device has a camera */
            private boolean checkCameraHardware(Context context) {
                if (context.getPackageManager().hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
                    // this device has a camera
                    return true;
                } else {
                    // no camera on this device
                    return false;
                }
            }

            private boolean checkSDCard() {
                boolean state = false;

                String sd = Environment.getExternalStorageState();
                if (Environment.MEDIA_MOUNTED.equals(sd)) {
                    state = true;
                }

                return state;
            }

            /**
             * A safe way to get an instance of the Camera object.
             */
            public static Camera getCameraInstance() {
                Camera c = null;
                try {
                    // attempt to get a Camera instance
                    c = Camera.open();
                } catch (Exception e) {
                    // Camera is not available (in use or does not exist)
                }

                // returns null if camera is unavailable
                return c;
            }

            private PictureCallback mPicture = new PictureCallback() {

                public void onPictureTaken(byte[] data, Camera camera) {

                    // Replacing the button after a photho was taken.
                    linearLayout1.setVisibility(View.GONE);
                    linearLayout2.setVisibility(View.VISIBLE);

                    File directory = new File(Environment.getExternalStoragePublicDirectory
                            (Environment.DIRECTORY_PICTURES) 
                                +"/Data/" + stringFolderName);                  

                    fileName = String.format("%d.jpg", System.currentTimeMillis());
                    File outFile = new File(directory, fileName);

                    try {
                        FileOutputStream purge = new FileOutputStream(outFile);
                        purge.write(data);
                        purge.close();                      
                    } catch (FileNotFoundException e) {
                        Log.d("DG_DEBUG", "File not found: " + e.getMessage());
                    } catch (IOException e) {
                        Log.d("DG_DEBUG", "Error accessing file: " + e.getMessage());
                    }

                    String cPath = Environment.getExternalStoragePublicDirectory
                            (Environment.DIRECTORY_PICTURES) 
                            +"/Data/" + stringFolderName + "/"+ fileName;

                    Bitmap bMap= BitmapFactory.decodeFile(cPath);
                    Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);
                    //Bitmap adjustedBitmap = Bitmap.createBitmap(out, 0, 0, 1024, 768, matrix, true);
                    Log.d("image-name:-", fileName);
                    File resizedFile = new File(directory, fileName);

                    OutputStream fOut=null;
                    try {
                        fOut = new BufferedOutputStream(new FileOutputStream(resizedFile));
                        out.compress(Bitmap.CompressFormat.JPEG, 85, fOut);
                        fOut.flush();
                        fOut.close();
                        bMap.recycle();
                        out.recycle();

                    } catch (Exception e) { // TODO

                    }


                    // Adding Exif data for the orientation. For some strange reason the
                    // ExifInterface class takes a string instead of a file.
                    try {
                        exif = new ExifInterface(directory + "/"+fileName);
                        exif.setAttribute(ExifInterface.TAG_ORIENTATION, "" + orientation);
                        exif.saveAttributes();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }

                }
            };
like image 915
Sophie Avatar asked Dec 05 '15 13:12

Sophie


2 Answers

Try this code and try to save image or video in background thread instead of UI

private PictureCallback mPicture = new PictureCallback() {
            @Override
            public void onPictureTaken(final byte[] data, Camera camera) {
                final File pictureFile = getOutputMediaFile();
                if (pictureFile == null) {
                    return;
                }

                Thread thread = new Thread() {
                    @Override
                    public void run() {
                        try {
                            FileOutputStream fos = new FileOutputStream(pictureFile);
                            fos.write(data);
                            fos.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                };

                thread.start();


            }
        };


        private File getOutputMediaFile() {
            File mediaStorageDir = new File(
                    Environment.getExternalStorageDirectory(),
                    "/Images");
            if (!mediaStorageDir.exists()) {
                if (!mediaStorageDir.mkdirs()) {
                    Log.d("Camera", "failed to create directory");
                    return null;
                }
            }
            // Create a media file name
            String timeStamp = new SimpleDateFormat("yyyyMMdd_HHmmss")
                    .format(new Date());
            File mediaFile;
            String image_path = mediaStorageDir.getPath() + File.separator
                    + "IMG_" + timeStamp + ".jpg";
            mediaFile = new File(image_path);
            return mediaFile;
        }
like image 144
Muhammad Umair Shafique Avatar answered Nov 12 '22 19:11

Muhammad Umair Shafique


When data dose not created.You can not use bitmap.

That means a little time need to create image.so bitmapcreate return null.

I think PictureCallback runs like a Thread

To resolve this problem. change this code

   Bitmap bMap= BitmapFactory.decodeFile(cPath);
   Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);

To

    Bitmap bMap = BitmapFactory.decodeByteArray(data, 0,.length);
    Bitmap out = Bitmap.createScaledBitmap(bMap, 1024, 768, true);

That code convert byte[] to bitmap (see data in picturecallback );

The camera API reference: Camera API tutorials

like image 44
shayan Avatar answered Nov 12 '22 21:11

shayan