Oculus展示如何为Unity 3D创建Android插件
文章相关引用及参考:oculus
本文来自Gabor Szauer
(映维网 2018年05月15日)本文将探讨如何为Unity 3D创建Android插件。如果你了解Android Studio,我们在下面提供了创建Android .aar文件分步骤截图。本文的示例插件与Android权限有关。
API Level 23,Marshmallow改变了在Android上请求权限的方式。借助API 23及更高版本,应用程序可以查询它们在运行时拥有的权限,并仅在需要时才要求新权限。只申请应用程序实际需要的权限,请求不必要的权限可能会导致系统的拒绝。
本文插件采用了两款软件:
- Android Studio: 3.0.1
- Unity 3D: 5.6.4p2
1. 创建aar
创建原生Android插件的第一步是创建一个Android库,该库存储在Android Archive(.aar)文件中。Android库可以使用Android Studio创建。你可以从谷歌开发者官网下载并安装Android Studio(点击前往)。
1.启动Android Studio并选择“Start a new Android Studio project(启动一个新的Android Studio项目)”选项。
2.将项目命名为“PermissionHelperApp”。插件的名称将是“PermissionHelper”,但项目需要不同的名称。
3.选择适当的API级别。这将取决于项目。移动VR应用程序的最低API级别为21,但23也是一个安全的候选。就目前而言,你可以选择“API 21:Android 5.0(Lollipop)”。
4.出现提示时,选择“Add no activity(不添加活动)”。由于这是一个插件而非完整的应用程序,因此不需要创建任何类型的默认activity。
5.等待Android Studio创建新项目。这可能需要一段时间。
6.1 当Android Studio完成时,切换到项目视图。首先单击IDE左侧的“Project(项目)”选项卡。接下来,从“Project(项目)”面板顶部的下拉菜单中选择“Project(项目)”。
6.2 请注意编辑器的底部,如果出现任何错误,这将是系统报告错误的位置。在首次运行Android Studio时,这个面板可能会包含一个链接,方便你为所选API级别下载相应的SDK。
7.展开“PermissionHelperApp”项目时,“App”文件夹将突出显示。此文件夹包含Android Studio自动创建的Android应用程序(.apk)。该应用程序位于com.company.permissionhelperapp包,这就是为什么在步骤2中我们需要将应用名称命名为“PermissionHelperApp”,而不是说“PermissionHelper”。
右键单击“PermissionHelperApp”项目,选择“New(新建)”,然后选择“Module(模块)”以添加一个新模块。
8.出现提示时,选择“Android Library(Android库)”作为新模块的类型。
9.将新模块命名为“PermissionHelper”,并且选择适当的最小API级别。为了保持一致,请选择与步骤3相同的最低API级别,API 21:Android 5.0(Lollipop)
10.在项目浏览器中展开“PermissionHelperApp”项目,并且展开新创建的“permissionhelper”模块。在这个模块中,展开“src”文件夹,然后展开“main”文件夹和“java”文件夹。最后一个嵌套的项目应该是:com.company.permissionhelper。
11.右键单击,选择“New(新建)”和“Java Class”
12.将这个新类命名为“PermissionHelper”。Unity将与这个类进行交互。
13.新创建的文件中应该存在一定的空白默认代码。
14.将两个新的成员变量添加到PermissionHelper类中。其中一个新变量应该是Application Context(应用程序前后关系),另一个应该是当前正在运行的Activity。不要忘记导入这些类。
package com.oculus.permissionhelper; import android.app.Activity; import android.content.Context; public class PermissionHelper { private Context mContext; private Activity mActivity; }
15.类的构造函数应该设置这两个变量。Unity使用与Application Context和Activity相同的对象。传入一个context并将其转换为activity。
package com.oculus.permissionhelper; import android.app.Activity; import android.content.Context; public class PermissionHelper { private Activity mActivity; public PermissionHelper(Context context) { mContext = context; mActivity = (Activity)context; } }
16.将以下函数添加到PermissionHelper类中:
- CheckForPermission:接受一个字符串,即权限名称。如果权限已授予应用程序,则返回true,否则返回false。
- RequestPermission:接受一个字符串,即权限名称。它什么都不返回。当被调用时,将显示一个Android弹出窗口,询问用户是否具有指定的权限。
有效的权限字符串可通过这里寻找(点击前往)。application context有一个checkSelfPermission函数,其可用于检查当前应用程序是否已被授予特定权限。application activity有一个requestPermissions函数,它将显示一个请求权限的android弹出窗口。
package com.oculus.permissionhelper; import android.app.Activity; import android.content.Context; import android.Manifest; import android.content.pm.PackageManager; public class PermissionHelper { private Context mContext; private Activity mActivity; public PermissionHelper(Context context) { mContext = context; mActivity = (Activity)context; } public boolean CheckForPermission(String permission) { return mContext.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; } public void RequestPermission(String permission) { mActivity.requestPermissions(new String[]{permission},1024); } }
17.以上代码仅适用于Android API 23及更高版本。如果项目API级别设置为小于23的任何值,上面的代码将不会编译。这是因为checkSelfPermission和requestPermissions函数只存在于API 23+之中。
为了保持向后兼容性,需要通过ContextCompat和ActivityCompat兼容性层来调用这些与权限相关的功能。这些类包含静态checkSelfPermission和requestPermissions函数,它们在旧版Android上运行时不会中断。
package com.oculus.permissionhelper; import android.app.Activity; import android.content.Context; import android.Manifest; import android.content.pm.PackageManager; import android.support.v4.app.ActivityCompat; import android.support.v4.content.ContextCompat; public class PermissionHelper { private Context mContext; private Activity mActivity; public PermissionHelper(Context context) { mContext = context; mActivity = (Activity)context; } public boolean CheckForPermission(String permission) { // Only available with API Level 23+: return mContext.checkSelfPermission(permission) == PackageManager.PERMISSION_GRANTED; return ContextCompat.checkSelfPermission(mContext, permission) == PackageManager.PERMISSION_GRANTED; } public void RequestPermission(String permission) { // Only available with API Level 23+: mActivity.requestPermissions(new String[]{permission},1024); ActivityCompat.requestPermissions(mActivity, new String[]{permission},1024); } }
以上代码是PermissionHelper插件的最终Java代码。要令兼容代码正常工作,应用程序需要链接到android-support-v4,它位于:/extras/android/m2repository/com/android/support/support-v4/23.0.0/support-v4-23.0.0.aar。
这将在本文后面的Unity部分进行详细讨论。
18.现在我们已经完成了插件代码,接下来的任务是创建aar文件。单击编辑器右侧的Gradle选项卡以调出Gradle创建工具。
19.在Gradle中依次展开“PermissionHelperApp”,“:permissionhelper”和“build”。 在“build”下拉列表中双击“build”。
20.等待Android Studio完成创建aar文件。
21.在项目浏览器中展开permissionhelper库的build文件夹。在build文件夹下展开output和aar文件夹。这两个文件中的一个是用于Unity插件的aar文件。
22.为了快速寻找文件,右键单击permissionhelper-release.aar文件并选择“Reveal in Finder(在Finder中显示)”。
23.将permissionhelper-release.aar重命名为permissionhelper.aar。将该文件保存在其他位置,它将作为Unity的原生权限插件。
2. 清单文件
Android需要知道应用程序可能要求的权限。应用程序在其生命周期中可能要求的每个权限都应该添加至应用程序的清单文件中。清单文件的权限条目格式如下所示:
< uses-permission android:name=”android.permission.PERMISSION_NAME”/ >
其中,PERMISSION_NAME将替换为所请求的android权限名称。有效的清单权限列表请在这里寻找(点击前往)。所有< uses-permission >标签都是< manifest >标签的直接子元素。例如:
< ?xml version="1.0" encoding="utf-8" standalone="no"? > < manifest xmlns:android="http://schemas.android.com/apk/res/android" > < uses-permission android:name="android.permission.INTERNET" / > < uses-permission android:name="android.permission.CAMERA" / > < uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" / > < application > ... < /application > < /manifest >
如果是使用Unity,请考虑将跳过权限对话框设置为true,从而避免请求默认的Unity权限:
< meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" / >
3. 制作Unity插件
要使用Unity创建权限插件,首先将permissionhelper.aar和support-v4-23.0.0.aar添加到Plugins/Android目录。
support-v4-23.0.0.aar位于< sdk-dir> /extras/android/m2repository/com/android/support/support-v4/23.0.0/目录中。
请记得将任何潜在的权限添加到清单文件之中。
我们需要一定的方法来调用位于permissionhelper.aar中的java代码。创建一个新文件PermissionHelper.cs。添加三个常量字符串:activity的名称,context的名称,以及PermissionHelper类的全名。
using UnityEngine; public static class PermissionHelper { private static string ACTIVITY_NAME = "com.unity3d.player.UnityPlayer"; private static string CONTEXT = "currentActivity"; private static string PERMISSION_HELPER_CLASS = "com.oculus.permissionhelper.PermissionHelper";
声明一个将用于调用本地代码的AndroidJavaObject。InitIfNeeded函数将初始化这个变量,当前平台是android,而permissionHelper变量为null。
private static AndroidJavaObject permissionHelper = null; private static void InitIfNeeded() { #if UNITY_ANDROID if (permissionHelper == null) { AndroidJavaObject context = new AndroidJavaClass (ACTIVITY_NAME).GetStatic (CONTEXT); permissionHelper = new AndroidJavaObject (PERMISSION_HELPER_CLASS, context); } #endif }
创建一个嵌套类,Permission。将应用程序可能需要的每个权限字符串添加到此类中。这个类将作为访问这些字符串的工具类。
public static class Permissions { public static string INTERNET = "android.permission.INTERNET"; public static string CAMERA = "android.permission.CAMERA"; public static string WRITE_EXTERNAL_STORAGE = "android.permission.WRITE_EXTERNAL_STORAGE"; };
RequestPermission和CheckForPermission辅助函数都将使用非公开的AndroidJavaObject来调用在permissionhelper.aar定义的java method。
public static void RequestPermission(string permission) { InitIfNeeded (); #if UNITY_ANDROID permissionHelper.Call("RequestPermission", permission); #endif } public static bool CheckForPermission(string permission) { InitIfNeeded (); #if UNITY_ANDROID return permissionHelper.Call ("CheckForPermission", permission); #else return false; #endif } }
在创建PermissionHelper类后,检查和请求权限可以是一对一的代码行:
public class UIInteraction : MonoBehaviour { - public void SaveDataToDisk() { - if (PermissionHelper.CheckForPermission (PermissionHelper.Permissions.WRITE_EXTERNAL_STORAGE)) { // Write actual data to disk } else { PermissionHelper.RequestPermission (PermissionHelper.Permissions.WRITE_EXTERNAL_STORAGE); } } }
4. 总结
在本文中创建的插件可以用来请求任何类型的权限。共同的要求是互联网访问,磁盘写入和麦克风访问。
按照上述步骤,你应该可以创建使用原生android库/功能的一切类型插件。