How to prevent Rooted Android Phones from Installing my app?

I had a similar requirement. I couldn't achieve that app should not be installed on rooted device, but I used a work around for that:

  • Check if your device is rooted in your activity's onResume.
  • If its rooted, just show him alert "This device is rooted. You can't use this app.", and exit from application.

Example:

@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 was a Utility class which returned if a device is rooted or not.

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");
    }
}

We had used 5 methods for testing, and I have just shown 2 here. You can use any of methods you find good.

Hope this helps.

P.S: I have put this call in all activity's onResume as user (with intention of hacking) can install application, navigate to some other activity, and then root device.


There is no need to block users with rooted phones as it normal user behaviour. So, what kind of danger or damage do you fear if you have no online connection for highscores, in-app purchases or the like in your game?

The player wants to cheat her way to the last level or to the top of the local(!) leaderboard? Where is the damage?

By preventing your game from running on rooted devices gains you nothing but repell legitimate users of your app.

Edit:

Use the cloud save service to save the player's highscores. if offline it will be encrypted and stored on the device. The next time online you read the highscore and send it to the play service. The play service provides an anti piracy feature you also might want.


private static boolean canExecuteCommand(String command) {
        boolean executedSuccesfully;
        try {
            Runtime.getRuntime().exec(command);
            executedSuccesfully = true;
        } catch (Exception e) {
            executedSuccesfully = false;
        }

        return executedSuccesfully;
    }