Android UserManager.isUserAGoat()方法的合理用例

Android UserManager.isUserAGoat()方法的合理用例

技术背景

Android UserManager.isUserAGoat() 方法是 Android 系统中的一个有趣方法。最初,该方法一直返回 false。从 API 21(Android 5.0/Lollipop SDK)开始,其实现被更改,用于检测设备是否安装了游戏 Goat Simulator。到了 Android R 版本,为了“保护山羊隐私”,此方法总是返回 false

实现步骤

早期版本

在早期版本中,该方法的实现如下:

1
2
3
4
5
6
7
8
/**
* Used to determine whether the user making this call is subject to
* teleportations.
* @return whether the user making this call is a goat
*/
public boolean isUserAGoat() {
return false;
}

API 21 版本

从 API 21 开始,方法实现变为检查是否安装了 Goat Simulator 游戏:

1
2
3
4
5
6
7
8
9
10
11
12
13
/**
* Used to determine whether the user making this call is subject to
* teleportations.
*
* <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
* now automatically identify goats using advanced goat recognition technology.</p>
*
* @return Returns true if the user making this call is a goat.
*/
public boolean isUserAGoat() {
return mContext.getPackageManager()
.isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

Android R 版本

在 Android R 版本中,方法实现为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
/**
* Used to determine whether the user making this call is subject to
* teleportations.
*
* <p>As of {@link android.os.Build.VERSION_CODES#LOLLIPOP}, this method can
* now automatically identify goats using advanced goat recognition technology.</p>
*
* <p>As of {@link android.os.Build.VERSION_CODES#R}, this method always returns
* {@code false} in order to protect goat privacy.</p>
*
* @return Returns whether the user making this call is a goat.
*/
public boolean isUserAGoat() {
if (mContext.getApplicationInfo().targetSdkVersion >= Build.VERSION_CODES.R) {
return false;
}
return mContext.getPackageManager()
.isPackageAvailable("com.coffeestainstudios.goatsimulator");
}

最佳实践

作为调试辅助

在 IDE 中调试时,isUserAGoat() 可作为占位符设置断点,替代可能产生警告的虚拟变量声明。例如:

1
2
3
while (isUserAGoat()) {
System.out.println("Unreachable but determined at runtime, not at compile time");
}

作为竞赛元素

在 Google I/O 竞赛中,该方法曾被用作竞赛问题,用于考察参赛者是否阅读了 API 差异报告。

常见问题

方法实现变更导致的问题

如果在代码中使用 isUserAGoat() 方法用于非文档说明的目的,由于方法实现可能会变更,可能会引入难以调试的错误。例如,在 API 21 之前该方法总是返回 false,之后变为根据是否安装 Goat Simulator 游戏返回结果。

混淆代码理解

由于该方法名称和实现的趣味性,可能会让开发者混淆其真实用途,在代码维护和协作时造成困扰。


Android UserManager.isUserAGoat()方法的合理用例
https://119291.xyz/posts/2025-05-09.android-usermanager-isuseragoat-method-use-cases/
作者
ww
发布于
2025年5月9日
许可协议