你的浏览器不支持canvas

让我们携手共创奇迹!

Unreal Plugin Language

Date: Author: LBD

本文章采用 知识共享署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可。转载请注明来自WindCrazy

这是一篇关于使用UE中允许插件对某些配置的更改,例如允许插件修改Android APK AndroidManfiest.xml文件或IOS IPA plist文件

修改AndroidManfiest.xml文件

参考:Android Manifest控制

我在做一个语音插件时需要在AndroidManfiest.xml文件中添加安卓权限请求,其实有很多方法可以做到

1.在Advanced APK Packaging中添加

在ProjectSettings中的Advanced APK Packaging中Extra Permissions添加

2.代码动态添加

在插件的StartupModule函数中获取AndroidRuntimeSettings,通过代码动态的在ProjectSettings中的Advanced APK Packaging中Extra Permissions添加权限条目

static const FString AndroidReadExternalStoragePermission = TEXT("android.permission.READ_EXTERNAL_STORAGE");
static const FString AndroidWriteExternalStoragePermission = TEXT("android.permission.WRITE_EXTERNAL_STORAGE");
static const FString AndroidReadMediaAudioPermission = TEXT("android.permission.READ_MEDIA_AUDIO");
static const FString AndroidRecordAudioPermission = TEXT("android.permission.RECORD_AUDIO");
void FAAAModule::StartupModule(){
UAndroidRuntimeSettings* AndroidRuntimeSettings = GetMutableDefault<UAndroidRuntimeSettings>();
if (!AndroidRuntimeSettings)
{
  UE_LOG(LogRuntimeAudioImporterEditor, Error, TEXT("Failed to get AndroidRuntimeSettings to add permissions"));
  return;
}
TArray<FString> NewExtraPermissions = AndroidRuntimeSettings->ExtraPermissions;

if (!AndroidRuntimeSettings->ExtraPermissions.Contains(AndroidReadExternalStoragePermission))
{
  NewExtraPermissions.Add(AndroidReadExternalStoragePermission);
}
if (!AndroidRuntimeSettings->ExtraPermissions.Contains(AndroidWriteExternalStoragePermission))
{
  NewExtraPermissions.Add(AndroidWriteExternalStoragePermission);
}
if (!AndroidRuntimeSettings->ExtraPermissions.Contains(AndroidReadMediaAudioPermission))
{
  NewExtraPermissions.Add(AndroidReadMediaAudioPermission);
}

if (!AndroidRuntimeSettings->ExtraPermissions.Contains(AndroidRecordAudioPermission))
{
  NewExtraPermissions.Add(AndroidRecordAudioPermission);
}

if (NewExtraPermissions.Num() > AndroidRuntimeSettings->ExtraPermissions.Num())
{
  AndroidRuntimeSettings->ExtraPermissions = NewExtraPermissions;
#if UE_VERSION_OLDER_THAN(5, 0, 0)
  AndroidRuntimeSettings->UpdateDefaultConfigFile();
#else
  AndroidRuntimeSettings->TryUpdateDefaultConfigFile();
#endif
}
}

3.使用UPL添加

在Build.cs中使用AdditionalPropertiesForReceipt,然后,创建一个名为MyGame_UPL.xml的新文件,该文件与Build.cs文件放在同一目录中。在androidManifestUpdates条目中添加所需安卓权限。这个是引擎在处理完游戏内容的Pak包到obb后才开始处理的几乎已经是最后了,这些选项是可选添加,也就是说,如果前面的ini已经添加进去了,就不会继续添加。

if (Target.Platform == UnrealTargetPlatform.Android)
{
// Add UPL to add configrules.txt to our APK
string PluginPath = Utils.MakePathRelativeTo(ModuleDirectory, Target.RelativeEnginePath);
AdditionalPropertiesForReceipt.Add("AndroidPlugin", System.IO.Path.Combine(PluginPath, "MyGame_UPL.xml"));
}
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">

<init>
  <log text="MyGame_UPL.xml INIT"/>
</init>

<!-- optional updates applied to AndroidManifest.xml -->
<androidManifestUpdates>
  <addPermission android:name="android.permission.RECORD_AUDIO"/>

	<addPermission android:name="android.permission.INTERNET"/>
  <addPermission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>
</androidManifestUpdates>
</root>

可以看一下log

UATHelper: Packaging (Android (ASTC)): ********** STAGE COMMAND COMPLETED **********
UATHelper: Packaging (Android (ASTC)): ********** PACKAGE COMMAND STARTED **********
UATHelper: Packaging (Android (ASTC)): BaseApkName = D:\UEProjects\KcpAudio\Binaries/Android\AudioCaptureTest.apk
UATHelper: Packaging (Android (ASTC)): Creating D:\UEProjects\MyGame\Saved\StagedBuilds\Android_ASTC.obb from D:\UEProjects\MyGame\Saved\StagedBuilds\Android_ASTC
UATHelper: Packaging (Android (ASTC)): [1/1] Adding Engine/Content/Renderer/TessellationTable.bin to OBB
UATHelper: Packaging (Android (ASTC)): [2/2] Adding Engine/Content/SlateDebug/Fonts/LastResort.tps to OBB
UATHelper: Packaging (Android (ASTC)): [3/3] Adding Engine/Content/SlateDebug/Fonts/LastResort.ttf to OBB
UATHelper: Packaging (Android (ASTC)): [4/4] Adding Engine/Extras/GPUDumpViewer/GPUDumpViewer.html to OBB
UATHelper: Packaging (Android (ASTC)): [5/5] Adding Engine/Extras/GPUDumpViewer/OpenGPUDumpViewer.bat to OBB
UATHelper: Packaging (Android (ASTC)): [6/6] Adding Engine/Extras/GPUDumpViewer/OpenGPUDumpViewer.sh to OBB
UATHelper: Packaging (Android (ASTC)): [7/7] Adding MyGame/Content/Paks/MyGame-Android_ASTC.pak to OBB
UATHelper: Packaging (Android (ASTC)): [8/8] Adding MyGame/Content/Paks/MyGame-Android_ASTC.ucas to OBB
UATHelper: Packaging (Android (ASTC)): [9/9] Adding MyGame/Content/Paks/MyGame-Android_ASTC.utoc to OBB
UATHelper: Packaging (Android (ASTC)): [10/10] Adding MyGame/Content/Paks/global.ucas to OBB
UATHelper: Packaging (Android (ASTC)): [11/11] Adding MyGame/Content/Paks/global.utoc to OBB
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: ..\..\UEProjects\MyGame\Plugins\MyGamePlugin\Source\MyGamePlugin\MyGame_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Plugins\Online\Android\OnlineSubsystemGooglePlay\Source\OnlineSubsystemGooglePlay_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Plugins\Runtime\AndroidPermission\Source\AndroidPermission\AndroidPermission_APL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Plugins\Runtime\AndroidFileServer\Source\AndroidFileServer\AndroidFileServer_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Plugins\Runtime\GoogleCloudMessaging\Source\GoogleCloudMessaging\GoogleCloudMessaging_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Plugins\Runtime\GooglePAD\Source\GooglePAD\GooglePAD_APL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Source\Runtime\Online\Voice\AndroidVoiceImpl_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Source\ThirdParty\EOSSDK\EOSSDK_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Source\ThirdParty\GoogleGameSDK\GoogleGameSDK_APL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Source\ThirdParty\HWCPipe\HWCPipe_UPL.xml
UATHelper: Packaging (Android (ASTC)): AndroidPlugin: Source\ThirdParty\heapprofd\heapprofd_UPL.xml

可以在项目路径下Intermediate/Android/ActiveUPL.xml,里面列出了当前项目中所有的 UPL 文件路径:

..\..\UEProjects\MyGame\Plugins\MyGamePlugin\Source\MyGamePlugin\MyGame_UPL.xml
Plugins\Online\Android\OnlineSubsystemGooglePlay\Source\OnlineSubsystemGooglePlay_UPL.xml
Plugins\Runtime\AndroidPermission\Source\AndroidPermission\AndroidPermission_APL.xml
Plugins\Runtime\AndroidFileServer\Source\AndroidFileServer\AndroidFileServer_UPL.xml
Plugins\Runtime\GoogleCloudMessaging\Source\GoogleCloudMessaging\GoogleCloudMessaging_UPL.xml
Plugins\Runtime\GooglePAD\Source\GooglePAD\GooglePAD_APL.xml
Source\Runtime\Online\Voice\AndroidVoiceImpl_UPL.xml
Source\ThirdParty\EOSSDK\EOSSDK_UPL.xml
Source\ThirdParty\GoogleGameSDK\GoogleGameSDK_APL.xml
Source\ThirdParty\HWCPipe\HWCPipe_UPL.xml
Source\ThirdParty\heapprofd\heapprofd_UPL.xml

看一下打包出来的AndroidManfiest.xml文件的请求权限部分

<!-- Requirements -->
<uses-feature android:glEsVersion="0x00030000" android:required="true" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="com.android.vending.CHECK_LICENSE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="com.android.vending.BILLING" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<!-- Supported texture compression formats (cooked) -->
<supports-gl-texture android:name="GL_KHR_texture_compression_astc_ldr" />
<!-- 添加在最下面,至于其他两项,一个是引擎添加的另一个我在方法二中动态的添加到了DefaultEngine.ini中的[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings] -->
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" __line="13" />

添加在最下面,至于其他两项,一个是引擎添加的另一个我在方法二中动态的添加到了DefaultEngine.ini中的[/Script/AndroidRuntimeSettings.AndroidRuntimeSettings]__line="13"这个不是语法中的,只是指代这个标签在 XML 文件中的行号,比如这个权限声明位于文件的第 13 行


通过上面三个方法比较,可以看出来使用UPL是最简单且可移植的

参考链接

1,UE4 Android第三方库导入,JNI调用详解

2,在Unreal开发中,通过plugin导入第三方库

3,UPL for Android

4,Unreal Plugin Language

5,Android Configuration Rules System


对于本文内容有问题或建议的小伙伴,欢迎提出问题