I can get a list of installed apps (both user and system apps). I am also able to uninstall user apps, however, not able to uninstall system apps.
Is there any way to uninstall system app?
If the phone is already rooted, will the following code work?
Intent intent = new Intent(Intent.ACTION_DELETE);
intent.setData(Uri.parse("package:"+appPackageName.getText().toString()));
context.startActivity(intent);
you can execute root commands with:
runCommand("su");
runCommand("rm /data/system/application.package.apk");
runCommand("rm /data/data/application.package");
//when this doesn´t work try
runCommand("rm -r /data/system/application.package.apk");
runCommand("rm -r /data/data/application.package");
public static void runCommand(String command){
try {
Process chmod = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(
new InputStreamReader(chmod.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
chmod.waitFor();
outputString = output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
There is also a nice library: https://github.com/Free-Software-for-Android/RootCommands
You need to have root access in order to remove system or vendor apps.
$ su
# rm /data/system/application.package.apk
# rm /data/data/application.package
Try this on Rooted Device...it works
Process reboot = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(reboot.getOutputStream());
os.writeBytes("pm uninstall co.example.demo\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
reboot.waitFor();
Related
I am making an app that can uninstall system apps. After going through all the answers from StackOverFlow, I can say that 99% of them are via ADB and the one which I found useful https://stackoverflow.com/a/34399068/9953518 ,this is now changed from Android O.
According to this article https://medium.com/#quaful/the-changes-of-apk-install-location-since-android-oreo-e646d1b53c4d it is now not possible to navigate to a specific folder of the app and we are bound to use .sourceDir. The problem that I have is after requesting for the root and getting the sourceDir, the .apk file doesn't uninstall and if it does, the complete files are not uninstalled or removed in this case. I am using the code below :
//appsSelected is the array with all the package names of the system apps selected to be uninstalled
case "uninstall":
for (int i = 0; i < appsSelected.size(); ++i) {
final int finalI = i;
Thread worker = new Thread(new Runnable() {
#Override
public void run() {
RootManager.getInstance().obtainPermission();
System.out.println("Public directory is "+ yup(appsSelected.get(finalI)));
runCommand("rm -rf "+ yup(appsSelected.get(finalI)) );
}
});
worker.start();
}
break;
This is the fucntion that returns the filePath:
String yup(String pack){
PackageManager m = getPackageManager();
PackageInfo p = null;
try {
p = m.getPackageInfo(pack, 0);
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return p.applicationInfo.sourceDir;
}
Finally the function that runs the commands:
public static void runCommand(String command) {
try {
Process chmod = Runtime.getRuntime().exec(command);
BufferedReader reader = new BufferedReader(
new InputStreamReader(chmod.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
chmod.waitFor();
String outputString = output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
I have the root permission ("su" command) and all the permissions required.
At first, run:
pm uninstall <package_name>
Then,
rm -r <applicationinfo.sourceDir>
Then,
rm -r <applicationinfo.publicSourceDir>
Then reboot the device, and the app should be uninstalled.
N.B: All these command should run as root!
I'm trying to reboot programmatically my Galaxy S3.
Things that I've tried:
try {
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", "reboot" });
proc.waitFor();
} catch (Exception ex) {
Log.i("RebootActivity", "Could not reboot", ex);
}
try {
Runtime.getRuntime().exec(new String[]{"su","-c","reboot now"});
} catch (IOException e) {
e.printStackTrace();
}
try
{
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("reboot now\n");
}
catch (Throwable t)
{
t.printStackTrace();
}
Do you guys have any idea how to accomplish this?
Thanks.
Try to do one normal string looking like 《su \n reboot; \n》 instead of an array.
Try to get the answer from the shell, that helps a lot for debugging.
What are the permissions of your su binary? If they would be wrong, you could try to 《chmod 7777 /system/xbin/su》 after 《mount -o remount,rw /system》
Here is some example code: (to run the string command, which is a \n and or ; separated list of linux shell commands)
StringBuffer commandOutput = new StringBuffer();
try {
Process process = Runtime.getRuntime().exec("su\n");
DataOutputStream out = new DataOutputStream(process.getOutputStream());
out.writeBytes("export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/vendor/lib:/system/lib\n");
out.writeBytes(command+"\n");
out.flush();
process.waitFor();
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
int numRead;
char[] buffer = new char[1000];
while ((numRead = in.read(buffer)) > 0) {
commandOutput.append(buffer, 0, numRead);
}
in.close();
process.waitFor();
} catch ...
return commandOutput.toString();
You could possibly use the PowerManager to make it reboot (this does not guarantee that it'll reboot - OS may cancel it):
http://developer.android.com/reference/android/os/PowerManager.html#reboot(java.lang.String
http://developer.android.com/reference/android/Manifest.permission.html#REBOOT
Background
We build and control the hardware devices on which the app will run.
(EDIT)We will build a custom version of the Android OS soon as well.
We're building an app which we expect to be "always-on."
We want the app to be able to self-update, independent of the market. Hence, we are hosting a service which the client app will periodically poll for updates, download the apk, and then install it. Therein lies...
The problem
I want the UpdateService to install the downloaded app update without giving the user the usual permission and update prompts - after all, we control the hardware and the software.
To do that, I think I need to give my app superuser permissions (tho, if there is some other way, then my question becomes something completely different).
But I can't figure out how to do that.
I have read about a superuser app that can be installed - but this seems like a user solution for users who want to root their own phones. Or a solution for devs who want to distribute an app that needs superuser, but they don't control the device on which their users will install it.
Is there a file somewhere in the android OS that lists apps or users which should have su? If so, it's no problem; we control everything.
first I download and then I run the uninstall and install ( the system is rooted)
private void uninstall() {
try {
Process p = Runtime.getRuntime().exec("su");
InputStream es = p.getErrorStream();
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("pm uninstall com.example.app\n");
os.writeBytes("exit\n");
os.flush();
int read;
byte[] buffer = new byte[4096];
String output = new String();
while ((read = es.read(buffer)) > 0) {
output += new String(buffer, 0, read);
}
p.waitFor();
} catch (Exception e) {
}
}
private void install() {
try {
// Do the magic
Process p = Runtime.getRuntime().exec("su");
InputStream es = p.getErrorStream();
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("pm install /mnt/sdcard/exampple/app.apk\n");
os.writeBytes("exit\n");
os.flush();
int read;
byte[] buffer = new byte[4096];
String output = new String();
while ((read = es.read(buffer)) > 0) {
output += new String(buffer, 0, read);
}
p.waitFor();
} catch (IOException e) {
Log.d("catch silant", "1");
} catch (InterruptedException e) {
Log.d("catch silant", "2");
}
}
look of this : https://code.google.com/p/auto-update-apk-client/downloads/detail?name=auto-update-apk-client_2012-10-04.tgz&can=2&q=
I think it can help you, I am also trying to do it now if you are success pleas write because I have an hard time with doing it.
This question has been asked here before but the solutions provided are not working..I am trying to display the contents of /data/dalvik-cache folder. I know that to do this we need to become su. I even did that but still i am unable to execute a shell command..
package org.linuxconfidg.Example2;
import android.app.Activity;
import android.widget.*;
import android.os.Bundle;
import java.io.*;
public class Example2Activity extends Activity {
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
String lsreturn=myFunLs();
TextView tv=new TextView(this);
tv.setText("Hello Sindhu !! Try to get it \n"+lsreturn);
setContentView(tv);
}
public String myFunLs()
{
try {
// Executes the command.
Process process;
process = Runtime.getRuntime().exec("/system/bin/su");
process = Runtime.getRuntime().exec("/system/bin/ls /data/dalvik-cache > /data/local");
pr
BufferedReader reader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
return output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
Can anyone please help me out in finding out how to run linux commands in android application. I am testing this app in my emulator which is defaultly rooted
You can't simply run 'su' on the emulator, there's no root access by default. You'll need to install the 'su' program as well as the SuperUser.apk, and you'll have to do this each time you start the emulator unless using snapshots.
More information and links to the files you need can be found here on SO as well as this blog post by Russell Davis
I think the problem comes from the fact that you are using TWO different process instances.
You have to be on the su process to carry on sending commands:
You can check the question "Read command output inside su process"
for an answer.
Then I tried & managed to make working code (I'm sure it works!)
public void runAsRoot(String[] cmds) throws Exception {
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
InputStream is = p.getInputStream();
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
int readed = 0;
byte[] buff = new byte[4096];
// if cmd requires an output
// due to the blocking behaviour of read(...)
boolean cmdRequiresAnOutput = true;
if (cmdRequiresAnOutput) {
while( is.available() <= 0) {
try { Thread.sleep(200); } catch(Exception ex) {}
}
while( is.available() > 0) {
readed = is.read(buff);
if ( readed <= 0 ) break;
String seg = new String(buff,0,readed);
console.println("#> "+seg);
}
}
}
os.writeBytes("exit\n");
os.flush();
}
In the below example, I try to execute "/system/bin/screencap" to capture android screen.
via adb:
> adb shell
# /system/bin/screencap -p /sdcard/myscreenshot.png
via Android app:
sh = Runtime.getRuntime().exec("su", null,null);
OutputStream os = sh.getOutputStream();
os.write(("/system/bin/screencap -p " + path).getBytes("ASCII"));
os.flush();
os.close();
sh.waitFor();
Hope this helps.
In my app, I want to run few shell command sand interpret the output. These commands are essentially the on that would run on rooted phone.
How do I do it?
First make sure that the shell command that you need is actually available in Android. I've run into issues by assuming you can do things like redirect output with >.
This method also works on non-rooted phones of I believe v2.2, but you should check the API reference to be sure.
try {
Process chmod = Runtime.getRuntime().exec("/system/bin/chmod 777 " +fileName);
BufferedReader reader = new BufferedReader(
new InputStreamReader(nfiq.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
chmod.waitFor();
outputString = output.toString();
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
While it's probably not 100% necessary, it's a good idea to have the process wait for the exec to complete with process.waitFor() since you said that you care about the output.
You need to first ensure you have busybox installed as that would install the list of most commonly used shell commands and then use the following code to run the command.
Runtime.getRuntime().exec("ls");