如果从未启动相机,则使用摄像头Kotlin应用不会返回图片
在我的应用程序中,我已经遇到了仿真相机的烦人问题。 (在真实设备上是同样的),
从对话框片段中使用了相机,以拍摄后来将上传到远程主机的图片。
private val cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
makeImageWithCamera()
} else {
dismiss()
}
}
private val cameraLauncher = registerForActivityResult(
ActivityResultContracts.TakePicture()
) { isSuccess ->
if (isSuccess) {
path?.let { path ->
viewModel.setPhoto(path = path)
}
}
dismiss()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeFlow(viewModel.action) { dismiss() }
with(binding) {
buttonCamera.setOnClickListener { useCamera() }
buttonCancel.setOnClickListener { dismiss() }
}
}
private fun useCamera() {
val isGranted = ContextCompat.checkSelfPermission(requireContext(), PERM_CAMERA) ==
PackageManager.PERMISSION_GRANTED
if (!isGranted) {
cameraPermissionLauncher.launch(PERM_CAMERA)
} else {
makeImageWithCamera()
}
}
private fun makeImageWithCamera() {
try {
val photoFileName = "photo${id}"
val photosDir = requireContext()
.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val photoFile = File.createTempFile(photoFileName, ".jpg", photosDir)
val photoUri: Uri = FileProvider.getUriForFile(
requireContext(),
"app.provider",
photoFile
)
path = photoFile.absolutePath
cameraLauncher.launch(photoUri)
} catch (err : IOException) {
Log.e(TAG, err.stackTraceToString())
}
}
该问题仅在设备上从未在设备上启动的情况下才会发生:
- 在我的应用程序内,我按下摄像机按钮
- 会收到来自我应用程序的相机使用权的请求并接受。
- 相机应用程序正在启动,并请求自己的权限访问地理位置(它想要在照片中添加基于位置的标签) - 此时,接受或拒绝它是无关紧要的。
- 相机进入现场。现在,如果我按Shot按钮,它会制作照片,并留在场景中,允许制作无限数量的照片,就好像我是常规启动相机应用程序一样。
- 如果我使用BACK按钮返回我的应用程序 - 根本没有任何更改,则对话只是解散。
如果我第二次启动相同的照片,或者只是启动摄像机应用程序本身并接受/拒绝权限请求,所有这些都已修复。相机完全拍摄一杆,并让我接受它,之后它又回到了我的应用程序并收到的照片。
因此,对于用户体验,这种行为可能很烦人,但它的概率很高使Firebase Robotests在这一点上失败。 问题的可能根源是什么?
I've stuck for a while with annoying issue with emulator's camera in my app. (The same is repro on a real device)
The camera is used from a dialog fragment to take a picture that later will be uploaded to remote host.
private val cameraPermissionLauncher = registerForActivityResult(
ActivityResultContracts.RequestPermission()
) { isGranted ->
if (isGranted) {
makeImageWithCamera()
} else {
dismiss()
}
}
private val cameraLauncher = registerForActivityResult(
ActivityResultContracts.TakePicture()
) { isSuccess ->
if (isSuccess) {
path?.let { path ->
viewModel.setPhoto(path = path)
}
}
dismiss()
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
subscribeFlow(viewModel.action) { dismiss() }
with(binding) {
buttonCamera.setOnClickListener { useCamera() }
buttonCancel.setOnClickListener { dismiss() }
}
}
private fun useCamera() {
val isGranted = ContextCompat.checkSelfPermission(requireContext(), PERM_CAMERA) ==
PackageManager.PERMISSION_GRANTED
if (!isGranted) {
cameraPermissionLauncher.launch(PERM_CAMERA)
} else {
makeImageWithCamera()
}
}
private fun makeImageWithCamera() {
try {
val photoFileName = "photo${id}"
val photosDir = requireContext()
.getExternalFilesDir(Environment.DIRECTORY_PICTURES)
val photoFile = File.createTempFile(photoFileName, ".jpg", photosDir)
val photoUri: Uri = FileProvider.getUriForFile(
requireContext(),
"app.provider",
photoFile
)
path = photoFile.absolutePath
cameraLauncher.launch(photoUri)
} catch (err : IOException) {
Log.e(TAG, err.stackTraceToString())
}
}
The issue happens only in situation when camera itself is never launched on a device:
- Inside my app I press camera button
- Receive a request for camera usage permission from my app and accept it.
- Camera app is starting and requests its own permission to access geolocation (it wants to add location-based tags to photos) - at this point it is irrelevant wether to accept or deny it.
- Camera enters the scene. Now if I press shot button it makes a photo and stays in the scene allowing to make infinite amount of photos, as if I've launched Camera app in regular way.
- If I use back button to return to my app - nothing have change at all, dialog is just dismisses.
If I launch the same second time, or just launch Camera app itself and accept/deny permissions request from it, all is fixed. Camera takes exactly one shot and allows me to accept it, after that it comes back to my app and processes received photo.
So while for the user experience this behaviour can be just annoying, it with a high probability makes the Firebase robotests to fail on this point.
What could be the possible root of a problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论