Я довольно новичок в программировании с Kotlin, и я пытаюсь создать приложение, которое снимает видео. Я попытался выполнить шаги, описанные здесь и здесь , но в обоих случаях я получаю ту же неизвестную ошибку от Android Studio (показано на этом изображении - код выхода 1073741819 (0xC0000005)). Я не уверен, что делаю неправильно, но я даже не знаю, с чего начать, чтобы решить мою проблему. У меня приличный компьютер, и моя память и графический процессор не используются до того, как я запустил этот код, поэтому я не думаю, что это аппаратная проблема. Вот мой код для обоих учебников:
Первый учебник (использует TextureView):
class CameraActivity : AppCompatActivity()
{
// JLELSE CODE
private val CAMERA_REQUEST_CODE = 200
private var cameraManager: CameraManager? = null
private var cameraFacing: Int = 0
private var surfaceTextureListener: TextureView.SurfaceTextureListener? = null
private var previewSize: Size? = null
private var cameraId: String = ""
private var backgroundThread: HandlerThread? = null
private var backgroundHandler: Handler? = null
private var cameraDevice: CameraDevice? = null
private var captureRequestBuilder: CaptureRequest.Builder? = null
private var captureRequest: CaptureRequest? = null
private var cameraCaptureSession: CameraCaptureSession? = null
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
// JLELSE CODE
ActivityCompat.requestPermissions(this, Array<String>(1) { Manifest.permission.CAMERA }, this.CAMERA_REQUEST_CODE)
this.cameraManager = getSystemService(Context.CAMERA_SERVICE) as? CameraManager
this.cameraFacing = CameraCharacteristics.LENS_FACING_BACK
surfaceTextureListener = object: TextureView.SurfaceTextureListener
{
override fun onSurfaceTextureAvailable(surface: SurfaceTexture?, width: Int, height: Int)
{
//Log.d(TAG, "width: $width height: $height")
setUpCamera()
openCamera()
}
override fun onSurfaceTextureSizeChanged(surface: SurfaceTexture?, width: Int, height: Int)
{
}
override fun onSurfaceTextureDestroyed(surface: SurfaceTexture?): Boolean
{
return false
}
override fun onSurfaceTextureUpdated(surface: SurfaceTexture?)
{
}
}
}
private fun setUpCamera()
{
try
{
for (cameraId in cameraManager?.cameraIdList!!)
{
var cameraCharacteristics = cameraManager!!.getCameraCharacteristics(cameraId)
if (cameraCharacteristics.get(CameraCharacteristics.LENS_FACING) == cameraFacing)
{
var streamConfigurationMap = cameraCharacteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)
this.previewSize = streamConfigurationMap?.getOutputSizes(SurfaceTexture::class.java)?.get(0)
this.cameraId = cameraId
}
}
}
catch (e: CameraAccessException)
{
e.printStackTrace()
}
}
private fun openCamera()
{
try
{
if (ActivityCompat.checkSelfPermission(this, android.Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED)
{
cameraManager?.openCamera(cameraId, object: CameraDevice.StateCallback()
{
override fun onOpened(cameraDevice: CameraDevice) {
this@CameraActivity.cameraDevice = cameraDevice
createPreviewSession()
}
override fun onDisconnected(cameraDevice: CameraDevice) {
cameraDevice.close()
this@CameraActivity.cameraDevice = null
}
override fun onError(cameraDevice: CameraDevice, error: Int) {
cameraDevice.close()
this@CameraActivity.cameraDevice = null
}
}, backgroundHandler)
}
}
catch (e: CameraAccessException)
{
e.printStackTrace()
}
}
private fun openBackgroundThread()
{
backgroundThread = object: HandlerThread("camera_background_thread") { }
(backgroundThread as HandlerThread).start()
backgroundHandler = object: Handler((backgroundThread as HandlerThread).looper) { }
}
override fun onResume()
{
super.onResume()
openBackgroundThread()
if (textureView.isAvailable)
{
setUpCamera()
openCamera()
}
else
{
textureView.surfaceTextureListener = surfaceTextureListener
}
}
override fun onStop()
{
super.onStop()
closeCamera()
closeBackgroundThread()
}
private fun closeCamera()
{
if (cameraCaptureSession != null)
{
cameraCaptureSession!!.close()
cameraCaptureSession = null
}
if (cameraDevice != null)
{
cameraDevice!!.close()
cameraDevice = null
}
}
private fun closeBackgroundThread()
{
if (backgroundHandler != null)
{
backgroundThread!!.quitSafely()
backgroundThread = null
backgroundHandler = null
}
}
private fun createPreviewSession()
{
try
{
var surfaceTexture = textureView.surfaceTexture
surfaceTexture.setDefaultBufferSize(previewSize!!.width, previewSize!!.height)
var previewSurface = object: Surface(surfaceTexture) {}
captureRequestBuilder = cameraDevice!!.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW)
captureRequestBuilder!!.addTarget(previewSurface)
cameraDevice!!.createCaptureSession(mutableListOf(previewSurface) as List<Surface>, object: CameraCaptureSession.StateCallback()
{
override fun onConfigured(cameraCaptureSession: CameraCaptureSession)
{
if (cameraDevice == null)
{
return
}
try
{
captureRequest = captureRequestBuilder!!.build()
this@CameraActivity.cameraCaptureSession = cameraCaptureSession
this@CameraActivity.cameraCaptureSession!!.setRepeatingRequest(captureRequest!!, null, backgroundHandler)
}
catch (e: Exception)
{
e.printStackTrace()
}
}
override fun onConfigureFailed(session: CameraCaptureSession)
{
//TODO("Not yet implemented")
}
}, backgroundHandler)
}
catch (e: Exception)
{
e.printStackTrace()
}
}
}
Второй учебник (использует SurfaceView):
/** Helper to ask camera permission. */
object CameraPermissionHelper
{
private const val CAMERA_PERMISSION_CODE = 0
private const val CAMERA_PERMISSION = Manifest.permission.CAMERA
/** Check to see we have the necessary permissions for the app. */
fun hasCameraPermission(activity: Activity): Boolean
{
return ContextCompat.checkSelfPermission(activity, CAMERA_PERMISSION) == PackageManager.PERMISSION_GRANTED
}
/** Check to see we have the necessary permissions for the app, and ask them if we don't. */
fun requestCameraPermission(activity: Activity)
{
ActivityCompat.requestPermissions(activity, arrayOf(CAMERA_PERMISSION), CAMERA_PERMISSION_CODE)
}
/** Check to see if we need to show the rationale for this permission. */
fun shouldShowRequestPermissionRationale(activity: Activity): Boolean
{
return ActivityCompat.shouldShowRequestPermissionRationale(activity, CAMERA_PERMISSION)
}
/** Launch Application Setting to grant permission. */
fun launchPermissionSettings(activity: Activity)
{
val intent = Intent()
intent.action = Settings.ACTION_APPLICATION_DETAILS_SETTINGS
intent.data = Uri.fromParts("package", activity.packageName, null)
activity.startActivity(intent)
}
}
// MEDIUM CODE
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray )
{
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (!CameraPermissionHelper.hasCameraPermission(this))
{
Toast.makeText(this, "Camera permission is needed to run this application", Toast.LENGTH_LONG).show()
if (!CameraPermissionHelper.shouldShowRequestPermissionRationale((this)))
{
// Permission denied with checking "Do not ask again."
CameraPermissionHelper.launchPermissionSettings(this)
}
finish()
}
recreate()
}
// MEDIUM CODE
override fun onCreate(savedInstanceState: Bundle?)
{
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_camera)
if (!CameraPermissionHelper.hasCameraPermission(this))
{
CameraPermissionHelper.requestCameraPermission(this)
return
}
surfaceView.holder.addCallback(surfaceReadyCallback)
}
// MEDIUM CODE
private fun startCameraSession()
{
val cameraManager = getSystemService(Context.CAMERA_SERVICE) as CameraManager
if (cameraManager.cameraIdList.isEmpty())
{
// no cameras
return
}
val firstCamera = cameraManager.cameraIdList[0]
if (ActivityCompat.checkSelfPermission(this, Manifest.permission.CAMERA) != PackageManager.PERMISSION_GRANTED)
{
// TODO: Consider calling
// ActivityCompat#requestPermissions
// here to request the missing permissions, and then overriding
// public void onRequestPermissionsResult(int requestCode, String[] permissions,
// int[] grantResults)
// to handle the case where the user grants the permission. See the documentation
// for ActivityCompat#requestPermissions for more details.
return
}
cameraManager.openCamera(firstCamera, object: CameraDevice.StateCallback()
{
override fun onDisconnected(cameraDevice: CameraDevice)
{
//cameraDevice.close()
//CameraActivity.this.cameraDevice = null
}
override fun onError(cameraDevice: CameraDevice, error: Int)
{
//cameraDevice.close()
//CameraActivity.this.cameraDevice = null
}
override fun onOpened(cameraDevice: CameraDevice)
{
// use the camera
val cameraCharacteristics = cameraManager.getCameraCharacteristics(cameraDevice.id)
cameraCharacteristics[CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP]?.let { streamConfigurationMap ->
streamConfigurationMap.getOutputSizes(ImageFormat.YUV_420_888)?.let { yuvSizes ->
val previewSize = yuvSizes.last() // lowest resolution size
val displayRotation = windowManager.defaultDisplay.rotation
val swappedDimensions = areDimensionsSwapped(displayRotation, cameraCharacteristics)
// swap width and height if needed
val rotatedPreviewWidth = if (swappedDimensions) previewSize.height else previewSize.width
val rotatedPreviewHeight = if (swappedDimensions) previewSize.width else previewSize.height
surfaceView.holder.setFixedSize(rotatedPreviewWidth, rotatedPreviewHeight)
val previewSurface = surfaceView.holder.surface
val captureCallback = object: CameraCaptureSession.StateCallback()
{
override fun onConfigureFailed(session: CameraCaptureSession)
{
//TODO("Not yet implemented")
}
override fun onConfigured(session: CameraCaptureSession)
{
/*
if (cameraDevice == null)
{
return
}
*/
// session configured
val previewRequestBuilder = cameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_PREVIEW).apply {
addTarget(previewSurface)
}
session.setRepeatingRequest(previewRequestBuilder.build(), object: CameraCaptureSession.CaptureCallback() {}, Handler { true })
}
}
cameraDevice.createCaptureSession(mutableListOf(previewSurface), captureCallback, Handler { true })
}
}
}
}, Handler { true })
}
// MEDIUM CODE
private fun areDimensionsSwapped(displayRotation: Int, cameraCharacteristics: CameraCharacteristics): Boolean
{
var swappedDimensions = false
when (displayRotation)
{
Surface.ROTATION_0, Surface.ROTATION_180 ->
{
if (cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) == 90 || cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) == 270)
{
swappedDimensions = true
}
}
Surface.ROTATION_90, Surface.ROTATION_270 ->
{
if (cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) == 0 || cameraCharacteristics.get(CameraCharacteristics.SENSOR_ORIENTATION) == 180)
{
swappedDimensions = true
}
}
else ->
{
// invalid display rotation
}
}
return swappedDimensions
}
// MEDIUM CODE
private val surfaceReadyCallback = object: SurfaceHolder.Callback
{
override fun surfaceChanged( holder: SurfaceHolder?, format: Int, width: Int, height: Int)
{
}
override fun surfaceDestroyed(holder: SurfaceHolder?)
{
}
override fun surfaceCreated(holder: SurfaceHolder?)
{
startCameraSession()
}
}