Nexus 10, Front facing camera Preview is black (no preview)
Asked Answered
R

3

7

So I'm working on a Camera related project, and I've been testing it on many devices and all of them passed the tests except for the Nexus 10.

I can't really figure out what is going on, and there is no one talking about the issue online.

I was able to replicate the issue on two different Nexus 10 (wifi) devices.

Here is my activity's code:

public class MainActivity extends Activity {
    private static Camera mCamera;
    private static boolean mCameraOpen;
    private static ImageView mPreviewImageView;
    private SurfaceView mPreviewSurfaceView;
    private static boolean mPreviewRunning;
    private static Handler mHandler;
    private static int TESTS_COUNT = 0;
    private Camera.Parameters mCameraParameters;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        mHandler = new Handler();
        mPreviewSurfaceView = (SurfaceView) findViewById(R.id.surfaceview);
        mPreviewImageView = (ImageView) findViewById(R.id.imageview);
        mPreviewSurfaceView.getHolder().addCallback(mCallback);

        TextView view = (TextView) findViewById(R.id.textview);
        view.setText("Format: " + String.valueOf(TESTS_COUNT));

    }

    @Override
    public void onResume(){
        super.onResume();
        if (mCamera == null){
            for (int i = 0; i < Camera.getNumberOfCameras(); i++){
                Camera.CameraInfo info = new Camera.CameraInfo();
                Camera.getCameraInfo(i, info);

                if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT){
                    mCamera = Camera.open(i);
                    Camera.Parameters params = mCamera.getParameters();
                    params.set("camera-id", 2);
                    List<Integer> formats = params.getSupportedPreviewFormats();
                    if (formats.size() > TESTS_COUNT) {
                        Log.e("Camera", "testing preview format at index: " + TESTS_COUNT);
                        params.setPreviewFormat(formats.get(TESTS_COUNT));
                        mCamera.setParameters(params);
                        mCameraOpen = true;
                        SurfaceHolder holder = mPreviewSurfaceView.getHolder();
                        if (holder != null && holder.getSurface() != null && holder.getSurface().isValid()) {
                            mCallback.surfaceCreated(holder);
                        }
                        mCameraParameters = params;
                        break;
                    } else {
                        finish();
                    }
                }

            }
        }
    }

    @Override
    public void onPause(){
        super.onPause();
        if (mPreviewRunning){
            mCamera.stopPreview();
            mCamera.setPreviewCallback(null);
            mPreviewRunning = false;
        }

        if (mCameraOpen){
            mCamera.release();
            mCamera = null;
            mCameraOpen = false;
        }
    }

    @Override
    public void onDestroy(){
        super.onDestroy();

    }

    private final SurfaceHolder.Callback mCallback =  new SurfaceHolder.Callback() {
        @Override
        public void surfaceCreated(SurfaceHolder surfaceHolder) {
                if (mCameraOpen && mCamera != null){
                    try {
                        mCamera.setPreviewDisplay(surfaceHolder);
                        mCamera.setPreviewCallback(new Camera.PreviewCallback() {
                            private int count;
                            private int total;
                            @Override
                            public void onPreviewFrame(byte[] bytes, Camera camera) {
                                if (count == 15){
                                    Camera.Size previewSize = mCamera.getParameters().getPreviewSize();
                                    // pWidth and pHeight define the size of the preview Frame
                                    ByteArrayOutputStream out = new ByteArrayOutputStream();

                                    // Alter the second parameter of this to the actual format you are receiving
                                    YuvImage yuv = new YuvImage(bytes, ImageFormat.NV21, previewSize.width, previewSize.height, null);

                                    // bWidth and bHeight define the size of the bitmap you wish the fill with the preview image
                                    yuv.compressToJpeg(new Rect(0, 0, previewSize.width, previewSize.height), 50, out);
                                    byte[] bitmapBytes = out.toByteArray();
                                    final Bitmap bitmap= BitmapFactory.decodeByteArray(bitmapBytes, 0, bitmapBytes.length);
                                    mHandler.post(new Runnable() {
                                        @Override
                                        public void run() {
                                            mPreviewImageView.setImageBitmap(bitmap);
                                        }
                                    });
                                    count = 0;
                                    total++;
                                    if (total > 5){
                                        TESTS_COUNT++;
                                        if (TESTS_COUNT == mCameraParameters.getSupportedPreviewSizes().size()) {
                                            finish();
                                            return;
                                        }
                                        Intent intent = new Intent( MainActivity.this, MainActivity.class);
                                        startActivity(intent);

                                    }

                                } else {
                                    count++;
                                }

                            }
                        });

                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
        }

        @Override
        public void surfaceChanged(SurfaceHolder surfaceHolder,  int format, int width, int height) {
            for (Camera.Size size : mCameraParameters.getSupportedPreviewSizes()){
                if (size.width == width && size.height == height){
                    if (mCameraOpen && mCamera != null && mPreviewRunning == false) {
                        mCameraParameters.setPreviewSize(width, height);
                        mCamera.setParameters(mCameraParameters);

                        mCamera.startPreview();

                        mPreviewRunning = true;
                        break;
                    }
                }
            }
            if (mPreviewRunning == false){
                Log.e("CameraPreview", "size not supported");
            }

        }

        @Override
        public void surfaceDestroyed(SurfaceHolder surfaceHolder) {

        }
    };

}

My layout:

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity"
    android:orientation="vertical"
    android:weightSum="2">
    <TextView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello"/>
<LinearLayout
    android:layout_width="match_parent"
    android:layout_height="match_parent" tools:context=".MainActivity"
    android:orientation="horizontal"
    android:layout_weight="1"
    android:weightSum="2">
        <SurfaceView
            android:layout_width="640px"
            android:layout_height="480px"
            android:id="@+id/surfaceview"/>
        <ImageView
            android:layout_width="0dp"
            android:layout_height="match_parent"
            android:layout_weight="1"
            android:id="@+id/imageview"/>
        <TextView
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:id="@+id/textview"
            android:textSize="40sp"/>
</LinearLayout>
</LinearLayout>

and manifest :

<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" />
<uses-feature android:name="android.hardware.camera.autofocus" />

There is no error messages and the screen is just black

Screenshot

Ranking answered 10/9, 2015 at 18:36 Comment(0)
A
1

Please verify your device by using an app called CtsVerifier, this app is included in the Android Open Source Project and is part of the Compatibility test suite for android devices(CTS). CTS Verifier have a series of tests that check the camera.check this link

You can be sure that if the front camera does not work within this app. Then your device is probably damaged, or some corruption has occurred on the hal layer. If that is the case you may attempt to downgrade/upgrade your android os. If not it probably is hardware damage.

Andrew answered 20/9, 2015 at 17:44 Comment(0)
U
6

The underlying question is, "How to debug this?" The answer, as always, is to think of as many hypotheses as possible that could explain these results, then test those hypotheses.

Here are some hypotheses (do think of more):

  • It's not finding any cameras.
  • It's not finding any front-facing cameras.
  • It's misinterpreting the camera parameters.
  • It's setting up mCallback too late, that is, after needed.
  • It's not finding a valid surface.
  • It's not successfully registering for camera frames.
  • It's registering but not receiving any camera frames.
  • It's receiving camera frames but failing to display them, e.g. the images aren't in the expected format, or the setImageBitmap(bitmap) Runnable isn't running.
  • TESTS_COUNT isn't doing what you want it to do.

You can test hypotheses via logging, but for much of this it'd be quicker and more informative to single-step through it in the debugger and examine data values such as params.

If you're not familiar with the debugger, now's the time!

Unchain answered 13/9, 2015 at 2:51 Comment(4)
Logging is a fine way to test hypotheses as long as you have some to test. I hope you're not looking for someone to buy this device and debug your code for you. We're here to teach and shed light.Unchain
You could be right about that. The question did not mention that concern nor the lack of device access. Do you know if these two devices have working front cameras as currently configured?Unchain
Please verify your device by using an app called CtsVerifier, this app is included in the Android Open Source Project and is part of the Compatibility test suite for android devices(CTS). CTS Verifier have a series of tests that check the camera.(check source.android.com/compatibility/cts/verifier.html) You can be sure that if the front camera does not work within this app. Then your device is probably damaged, or some corruption has ocurred on the hal layer. If that is the case you may attempt to downgrade/upgrade your android os. If not it probably is hardware damage.Andrew
@Andrew I'm going to do that, please make your comment an answer so that I can accept it, this is the closest I think to make sure that the platform is damaged or not.Ranking
A
1

Please verify your device by using an app called CtsVerifier, this app is included in the Android Open Source Project and is part of the Compatibility test suite for android devices(CTS). CTS Verifier have a series of tests that check the camera.check this link

You can be sure that if the front camera does not work within this app. Then your device is probably damaged, or some corruption has occurred on the hal layer. If that is the case you may attempt to downgrade/upgrade your android os. If not it probably is hardware damage.

Andrew answered 20/9, 2015 at 17:44 Comment(0)
F
0

I test the activity on an Nexus 10 with Lollipop 5.1. I notice sometimes, expectially when i rotate the screen, the application crashes. I fix this problem modifying the beginning of method surfaceChanged with:

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

Moreover, if you want to study a working example about using camera hardware on android, you can consult the project android_instacam and its source code.

Farica answered 18/9, 2015 at 2:5 Comment(7)
The code does not crash after the fix when I rotate the screen and when I put on pause the screen. Istacam works on nexus 10, with both camera. It has only a problem with the aspect ratio.Farica
Your code with my fix works (display camera preview) on Nexus10.Farica
Sorry I test it again. After some seconds thepreview camera stop to work. I suggest you to start with source code of istacam.Farica
Format 0 works perfectly. Format 1 display preview and freeze, Format 2 display black preview.Farica
In the manifest of the app you will see that it has the minSdkVersion with value 15 (Android 4.0.3).Farica
Ok, just because i'm curious.. why did you not update Nexus 10 to Lollipop? Having lastest version of OS it's the reason to buy devices of the Nexus's family...Farica
This device is running on AWS device farm, its the only device that failed the automated UI test. so I can't control it, I can't update it, and I can't debug on it.Ranking

© 2022 - 2024 — McMap. All rights reserved.