Table of Contents

在 Android 應用中啓用 EasyAR 功能

本章介紹如何在 Android Studio 中配置 EasyAR 的 Android 工程,無需使用 Unity 等 3D 引擎。

準備工作

開始之前,您需要準備:

  • 最新版本的 Android Studio

  • JDK 8/11/17

  • Android Gradle Plugin 4.0 或以上

  • Android NDK r28 或以上

  • 獲取 EasyAR 授權許可證

  • 選擇 EasyAR Sense 發佈版本並下載

附註

並非所有安卓設備均支持 EasyAR Sense 的所有功能,部分功能依賴額外硬件或配置,具體可查閱對應功能支持的設備列表。

導入 EasyAR Sense for Android

本節介紹如何在非 Unity 的 Android 工程中導入 EasyAR Sense SDK。 EasyAR Sense 提供 Java 和 C++ API,並支持 Kotlin,您可以使用最習慣的語言進行開發。

由於不同 IDE 的配置方式可能存在差異,這裏僅說明基於 Android Studio + Gradle 的典型配置方式

選擇 API 使用方式

EasyAR Sense for Android 提供兩種 API 使用方式:

  • 僅使用 Java API
  • 使用 Java 和 C++ API

請根據項目需求選擇其中一種進行配置。

僅使用 Java API

當僅使用 EasyAR 的 Java API 時,無需配置 NDK

EasyAR.aar 放入app/libs/ 或 Gradle 指定目錄。

使用 Java 和 C++ API

當需要同時使用 EasyAR 的 C++ API 時,需要同時配置 Java 依賴與原生庫。

  • Java 層文件

    EasyAR.jar 放入 app/libs/ 或 Gradle 指定路徑。

  • 原生庫(.so

    將 EasyAR 提供的原生庫按 ABI 放入以下路徑或 Gradle 指定路徑。

    app/src/main/jniLibs/
    ├── armeabi-v7a/
    │   └── libEasyAR.so
    └── arm64-v8a/
        └── libEasyAR.so
    
  • C++ 頭文件

    將 EasyAR SDK 中 include 目錄下的 easyar 文件夾拷貝到以下路徑或 Android.mk/CMakeLists.txt 指定路徑。

    app/src/main/jni/easyar/
    

    頭文件路徑需在 Android.mkCMakeLists.txt 中顯式指定。

Gradle 配置說明

當您使用 C++ API 時,需要在 Gradle 中啓用 Native Build, 僅適用 Java API 無需配置。 您可以使用 ndk-build(Android.mk)進行配置。

app/build.gradle 中添加:

android {
    externalNativeBuild {
        ndkBuild {
            path "src/main/jni/Android.mk"
        }
    }
}

如果使用 CMake,請參考 Google 官方文檔進行配置。

NDK 配置

聲明 EasyAR 爲預編譯庫

include $(CLEAR_VARS)

# 確保該路徑指向 jniLibs 中當前 ABI 目錄
LOCAL_PATH := $(LOCAL_PATH_TOP)/../jniLibs/$(TARGET_ARCH_ABI)

LOCAL_MODULE := EasyAR
LOCAL_SRC_FILES := libEasyAR.so

include $(PREBUILT_SHARED_LIBRARY)

鏈接 EasyAR 與系統庫

LOCAL_SHARED_LIBRARIES += EasyAR

# OpenGL ES(必需)
LOCAL_LDLIBS += -lGLESv3

EasyAR 運行至少需要 OpenGL ES 2.0,推薦使用 OpenGL ES 3.0(GLESv3)。

指定 ABI 架構

app/build.gradle 中顯式指定 ABI,避免無效架構被打包:

android {
    defaultConfig {
        ndk {
            abiFilters "armeabi-v7a", "arm64-v8a"
        }
    }
}

如果只需要其中一種架構,可只保留對應項。

AndroidManifest 權限配置

EasyAR Sense 需要以下權限,缺失將導致初始化失敗或黑屏:

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

完整示例:

<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="cn.easyar.samples.helloar">

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

</manifest>

初始化 EasyAR

在應用啓動時調用 Engine.initialize 進行初始化。

示例(Java):

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    Engine.initialize(this, key);
}
附註

初始化必須在使用 EasyAR 相關功能之前完成。

額外配置

在 Android 平臺上,根據系統版本及所使用的功能不同,可能還需要注意以下配置和限制。

配置使用 ARCore

如果項目中使用 ARCore,請參考其官方文檔完成 AndroidManifest.xmlbuild.gradle 的相關配置。

此外,在初始化 EasyAR 之前,必須顯式加載 ARCore 的原生庫:

System.loadLibrary("arcore_sdk_c");
附註

使用 ARCore v1.19.0 之前的版本時,在 Android 11 上將無法被檢測到。 這是由於 Android 11 開始引入了應用可見性限制,需要在 AndroidManifest.xml 中聲明 ARCore 包名。

<queries>
    <package android:name="com.google.ar.core" />
    
</queries>

配置混淆(ProGuard)

如果對 Java 代碼啓用混淆,需要 排除 cn.easyar 命名空間

EasyAR Sense 在運行時會通過 JNI 使用 類名反射獲取 Java 類型。 如果 cn.easyar 下的類被混淆或重命名,可能導致未定義行爲。

基本規則

-keep class cn.easyar.** { *; }

推薦的精確規則

-dontwarn javax.annotation.Nonnull
-dontwarn javax.annotation.Nullable
-keepattributes *Annotation*

-keep class cn.easyar.RefBase { native <methods>; }
-keepclassmembers class cn.easyar.* {
    <fields>;
    protected <init>(long, cn.easyar.RefBase);
}
-keep,allowobfuscation interface cn.easyar.FunctorOf* { *; }

-keep class cn.easyar.Buffer { native <methods>; }
-keep class cn.easyar.Engine { native <methods>; }
-keep class cn.easyar.JniUtility { native <methods>; }

-keep class cn.easyar.engine.** { *; }
-keep class cn.easyar.CameraParameters
-keep interface cn.easyar.FunctorOfVoidFromInputFrame

上述 ProGuard 規則 已包含在 EasyAR 的 aar 庫中,通常無需重複配置。

Scoped Storage

Android 10 開始引入的 Scoped Storage(分區存儲) 機制,會對部分依賴文件路徑的 API 造成影響。這是由於 /sdcard 下的非媒體路徑(如自定義目錄)在 Android 10 上無法直接訪問所致。對 EasyAR 的影響體現在部分需要傳入文件路徑的 API(如錄屏)在 Android 10 上,不支持直接讀寫媒體路徑,但是在 Android 11 上可以正常工作。

解決方式

  • 簡便方案(Android 10) 在 AndroidManifest.xml 中禁用 Scoped Storage:

    <application
        android:requestLegacyExternalStorage="true"
        ... >
    </application>
    
  • 推薦方案

    • 僅使用應用內部存儲
    • 或通過 MediaStore 與媒體路徑進行數據交換

Android Gradle Plugin 與 NDK

自 NDK r22 起,默認使用 LLD 鏈接器,並需要配合 llvm-strip 使用;這與 Android Gradle Plugin 4.0 以下版本內置的 strip 工具不兼容。 解決方式:

  • 升級至 Android Gradle Plugin 4.0 或以上
  • 或在 packagingOptions 中使用 doNotStrip 禁用 stripping(不推薦)

Windows 路徑長度限制

在 Windows 系統上,如果工程中任意文件(包括構建過程中生成的臨時文件)的絕對路徑長度超過 260 個字符, 可能會導致 Android Studio 構建失敗。

解決方式

  • 將工程放置在更短路徑下(例如 C:\user\project
  • 避免過深的目錄層級

延伸閱讀