IT评测·应用市场-qidao123.com

标题: Unity 之 Android 【获取设备的序列号 (Serial Number)/Android_ID】功能的 [打印本页]

作者: 丝    时间: 2024-7-19 09:31
标题: Unity 之 Android 【获取设备的序列号 (Serial Number)/Android_ID】功能的
Unity 之 Android 【获取设备的序列号 (Serial Number)/Android_ID】功能的简单封装


目录
Unity 之 Android 【获取设备的序列号 (Serial Number)/Android_ID】功能的简单封装
一、简单先容
二、获取设备的序列号 (Serial Number) 实现原理
1、Android
2、 Unity
三、注意实现
四、案例实现简单步骤
五、关键代码


一、简单先容

Unity 是一个功能强大的跨平台游戏引擎,广泛用于开发视频游戏和其他及时3D互动内容,如模拟器和虚拟实际应用。
   游戏引擎:
  
  开发环境:
  
  编程语言:
  
  Unity 进阶开发涉及更复杂的技能和更深入的知识,以创建高性能、复杂和专业的游戏和应用程序。以下是一些 Unity 进阶开发的关键领域和技能:
   设计模式:
  
  异步编程:
  
  依赖注入:
  
  
二、获取设备的序列号 (Serial Number) 实现原理

1、Android

在 Android 10 及以上版本,由于隐私和安全缘故起因,获取设备的序列号 (SN) 变得更加受限。
在 Android 10 及以上版本,可以使用 Build.getSerial() 方法来获取设备的序列号。不过,这需要获取 READ_PRIVILEGED_PHONE_STATE 权限,该权限仅限于系统应用。因此,对于普通应用,可以使用 Build.SERIAL 作为替代,但在 Android 10 上,这个常量已经被弃用并会返回一个占位符值。
  1. if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
  2.     String serial = Build.getSerial();
  3. } else {
  4.     String serial = Build.SERIAL;
  5. }
复制代码
  需要注意的是,在 Android 9(API 28)及以下版本,Build.SERIAL 可以直接使用。在 Android 10 及以上版本,需要系统权限。
  2、 Unity

在 Unity 中开发 Android 应用时,获取设备的序列号(SN)也受到 Android 10 及以上版本隐私和安全策略的影响。以下是怎样在 Unity 中实现这些功能的方法:
对于 Android 10 及以上版本,获取设备序列号需要使用 Build.getSerial() 方法,并且需要特定的权限。由于 Unity 使用 C# 代码,你需要通过调用 Java 方法来实现这一点。
1)首先,需要在 AndroidManifest.xml 文件中声明权限:
  1. <uses-permission android:name="android.permission.READ_PHONE_STATE"/>
  2. <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
复制代码
2)然后,使用 Unity 的 AndroidJavaObject 类来调用 Java 代码:
  1. using UnityEngine;
  2. public class DeviceInfo : MonoBehaviour
  3. {
  4.     public string GetSerialNumber()
  5.     {
  6.         string serialNumber = "Unknown";
  7.         if (Application.platform == RuntimePlatform.Android)
  8.         {
  9.             try
  10.             {
  11.                 using (AndroidJavaClass buildClass = new AndroidJavaClass("android.os.Build"))
  12.                 {
  13.                     if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O)
  14.                     {
  15.                         using (AndroidJavaObject buildObject = buildClass.CallStatic<AndroidJavaObject>("getSerial"))
  16.                         {
  17.                             serialNumber = buildObject.Call<string>("toString");
  18.                         }
  19.                     }
  20.                     else
  21.                     {
  22.                         serialNumber = buildClass.GetStatic<string>("SERIAL");
  23.                     }
  24.                 }
  25.             }
  26.             catch (System.Exception e)
  27.             {
  28.                 Debug.LogError("Error getting serial number: " + e.Message);
  29.             }
  30.         }
  31.         return serialNumber;
  32.     }
  33. }
复制代码

三、注意实现

通过上述步骤,你应该可以大概在 Unity 中乐成获取 Android 10 及以上版本设备的序列号。

四、案例实现简单步骤

1、创建 Unity 工程


2、新建脚本 DeviceInfo ,编写代码获取设备的序列号


3、由于这个可能需要权限申请,编写代码申请权限


4、实现申请电话权限,获取设备序列号(TestDeviceInfo.cs)


5、把脚本 TestDeviceInfo.cs 挂载到场景中


6、在 Player Settings 中的 Build 中勾选 Custom Main Manifest ,添加相干 Phone 权限申请



7、打包运行,可能报如下错误
Exception getting serial number: java.lang.SecurityException: getSerial: The uid 10170 does not meet the requirements to access device identifiers.

错误表明尝试获取设备序列号时碰到了权限问题。在 Android 10(API level 29)及以上版本中,获取设备的序列号需要特别权限,而这些权限通常不适用于普通应用程序。使用 Settings.Secure.ANDROID_ID 是一种更合适的替代方案,因为它不需要这些特别权限。

8、下面是怎样精确使用 Settings.Secure.ANDROID_ID 来获取设备的 Android ID:
  1.     /// <summary>
  2.     /// 获取设备的 Android ID
  3.     /// </summary>
  4.     /// <returns></returns>
  5.     public static string GetAndroidId()
  6.     {
  7.         string deviceId = string.Empty;
  8. #if UNITY_ANDROID && !UNITY_EDITOR
  9.         try
  10.         {
  11.             using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
  12.             {
  13.                 AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
  14.                 using (AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject>("getContentResolver"))
  15.                 {
  16.                     using (AndroidJavaClass secure = new AndroidJavaClass("android.provider.Settings$Secure"))
  17.                     {
  18.                         deviceId = secure.CallStatic<string>("getString", contentResolver, "android_id");
  19.                     }
  20.                 }
  21.             }
  22.         }
  23.         catch (AndroidJavaException e)
  24.         {
  25.             Debug.LogError("Exception getting Android ID: " + e.Message);
  26.         }
  27. #endif
  28.         return deviceId;
  29.     }
复制代码

9、打包运行,能获取到 设备的 Android ID


10、获取设备的 Android ID的 注意事项


五、关键代码

1、DeviceInfo
  1. using UnityEngine;public class DeviceInfo {    /// <summary>    /// 获取设备序列号    /// 需要系统权限    /// </summary>    public static string GetSerialNumber()    {        string serialNumber = string.Empty;#if UNITY_ANDROID && !UNITY_EDITOR        try        {            using (AndroidJavaClass buildClass = new AndroidJavaClass("android.os.Build"))            {                if (GetSDKInt() >= 26) // Build.VERSION_CODES.O == 26                {                    serialNumber = buildClass.CallStatic<string>("getSerial");                }                else                {                    serialNumber = buildClass.GetStatic<string>("SERIAL");                }            }        }        catch (AndroidJavaException e)        {            Debug.LogError("Exception getting serial number: " + e.Message);        }#endif        return serialNumber;    }    /// <summary>    /// 获取版本    /// </summary>    /// <returns></returns>    private static int GetSDKInt()    {        int sdkInt = 0;#if UNITY_ANDROID && !UNITY_EDITOR        using (AndroidJavaClass versionClass = new AndroidJavaClass("android.os.Build$VERSION"))        {            sdkInt = versionClass.GetStatic<int>("SDK_INT");        }#endif        return sdkInt;    }    /// <summary>
  2.     /// 获取设备的 Android ID
  3.     /// </summary>
  4.     /// <returns></returns>
  5.     public static string GetAndroidId()
  6.     {
  7.         string deviceId = string.Empty;
  8. #if UNITY_ANDROID && !UNITY_EDITOR
  9.         try
  10.         {
  11.             using (AndroidJavaClass unityPlayer = new AndroidJavaClass("com.unity3d.player.UnityPlayer"))
  12.             {
  13.                 AndroidJavaObject currentActivity = unityPlayer.GetStatic<AndroidJavaObject>("currentActivity");
  14.                 using (AndroidJavaObject contentResolver = currentActivity.Call<AndroidJavaObject>("getContentResolver"))
  15.                 {
  16.                     using (AndroidJavaClass secure = new AndroidJavaClass("android.provider.Settings$Secure"))
  17.                     {
  18.                         deviceId = secure.CallStatic<string>("getString", contentResolver, "android_id");
  19.                     }
  20.                 }
  21.             }
  22.         }
  23.         catch (AndroidJavaException e)
  24.         {
  25.             Debug.LogError("Exception getting Android ID: " + e.Message);
  26.         }
  27. #endif
  28.         return deviceId;
  29.     }}
复制代码

2、PermissionWrapper
  1. using UnityEngine;
  2. using UnityEngine.Android;
  3. public class PermissionWrapper : MonoSingleton<PermissionWrapper>
  4. {
  5.     /// <summary>
  6.     /// 请求权限
  7.     /// </summary>
  8.     /// <param name="permission">权限名称</param>
  9.     /// <param name="callback">权限回调:true 权限获取成功回调,false 权限获取失败回调</param>
  10.     public void RequestPermission(string permission, System.Action<string, bool> callback)
  11.     {
  12.         if (Permission.HasUserAuthorizedPermission(permission))
  13.         {
  14.             callback?.Invoke(permission, true);
  15.         }
  16.         else
  17.         {
  18.             StartCoroutine(RequestAndCheckPermission(permission, callback));
  19.         }
  20.     }
  21.     /// <summary>
  22.     /// 协程请求权限
  23.     /// </summary>
  24.     /// <param name="permission">权限名称</param>
  25.     /// <param name="callback">权限回调:true 权限获取成功回调,false 权限获取失败回调</param>
  26.     /// <returns></returns>
  27.     private System.Collections.IEnumerator RequestAndCheckPermission(string permission, System.Action<string, bool> callback)
  28.     {
  29.         Permission.RequestUserPermission(permission);
  30.         yield return new WaitForSeconds(1.0f);
  31.         bool granted = Permission.HasUserAuthorizedPermission(permission);
  32.         callback?.Invoke(permission, granted);
  33.     }
  34. }
复制代码

3、TestDeviceInfo
  1. using UnityEngine;
  2. public class TestDeviceInfo : MonoBehaviour
  3. {
  4.     /// <summary>
  5.     /// TAG
  6.     /// </summary>
  7.     const string TAG = "[TestDeviceInfo] ";
  8.     // Start is called before the first frame update
  9.     void Start()
  10.     {
  11.         GetSerialNumber();
  12.     }
  13.     private void GetSerialNumber()
  14.     {
  15.         string permission = "android.permission.READ_PHONE_STATE";
  16.         string sn = string.Empty;
  17.         PermissionWrapper.Instance.RequestPermission(permission, (permission, isGranted) => {
  18.             if (isGranted)
  19.             {
  20.                 //sn = DeviceInfo.GetSerialNumber();
  21.                 sn = DeviceInfo.GetAndroidId();
  22.             }
  23.             else
  24.             {
  25.                 sn = "unknown";
  26.             }
  27.             Debug.Log(TAG + "GetAndroidId() = " + sn);
  28.         });
  29.     }
  30. }
复制代码

4、AndroidManifest.xml
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <manifest
  3.     xmlns:android="http://schemas.android.com/apk/res/android"
  4.     package="com.unity3d.player"
  5.     xmlns:tools="http://schemas.android.com/tools">
  6.     <!-- 获取 sn 的权限 Start-->
  7.     <uses-permission android:name="android.permission.READ_PHONE_STATE"/> 
  8.     <uses-permission android:name="android.permission.READ_PRIVILEGED_PHONE_STATE" />
  9.     <!-- 获取 sn 的权限 End-->
  10.    
  11.     <application>
  12.         <activity android:name="com.unity3d.player.UnityPlayerActivity"
  13.                   android:theme="@style/UnityThemeSelector">
  14.             <intent-filter>
  15.                 <action android:name="android.intent.action.MAIN" />
  16.                 <category android:name="android.intent.category.LAUNCHER" />
  17.             </intent-filter>
  18.             <meta-data android:name="unityplayer.UnityActivity" android:value="true" />
  19.         </activity>
  20.     </application>
  21. </manifest>
复制代码


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 IT评测·应用市场-qidao123.com (https://dis.qidao123.com/) Powered by Discuz! X3.4