IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> ARFoundation入门教程U1-android权限申请和导出unityLibrary库配置升级 -> 正文阅读

[游戏开发]ARFoundation入门教程U1-android权限申请和导出unityLibrary库配置升级

Android访问sd卡权限,各个版本有不同的方式。使用ARFoundation编程android项目时,可以使用unity提供的Permission申请android权限,提示有UnauthorizedAccessException的报错,基本为权限问题。

Android中sd卡的路径一般为:/storage/emulated/0/…

比如/storage/emulated/0/DCIM 为相机目录。

从《ARFoundation从零开始3-arfoundation项目》创建项目

一、android各版本的权限申请

1.安卓6.0(API 23)以下,访问只需要在清单文件中添加如下权限

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

2. 在安卓6.0(API 23)及以上系统,还需要在代码中动态申请权限

ActivityCompat.requestPermissions(MainActivity.this, permissions, PERMISSION_REQUEST);

3. 安卓10系统以上,还需要在清单文件中application节点加上:android:requestLegacyExternalStorage="true"

二、unity配置

1.新增自定义项AndroidManifest.xml,用来设置android权限的配置。Edit-ProjectSettings-Player-Publishing Settings,勾选自定义Manifest:

2.进入当前项目目录\Assets\Plugins\Android,修改AndroidManifest.xml文件:

修改主Activity为com.unity3d.player.MainActivity,文件内容修改为:

<?xml version="1.0" encoding="utf-8"?>

<!-- GENERATED BY UNITY. REMOVE THIS COMMENT TO PREVENT OVERWRITING WHEN EXPORTING AGAIN-->

<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.unity3d.player" xmlns:tools="http://schemas.android.com/tools">

? <application android:requestLegacyExternalStorage="true">

??? <activity android:name="com.unity3d.player.MainActivity" android:theme="@style/UnityThemeSelector" android:screenOrientation="fullSensor" android:launchMode="singleTask" android:configChanges="mcc|mnc|locale|touchscreen|keyboard|keyboardHidden|navigation|orientation|screenLayout|uiMode|screenSize|smallestScreenSize|fontScale|layoutDirection|density" android:hardwareAccelerated="false">

????? <intent-filter>

??????? <action android:name="android.intent.action.MAIN" />

??????? <category android:name="android.intent.category.LAUNCHER" />

????? </intent-filter>

????? <meta-data android:name="unityplayer.UnityActivity" android:value="true" />

????? <meta-data android:name="android.notch_support" android:value="true" />

??? </activity>

??? <meta-data android:name="unity.splash-mode" android:value="0" />

??? <meta-data android:name="unity.splash-enable" android:value="True" />

??? <meta-data android:name="notch.config" android:value="portrait|landscape" />

??? <meta-data android:name="unity.build-id" android:value="…" />

??? <meta-data android:name="com.google.android.ar.API_KEY" android:value="…" />

??? <meta-data android:name="unityplayer.SkipPermissionsDialog" android:value="true" />

??? <meta-data android:name="com.google.ar.core" android:value="required" />

? </application>

? <uses-feature android:glEsVersion="0x00030000" />

? <uses-permission android:name="android.permission.INTERNET" />

? <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

? <uses-feature android:name="android.hardware.location.gps" android:required="True" />

? <uses-feature android:name="android.hardware.location" android:required="True" />

? <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

??? <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

? <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.ACCESS_COARSE_LOCATION" android:minSdkVersion="31" />

? <uses-permission android:name="android.permission.CAMERA" />

? <uses-feature android:name="android.hardware.camera.ar" android:required="true" />

? <uses-feature android:name="com.google.ar.core.depth" android:required="true" />

</manifest>

2.进入当前项目\Assets\Plugins\Android目录,新建MainActivity.java文件,作为主启动Activity:

3. 进入当前项目\Assets\Plugins\Android目录,mainTemplate.gradle.meta文件repositories修改为:

google()

?????? mavenCentral()

与android studio中保持一致!

4.unity中-Project Settings-Player-Other Settings-Write Permission选择External:

5.MainActivity.java代码:

package com.unity3d.player;

import android.os.Bundle;

import android.view.KeyEvent;

import android.widget.Toast;

public class MainActivity extends UnityPlayerActivity{

??? private static MainActivity instance;

??? @Override

??? protected void onCreate(Bundle savedInstanceState) {

??????? super.onCreate(savedInstanceState);

??????? instance = this;

??? }

??? public static MainActivity GetInstance()

??? {

??????? return instance;

??? }

??? @Override public boolean dispatchKeyEvent(KeyEvent event)

??? {

??????? if(event.getKeyCode() == KeyEvent.KEYCODE_BACK){

??????????? onBackPressed();

??????????? return true;

??????? }

??????? if (event.getAction() == KeyEvent.ACTION_MULTIPLE)

?????? ?????return mUnityPlayer.injectEvent(event);

??????? return super.dispatchKeyEvent(event);

??? }

??? //------

??? @Override

??? public void onBackPressed() {

??????? runOnUiThread(new Runnable() {

??????????? @Override

??????????? public void run() {

??? ????????????mUnityPlayer.quit();

??????????? }

??????? });

??????? super.onBackPressed();

??? }

??? //unity调用android的方法

??? public int Sum(int x, int y)

??? {

??????? return x + y;

??? }

??? public String OnUnityFinished(String str){

??????? runOnUiThread(new Runnable() {

??????????? @Override

??????????? public void run() {

??????????????? Toast.makeText(

??????????????????????? instance,

??????????????????????? "OnUnityFinished=" + str,

??????????????????????? Toast.LENGTH_LONG).show();

??????????? }

??????? });

??????? return "ok";

??? }

??? public void CallUnityFun(String str)

??? {

??????? String receiveObj = "MainCamera";//unity中脚本挂载的Object的name

??????? String receiveMethod = "Receive";//unity中Object挂载脚本的方法名

??????? String params = str + " Android Call Unity.";//方法要穿的参数

??????? //android调用unity,

??????? UnityPlayer.UnitySendMessage(receiveObj, receiveMethod, params);

??? }

}

三、unity申请android权限代码

Unity中自带的Android权限申请类Permission:

Unity - Scripting API: Permission

其中主要用到的方法:

HasUserAuthorizedPermission方法用来判断是否获得了该权限:

Permission.HasUserAuthorizedPermission("android.permission.READ_PHONE_STATE")

RequestUserPermission方法用来请求该权限:

Permission.RequestUserPermission("android.permission.READ_PHONE_STATE");

1.编写android权限申请类,项目Scripts文件夹下新建AndroidPermissions.cs文件,挂载到AR Session Origin下:

代码:

using System.Collections;

using System.Collections.Generic;

using UnityEngine;

using UnityEngine.Android;

namespace FrameworkDesign.Example

{

??? public class AndroidPermissions : MonoBehaviour

??? {

??????? private static AndroidPermissions instance;

??????? private int index;

???? ???private List<string> permissionList = new List<string>();

??????? private void Awake()

??????? {

??????????? if(instance == null)

??????????? {

??????????????? instance = this;

??????????????? Init();

??????????? }?????????????????????????????????

??????? }

??????? //初始化,权限申请要尽可能早

??????? [RuntimeInitializeOnLoadMethod(RuntimeInitializeLoadType.BeforeSceneLoad)]

??????? public void Init()

??????? {

??????????? //权限添加进列表

??????????? permissionList.Clear();

??????????? index = 0;

??????????? //permissionList.Add("android.permission.READ_PHONE_STATE");

??????????? permissionList.Add(Permission.ExternalStorageRead);

??????????? permissionList.Add(Permission.ExternalStorageWrite);

?????????? // permissionList.Add(Permission.FineLocation);

?????? ????// permissionList.Add(Permission.CoarseLocation);

??????????? StartCheckPermission(0.02f); //开始申请

??????????? Logger.Log("权限申请完毕");

??????? }

??????? public void StartCheckPermission(float time)

??????? {

??????????? //Logger.Log("开始权限申请");

??????????? if (permissionList.Count > 0)

??????????? {

??????????????? Get(permissionList[index], time);

??????????? }

??????? }

??????? /// <summary>

??????? /// 判断并申请权限

??????? /// </summary>

??????? /// <param name="type">权限名</param>

??????? /// <param name="time">如拒绝延迟多久再次申请</param>

??????? void Get(string type, float time)

??????? {

??????????? if (!Permission.HasUserAuthorizedPermission(type))

??????????? {

??????????????? Permission.RequestUserPermission(type);

??????????????? Logger.Log("正在获取的权限:" + type);

??????????????? StartCoroutine(Check(type, time));

??????????? }

??????????? else

??????????? {

??????????????? Logger.Log("权限已经获取:" + type);

??????????????? if (index < permissionList.Count - 1)

??????????????? {

??????????????????? index += 1;

??????????????????? Get(permissionList[index], time);

??????????????? }

??????????? }

??????? }

??????? IEnumerator Check(string type, float time)

??????? {

??????????? yield return new WaitForSeconds(time);

??????????? Get(type, time);

??????? }

??? }

}

2.打包运行:

??

当用户尚未授权时,程序弹出Android权限申请界面,点击授权即可。

四、unity导出lib库

unity导出lib库,(先删除原来导出的lib库文件夹下所有文件,确保修改的文件更新):

五、android studio升级

1.java JDK升级到11,配置环境变量。

2.Android studio升级到2021.2.1:下载安装包安装,提示删除旧版,点击确定安装新版。

3. Android studio配置gradle,file-project structure-project,配置7.2.1和7.3.3:

点击SDK Location-Gradle Settings-Gradle JDK,选择11:

六、android studio导入unity库

1.复制unityLibrary到android studio工程根目录(先删除原有unityLibrary文件夹),启动android studio

2.gradle.properties文件注释掉android.enableR8=false
#android.enableR8=false

3.app的build.gradle的buildToolsVersion 
buildToolsVersion '30.0.3'

4.打包出错:

原因是androidx兼容问题,android代码使用了androidx,删除unityLibrary的build.gradle内以下内容:

打包成功

MainActivity 继承UnityPlayerActivity,实现与unity的接口调用,相关代码都在MainActivity中编写。

三、android打包运行

如未配置,参看《ARFoundation从零开始3-arfoundation项目》。

安装运行:

??

对于Unity工程不单独打包,而是接入到其他android工程里的情况,android权限的申请最好在android端进行,不能确保在android申请的时候再在unity端申请。

Android端申请权限代码:



//----1.android端申请权限,以下代码放到当前Activity类里-----------------

//------2.在当前ActivityonCreate方法里调用checkPermission();

String[] permissions = new String[]{Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,Manifest.permission.WRITE_SETTINGS};

List<String> mPermissionList = new ArrayList<>();



private static final int PERMISSION_REQUEST = 1;

// 检查权限

private void checkPermission() {

??? mPermissionList.clear();

??? //判断哪些权限未授予

??? for (int i = 0; i < permissions.length; i++) {

??????? if (ContextCompat.checkSelfPermission(this, permissions[i]) != PackageManager.PERMISSION_GRANTED) {

??????????? mPermissionList.add(permissions[i]);

??????? }

??? }

??? //判断是否为空

??? if (mPermissionList.isEmpty()) {//未授予的权限为空,表示都授予了



??? } else {//请求权限方法

??????? String[] permissions = mPermissionList.toArray(new String[mPermissionList.size()]);//List转为数组

??????? ActivityCompat.requestPermissions(MainActivity.this, permissions, PERMISSION_REQUEST);

??? }

}

/**

?* 响应授权

?* 这里不管用户是否拒绝,都进入首页,不再重复申请权限

?*/

@Override

public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {

??? super.onRequestPermissionsResult(requestCode, permissions, grantResults);

??? switch (requestCode) {

??????? case PERMISSION_REQUEST:



?????????? ?break;

??????? default:

??????????? super.onRequestPermissionsResult(requestCode, permissions, grantResults);

??????????? break;

??? }

}

//----android端申请权限-----------------

四、常见问题

(unity的gradle没有与android studio同步,仍使用的gradle6.7.1+jdk1.8,没有升级到gradle7.3.3+jdk11)

五、参考资料

1. Unity api:

Unity - Scripting API: Permission

2.ARFoundation示例:

GitHub - Unity-Technologies/arfoundation-samples: Example content for Unity projects based on AR Foundation

3.ARCore文档:

在 Unity (AR Foundation) 应用中执行光线投射 ?|? ARCore ?|? Google Developers

  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-08-06 11:13:03  更:2022-08-06 11:14:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/23 6:05:45-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码