此背景下的目的是防止在LeaderBoard中报告错误的高分(我的应用程序是游戏)。 Flappy Birds发生了这种情况 - 请参阅此链接 - http://www.androidpit.com/forum/589832/flappy-bird-high-score-cheat-set-your-own-high-score
由于root用户可以使用他的手机做任何他想做的事情,我想其他任何工作都不会起作用,唯一的解决方案是阻止root用户安装应用程序。我对吗?有办法吗?
PS:我的游戏总是不需要互联网连接,因此在其他服务器发生时报告分数是不可行的。只有在互联网连接可用时,才会向排行榜报告高分。
答案 0 :(得分:15)
我有类似的要求。我无法实现应用程序不应该安装在root设备上,但我使用了一个解决方法:
onResume
。 示例:强>
@Override
protected void onResume() {
// TODO Auto-generated method stub
super.onResume();
if(new DeviceUtils().isDeviceRooted(getApplicationContext())){
showAlertDialogAndExitApp("This device is rooted. You can't use this app.");
}
}
public void showAlertDialogAndExitApp(String message) {
AlertDialog alertDialog = new AlertDialog.Builder(MainActivity.this).create();
alertDialog.setTitle("Alert");
alertDialog.setMessage(message);
alertDialog.setButton(AlertDialog.BUTTON_NEUTRAL, "OK",
new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Intent intent = new Intent(Intent.ACTION_MAIN);
intent.addCategory(Intent.CATEGORY_HOME);
intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
startActivity(intent);
finish();
}
});
alertDialog.show();
}
DeviceUtis.java
是一个Utility类,如果设备是否为root,则返回。
public class DeviceUtils {
public Boolean isDeviceRooted(Context context){
boolean isRooted = isrooted1() || isrooted2();
return isRooted;
}
private boolean isrooted1() {
File file = new File("/system/app/Superuser.apk");
if (file.exists()) {
return true;
}
return false;
}
// try executing commands
private boolean isrooted2() {
return canExecuteCommand("/system/xbin/which su")
|| canExecuteCommand("/system/bin/which su")
|| canExecuteCommand("which su");
}
}
我们使用了5种方法进行测试,我刚刚在这里展示了2种。您可以使用任何您认为合适的方法。
希望这有帮助。
PS:我已将此调用放在所有活动的onResume
中,因为用户(有黑客攻击)可以安装应用程序,导航到其他一些活动,然后导入根设备。
答案 1 :(得分:4)
无需像普通用户行为那样阻止使用root用户的用户。那么,如果您在游戏中没有高分,应用内购买等的在线连接,您会担心会有什么样的危险或损害?
玩家想欺骗她的方式到最后一级或本地(!)排行榜的顶部?损坏在哪里?
通过阻止您的游戏在root设备上运行,您只需取消应用程序的合法用户即可获得。
编辑:
使用云端保存服务保存播放器的高分。如果离线,它将被加密并存储在设备上。下次在线阅读高分并将其发送到播放服务。播放服务提供了您可能想要的反盗版功能。
答案 2 :(得分:2)
private static boolean canExecuteCommand(String command) {
boolean executedSuccesfully;
try {
Runtime.getRuntime().exec(command);
executedSuccesfully = true;
} catch (Exception e) {
executedSuccesfully = false;
}
return executedSuccesfully;
}
答案 3 :(得分:0)
我们在Playstore控制台中提供了一个 SafetyNet排除选项,我们可以使用该选项来阻止应用程序出现在Playstore上以便在有根设备上下载。
我们提供了 Google Play服务的 Safety Net Attestation API ,通过它我们可以评估设备并确定其是否被扎根/被篡改。
对于想要处理植根设备的用户,请仔细阅读我的回答:https://stackoverflow.com/a/58304556/3908895
答案 4 :(得分:0)
使用Kotlin Extension,您可以轻松检查设备是否已植根。以下是可以帮助您的代码
DeviceUtils.kt
object DeviceUtils {
fun isDeviceRooted(context: Context?): Boolean {
return isRooted1 || isRooted2
}
private val isRooted1: Boolean
get() {
val file = File("/system/app/Superuser.apk")
return file.exists()
}
// try executing commands
private val isRooted2: Boolean
get() = (canExecuteCommand("/system/xbin/which su")
|| canExecuteCommand("/system/bin/which su")
|| canExecuteCommand("which su"))
private fun canExecuteCommand(command: String): Boolean {
return try {
Runtime.getRuntime().exec(command)
true
} catch (e: Exception) {
false
}
}
}
Extention.kt
fun Activity.checkDeviceRoot(): Boolean {
return if (DeviceUtils.isDeviceRooted(this)) {
AlertDialog.Builder(this)
.setMessage("Your device is rooted. you can not use this app into rooted device.")
.setCancelable(false)
.setPositiveButton(R.string.alert_ok) { _, _ ->
exitProcess(0)
}.show()
true
} else {
false
}
}
如何使用此扩展:
class MyActivity : Activity{
...
override
fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_splash)
if(checkDeviceRoot())
return
....
....
}
}
希望这个答案会帮助您。