Android Camerax 在真实设备上崩溃
Posted
技术标签:
【中文标题】Android Camerax 在真实设备上崩溃【英文标题】:Android Camerax crash on real devices 【发布时间】:2020-04-23 03:19:34 【问题描述】:我开始在我的 android 应用程序中使用 CameraX (1.0.8 alpha) 库,并且在真正的三星 A50 设备 + 模拟器上进行开发期间一切正常。但是当它发布到 Play 商店时 - 我在 Pixel 2XL 和 Nexus 5X 设备上看到了很多崩溃(我在此设备的模拟器上尝试了我的应用程序,但一切都是工作正常)。
我只是调用 bindToLifecle:
Fatal Exception: java.lang.IllegalArgumentException: Can not get supported output size under supported maximum for the format: 34
at androidx.camera.camera2.internal.SupportedSurfaceCombination.getSupportedOutputSizes(SupportedSurfaceCombination.java:29)
at androidx.camera.camera2.internal.Camera2DeviceSurfaceManager.getSuggestedResolutions(Camera2DeviceSurfaceManager.java:29)
at androidx.camera.core.CameraX.calculateSuggestedResolutions(CameraX.java:14)
at androidx.camera.lifecycle.ProcessCameraProvider.bindToLifecycle(ProcessCameraProvider.java)
有人遇到过这样的问题吗?
初始化代码:
@SuppressLint("RestrictedApi")
private void definePermissionsCallback()
allPermissionsCheck = Dexter.withActivity(this)
.withPermissions(WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA)
.withListener(new MultiplePermissionsListener()
@Override
public void onPermissionsChecked(MultiplePermissionsReport report)
if (report.areAllPermissionsGranted())
isFileStoragePermissionGiven = true;
isCameraPermissionGiven = true;
SharedPreferences sharedPreferences = getSharedPreferences(APPLICATION_SETTINGS, MODE_PRIVATE);
sharedPreferences.edit().putBoolean(ALLOW_CAMERA, true).apply();
findViewById(R.id.switch_camera).setEnabled(true);
cameraProviderFuture = ProcessCameraProvider.getInstance(MainActivity.this);
cameraProviderFuture.addListener(() ->
try
cameraProvider = (ProcessCameraProvider) cameraProviderFuture.get();
bindPreview();
catch (ExecutionException | InterruptedException e)
Crashlytics.logException(e);
, ContextCompat.getMainExecutor(MainActivity.this));
return;
...
void bindPreview()
cameraProvider.unbindAll();
Preview preview = new Preview.Builder()
.setTargetName("Preview")
.build();
preview.setPreviewSurfaceProvider(previewView.getPreviewSurfaceProvider());
cameraSelector = new CameraSelector.Builder().requireLensFacing(lensFacing).build();
cameraProvider.bindToLifecycle(this, cameraSelector, preview);
【问题讨论】:
请分享您用于设置相机的代码。有两点需要注意: 1. 所有设备对不同格式支持的分辨率都有不同的支持。 2. 对不同配置的支持也因设备而异:有的可以支持full resolution jpeg + full resolution yuv,有的不能。请分享用于设置的代码。 嗨@Minhaz。当然,这是用于初始化的标准代码 - 我已添加到主要问题中。我很惊讶像 Pixel 2 和 Nexus(都是 Google Native)这样的流行设备有这个问题。 补充了我的想法,甚至可能不起作用,但完全值得一试。 【参考方案1】:这可能无法完美回答,我可能是错的,但请尝试以下:
您用于绑定到生命周期的 Preview 实例具有允许使用 setTargetResoltion 或 setTargetAspectRation 设置目标分辨率或目标纵横比的 Builder。
如果没有设置,它会调用
如果未设置,默认选择的分辨率将是与设备屏幕分辨率或 1080p (1920x1080) 匹配的最佳尺寸,以较小者为准。
和
如果未设置,将优先考虑纵横比为 4:3 的分辨率。
分别。
根据错误信息
在格式支持的最大值下无法获得支持的输出大小
它似乎无法获得它试图为某些设备的默认值查找的输出大小。这是可能的,因为相机的 HAL 实现是由 OEM(如诺基亚、华为等)完成的,并且可以支持不同的支持尺寸。如果您想查看给定设备支持的分辨率,可以使用此应用:Camera2Api Probe
指向how Camera X selects automatic resolution的指针
TL;DR; 虽然 API 应该隐式提供这种支持,但在 alpha 中考虑它,尝试显式设置纵横比或目标分辨率,以便它适用于大多数设备。为了使其高度可配置,您可以使用this api查询支持的分辨率
请注意,我与提到的应用程序 Camera2Api 没有链接或所有权,但我用它来查询我工作中设备的 Camera2 信息。
【讨论】:
【参考方案2】:当您使用旧版本或新版本的 lib 时,有时会发生这种情况。尝试改变它
【讨论】:
【参考方案3】:来自官方文档: “CameraX 库处于 alpha 阶段,因为它的 API 表面尚未最终确定。我们不建议在生产中使用 Alpha 库。库应严格避免在生产中依赖 Alpha 库,因为它们的 API 表面可能会在源和二进制不兼容的方式。” 您可以等待稳定版本或使用Camera或Camera2的api。
【讨论】:
【参考方案4】:According to official code:
(outputSizeCandidates.isEmpty() && !isDefaultResolutionSupported)
throw new IllegalArgumentException(
"Can not get supported output size for the desired output size quality for "
+ "the format: "
+ imageFormat);
我在支持旧版相机的设备上也有同样的功能。希望对找到答案有所帮助。
UPD:发生这种情况是因为 CameraX 库无法找到适合显示分辨率的相机输出的最佳分辨率。例如:
显示分辨率:1280x720 支持的最接近的相机分辨率:1920x720 DispRes
如果显示分辨率小于相机分辨率,Lib 可以工作。
例如: 显示分辨率:1280x800 支持的最接近的相机分辨率:1280x720 DispRes > CamRes。成功!
【讨论】:
【参考方案5】:您可以使用这个函数(用 Kotlin 编写)来获取可能的输出大小:
private fun getOutputSizes(lensFacing: Int = CameraCharacteristics.LENS_FACING_BACK): Array<Size>?
val manager = context.getSystemService(Context.CAMERA_SERVICE) as CameraManager
for (cameraId in manager.cameraIdList)
val characteristics = manager.getCameraCharacteristics(cameraId)
val orientation = characteristics[CameraCharacteristics.LENS_FACING]!!
if (orientation == lensFacing)
val configurationMap = characteristics.get(CameraCharacteristics.SCALER_STREAM_CONFIGURATION_MAP)!!
return configurationMap.getOutputSizes(SurfaceTexture::class.java)
return null
只需尝试它们,直到其中一个起作用:
for (outputSize in getOutputSizes()!!)
try
CameraX.bindToLifecycle(this, qrCodePreview.useCase, qrCodeImageAnalysis.useCase)
return
catch (e: IllegalArgumentException)
TODO("No valid output size found, handle error ...")
【讨论】:
以上是关于Android Camerax 在真实设备上崩溃的主要内容,如果未能解决你的问题,请参考以下文章
Xamarin表单,在Visual Studio Android Emulator上运行的应用程序但在真实设备上崩溃
Play商店预发布报告中的Android应用程序崩溃但在真实设备中工作
在flutter中从image_picker包中打开相机会导致真实设备上的应用程序崩溃,但在模拟器(android)中运行良好