你的浏览器不支持canvas

让我们携手共创奇迹!

安卓权限

Date: Author: LBD

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

这是一篇关于使用UE请求安卓权限的一些经验技巧

0、前言

随着 Android 系统不断升级,他的权限控制越来越严格[引用],在我写一个需要读取外部文件的功能时,发现以前的android.permission.ACCESS_NETWORK_STATEandroid.permission.WRITE_EXTERNAL_STORAGE已经不管用了,因此有了此篇内容

1、UPL与JNI

参考:UE4 安卓互相调用

UPL 与 JNI 调用的最佳实践

我们需要编写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 脚本,注意 AndroidPluginIOSPlugin不可修改,文件路径可以根据 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中使用了,一般放在游戏刚开始就请求安卓权限


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