前天我们项目有这么个需求, 台湾版本由于要上谷歌 Play 要求安卓系统 6.0 以上的动态申请权限, 对于一个做 Unity 的来说, 是不是有点懵逼, 这我该何去何从呢? 我想静静, 静静的想一想, 权限也不就那么点事吗? 这算是事吗? 这都不是事, 遇到问题, 不要急着去解决, 这里不是不解决, 是不要着急为了解决而解决! 软件工程告诉我们需求分析才是第一位的, 大学都觉的软件工程是很扯淡的课, 其实不然, 它是灰常重要的, 灰常重要, 灰常重要!!! 重要的事情说三变再复习下软件工程的几个步骤: 需求分析 -> 概要设计 -> 详细设计 -> 码代码 -> 测试 -> 维护! 上课基本听老师扯淡了, 大致是这么个流程!!!
Q1: 我怎么知道的 APK 到底有多少个权限?
A1: 这里我要引用我们策划经常说的一句话了, 小伙子, 这个问题问的好! 作为一个懂开发的猿, 这个要是不知道, 我也不知道该不该说你了 AndroidManifest.xml 这个你眼熟吧? 不错, 是你是你就是你!!
Q2: 这些权限看到是看到了, 我怎么和他们交个朋友了, 熟悉了好办事啊?
A2: 注意, 首先你是一个会写代码的猿, 看懂代码对你来说是事吗? 其实我也是现学的, 没做过安卓开发, 既然都是小白, 那还怕什么, 有人是不是在静静的看着楼主装 X
1 如何获取呢, 请睁大你的双眼, 这里是部分代码, 稍后完整的工程会全部奉上!!!
- final Bundle bundle = getArguments();
- final String[] permissions = bundle.getStringArray(PERMISSIONS);
- if (permissions != null)
- {
- Collections.addAll(requestedPermissions, permissions);
- allPermissions = permissions;
- }
轻轻松松拿到了我们想要的一切权限, 是不是 So Easy!
拿到了权限我们该怎么处理呢? 目前需求是这样的, APK 必须的权限都已授权, OK, 结束! 否则用户不想授予某个权限, 例如读取你的联系人之类的, 那就没办法了, 应用关闭, 结束! 我感觉这么处理有点太直接了, 说不定一个潜在的金主爸爸就这么流失了, 我们是不是可以这样, 既然拿到权限列表了, 最笨的方法也是最有效的, 我逐个检测是否授权不就得了, 未授权, 我给你弹个获取权限的框, 说不定, 用户一想, 授权这也没什么啊, 即使读取隐私, 也是光明正大的了! 那么读取联系人的权限就拿到了, 下一个权限权限列表请求一遍了, 发现还有未授权的, 那就真的 GG 了, 此时不能再弹框申请权限了, 用户会烦的, 一位哪个傻逼写了个死循环呢! 所以这是没办法了, 要么此时来个温馨提示, 由于您未授权读取联系人, 部分功能无法启动, 请打开权限后再次使用, 谢谢!
我们接下来要做的就是拿到权限列表了, 如何动态请求权限呢?
- public static void AskPermissions(final String gameObject, final int requestCode, final String[] permissions) {
- UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
- @Override
- public void run() {
- final Bundle bundle = new Bundle();
- bundle.putString(GAME_OBJECT, gameObject);
- bundle.putInt(REQUEST_CODE, requestCode);
- bundle.putStringArray(PERMISSIONS, permissions);
- final PermissionProvider fragment = new PermissionProvider();
- fragment.setArguments(bundle);
- UnityPlayer.currentActivity
- .getFragmentManager()
- .beginTransaction()
- .add(fragment, PermissionProvider.class.getCanonicalName())
- .commit();
- }
- });
- }
- /**
- * Once user allow or deny permissions this method is called
- */
- @Override
- public void onRequestPermissionsResult(final int requestCode, final String[] permissions, final int[] grantResults) {
- LogExtensions.v(TAG, "[onRequestPermissionsResult]" + requestCode + "|" + Arrays.toString(permissions) + "|" + Arrays.toString(grantResults));
- if (requestCode == this.requestCode) {
- boolean result = true;
- for (int i : grantResults) {
- if (i != PackageManager.PERMISSION_GRANTED) {
- result = false;
- break;
- }
- }
- // 权限请求后的回调, 告诉 Unity 我是否被授权了
- onComplete(gameObject, requestCode, result);
- }
- super.onRequestPermissionsResult(requestCode, permissions, grantResults);
- }
在 Unity 那边我只要记录一个权限列表的字典, 被授权的在回掉中从自字典中删除该权限, 到最后检测该字典的 Count 是否大于 0 即可, 授权后且字典的 Count 大于 0, 第一轮的逐个权限请求还未结束, 继续直到权限全部授权结束! 这是我们期望的结果, 第二种结果是, 其中一个用户未授权, 那么 gg 了, 弹框提示, 退出应用, 一首凉凉送给自己!
- using UnityEngine;
- using System.Collections;
- using System;
- using Platform.Android.Stubs;
- namespace Platform.Android
- {
- public class PermissionProvider : MonoBehaviour
- {
- public static event Action<bool> OnReceiveStoragePermission;
- #if UNITY_ANDROID
- private AndroidJavaClass _request;
- public AndroidJavaClass Request {
- get {
- if (_request == null)
- _request = new AndroidJavaClass ("com.example.androidpermissionmgr.PermissionProvider");
- return _request;
- }
- }
- #else
- public AndroidJavaClassStub Request = new AndroidJavaClassStub ();
- #endif
- public void VerifyStorage (Action<bool> action)
- {
- Debug.Log ("[PermissionProvider] VerifyStorage" );
- OnReceiveStoragePermission += action;
- RequestPermissions (1001, "android.permission.READ_EXTERNAL_STORAGE", "android.permission.ACCESS_NETWORK_STATE");//android.permission.ACCESS_NETWORK_STATE "android.permission.WRITE_EXTERNAL_STORAGE"
- }
- public void RequestPermissions (int requestCode, params string[]permissions)
- {
- Debug.Log ("[PermissionProvider] Requesting permissions:"+ requestCode + " " + permissions );
- Request.CallStatic ("verifyPermissions", gameObject.name, requestCode, permissions);
- }
- public void OnGranted (string requestCode)
- {
- Debug.Log("[PermissionProvider] OnGranted" + requestCode);
- Example.result = "[PermissionProvider] OnGranted" + requestCode;
- if (requestCode.Equals("1001"))
- {
- if (OnReceiveStoragePermission != null)
- OnReceiveStoragePermission(true);
- }
- if (Example.permissionDic.ContainsValue(int.Parse(requestCode)))
- {
- foreach (var item in Example.permissionDic)
- {
- if (item.Value == int.Parse(requestCode))
- {
- Example.permissionDic.Remove(item.Key);
- break;
- }
- }
- }
- CheckPermissionAgain();
- }
- public void OnDenied (string requestCode)
- {
- Debug.Log("[PermissionProvider] OnDenied" + requestCode);
- Example.result += "[PermissionProvider] OnDenied" + requestCode;
- if (requestCode.Equals("1001"))
- {
- if (OnReceiveStoragePermission != null)
- OnReceiveStoragePermission(false);
- }
- // 只要有一个重要权限未授权直接退出, 或者再次请求权限
- if (Example.permissionDic.Count>0)
- {
- Application.Quit();
- }
- }
- public void AskForPermission()
- {
- RequestPermissions(100, "android.permission.READ_CONTACTS");//android.permission.ACCESS_NETWORK_STATE "android.permission.WRITE_EXTERNAL_STORAGE"
- Example.result += "AskForPermission";
- }
- public void GetNoGrantPermission()
- {
- Request.Call("GetNoGrantPermission");
- }
- public void AskForAllPermission()
- {
- foreach (var item in Example.permissionDic)
- {
- RequestPermissions(item.Value, item.Key);
- }
- }
- public void CheckPermissionAgain()
- {
- if (Example.permissionDic.Count> 0)
- {
- AskForAllPermission();
- }
- else
- {
- Example.result = "APK 已全部授权成功!";
- }
- }
- }
- }
由于写的比较粗糙, 基本功能是实现了! 大家有问题了可以 @我, 共同学习!!!
不知不觉又凌晨了, 明天要继续上班, 碎觉了, 做一只按时睡觉的猿!!!
截图
工程地址: https://gitee.com/wuzhang/UnityAndroidPermissionProject.git
欢迎 Fork 和 Star!
来源: https://www.cnblogs.com/wuzhang/p/wuzhang20180319.html