【Unity开发】安卓应用开发中,用户进行权限请求

一、作用

在开发安卓应用时,根据功能需求获取对应的权限

1、Unity中封装好的权限

相机、麦克风、精细位置、粗略定位、存储

2、自己添加的权限

获取wifi信息、打开设置界面等

需要自己写对应的扩展

二、具体实现

1、Unity中封装好的权限

(1)创建自定义Manifest.xml文件

ProjectSettings/Player/Android/Publishing Settings/Custom Main Manifest 打开

自动创建文件 Assets/Plugins/Android/AndroidManifest.xml

(2)打开AndroidManifest.xml添加要请求的对应权限

(3)调用代码(以调用相机为例)

csharp 复制代码
	//获取相机权限
	void GetCamera()
	{
		hasCameraDeniedBefore = PlayerPrefs.GetInt("hasCameraDeniedBefore");
		if (!Permission.HasUserAuthorizedPermission(Permission.Camera))
		{
			//之前已经拒绝过,显示打开设置界面提示
			if (hasCameraDeniedBefore==1)
			{
				GFBuiltin.BuiltinView.ShowDialog(GFBuiltin.Localization.GetString("权限请求!"),
										 GFBuiltin.Localization.GetString("该功能需要打开相机权限,否则无法使用,请前往设置中进行授权"),
										 GFBuiltin.Localization.GetString("前往"),
										 GFBuiltin.Localization.GetString("拒绝"),
										 () =>
										 {
											 OpenAppSettings();
										 },
										 GFBuiltin.BuiltinView.HideDialog);
			}
			//显示权限请求弹窗
			else
			{
				GFBuiltin.BuiltinView.ShowDialog(GFBuiltin.Localization.GetString("权限请求!"),
											 GFBuiltin.Localization.GetString("请求相机权限"),
											 GFBuiltin.Localization.GetString("同意"),
											 GFBuiltin.Localization.GetString("拒绝"),
											 () =>
											 {
												 PermissionCallbacks callbacks = new PermissionCallbacks();
												 callbacks.PermissionGranted += PerssionGranted;
												 callbacks.PermissionDenied += PerssionDenied;
												 Permission.RequestUserPermission(Permission.Camera, callbacks);
											 },
											 GFBuiltin.BuiltinView.HideDialog);
			}			
		}
		else
		{
			Debug.Log("开始拍照");
		}
	}

	//权限允许回调
	void PerssionGranted(string permission)
	{
		Debug.Log(permission + "请求允许");
	}

	//权限拒绝回调
	void PerssionDenied(string permission)
	{

		// 记录对应权限已拒绝过
		if (permission == Permission.Camera)
		{
			hasCameraDeniedBefore = 1;
			PlayerPrefs.SetInt("hasCameraDeniedBefore", hasCameraDeniedBefore);
		}			
		else if (permission == Permission.FineLocation)
		{
			PlayerPrefs.SetInt("hasLocationDeniedBefore", 1);
		}
			
		else if (permission == Permission.Microphone)
		{
			PlayerPrefs.SetInt("hasLocationDeniedBefore", 1);
		}
		PlayerPrefs.Save();


		Debug.Log(permission + "请求拒绝");
		Debug.Log("权限拒绝后的值:"+hasCameraDeniedBefore);

	}

	//打开应用权限设置界面
	void OpenAppSettings()
	{
		using (var unityActivity =
			new AndroidJavaClass("com.unity3d.player.UnityPlayer")
			.GetStatic<AndroidJavaObject>("currentActivity"))
		{
			using (var intent = new AndroidJavaObject("android.content.Intent",
				"android.settings.APPLICATION_DETAILS_SETTINGS"))
			{
				string packageName = unityActivity.Call<string>("getPackageName");
				AndroidJavaObject uri = new AndroidJavaClass("android.net.Uri")
					.CallStatic<AndroidJavaObject>("parse", "package:" + packageName);

				intent.Call<AndroidJavaObject>("setData", uri);
				unityActivity.Call("startActivity", intent);
			}
		}
	}

(4)请求权限流程

(5)注意点

  • 电脑使用安卓模拟器会自动拿到需要的权限,不会像用户进行请求
  • 在请求权限时,用户选择拒绝并不再询问(在较新的 Android 版本中,它通过第二次拒绝来表达)或操作系统确定不再需要请求时执行。如果未订阅此事件,PermissionCallbacks.PermissionDenied 将作为后备触发。在较新的 Android 版本上不可靠,建议仅连接到PermissionCallbacks.PermissionDenied。

2、自己扩展的权限调用(以Wifi信息获取为例)

(1)在 Assets/Plugins/Android/AndroidManifest.xml文件中添加对应的权限

(2)写对应的java插件放在Assets/Plugins/Android文件夹下

java 复制代码
//java文件内容
package com.example.networkinfo;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkCapabilities;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;

import com.unity3d.player.UnityPlayer;

public class NetworkInfoPlugin {

    private static Context getContext() {
        return UnityPlayer.currentActivity.getApplicationContext();
    }

    // 获取网络类型(安全)
    public static String getNetworkType() {
        ConnectivityManager cm =
            (ConnectivityManager) getContext().getSystemService(Context.CONNECTIVITY_SERVICE);

        if (cm == null) return "No Network";

        NetworkCapabilities nc = cm.getNetworkCapabilities(cm.getActiveNetwork());
        if (nc == null) return "No Network";

        if (nc.hasTransport(NetworkCapabilities.TRANSPORT_WIFI))
            return "WiFi";

        if (nc.hasTransport(NetworkCapabilities.TRANSPORT_CELLULAR))
            return "Cellular";

        return "Unknown";
    }

    // 获取 WiFi 名称
    public static String getWifiSSID() {
        WifiManager wm =
            (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
        if (wm == null) return "";

        WifiInfo info = wm.getConnectionInfo();
        if (info == null) return "";

        return info.getSSID();
    }

    // WiFi 信号强度(0-100)
    public static int getWifiSignalLevel() {
        WifiManager wm =
            (WifiManager) getContext().getSystemService(Context.WIFI_SERVICE);
        if (wm == null) return 0;

        WifiInfo info = wm.getConnectionInfo();
        if (info == null) return 0;

        return WifiManager.calculateSignalLevel(info.getRssi(), 100);
    }
}

(3)进行调用

csharp 复制代码
using System.Collections;
using System.Collections.Generic;
using System.Security;
using UnityEngine;

public class WifiPermission
{
	static AndroidJavaClass pluginClass;
	public WifiPermission()
	{
		pluginClass = new AndroidJavaClass("com.example.networkinfo.NetworkInfoPlugin");
	}


#if UNITY_EDITOR
	public string GetNetworkType()
	{
		switch (Application.internetReachability)
		{
			case NetworkReachability.NotReachable:
				return "No Network";
			case NetworkReachability.ReachableViaCarrierDataNetwork:
				return "Mobile Data";
			case NetworkReachability.ReachableViaLocalAreaNetwork:
				return "WiFi";
			default:
				return "Unknown";
		}
	}

	public string GetNetworkName()
	{
		return "PC端无法获取网络名称";
	}
	public int GetNetworkLevel()
	{
		return 0;
	}
	public void OpenWifiSettings()
	{
		//模拟Wifi界面 
		GFBuiltin.BuiltinView.ShowDialog("WiFi设置界面", "是否连接WiFi", "连接", "取消");
	}



#elif UNITY_ANDROID
	public string GetNetworkType()
	{
		return pluginClass.CallStatic<string>("getNetworkType");
	}
	
	public string GetNetworkName()
	{
		return pluginClass.CallStatic<string>("getWifiSSID");
	}

	public int GetNetworkLevel()
	{
		return pluginClass.CallStatic<int>("getWifiSignalLevel");
	}

	public void OpenWifiSettings()
	{
        using (AndroidJavaClass unityPlayer =
               new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
        {
            AndroidJavaObject activity =
                unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");

            using (AndroidJavaObject intent =
                   new AndroidJavaObject("android.content.Intent",
                       "android.settings.WIFI_SETTINGS"))
            {
                activity.Call("startActivity", intent);
            }
        }
	}

#elif UNITY_IOS
	//TODO

#else
	public string GetNetworkType()
	{
		return "Not supported";
	}
	public string GetNetworkName()
	{
		return "Not supported";
	}
	public int GetNetworkLevel()
	{
		return 0;
	}
	public void OpenWifiSettings()
	{
		//模拟Wifi界面
		GFBuiltin.BuiltinView.ShowDialog("WiFi设置界面", "是否连接WiFi", "连接", "取消");
	}
#endif

}
相关推荐
共享家95272 小时前
MySQL-基础查询(下)
android·mysql
君莫愁。2 小时前
【Unity】相机与UI的自适应
ui·unity·c#·游戏引擎
查克陈Chuck2 小时前
Launcher3模块化-组件化
android·launcher开发
千里马学框架2 小时前
google官方文档:深入剖析ProtoLog原理及Winscope的查看方式
android·车载系统·framework·perfetto·系统开发·winscope
apihz2 小时前
获取当前北京时间的免费API接口教程
android
apihz2 小时前
货币汇率换算免费API接口(每日更新汇率)
android·java·开发语言
恋猫de小郭3 小时前
八年开源,GSY 用五种技术开发了同一个 Github 客户端,这次轮到 AI + Compose
android·前端·flutter
sc.溯琛11 小时前
MySQL 高级实战:触发器、事务与数据库备份恢复全攻略
android·adb
zhuzewennamoamtf12 小时前
Linux SPI设备驱动
android·linux·运维