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();
}
}
}
Related
I am trying to start internal logs within my android devices without having to go directly into the adb shell. I have to script this process so I can run it from a program.
I am aware that you can take the following steps to start internal logs on an android device:
Open a cmd prompt
enter 'adb shell'
enter 'logcat -v time -f /sdcard/LogFile.txt&'
The above will start a logcat process within the actual device. I can now unplug my phone from the computer and move around then come back and collect the logs once my test is complete. It's crucial that I am able to start this process and be able to unplug my device with the logs still running.
To my knowledge running 'adb shell' in front of any command would run as if it were in the shell. Therefore by this logic I tried running:
Method 1:
'adb shell logcat -v time -f /sdcard/LogFile.txt&'
This command did properly start the log on the device which is great. However, once I unplug from my computer the logcat process stops.
Method 2:
'adb shell "logcat -v time -f /sdcard/LogFile.txt&" '
This didn't seem to do anything at all on the phone and I don't know why.
Method 3
I have tried the scripting method as well where I run a Batch file that contains only:
'adb shell < Commands.txt'
Where commands has the single line:
'logcat -v time -f /sdcard/LogFile.txt&'
This doesn't appear to do anything. It appears to send the command once the window comes up but doesn't actually perform the action.
Any help on this topic would be greatly appreciated. Thanks.
you can use this code in application class. so when app will launch this code will start executing. and it will create new log file according to current time.
Thread t = new Thread(new Runnable() {
public void run() {
while (collectLog == true) {
try {
Thread.sleep(1000 * 60 * 6);
StringBuilder log = null;
Date now = new Date();
String fileName = formatter.format(now);
File file = new File(dir, fileName + "_logcat2.txt");
try {
Process process = Runtime.getRuntime().exec("logcat -d");// d will dump logs
//Process process = Runtime.getRuntime().exec("logcat -c"); c will clear logs
// process = Runtime.getRuntime().exec("logcat -f " + file);
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
log = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append("\n");
}
} catch (IOException e) {
}
try {
//to write logcat in text file
FileOutputStream fOut = new FileOutputStream(file);
OutputStreamWriter osw = new OutputStreamWriter(fOut)
// Write the string to the file
osw.append(log.toString());
osw.flush();
osw.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
});
t.start();
I am trying to get my app to download an update from an ftp site, in the form of a new version of the apk. After download the apk should be installed silently, without any confirmation from a user. I have the download part under control. I can also do this with confirmation from the user. The problem is the silent update part.
From what I can tell the only way to do this is by installing the app as a system app. This is where I need some help.
I have tried alot of things. The most success I have had is the following:
Rooting the device.
Adding *android:sharedUserId="android.uid.system" to the manifest.
Adding the following permissions to the manifest:
android.permission.ACCESS_SUPERUSER and android.permission.INSTALL_PACKAGES
Signing the apk with Android Studio->Build->Generate Signed APK... using a signature generated like this:
./keytool-importkeypair -k google_certificate.keystore -p android -pk8 platform.pk8 -cert platform.x509.pem -alias platform
where I got the pk8 and pem files from the Android source mirror on GitHub.
Moving the signed apk to system/app on the device and clicking install on it.
The first thing I get is a huge list of permissions that the app is requesting which I never did. So I guess this is the permissions a system app has, so far so good :)
The immediately after I get the message:
App not installed.
Google could not tell why this error occures, so I am asking here.
Am I on the right path?
Why was the app not installed?
So after a couple of years I got to that problem again, and I managed to solve it. So the most important part is rooting the phone properly: This was done with the SuperSU app.
After downloading the .apk file, a method similar to the following is used to install the update:
private Boolean Install(String path)
{
File file = new File(path);
if(file.exists()){
try {
Process proc = Runtime.getRuntime().exec(new String[]{"su","-c","pm install -r -d " + path});
proc.waitFor();
BufferedReader input = new BufferedReader(new InputStreamReader(proc.getErrorStream()));
String line;
Boolean hasError = false;
while ((line = input.readLine()) != null) {
if(line.contains("Failure")){
hasError = true;
}
}
if(proc.exitValue() != 0 || hasError){
return false;
}
} catch (Exception e) {
e.printStackTrace();
return false;
}
return true;
}
return false;
}
If you device is rooted you can execute this command:
pm install com.example.myapp
How to execute this command?
There are two ways:
Way #1:
Use RootTools library:
Command command = new Command(0, "pm install com.example.myapp") {
#Override
public void commandCompleted(int arg0, int arg1) {
Log.i(TAG, "App installation is completed");
}
#Override
public void commandOutput(int arg0, String line) {
}
#Override
public void commandTerminated(int arg0, String arg1) {
}
}
RootTools.getShell(true).add(command);
Way #2:
This way not requires libraries, but it's harder than first way.
//Start a new process with root privileges
Process process = Runtime.getRuntime().exec("su");
//Get OutputStream of su to write commands to su process
OutputStream out = process.getOutputStream();
//Your command
String cmd = "pm install com.example.myapp";
//Write the command to su process
out.write(cmd.getBytes());
//Flush the OutputStream
out.flush();
//Close the OutputStream
out.close();
//Wait until command
process.waitFor();
Log.i(TAG, "App installation is completed");
We are writing an Android app that shows ads on large screens.
We have a backend where advertisers can select the ads, so they are updated almost instantly.
Because there will be a lot of Android boxes running (plugged into HDMI screens), we should be able to update our software remotely.
This is the case:
Main app is running continuously (unless turned off) and the users never see anything Android related.
We need an updater app that listens for updates and deletes the main apk, installs a new apk.
While updating we will show an activity with "Updating, please wait", until the new main apk is installed and showing.
What we need:
We need help on how to implement the update mechanism without prompting the user on ROOTED DEVICE.
What we have:
The updater app is hooked into the boot received event, where a service starts (this service will listen for updates, which will be implemented by a colleague soon).
The service can start an activity which will prompt the update info while updating.
In the updater activity
try {
Process proc = Runtime.getRuntime().exec(new String[]{"su", "pm install -r /mnt/sdcard/MYFOLDER/testAPK.apk"});
stringBuilder.append(String.valueOf(proc.waitFor()));
stringBuilder.append("\n");
} catch (Exception e) {
if (e instanceof IOException) {
Log.d(TAG, "IOException");
} else if (e instanceof InterruptedException) {
Log.d(TAG, "InterruptedException");
} else {
e.printStackTrace();
}
}
The StringBuilder prints 11, but does the same if I give random unexisting command..
In the Manifest
<!-- Permission to start UpdaterService on boot -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<!-- Install/delete permissions, only granted to system apps -->
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
The Install packages and delete packages are useless if I don't install my app as system app, am I correct?
Long story short, no installation of my test APK, and I have no idea how to solve this.
Any help would be appreciated!
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;
command = "adb install -r " + filename;
Process proc = Runtime.getRuntime().exec(new String[] { "su", "-c", command });
proc.waitFor();
} catch (Exception e) {
e.printStackTrace();
}
}
}
OR
Please check
http://paulononaka.wordpress.com/2011/07/02/how-to-install-a-application-in-background-on-android/
public void InstallAPK(String filename){
Process process = Runtime.getRuntime().exec("su");
OutputStream out = process.getOutputStream();
String reinstall = "pm install -r " + filename + "\n";
String am = "am start -a android.intent.action.MAIN -n yourPackage/.MainActivity";
String cmd = reinstall + am + " &";
out.write(cmd.getBytes());
out.flush();
out.close();
process.waitFor();
}
I am trying to run these shell commands via java but no success.Code executes perfectly but .so file do not exectue. while i use these commands in adb everything work perfeclty.
private void submit() {
System.out.println("doooooooooo");
try {
String[] commands = {"cd /data/data/com.dailydeals.usethisnow/lib",
"./libdeals.so" };
Process p = Runtime.getRuntime().exec("/system/bin/sh -");
DataOutputStream os = new DataOutputStream(p.getOutputStream());
for (String tmpCmd : commands) {
os.writeBytes(tmpCmd+"\n");
}
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("doneooooooooo");
}
Executing shell commands in Android Applications (Android Programming)
I have successfully build Gingerbread 2.3.4 for beagleboard xM rev C. Now i want to check Linux kernel version name inside a script which runs after the init.rc. In linux we can find the same using the command uname -r. But it is not found in android kernel. can somebody help me with some sample script to do the same.
There is a version file in the /proc directory. Try cat /proc/version in a shell and it should display informations about your kernel.
If your phone is rooted and BusyBox is installed then uname -r should work.
You can get kernel version using
adb shell cat /proc/version
or
with the help of
System.getProperty("os.version");
This worked for me
public static String getKernelVersion() {
try {
Process p = Runtime.getRuntime().exec("uname -a");
InputStream is = null;
if (p.waitFor() == 0) {
is = p.getInputStream();
} else {
is = p.getErrorStream();
}
BufferedReader br = new BufferedReader(new InputStreamReader(is));
String line = br.readLine();
Log.i("Kernel Version", line);
br.close();
return line;
} catch (Exception ex) {
return "ERROR: " + ex.getMessage();
}
}
Take a look at the AOSP DeviceInfoSettings:
https://github.com/android/platform_packages_apps_settings/blob/master/src/com/android/settings/DeviceInfoSettings.java#L378
'uname -r' command also should work