Android 如何防止根安卓手机安装我的应用程序?
本文的目的是防止在排行榜中报告虚假高分(我的应用程序是一款游戏)。这种情况发生在Flappy鸟身上-参见此链接- 由于root用户可以用他的手机做任何他想做的事情,我想其他解决办法都行不通,唯一的解决办法是阻止root用户安装应用程序。我说得对吗?有办法吗Android 如何防止根安卓手机安装我的应用程序?,android,mobile,anti-cheat,Android,Mobile,Anti Cheat,本文的目的是防止在排行榜中报告虚假高分(我的应用程序是一款游戏)。这种情况发生在Flappy鸟身上-参见此链接- 由于root用户可以用他的手机做任何他想做的事情,我想其他解决办法都行不通,唯一的解决办法是阻止root用户安装应用程序。我说得对吗?有办法吗 PS:我的游戏并不总是需要互联网连接,因此当它发生在另一台服务器上时报告分数是不可行的。只有当互联网连接可用时,才会向排行榜报告高分。我也有类似的要求。我无法实现应用程序不应安装在根设备上,但我使用了一种解决方法: 检查您的设备是否在活动的
PS:我的游戏并不总是需要互联网连接,因此当它发生在另一台服务器上时报告分数是不可行的。只有当互联网连接可用时,才会向排行榜报告高分。我也有类似的要求。我无法实现应用程序不应安装在根设备上,但我使用了一种解决方法:
- 检查您的设备是否在活动的
中扎根李>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
是一个实用程序类,在设备是否根目录时返回
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种。你可以使用任何你觉得好的方法
希望这有帮助
p.S:我已经在所有活动的
onResume
中打了这个电话,因为用户(有黑客意图)可以安装应用程序,导航到其他活动,然后是根设备。没有必要用根手机阻止用户,因为这是正常的用户行为。那么,如果你在游戏中没有高分、应用程序内购买等在线连接,你会担心什么样的危险或损害
玩家想要通过作弊达到最后一级或者在本地(!)排行榜上名列前茅?损坏在哪里
阻止游戏在根设备上运行只会让你排斥应用程序的合法用户
编辑:
使用云保存服务保存玩家的高分。如果离线,它将被加密并存储在设备上。下次在线时,您将阅读高分并将其发送到播放服务。play服务提供了您可能也需要的反盗版功能。我们在playstore控制台中提供了一个选项,可以使用该选项防止应用程序出现在playstore上,以便在根设备上下载。
有谷歌游戏服务的安全网认证API,我们可以通过该API评估设备并确定其是否已根植/篡改。
对于想要处理根设备的用户,请仔细阅读我的答案:
使用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
}
}
}
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
}
}
extension.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
}
}
}
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
....
....
}
}
希望这个答案能帮助您。很抱歉让您困惑。我重新编写了PS。我的游戏需要互联网连接(向排行榜报告分数),但并不总是如此(因此在游戏结束时检查分数是否“有效”,总是失败)。@DroidHeaven啊,好吧,我误解了。你在使用谷歌Play服务吗?或者你在推出自己的董事会系统吗?我使用谷歌PlayServices@DroidHeaven那就容易了。使用云保存服务保存玩家的高分。如果离线,它将被加密并存储在设备上。下次在线时,您将阅读高分并将其发送到播放服务。play服务提供了你可能也想要的反盗版功能。啊,现在我不知道应该接受哪个答案。你的和下面的都是有效的:)你可以说,在安装应用程序之前,有任何可能性吗?比如在android设备上安装应用程序时,我们可以检查设备是否根目录吗?但是为什么在onResume()中,为什么不在onCreate()方法中,我认为如果它在onCreate()中就好了在所有活动中。用户可以通过按后退按钮绕过警报。这里的命令是什么?如果你能解释一下它是如何工作的,我们将不胜感激。