我使用的是 Unity 2022.2.7 和 Vuforia Engine v10.14.4。为了进行测试,我使用了 Android 版本 12 的小米 11 Lite 5G NE。这是我使用的代码:
public void ToggleFlashLight()
{
if(isFlashLightOn)
{
isFlashLightOn = false;
}
else
{
isFlashLightOn = true;
}
bool wasFlashLisgtActivated = VuforiaBehaviour.Instance.CameraDevice.SetFlash(isFlashLightOn);
Debug.Log("flashlight is on: " + wasFlashLisgtActivated);
}
我从一个按钮调用
ToggleFlashLight()
函数。但它不会打开手电筒。当我按下按钮时,Android logcat 中的输出是“手电筒打开:False”和“无法设置相机闪光灯模式”。当我调用这个函数时,Vuforia 已经初始化,并且相机已经在工作,所以这不是问题。
这是我的 AndroidManifest:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.unity3d.player" >
<uses-sdk
android:minSdkVersion="26"
android:targetSdkVersion="32" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:glEsVersion="0x00030000" />
<uses-feature
android:name="android.hardware.camera"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.autofocus"
android:required="false" />
<uses-feature
android:name="android.hardware.camera.front"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen.multitouch"
android:required="false" />
<uses-feature
android:name="android.hardware.touchscreen.multitouch.distinct"
android:required="false" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<application android:extractNativeLibs="true" >
<meta-data
android:name="unity.splash-mode"
android:value="0" />
<meta-data
android:name="unity.splash-enable"
android:value="True" />
<meta-data
android:name="unity.launch-fullscreen"
android:value="True" />
<meta-data
android:name="unity.allow-resizable-window"
android:value="False" />
<meta-data
android:name="notch.config"
android:value="portrait|landscape" />
<activity
android:name="com.unity3d.player.UnityPlayerActivity"
android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density"
android:exported="true"
android:hardwareAccelerated="false"
android:launchMode="singleTask"
android:resizeableActivity="false"
android:screenOrientation="portrait"
android:theme="@style/UnityThemeSelector" >
<intent-filter>
<category android:name="android.intent.category.LAUNCHER" />
<action android:name="android.intent.action.MAIN" />
</intent-filter>
<meta-data
android:name="unityplayer.UnityActivity"
android:value="true" />
<meta-data
android:name="notch_support"
android:value="true" />
</activity>
<receiver
android:name="com.unity.androidnotifications.UnityNotificationManager"
android:exported="false" />
<receiver
android:name="com.unity.androidnotifications.UnityNotificationRestartOnBootReceiver"
android:enabled="false"
android:exported="false" >
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
</receiver>
<meta-data
android:name="com.unity.androidnotifications.exact_scheduling"
android:value="0" />
<meta-data
android:name="com.google.ar.core"
android:value="optional" />
</application>
</manifest>
确保您的进程有权使用相机硬件,并且您应该能够使用您的代码切换闪光灯
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.flashlightapp">
<!-- Required permission -->
<uses-permission android:name="android.permission.CAMERA" />
</manifest>
然后还要求用户使用以下 Android Xamarin C# 代码向应用程序授予在运行时使用相机硬件的权限。
using Android;
using Android.Content.PM;
using Android.Support.V4.App;
class Activity:AppCompatActivity{
void RequestPermisions(){
// Check if the camera permission is granted
if(ContextCompat.CheckSelfPermission(this,
Manifest.Permission.Camera) == Permission.Granted)
{
// Camera permission already granted, you can proceed with using the flashslight
}
else
{
// Camera permission not granted, request it
ActivityCompat.RequestPermissions(this,
new string[] { Manifest.Permission.Camera }, 0);
}
protected override void OnCreate(Bundle savedInstanceState){
base.Oncreate(savedInstanceState);
//request permissions
RequestPermissions();
}
}
Android 上的 Vuforia 引擎默认使用 ARCore,它可以完全控制本机相机 API。不幸的是,ARCore API 不公开 Flash 控件(参见此处的讨论https://github.com/google-ar/arcore-android-sdk/issues/153)。这就是 Engine Flash API 不起作用的原因。
通过设置不同的 Fusion Provider (https://library.vuforia.com/environments/vuforia-fusion#fusion-apis),Vuforia 可以在没有 ARCore 的情况下直接使用原生相机。这将使 Flash 工作。然而,它是有代价的,因为一些引擎功能(例如,设备跟踪器)也需要 ARCore 才能正常运行(参见https://library.vuforia.com/platform-support/recommended-devices)。