Android获取用户名时触发java.lang.SecurityException问题求助
问题分析
你遇到的java.lang.SecurityException是因为UserManager.getUserName()需要的是系统级特权权限,这类权限普通第三方APP无法仅通过清单声明获取,只有系统应用或拥有root权限的应用才能使用。
替代解决方案
普通APP可以通过以下几种方式获取用户相关标识,替代直接调用系统用户名接口:
1. 获取当前用户显示名称(适配Android 10+)
从Android 10(API 29)开始,UserManager.getDisplayName()无需特殊权限,可直接返回当前用户的显示名称:
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) { UserManager userMgr = (UserManager) getSystemService(USER_SERVICE); if (userMgr != null) { String displayName = userMgr.getDisplayName(); textUserName.setText(displayName); Log.d("UserName", displayName); } }
2. 获取Google账户名称(需GET_ACCOUNTS权限)
若用户设备绑定了Google账户,可通过账户管理器获取:
首先在清单文件添加权限:
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
然后实现代码逻辑:
AccountManager accountManager = AccountManager.get(this); Account[] accounts = accountManager.getAccountsByType("com.google"); if (accounts.length > 0) { String userName = accounts[0].name; textUserName.setText(userName); Log.d("UserName", userName); }
注意:Android 6.0及以上版本需要动态申请GET_ACCOUNTS权限。
3. 获取设备名称
如果仅需要一个用户可见的标识,可直接获取设备名称:
String deviceName = Settings.Secure.getString(getContentResolver(), "bluetooth_name"); if (deviceName == null || deviceName.isEmpty()) { deviceName = Build.MODEL; } textUserName.setText(deviceName); Log.d("UserName", deviceName);
4. 自定义用户标识
若以上方法都不满足需求,可让用户在APP内设置自定义用户名,存储到SharedPreferences中供后续使用。
原方法不可行的原因
MANAGE_USERS、CREATE_USERS、QUERY_USERS、GET_ACCOUNTS_PRIVILEGED这类权限属于signature|privileged级别,意味着:
- 只有系统签名的应用才能声明使用
- 或者应用被放置在系统的
priv-app目录下
普通第三方APP无法获取这些权限,因此调用userMgr.getUserName()必然会抛出SecurityException。
内容的提问来源于stack exchange,提问作者Mayuri
相关产品推荐
相关产品推荐

