【问题标题】:How to use Android's camera or camera2 API to support old and new API versions without deprecation notes?如何使用 Android 的 camera 或 camera2 API 来支持新旧 API 版本而没有弃用说明?
【发布时间】:2015-02-01 01:58:37
【问题描述】:

新的 camera2 API 让我很困惑。我想开发一个使用设备摄像头的应用(适用于 Android API 10 - 21)。如here 所述,我应该使用“相机”API。

但是,当我尝试将“相机”API (android.hardware.Camera) 添加到清单的用户功能时,it is marked as deprecated。另一方面,我无法将其更改为“camera2”API (android.hardware.camera2),因为它仅与 Android API 21+(Android 5 - Lollipop)兼容 - 会链接它也是,但我只能添加 2 个链接。

我不仅希望我的应用在旧版本的 Android 上运行,而且还希望在最新版本上运行...

【问题讨论】:

    标签: android camera android-camera android-camera2


    【解决方案1】:

    即使旧的相机 API 被标记为已弃用,它仍然可以正常工作,并且会在很长一段时间内保持这种状态(因为目前 Play 商店中几乎所有使用相机的应用程序都在使用它)。

    您必须忽略 Android Studio 关于它已被弃用的抱怨,但如果您想支持早于 21 的 Android 版本,则必须使用旧 API。

    在 API 级别 21 上,您当然可以使用新的 API 及其新功能,但目前如果您在 API 之间切换,您必须在应用中维护一个完全独立的流程。不幸的是,这两个 API 的世界观完全不同,因此很难编写一个支持库,让您在旧设备上也可以使用类似新 API 的东西(如果没有,库从新 API 映射到旧 API API 21+)。

    【讨论】:

    • 好答案。因此,如果您想支持 API 级别 16 及更高级别,最好还是暂时使用旧相机,对吧?
    • 所以唯一的办法就是用if语句和android.os.Build.VERSION.SDK_INT分开代码?
    • 所以对于开发人员来说,如果您只针对 API 21 及更高版本,请使用 Camera2,但如果您需要旧版支持,请使用 Camera?或者您会建议使用不同的 API 检测构建版本并编写 2 种不同的方法吗?
    • 这取决于你的应用做什么。如果相机功能是简单的傻瓜相机,并且您想要针对旧 API,只需使用旧相机 API。但是,如果您想做的不仅仅是抓取 JPEG 和绘制预览,或者如果您只是针对新的 API,请使用 camera2。在(硬)中间是想要在 camera2 上提供花哨的可选功能但也可以在旧设备上工作的应用程序。在那里,您必须构建两个单独的代码路径,每个 API 一个。
    • 弃用相机 API 是一个错误,他们应该引入相机高级 API(用于高级应用程序,例如成熟的相机应用程序) - 否则(大多数)应用程序使用相机只是为了拍照将不得不维护2个api。谷歌至少应该引入一个紧凑的库(一如既往)
    【解决方案2】:

    将所有需要的相机方法放在一个接口中,然后像这样创建一个相机实例

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            Log.d(TAG, "camera2 selected");
            this.camera = new Camera2(getContext());
        } else {
            Log.d(TAG, "camera1 selected");
            this.camera = new Camera1(getContext());
        }
    

    这样你就可以把所有的东西都分开了,这会让你的生活变得更轻松。

    忠告 - 使用 camera2 的生活并不是那么美好。供应商仍然在做垃圾实现,因此您将不得不添加许多条件和解决方法。

    示例 1 - S6 报告它不支持闪存 :) 示例 2 - LG 设备报告支持的图像尺寸列表 - 但实际上并非所有这些尺寸都受支持!!

    【讨论】:

    • 这是真的。 camera 2 API 实际上将相机设备分为三类:LEGACY、LIMITED 和 FULL。如果相机被归类为 LEGACY,那么所有的 camera2 API 调用都在引擎盖下被转换为 camera1,所以真的不值得费心。我的建议是调用CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraID); if (characteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL) == CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL_LEGACY)...,如果是真的选择旧的API。
    【解决方案3】:

    要支持您想要的 api,请使用以下代码。只需确定相应的名称对应的 api 级别。例如,API 21 是 LOLLIPOP,API 15 是 ICE_CREAM_SANDWICH_MR1。

     if ((Build.VERSION.SDK_INT >= Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)  
                                        && ((Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP))) {
               // your code here - is between 15-21
    
     } else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
               // your code here - is api 21
     }
    

    【讨论】:

    • 这对于完整的相机实现来说几乎是不切实际的。另外,现在您必须维护两个代码路径。版本检查在 android 开发中确实有用,但不是这样。
    • 如果用户运行 Build.VERSION_CODES.LOLLIPOP_MR1 会发生什么?或者上面的东西?我认为您的第二次检查应该是“else if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP)”
    • 亲爱的,如果我的应用程序应该在 16 和更新的 api 中运行,我该如何构建相同的 apk camera2 和旧 api?口味对这项工作有好处吗?
    • 你必须实现这两个api。只需保留一个接口和两个类,其中实现了相机功能。在创建运行相机的实例之一之前,调用上面提到的方法,这样它就可以找出调用哪个类和功能
    【解决方案4】:

    虽然 Google 推荐使用 Camera2 Api >= 21,但手动设置可能会有问题。

    当您需要使用自动设置模式拍摄照片时,它可以正常工作。 但!如果需要创建具有手动设置模式实现的应用,对于 API >= 21 的设备,首先需要检查支持的硬件级别:

    选择摄像头(正面、正面),获取其特征并检查硬件级别。

    mCameraCharacteristics = mCameraManager.getCameraCharacteristics(mCameraId)
    
    val level = mCameraCharacteristics.get(CameraCharacteristics.INFO_SUPPORTED_HARDWARE_LEVEL)
    

    CameraCharacteristics 表示下一个支持的级别: LIMITED、FULL、LEGACY、LEVEL_3、EXTERNAL。

    概括地说,级别是:

    LEGACY 设备以向后兼容模式运行,适用于较旧的 Android 设备,并且功能非常有限。

    LIMITED 设备代表基线功能集,还可能包含属于 FULL 子集的其他功能。

    FULL 设备还支持每帧手动控制传感器、闪光灯、镜头和后处理设置,以及高速图像捕获。

    LEVEL_3 设备还支持 YUV 再处理和 RAW 图像捕获,以及额外的输出流配置。

    如果您获得了 LEGACY 支持级别,则应该使用旧的 Camera Api

    【讨论】:

      【解决方案5】:

      使用支持注解

          @TargetApi(21)
      

      避免检查

      【讨论】:

      • 所以你不支持21之前的安卓设备!
      【解决方案6】:

      我发现最好的选择是创建两个活动。使用通用方式检查当前设备 API

      Intent i;
      if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
          i = new Intent(context,camera2.class)
      } else {
          i = new Intent(context,camera.class);
      }
      startActivity(i);
      

      这样我在回顾代码时不必有很多困惑。代码是分开的,很容易修改。

      【讨论】:

        【解决方案7】:

        请阅读链接Camera Version Support 他们说......
        相机 API1
        Android 5.0 弃用了 Camera API1,随着新平台的开发侧重于 Camera API2,该 API1 将继续被淘汰。但是,淘汰期会很长,Android 版本将在一段时间内继续支持 Camera API1 应用程序。具体来说,继续支持:

      • 应用程序的相机 API1 接口。基于 Camera API1 构建的相机应用程序应该可以像在运行早期 Android 版本的设备上一样工作。
      • 相机 HAL 版本。包括对相机 HAL1.0 的支持。
      • 【讨论】:

          猜你喜欢
          • 2016-02-14
          • 2012-04-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-03-29
          • 1970-01-01
          相关资源
          最近更新 更多