I am doing a small application for a private circulation so that I do not use google play to install and update the app.
In my MainActivity, I will check whether app updation found or not via an api. If any update found my app download the updated apk file into download folder on the SDCard and install by:
intent.setDataAndType(Uri.fromFile(new File(destination)), "application/vnd.android.package-archive");
it works fine, but my problem is users can get the apk file in the download folder. So that I decided to download the file into /data/data/com.xxx.aaa. This idea, download the file into the /data... path. But I could not be installed the apk file. I make sure the apk file is present into the download folder by the following code:
if(new File(destination).exists()){
// apk file is present into download folder.
}
my method showing Parsing Error as below:
My Questions is:
How can I get install the updated apk file from the /data.... path?
I guess root privilege is the problem to install apk.
please help me.
Edited question:-
To get root access my application I run the following command:
try {
Runtime.getRuntime().exec("su");
}
after executing this command I can list /data/data/com.xxx.aaa path. and I have verified my downloaded apk file is presented here.
To install the apk, as told in the comment I run mount command in various option but no luck. I get Parsing error as shown in the figure.
I have tried the mount in the following ways:
1) mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
2) mount -o rw,remount -t yaffs2 /data/data.com.xxx.aaa/appinfo.apk
3) mount
4) mount /system
I do not know the right way to mount /data/data/.... path. How to mount the /data/data/.... path.
please help me.
To List Files From /data/app/
[1] su
[2] ls /data/app/
To get apk from "/data/app/" folder
# ls /data/app/
i am getting following apk list
com.android.vending-1.apk
com.google.android.gms-1.apk
com.noshufou.android.su-1.apk
com.corusen.accupedo.te-1.zip
com.microsoft.office.lync-1.apk
com.okythoos.android.tdmpro-1.apk
com.devindia.acr-1.apk
for example i want to get "com.android.vending-1.apk" out to /sdcard
[1] su
[2] cat /data/app/com.android.vending-1.apk > /sdcard/com.android.vending-1.apk
[3] adb pull /sdcard/com.android.vending-1.apk /path-to-your-folder/
To Run application as system app
[1] adb push your-app.apk /sdcard/
[2] adb shell
[3] su
[4] mount -o remount,rw /system
[5] cat /sdcard/your-app.apk > /system/app/your-app.apk
[6] chmod 0644 /system/app/your-app.apk
Run Command As Root User, From Your Android Code :
for example if you want to run command "chmod 0644 /system/app/your-app.apk" form root user
Example Steps :
[1] Execute From Computer
adb push your-app.apk /sdcard/
[2] Execute From Android Code
Exec_SU("mount -o remount,rw /system");
Exec_SU("cat /sdcard/your-app.apk > /system/app/your-app.apk");
Exec_SU("chmod 0644 /system/app/your-app.apk");
Here is implementation of above function "Exec_SU" :
public static void Exec_SU(String str_command)
{
// working well
Runtime runtime = Runtime.getRuntime();
Process proc = null;
OutputStreamWriter osw = null;
StringBuilder sbstdOut = new StringBuilder();
sbstdErr = new StringBuilder();
String command=str_command;
try {
// Run Script
proc = runtime.exec("su");
osw = new OutputStreamWriter(proc.getOutputStream());
osw.write(command);
osw.flush();
osw.close();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (osw != null) {
try {
osw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
try {
if (proc != null)
proc.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
i think this will helpful to you. Thanks.
Related
so im having problem with accessing root app data directory
my example dir:
/data/app/com.android.chrome-jAB96abq4RXcFrKebL0BUQ==
i want to get into /data/app/com.android.chrome without extension name to get list folder
tried /data/app/* com.android.chrome */ but got null
and here's my code
String path = "/data/app/*com.android.chrome*";
File file = new File(path);
String[] dir = file.list();
for(int i=0;i<dir.length;i++) {
Toast.makeText(this, "File: "+dir[i], Toast.LENGTH_LONG).show();}
and before that i've done changing the permission to 777 and using * com.android.chrome * goes well but my code above return null when try to listing directory
try {
Runtime.getRuntime().exec("su -c chmod 777 /data");
Runtime.getRuntime().exec("su -c chmod 777 /data/app");
Runtime.getRuntime().exec("su -c chmod 777 /data/app/*com.android.chrome*")
} catch (IOException e) { e.printStackTrace(); }
tried without * package * and still got null
sry the stars doesnt have whitespace...got to whitespace because the texteditor recognize as text format
thanks before
Your code does not work, because java.io.File can not handle wildcards.
You have to specify the exact path.
As /data is not readable for regular users Java code will never be able to list a directory in this directory (a wildcard requires directory listing).
Get the app info via PackageManager and the dataDir from the ApplicationInfo for the app you are interested in:
context.getPackageManager().getPackageInfo("com.android.chrome", 0).applicationInfo.dataDir;
source
Alternatively you can run a shell ls command with su/root that lists the /data/data directory and parse the result for the chrome app data directory.
I have the following problem.
I need to lock my tablet for a specific app. I am using my application in KioskMode, however I need to block some buttons, "Switch_app", "Volume_UP", "Volume_DOWN", etc.
I was able to block these buttons by accessing the ES File Explorer and changing the file manually, saving and restarting the tablet.
However, I would like to change this file progammatically.
I've tried the following:
{
using (StreamReader sr = new StreamReader("/system/usr/keylayout/Generic.kl"))
{
string line;
// Read and display lines from the file until the end of
// the file is reached.
while ((line = sr.ReadLine()) != null)
{
if (line.Contains("VOLUME"))
{
line = $"# {line}";
}
text += line + "\n";
System.Console.WriteLine(text);
}
}
CreateFile();
TransferFile();
};
void CreateFile()
{
string sdCard = Android.OS.Environment.ExternalStorageDirectory.AbsolutePath;
string path = Path.Combine(sdCard, "MyFolder/Generic.kl");
// This text is added only once to the file.
if (!System.IO.File.Exists(path))
{
// Create a file to write to.
System.IO.File.WriteAllText(path, text);
}
}
And to transfer the created file to / system / usr / Keylayout I use this:
Java.Lang.Runtime.GetRuntime().Exec("su -c mount -o rw,remount,rw /system");
Java.Lang.Runtime.GetRuntime().Exec("su -c rm system/usr/keylayout/Generic.kl");
Java.Lang.Runtime.GetRuntime().Exec("su -c mv /storage/emulated/0/MyFolder/Generic.kl system/usr/keylayout/Generic.kl");
When I use these commands, the file is copied, but when I restart the tablet no more physical buttons work. So I believe it's some problem related to deleting the old file and adding the new one.
Any help will be very welcome as well as ideas.
Thank you all.
There is no need to worry about ownership, permissions, etc. if you would use sed's in place editing:
GetRuntime().Exec("su 0 mount -o remount,rw /system");
GetRuntime().Exec("su 0 sed -i 's/^[^#]*VOLUME_DOWN/# &/' /system/usr/keylayout/Generic.kl");
GetRuntime().Exec("su 0 sed -i 's/^[^#]*VOLUME_UP/# &/' /system/usr/keylayout/Generic.kl");
GetRuntime().Exec("su 0 sed -i 's/^[^#]*APP_SWITCH/# &/' /system/usr/keylayout/Generic.kl");
You still need to reboot though.
That's the solution Rooted devices
Java.Lang.Runtime.GetRuntime().Exec("su -c mount -o rw,remount,rw /system");
Java.Lang.Runtime.GetRuntime().Exec("su -c rm system/usr/keylayout/Generic.kl");
Java.Lang.Runtime.GetRuntime().Exec("su -c mv /storage/emulated/0/MyFolder/Generic.kl system/usr/keylayout/");
**Java.Lang.Runtime.GetRuntime().Exec("su -c chmod 644 /system/usr/keylayout/Generic.kl");
Java.Lang.Runtime.GetRuntime().Exec("su -c chown system.system /system/usr/keylayout/Generic.kl");**
I am going to develop an android app it works as font installer.
the target of my app is rooted device which does not include the desired font, and it goes to install from war\fonts\ to \system\fonts folder.
any help
Try this:
First to test this code you must copy your custom fonts to /sdcard/ I don't know if you are going to put them in assets or download them from internet. Anyways to test, use the following command lines:
cd /<path_to_sdk>/platforms-tools/
./adb root
./adb remount
./adb push sample.ttf /sdcard/
Now the code:
This code only execute a bunch of commands. Note that the important part is that this commands change the default android fonts by your own fonts. Make sure of always make a backup.
Process process;
try {
process = Runtime.getRuntime().exec("mount -o remount /dev/mtdblock4 /system");
process = Runtime.getRuntime().exec("cat /system/fonts/DroidSansFallback.ttf >> /sdcard/DroidSansFallback.ttf");
process = Runtime.getRuntime().exec("cat /sdcard/sample.ttf >> /system/fonts/DroidSansFallback.ttf");
process = Runtime.getRuntime().exec("mount -o ro,remount /dev/mtdblock4 /system");
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));
} catch (IOException e) {
e.printStackTrace();
}
Also, you must reboot your device after do this.
my app have root right ,i want to using code to build a dir or file at /system or other dir of device.
i know common java build file as:
File file = new File(destFileName);
if (file.exists()) {
return false;
}
if i can build dir at system like the above code?if i need use su command before build file dir as
Process p = null;
p = Runtime.getRuntime().exec("su");
edit: i have read Create a file in /system directory but i cannot using code write :
" hint: use the "adb shell" and check if the upper steps can lead to success (su && remount -o remount,rw /system && touch /system/test)"
You need to get /system be mounted for write. By default it is read-only. You can use command like mount -o remount,rw /system
You can create dir using mkdir command
You can change the owner user by chown command
After that you can use java code as ususal.
I've written an app that modifies file system contents. One of the requirements to do this is mounting the system as read-write. From here and other sources, I've found the widely accepted command is this:
mount -o rw,remount -t yaffs2 /dev/block/mtdblock3 /system
I'm hoping someone can better explain how this works. I understood it to mean that we're working with a yaffs2 file system and going to mount the directory /dev/block/mtdblock3 as /system. When I issue the mount command on my phone though, /system is listed as ext3, not yaffs2 (if I substitute ext3 for yaffs2 the command works equally well). Also, /dev/block/mtdblock3 is not an existing directory.
This may be more of a Linux question than Android, but I'm sure someone knows all about this. Most importantly, how universal is this command? I'm planning on releasing this to a huge variety of devices, do I need to accomodate other file systems? Or will this "just work"?
I use this in one of my apps to make it as universal as possible. Of course it needs a rooted phone in order to work.
FileInputStream inputStream;
BufferedReader r;
String line, device = "", fs = "";
try {
inputStream = new FileInputStream("/proc/mounts");
} catch (FileNotFoundException e) {
Log.e("Could not read mounts");
return;
}
r = new BufferedReader(new InputStreamReader(inputStream));
//find device mounted as system and file system type
try {
while ((line = r.readLine()) != null) {
if(line.indexOf("/system") >= 0) {
String mount[] = line.split(" ");
device = mount[0];
fs = mount[2];
break;
}
}
inputStream.close();
} catch (IOException e) {
Log.e("Could not read mounts");
return;
}
//mount system as rw
CommandCapture command = new CommandCapture(0, "mount -o rw,remount -t " + fs + " " + device + " /system");
try {
RootTools.getShell(true).add(command).waitForFinish();
} catch (Exception e) {
Log.e("Couldn't mount system as rw!");
return;
}
It uses RootTools for convenience on shell commands and assumes the user already granted root access to your app.
The location of the device corresponding to the /system partition is device-specific, as is the filesystem in use; there is no single standard command. Moreover, there is no guarantee that the filesystem will be mutable at all; it's perfectly possible for the root fs to be on cramfs, or on some type of flash that's not easily randomly overwritten. For some phones it may be enough to check /proc/mounts for the actual device and fs-type corresponding to /system; for others you may not be able to remount it read-write.
Try this:
grep " /system " /proc/mounts | awk '{system("mount -o rw,remount -t "$3" "$1" "$2)}'
Remember your android device must be rooted and busybox must be installed.
Chat again