My app has a certain piece of functionality that will only work on a device where root is available. Rather than having this feature fail when it is used (and then show an appropriate error message to the user), I'd prefer an ability to silently check if root is available first, and if not,hide the respective options in the first place.
Is there a way to do this?
Here is a class that will check for Root one of three ways.
In my application I was checking if device is rooted or not by executing "su" command. But today I've removed this part of my code. Why?
Because my application became a memory killer. How? Let me tell you my story.
There were some complaints that my application was slowing down devices(Of course I thought that can not be true). I tried to figure out why. So I used MAT to get heap dumps and analyze, and everything seemed perfect. But after relaunching my app many times I realized that device is really getting slower and stopping my application didn't make it faster (unless I restart device). I analyzed dump files again while device is very slow. But everything was still perfect for dump file. Then I did what must be done at first. I listed processes.
Surprize; there were many processes for my application (with my application's process tag at manifest). Some of them was zombie some of them not.
With a sample application which has a single Activity and executes just "su" command, I realized that a zombie process is being created on every launch of application. At first these zombies allocate 0KB but than something happens and zombie processes are holding nearly same KBs as my application's main process and they became standart processes.
There is a bug report for same issue on bugs.sun.com: http://bugs.sun.com/view_bug.do?bug_id=6474073 this explains if command is not found zombies are going to be created with exec() method. But I still don't understand why and how can they become standart processes and hold significant KBs. (This is not happening all the time)
You can try if you want with code sample below;
Simple command execution method;
To sum up; I have no advice for you to determine if device is rooted or not. But if I were you I would not use Runtime.getRuntime().exec().
By the way; RootTools.isRootAvailable() causes same problem.
http://code.google.com/p/roottools/
If you do not want to use the jar file just use the code:
Program will try to find su folder:
Example:
The RootTools library offers simple methods to check for root:
Reference
Instead of using isRootAvailable() you can use isAccessGiven(). Direct from RootTools wiki:
Reference
Many of the answers listed here have inherent issues:
The RootTools library from Stericson seems to be checking for root more legitimately. It also has lots of extra tools and utilities so I highly recommend it. However, there's no explanation of how it specifically checks for root, and it may be a bit heavier than most apps really need.
I've made a couple of utility methods that are loosely based on the RootTools library. If you simply want to check if the "su" executable is on the device you can use the following method:
This method simply loops through the directories listed in the "PATH" environment variable and checks if a "su" file exists in one of them.
In order to truly check for root access the "su" command must actually be run. If an app like SuperUser is installed, then at this point it may ask for root access, or if its already been granted/denied a toast may be shown indicating whether access was granted/denied. A good command to run is "id" so that you can verify that the user id is in fact 0 (root).
Here's a sample method to determine whether root access has been granted:
It's important to actually test running the "su" command because some emulators have the "su" executable pre-installed, but only allow certain users to access it like the adb shell.
It's also important to check for the existence of the "su" executable before trying to run it, because android has been known to not properly dispose of processes that try to run missing commands. These ghost processes can run up memory consumption over time.