【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

}
相关推荐
工程师老罗13 小时前
如何在Android工程中配置NDK版本
android
在路上看风景16 小时前
4.5 顶点和片元
unity
Libraeking17 小时前
破壁行动:在旧项目中丝滑嵌入 Compose(混合开发实战)
android·经验分享·android jetpack
市场部需要一个软件开发岗位17 小时前
JAVA开发常见安全问题:Cookie 中明文存储用户名、密码
android·java·安全
JMchen12319 小时前
Android后台服务与网络保活:WorkManager的实战应用
android·java·网络·kotlin·php·android-studio
crmscs20 小时前
剪映永久解锁版/电脑版永久会员VIP/安卓SVIP手机永久版下载
android·智能手机·电脑
localbob20 小时前
杀戮尖塔 v6 MOD整合版(Slay the Spire)安卓+PC端免安装中文版分享 卡牌肉鸽神作!杀戮尖塔中文版,电脑和手机都能玩!杀戮尖塔.exe 杀戮尖塔.apk
android·杀戮尖塔apk·杀戮尖塔exe·游戏分享
机建狂魔20 小时前
手机秒变电影机:Blackmagic Camera + LUT滤镜包的专业级视频解决方案
android·拍照·摄影·lut滤镜·拍摄·摄像·录像
hudawei99620 小时前
flutter和Android动画的对比
android·flutter·动画
lxysbly1 天前
md模拟器安卓版带金手指2026
android