I'm writing a Uninstall App. I want to remove System App, of course my phone is Rooted. I use code from How to uninstall Android App with root permissions?.
private void delApp() {
String deleteCMD = "pm " + applicationInfo.packageName;
Process process;
try
{
process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("mount -o remount,rw -t rfs /dev/stl5 /system; \n");
os.writeBytes(deleteCMD+"; \n");
os.writeBytes("mount -o remount,ro -t rfs /dev/stl5 /system; \n");
os.flush();
}
catch (IOException e)
{
e.printStackTrace();
}
}
but my phone Toast a message "... has been Granted super User Permissons" and not remove app I choosed. I try with both User App and System App but not different. What am I missing ? How to remove System App with Root permissons and How to remove App without this Dialog (fast remove and automaticaly).
EDIT
I solved my problem using this code, hope it help someone.
Process process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("mount -o rw,remount /system\n");
os.writeBytes("rm -r "+ "[SourceDir]" + "\n");
os.writeBytes("mount -o ro,remount /system\n");
os.flush();
os.close();
process.waitFor();
note: [SourceDir] is your system app directory
Related
I need to set permissions for a file and its folder. Both are in /data/ folder on internal storage. The only way my app can do that is:
String[] cmd = { "su", "-c", "chmod 777 " + myakDB.getParentFile().getPath()};
Process process = Runtime.getRuntime().exec(cmd);
process.waitFor();
cmd = new String[] { "su", "-c", "chmod 666 " + myakDB.getPath() };
process = Runtime.getRuntime().exec(cmd);
process.waitFor();
Thus it asks the Superuser two times for permission. This is unwanted behaviour i guess for my app's users. So searching the same problem over the internet gave me the following solution (using stream):
Process process = Runtime.getRuntime().exec("su");
DataOutputStream out = new DataOutputStream(process.getOutputStream());
out.writeBytes("chmod 777 " + myakDB.getParentFile().getPath());
out.writeBytes("chmod 666 " + myakDB.getPath());
out.writeBytes("exit\n");
out.flush();
But it doesn't work. Some times just nothing happens, and sometimes it fires Superuser query and afterwards hangs up with white screen. So what's wrong with my process?
You need to add a new line after each command:
Process process = Runtime.getRuntime().exec("su");
DataOutputStream out = new DataOutputStream(process.getOutputStream());
out.writeBytes("chmod 777 " + myakDB.getParentFile().getPath() + "\n");
out.writeBytes("chmod 666 " + myakDB.getPath() + "\n");
out.writeBytes("exit\n");
out.flush();
I have the same issue with you. So I use the code below to check what was wrong.
Runtime rt = Runtime.getRuntime();
String[] commands = {"su"};
Process proc = rt.exec(commands);
String exit1 = "exit\n";
proc.getOutputStream().write("rm /system/app/.apk\n".getBytes());
proc.getOutputStream().write(exit1.getBytes());
proc.waitFor();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(proc.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(proc.getErrorStream()));
// read the output from the command
Log.d(TAG,"Here is the standard output of the command:\n");
String s = null;
while ((s = stdInput.readLine()) != null) {
Log.d(TAG,s);
}
// read any errors from the attempted command
Log.d(TAG,"Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
Log.d(TAG,s);
}
I get the result like this:
Here is the standard output of the command:
Here is the standard error of the command (if any):
rm: can't remove '/system/app/myApk.apk': Permission denied
But fortunately, Runtime.getRuntime().exec("su","-c","rm /system/app/myApk.apk"); worked for me.
so you may try this.
I want to install .apk silently in background by BusyBox command. I`ve seen some similar questions like THIS, but I still cant get working my code properly...
I have:
My .apk I need to install on /sdcard/download/app.apk
Root
BusyBox installed
Code (not working):
String sss = Environment.getExternalStorageDirectory() + "/download/" + "app.apk";
Process install;
install = Runtime.getRuntime().exec("/system/xbin/busybox pm install " + sss);
int success = install.waitFor();
If I use "install" instead of "pm install" it copies file well.
P.S. Code above is executing in AsyncTask. No errors, but also nothing happens...
Please help!
Also I tried this, but I`m getting exit value 139 and no result:
Process process;
process = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(process.getOutputStream());
os.writeBytes("pm install /mnt/sdcard/app.apk\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
int i = process.waitFor();
maybe this code will help you
Process p = null;
try
{
p = Runtime.getRuntime().exec("su");
DataOutputStream outs=new DataOutputStream(p.getOutputStream());
String cmd="pm install /mnt/sdcard/app.apk";
outs.writeBytes(cmd+"\n");
}
catch (IOException e)
{
e.printStackTrace();
}
After a lot of investigations on many android devices I realized that this code is correct and works!
There was just some problem with one device (Samsung Galaxy Tab 2 7.0 - 4.0.3 ICS). Maybe that is some strange feature of ICS. After updating firmware to 4.1.2 (Jelly Bean) problem has been resolved.
You can simply use adb install command to install/update APK silently. Sample code is below
public static void InstallAPK(String filename){
File file = new File(filename);
if(file.exists()){
try {
String command;
filename = StringUtil.insertEscape(filename);
command = "adb install -r " + filename;
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
I want to make my app become system app programmatically. I managed to do it in my phone with root and busybox. any idea how achieve this without busybox?
Runtime.getRuntime().exec(new String[] { "su", "-c", "mount -o rw,remount -t yaffs2 /system; " +
"cp `ls /data/app/xxx*` /system/app; " +
"rm /data/app/xxx*; " +
"mount -o ro,remount -t yaffs2 /system; " +
"reboot" });
Beside this, I also faced another issue. If i switch back my app from system app > user app and reboot. Android system still recognize my app as system app even though the app already reside in /data/app.
I use code below to check whether my app is system app:
android.content.pm.ApplicationInfo.FLAG_SYSTEM
Refer the below code to move user app apk into system app apk in rooting device with the help of RootTools method .
PackageInfo paramPackageInfo = null;
try {
paramPackageInfo = this.getPackageManager().getPackageInfo(
this.getPackageName(), 0);
} catch (NameNotFoundException e) {
e.printStackTrace();
}
ApplicationInfo localApplicationInfo = paramPackageInfo.applicationInfo;
String str1 = "/system/app/" + localApplicationInfo.packageName
+ ".apk";
String str2 = "busybox mv " + localApplicationInfo.sourceDir + " "
+ str1;
RootTools.remount("/system", "rw");
RootTools.remount("/mnt", "rw");
CommandCapture command = new CommandCapture(0, str2,
"busybox chmod 644 " + str1);
try {
RootTools.getShell(true).add(command).waitForFinish();
} catch (InterruptedException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (TimeoutException e) {
e.printStackTrace();
} catch (RootDeniedException e) {
e.printStackTrace();
}
RootTools.remount("/system", "ro");
RootTools.remount("/mnt", "ro");
Necessary of Busybox and superuser app while use the above code in your application.
I need to open USB Mass Storage Activity from my application.
Is there any Intent to do this?
something like
startActivity(new Intent(Settings.ACTION_APPLICATION_DEVELOPMENT_SETTINGS))
You can try to use following:
su -c setprop sys.usb.config <command>
Full list of can be found by this one command:
cat init.usb.rc
Function to be able to run command from app:
public void RunAsRoot(String[] cmds){
Process p = Runtime.getRuntime().exec("su");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : cmds) {
os.writeBytes(tmpCmd+"\n");
}
os.writeBytes("exit\n");
os.flush();
}
I have an app on the market that is for rooted devices only. I have tested the app extensively on a rooted and unrooted G1, MT3G and Cliq with no errors. I am receiving a number of low ratings from people with supposedly rooted devices, saying that the app tells them that they are not rooted (of course, they usually don't leave important info like what phone and what rom)
Here is the code that generates the error... can anyone see out what the problem might be?
final Button button = (Button) findViewById(R.id.******);
button.setOnClickListener(new View.OnClickListener() {
public void onClick(View v) {
String command1 = "mount -o remount,rw -t yaffs2 /dev/block/mtdblock3 /system";
String command2 = "cp -f /sdcard/******* /etc/";
String command3 = "dos2unix -u /etc/*****";
String command4 = "mount -o ro,remount -t yaffs2 /dev/block/mtdblock3 /system";
execCommandLine1(command1);
execCommandLine1(command2);
execCommandLine1(command3);
execCommandLine1(command4);
}
void execCommandLine1(String command)
{
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
try
{
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
}
catch (IOException ex)
{
Log.e("execCommandLine()", "Command resulted in an IO Exception: " + command);
return;
}
finally
{
if (osw != null)
{
try
{
osw.close();
}
catch (IOException e){}
}
}
try
{
proc.waitFor();
}
catch (InterruptedException e){}
if (proc.exitValue() != 0)
{
**// Error Dialog that is being erroneously displayed**
}
else {
// Success Dialog
}
}
I agree with Christopher's comment: you appear to be making some assumptions:
/system is at /dev/block/mtdblock3
/dev/block/mtdblock3 is yaffs2
/etc/ is a hardlink or symlink to something on /system
mount exists
dos2unix exists
cp exists
su exists
Most of those should be testable at runtime, though the /etc/ check might be a bit tricky. Test that stuff out on the first run of your app, then do whatever makes sense:
an "sorry, this app won't work" if you detect a failure
disable the menu/button/whatever that leads to whatever is executing your code