Julien Attard
Julien Attard

Reputation: 83

Android Camera - Attempt to read from field 'int android.hardware.Camera$Size.width' on a null object reference

I am developing an android application. I use a custom camera in a Fragment of a ViewPager. I have a problem of compatibility, my app works on android 4.2.2 , 4.4.4, 5.0.1 . But if i try with an android version 5.1.0 or 5.1.1 , the app crash . I have this log :

12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: FATAL EXCEPTION: main 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: Process: fr.jumaxdev.lekeen, PID: 1999 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: java.lang.NullPointerException: Attempt to read from field 'int android.hardware.Camera$Size.width' on a null object reference 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at fr.jumaxdev.lekeen.Fragment_Photo.initPreview(Fragment_Photo.java:200) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at fr.jumaxdev.lekeen.Fragment_Photo.access$200(Fragment_Photo.java:35) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at fr.jumaxdev.lekeen.Fragment_Photo$5.surfaceChanged(Fragment_Photo.java:267) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.SurfaceView.updateWindow(SurfaceView.java:699) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.SurfaceView$3.onPreDraw(SurfaceView.java:200) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.ViewTreeObserver.dispatchOnPreDraw(ViewTreeObserver.java:1018) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2301) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1300) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7017) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.Choreographer$CallbackRecord.run(Choreographer.java:777) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.Choreographer.doCallbacks(Choreographer.java:590) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.Choreographer.doFrame(Choreographer.java:560) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:763) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.os.Handler.handleCallback(Handler.java:739) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.os.Handler.dispatchMessage(Handler.java:95) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.os.Looper.loop(Looper.java:145) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at android.app.ActivityThread.main(ActivityThread.java:6891) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at java.lang.reflect.Method.invoke(Native Method) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at java.lang.reflect.Method.invoke(Method.java:372) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404) 12-17 11:13:20.081 1999-1999/fr.jumaxdev.lekeen E/AndroidRuntime: at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)

So the problem is "java.lang.NullPointerException: Attempt to read from field 'int android.hardware.Camera$Size.width' on a null object reference" , the camera size is null ..

Here are some codes :

@Override
public void onResume() {
    super.onResume();
    camera = getCamera("back");
    currentCamera = 1;
    startPreview();
}

@Override
public void onPause() {
    if (inPreview) {
        camera.stopPreview();
    }
    camera.release();
    camera = null;
    inPreview = false;

    super.onPause();
}

private Camera.Size getOptimalPreviewSize(List<Camera.Size> sizes, int width, int height)
{
    // Source: http://stackoverflow.com/questions/7942378/android-camera-will-not-work-startpreview-fails
    Camera.Size optimalSize = null;

    final double ASPECT_TOLERANCE = 0.1;
    double targetRatio = (double) height / width;

    // Try to find a size match which suits the whole screen minus the menu on the left.
    for (Camera.Size size : sizes){

        if (size.height != width) continue;
        double ratio = (double) size.width / size.height;
        if (ratio <= targetRatio + ASPECT_TOLERANCE && ratio >= targetRatio - ASPECT_TOLERANCE){
            optimalSize = size;
        }
    }

    // If we cannot find the one that matches the aspect ratio, ignore the requirement.
    if (optimalSize == null) {
        // TODO : Backup in case we don't get a size.
    }

    return optimalSize;
}

private void initPreview(int width, int height) {
    if (camera != null && cameraPreviewHolder.getSurface() != null) {
        try {
            camera.setPreviewDisplay(cameraPreviewHolder);
        } catch (Throwable t) {
        }

        if (!cameraConfigured) {
            Camera.Parameters parameters = camera.getParameters();

            if (camera.getParameters().getSupportedPreviewSizes() != null){
                Camera.Size previewSize = getOptimalPreviewSize(camera.getParameters().getSupportedPreviewSizes(), width, height);;
                parameters.setPreviewSize(previewSize.width, previewSize.height);
            }
            camera.setParameters(parameters);
            cameraConfigured = true;
        }
    }
}

@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
private void startPreview() {
    if (cameraConfigured && camera != null) {
        camera.startPreview();
        inPreview = true;
        camera.setDisplayOrientation(90);
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
            camera.enableShutterSound(false);
        }
    }
}

To resume, if the android version in > 5.0.1, the app crash. But why is it depending on the android version ...?

If someone can solve my problem, i pay him a beer ! Thanks. Attard Julien.

Upvotes: 2

Views: 1796

Answers (1)

TheTool
TheTool

Reputation: 309

Permissions changed recently.

Use this in the onCreate():

String[] permissions = {"android.permission.CAMERA"};
int permissionRequestCode = 200;
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M && checkSelfPermission(permissions[0]) != PackageManager.PERMISSION_GRANTED)
    {
        requestPermissions(permissions, permissionRequestCode);
    }

The permissionRequestCode is needed to check if the user actually accepted the permission in the callback: 'onRequestPermissionsResult()'

@Override
public void onRequestPermissionsResult(int requestCode, String permissions[], int[] grantResults) {
    switch (requestCode) {
        case 200: {
            // If request is cancelled, the result arrays are empty.
            if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
                //Permission Granted
            } else {
                //Permission Denied
            }
            return;
        //Use other case lines for other requests (with different requestCodes)
        }
    }
}

Upvotes: 2

Related Questions