1

I have created a custom camera application and it works perfectly fine on almost all devices but it seems to be crashing on devices listed as other in the developer portal. These users are all giving me bad reviews I would like to solve this problem but it is very hard for me to figure it out, because it works perfectly on all the devices I own.

camera.setPreviewDisplay(holder); is what is causing the error and it is occurring when the app launches.`

public class CamPreview extends SurfaceView implements SurfaceHolder.Callback
{
SurfaceHolder holder;
Camera camera;
private List<Camera.Size> sizes;

public CamPreview(Context context, Camera camera)
{
    super(context);
    this.camera = camera;
    holder = this.getHolder();

           holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
    holder.addCallback(this);

}

private Camera.Size getBestPreviewSize(int width, int height)
{
    Camera.Size result=null;
    Camera.Parameters p = camera.getParameters();
    for (Camera.Size size : p.getSupportedPreviewSizes()) {
        if (size.width<=width && size.height<=height) {
            if (result==null) {
                result=size;
            } else {
                int resultArea=result.width*result.height;
                int newArea=size.width*size.height;

                if (newArea>resultArea) {
                    result=size;
                }
            }
        }
    }
    return result;

}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
    if (holder.getSurface() == null) return;

    Camera.Parameters parameters = camera.getParameters();

    sizes = parameters.getSupportedPreviewSizes();
    Camera.Size optimalSize = getBestPreviewSize(width, height);
    try{
    parameters.setPreviewSize(optimalSize.width,optimalSize.height);
        camera.setParameters(parameters);

    }
    catch (NullPointerException a)
    {

    }
    camera.startPreview();


}


@Override
public void surfaceCreated(SurfaceHolder holder)
{

    try
    {
        camera.setPreviewDisplay(holder);
    }
    catch (IOException e)
    {
        camera.release();
        camera=null;
        Log.d("FrontCam", "Error creating surface: " + e.getMessage());
    }
}

@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
    if (camera != null) {
        camera.stopPreview();
        camera.setPreviewCallback(null);
        camera.release();
    }


}
}

logcat:

    java.lang.NullPointerException
    at com.me.frontcam.CamPreview.surfaceCreated(CamPreview.java:136)
    at android.view.SurfaceView.updateWindow(SurfaceView.java:552)
    at android.view.SurfaceView.dispatchDraw(SurfaceView.java:350)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1644)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.View.draw(View.java:6883)
    at android.widget.FrameLayout.draw(FrameLayout.java:357)
    at android.view.ViewGroup.drawChild(ViewGroup.java:1646)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:1373)
    at android.view.View.draw(View.java:6883)
    at android.widget.FrameLayout.draw(FrameLayout.java:357)
    at com.android.internal.policy.impl.PhoneWindow$DecorView.draw(PhoneWindow.java:1921)
    at android.view.ViewRoot.draw(ViewRoot.java:1528)
    at android.view.ViewRoot.performTraversals(ViewRoot.java:1264)
    at android.view.ViewRoot.handleMessage(ViewRoot.java:1866)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:130)
    at android.app.ActivityThread.main(ActivityThread.java:3687)
    at java.lang.reflect.Method.invokeNative(Native Method)
    at java.lang.reflect.Method.invoke(Method.java:507)
    at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:867)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:625)
    at dalvik.system.NativeStart.main(Native Method)

how I open the camera

void initCamera()
{
    //check for front camera
    if(Camera.getNumberOfCameras()>1)
    {

     camera= Camera.open(1);
        try
        {
                camera.cancelAutoFocus();
        }
        catch (RuntimeException a)
        {

        }


        try{

            camera.setDisplayOrientation(90);
        }
        catch (NullPointerException a)
        {
            camera.setDisplayOrientation(90);
        }

    }

    else
    {
        new AlertDialog.Builder(this)
                .setTitle("Sorry but you cant use this app")
                .setMessage("You do not have a front camera")
                .setPositiveButton("Quit", new DialogInterface.OnClickListener() {

                    //Quits application
                    public void onClick(DialogInterface dialog, int which) {
                       finish();
                    }
                })

                .show();
    }



}

I then call the initUI method where the CamPreview constructor is called

void initUI()
{
    white= new ImageView(this);
    imgShoot = (ImageButton) findViewById(R.id.imgShoot);
    imgShoot.setOnClickListener(imgShootOnClick);

     frmPreview = (FrameLayout) findViewById(R.id.frmPreview);
    preview = new CamPreview(this, camera);

    frmPreview.addView(white);
    white.setImageResource(R.drawable.aperture_opening);
    frmPreview.addView(preview);
    frmPreview.bringChildToFront(preview);  

}

Ive looked at both of these and they did not solve my problem Android - cam.setPreviewDisplay(holder) running into IOError

.setPreviewDisplay(holder) throwing null pointer exception

Any help appreciated greatly!

Community
  • 1
  • 1
Will Jamieson
  • 918
  • 1
  • 16
  • 32

3 Answers3

3

Please check if you have added the required permission in your manifest, this worked for me

Aniruddha K.M
  • 7,361
  • 3
  • 43
  • 52
2

If you are crashing with a NullPointerException in the surfaceCreated() method shown above, then it should be obvious what your problem is: camera is null.

Since you are passing camera into the constructor of CamPreview, you will need to investigate how you are calling this constructor.

CommonsWare
  • 986,068
  • 189
  • 2,389
  • 2,491
  • I just added more code. My camera is initiated before I call the constructor so I still dont see what could be wrong – Will Jamieson Jul 23 '13 at 00:48
  • @WillJamieson: Well, first, if the user cancels out of your "you need 2+ cameras" dialog, `camera` will be `null`. Second, assuming that `Camera.open(1)` is a front-facing camera is completely wrong. For example, on a Nexus 7, there is only one camera, which is front-facing. – CommonsWare Jul 23 '13 at 10:07
  • So would opening camera by using the answer here:http://stackoverflow.com/questions/2779002/how-to-open-front-camera-on-android-platform solve my problem? – Will Jamieson Jul 23 '13 at 12:35
  • @WillJamieson: [This specific answer](http://stackoverflow.com/a/4767832/115145) will open a FFC, if there is a FFC. However, the device might not have an FFC, so you still need to do a bit better job of dealing with that scenario. – CommonsWare Jul 23 '13 at 12:47
  • well if I change it to then the app wouldnt be able to download unless the device had a FFC – Will Jamieson Jul 23 '13 at 12:55
  • @WillJamieson: In theory, yes. Your problem, though, is "devices listed as other in the developer portal". I am under the distinct impression that this is a fig leaf for "devices that do not have a legitimate license for the Play Store, where the manufacturer has installed a pirated copy". All bets are off with such devices and whether or not `` will be handled properly. So, *in addition* to the ``, you would need to handle this case in code, at least if you are worried about crashes on these devices, which is the point behind your question. – CommonsWare Jul 23 '13 at 13:12
  • What Is your solution? change it to ? – D T Dec 24 '15 at 16:29
  • @DT The solution is to confirm at runtime that the camera exists, and not to rely solely on elements. – CommonsWare Dec 24 '15 at 21:41
0

I will advice you to check first, if either your camera object or your holder object are null in your surfaceCreathed method. You should also check if you have already opened your camera: camera.open()

AitorTheRed
  • 553
  • 4
  • 15