这是一篇关于使用UE请求安卓权限的一些经验技巧
0、前言
随着 Android 系统不断升级,他的权限控制越来越严格[引用],在我写一个需要读取外部文件的功能时,发现以前的android.permission.ACCESS_NETWORK_STATE和android.permission.WRITE_EXTERNAL_STORAGE已经不管用了,因此有了此篇内容
1、UPL与JNI
参考:UE4 安卓互相调用
我们需要编写xml文件,一般放在模块下根目录:ModuleDirectory
<?xml version="1.0" encoding="utf-8"?>
<root xmlns:android="http://schemas.android.com/apk/res/android">
<!-- AndroidManifest 权限声明 管理整个外部存储-->
<androidManifestUpdates>
<addPermission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"/>
</androidManifestUpdates>
<!-- 内联 Java 代码注入到 GameActivity -->
<gameActivityImportAdditions>
<insert>
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;
import android.provider.Settings;
</insert>
</gameActivityImportAdditions>
<gameActivityClassAdditions>
<insert>
public boolean hasManageStoragePermission()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
{
return Environment.isExternalStorageManager();
}
return true;
}
public void requestManageStoragePermission()
{
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R)
{
Intent intent = new Intent(Settings.ACTION_MANAGE_APP_ALL_FILES_ACCESS_PERMISSION);
intent.setData(Uri.parse("package:" + getPackageName()));
startActivity(intent);
}
}
</insert>
</gameActivityClassAdditions>
</root>
写完了 UPL 的脚本之后还需要在需要添加该 UPL 的 Module 的 build.cs 中添加以下代码:
// for Android
if (Target.Platform == UnrealTargetPlatform.Android)
{
AdditionalPropertiesForReceipt.Add("AndroidPlugin", Path.Combine(ModuleDirectory, "FGame_Android_UPL.xml"));
}
// for IOS
if (Target.Platform == UnrealTargetPlatform.IOS)
{
AdditionalPropertiesForReceipt.Add("IOSPlugin",Path.Combine(ModuleDirectory,"UPL/IOS/FGame_IOS_UPL.xml"));
}
通过 AdditionalPropertiesForReceipt 来指定我们的 UPL 脚本,注意 AndroidPlugin 和IOSPlugin不可修改,文件路径可以根据 UPL 文件在项目中的位置指定。
将内容嵌入到java后想要调用需要用到JNI的C++ to Java,就下来我们写两个函数来调用嵌入java中的函数
#if PLATFORM_ANDROID
#include "Android/AndroidApplication.h"
#include "Android/AndroidJNI.h"
#endif
bool UWe_FunctionLibrary::HasManageExternalStoragePermission()
{
#if PLATFORM_ANDROID
if (FAndroidMisc::GetAndroidBuildVersion() >= 30)
{
JNIEnv* Env = FAndroidApplication::GetJavaEnv();
jobject Activity = FJavaWrapper::GameActivityThis;
jclass ActivityClass = Env->GetObjectClass(Activity);
jmethodID Method = Env->GetMethodID(ActivityClass,
"hasManageStoragePermission", "()Z");
return (bool)Env->CallBooleanMethod(Activity, Method);
}
#endif
return true;
}
void UWe_FunctionLibrary::RequestManageExternalStoragePermission()
{
#if PLATFORM_ANDROID
JNIEnv* Env = FAndroidApplication::GetJavaEnv();
jobject Activity = FJavaWrapper::GameActivityThis;
jclass ActivityClass = Env->GetObjectClass(Activity);
jmethodID Method = Env->GetMethodID(ActivityClass,
"requestManageStoragePermission", "()V");
Env->CallVoidMethod(Activity, Method);
#endif
}
然后我们就可以随意在ue中使用了,一般放在游戏刚开始就请求安卓权限