kotlin – Cannot start Camera preview for Android 5.0.1 , Fail to connect to camera service-ThrowExceptions

Exception or error:

I am using and Android App to start a Camera preview in order to do some OCR operations , but i can’t make it work on Android 5.0.1 device.

i am getting an error on surfaceCreated :

Fail to connect to camera service

here is my sample code :

class OCRActivity : AppCompatActivity()
{
private var mCameraSource by Delegates.notNull<CameraSource>()
private var textRecognizer by Delegates.notNull<TextRecognizer>()
private var tryToOpenView = false

private val PERMISSION_REQUEST_CAMERA = 100


override fun onCreate(savedInstanceState: Bundle?)
{
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_ocr)

    supportActionBar?.hide()


    window.setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN)

    .......

    generateOCRView()
}


override fun onResume()
{
    super.onResume()
}


private fun generateOCRView()
{
    //  Create text Recognizer
    textRecognizer = TextRecognizer.Builder(this).build()

    if (!textRecognizer.isOperational)
    {
        Toast.makeText(this, MSG, Toast.LENGTH_LONG ).show()
        finish()
        return
    }

    var bestPreviewSize: Camera.Size? = null

    if (isCameraPermissionGranted())
    {
        // Get best preview size for the camera
        val mCamera = Camera.open()

        if (mCamera != null)
        {
            val mCameraParameters = mCamera.parameters

            if (mCameraParameters != null)
            {
                val thisBestPreviewSize = getBestPreviewSize(mCameraParameters)

                if (thisBestPreviewSize != null)
                {
                    bestPreviewSize = thisBestPreviewSize
                }
            }
        }
    }

    //  Init camera source to use high resolution and auto focus
    mCameraSource = if (bestPreviewSize != null)
    {
        CameraSource.Builder(this, textRecognizer)
            .setFacing(CameraSource.CAMERA_FACING_BACK)
            .setAutoFocusEnabled(true)
            .setRequestedFps(30.0f)
            .setRequestedPreviewSize(bestPreviewSize.height, bestPreviewSize.width)
            .build()
    }
    else
    {
        // Default camera size, can be stretched...
        CameraSource.Builder(this, textRecognizer)
            .setFacing(CameraSource.CAMERA_FACING_BACK)
            .setAutoFocusEnabled(true)
            .setRequestedFps(30.0f)
            .setRequestedPreviewSize(1920, 1080)
            .build()
    }

    surface_camera_preview.holder.addCallback(object : SurfaceHolder.Callback
    {

        override fun surfaceChanged(p0: SurfaceHolder?, p1: Int, p2: Int, p3: Int)
        {
            Log.d("surfaceChanged", "surfaceChanged")
            return
        }

        override fun surfaceDestroyed(p0: SurfaceHolder?)
        {
            Log.d("surfaceDestroyed", "surfaceDestroyed")
            mCameraSource.stop()
        }

        @SuppressLint("MissingPermission")
        override fun surfaceCreated(p0: SurfaceHolder?)
        {
            try
            {
                // If the camera permission is granted
                if (isCameraPermissionGranted())
                {
                    Log.d("surfaceCreated", "surfaceCreated with permission granted")
                    // Show camera preview
                    mCameraSource.start(surface_camera_preview.holder)
                }
                else
                {
                    requestForPermission()
                }
            } catch (e: Exception) {
                Log.e(localClassName, "surfaceCreated error:  ${e.message}")
                finish()
            }
        }
    })

    textRecognizer.setProcessor(object : Detector.Processor<TextBlock>
    {
        override fun release()
        {
            return
        }

        override fun receiveDetections(detections: Detector.Detections<TextBlock>)
        {
            val items = detections.detectedItems

            if (items.size() <= 0)
            {
                return
            }

            tryToOpenView = false

            mrzResult.post {
                val stringBuilder = StringBuilder()

                for (i in 0 until items.size())
                {
                    val item = items.valueAt(i)
                    stringBuilder.append(item.value)
                    stringBuilder.append("\n")
                }

                ...........
            }
        }
    })
}

/**
 * isCameraPermissionGranted function: Check if camera permission is granted.
 *
 * @return Boolean: true if camera permission is granted and false if not.
 */
fun isCameraPermissionGranted(): Boolean
{
    return ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED
}

/**
 * requestForPermission function:
 */
private fun requestForPermission()
{
    ActivityCompat.requestPermissions(this, arrayOf(Manifest.permission.CAMERA), PERMISSION_REQUEST_CAMERA)
}


@SuppressLint("MissingPermission")
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray)
{
    // Go back to previous if camera permission is refuses
    if (requestCode != PERMISSION_REQUEST_CAMERA)
    {
        // Go to previous view
        Toast.makeText(this, MSG, Toast.LENGTH_LONG).show()
        finish()
    }
    else
    {
        if (grantResults[0] == PackageManager.PERMISSION_GRANTED)
        {
            // If the camera permission is granted
            if (isCameraPermissionGranted())
            {
                // Show camera preview
                mCameraSource.start(surface_camera_preview.holder)
            }
            else
            {
                // Go to previous view
                Toast.makeText(this, MSG, Toast.LENGTH_LONG).show()
                finish()
            }
        }
        else
        {
            // Go to previous view
            Toast.makeText(this, MSG, Toast.LENGTH_LONG).show()
            finish()
        }
    }
}

private fun getBestPreviewSize(parameters: Camera.Parameters): Camera.Size?
{
    var bestSize: Camera.Size? = null
    val sizeList = parameters.supportedPictureSizes

    bestSize = sizeList[0]

    for (i in 1 until sizeList.size)
    {
        if (sizeList[i].width * sizeList[i].height > bestSize!!.width * bestSize.height)
        {
            bestSize = sizeList[i]
        }
    }

    return bestSize
}

}

How to solve:

Make sure that you set these permissions at the top of your manifest:

<uses-permission android:name="android.permission.CAMERA" />

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

If this isn’t the case, initialize the mCamera as a instance variable outside of your method definition. Hope this helps 🙂

Leave a Reply

Your email address will not be published. Required fields are marked *