Can not access android /data folder? - android

try {
Runtime rt = Runtime.getRuntime();
Process pcs = rt.exec("ls -l /data");
BufferedReader br = new BufferedReader(new InputStreamReader(pcs
.getInputStream()));
String line = null;
while ((line = br.readLine()) != null) {
Log.e("line","line="+line);
}
br.close();
pcs.waitFor();
int ret = pcs.exitValue();
Log.e("ret","ret="+ret);
} catch (Exception e) {
Log.e("Exception", "Exception", e);
}
only print "ret=0",How to print the correct path?

Android protects it's internal directories. You can only access your directory under /data/data/your_package. I believe that the normal user does not have Read privileges for the /data directory on a normal device.

data folder is inaccessible on a device except by system processes. You cannot access data folder of a unrooted phone through adb. You can access data folder of emulator or rooted phones.

Did you try doing it with your own app, and not by spawning another process (e.g. Runtime.exec())
File dataDir = new File("/data");
String[] files = dataDir.list();
for (int i = 0 ; i < files.length ; i++ ) {
Log.d(TAG, "File: "+files[i]);
}
Also, I'd look at the different read permissions, maybe there's another way to get to the data you're looking for via ContentProviders.

If you'll want to access /data folder not from java code, but from your PC console - you can use a adb shell command. it has no restrictions.
remember to have an emulator running, or connect your phone via USB before running that

Related

How Thirdparty Apps access All details about installed apps

In my app , I am showing the memory usage of each app. I tried the solutions provided in SOF as,
Getting from MemInfo shell command
Process process = Runtime.getRuntime().exec("dumpsys meminfo " + info.packageName);
Permission denied to run this command.
Tried with TOP command
Process process = Runtime.getRuntime().exec("top -n 1 -d 1");
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
for(int i=0;i<5;i++)
in.readLine();
do {
try {
String trial[] = in.readLine().split(" ");
int j=0;
String array[]=new String[trial.length];
for(String a:trial)
{
if(!a.isEmpty()) {
array[j] = a;
j++;
}
}
String package_name=array[9];
if(package_name!=null)
{
if(package_name.contains(":"))
package_name=package_name.substring(0,package_name.indexOf(":"));
}
publishProgress(package_name);
Debug.MemoryInfo[] procsMemInfo = manager.getProcessMemoryInfo(new int[] {Integer.parseInt(array[0])});
long memory=0;
for (Debug.MemoryInfo info:procsMemInfo)
{
memory+=info.getTotalPss();
}
processDescriptions.add(new ProcessDescription(array[0], Integer.parseInt(array[1]),
array[2], MemorySizeConverter.MBorKB_Converter((double) memory, 1), array[8], package_name));
}
catch (Exception e)
{
Log.d("skipped",e.toString());
}
} while (in.readLine() != null );
It worked and I can get running processes memory info. Not for all installed apps.
As this statement, My app should be signed with the platform key, or installed in the system partition to access it. But how third party apps available in playstore are accessing it . Can anyone help me.

Is there the unique identifier of SD card in Android API? And how to get it?

Is there the unique identifier of SD card in Android API, And how to get it? How to distinguish between different SD card in my phone? I need the ID of SD card, please tell me, thanks.
Short answer is that there is no straight forward Java API in Android for that, as of now.
If you really need it, one way is to run the following commands and analyse the output (you can use terminal emulator app to test these):
mount
This will list mounted partitions, usually there will be a /mnt/sdcard and its related /dev/sdb1 in its output. You can process output and find sd-card partitions you are interested in.
blkid
This requires root access, that is, run su command first. This will print block device info, and /dev/sdb1 or so will have a UID associated with it.
You can use below method to get SD Card id
public String getSDCardUniqueId()
{
String sd_cid = null;
try {
File file = new File("/sys/block/mmcblk1");
String memBlk;
if (file.exists() && file.isDirectory()) {
memBlk = "mmcblk1";
} else {
//System.out.println("not a directory");
memBlk = "mmcblk0";
}
Process cmd = Runtime.getRuntime().exec("cat /sys/block/"+memBlk+"/device/cid");
BufferedReader br = new BufferedReader(new InputStreamReader(cmd.getInputStream()));
sd_cid = br.readLine();
//System.out.println(sd_cid);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return sd_cid;
}

Android superuser

I've built a system app running on a rooted/customized version of AOSP Android.
It could happen that I need to download new version of my app from my personal website and replace it on Android system with the new one.
This must be done automatically by the app itself and not manually with adb command.
WHAT I TRIED
Let's say i already got my apk downloaded in fpath.
With the following snippet i'm trying to remount /system/ folder with read/write permission and then move my updated apk on that folder.
try {
String line;
Process p = Runtime.getRuntime().exec("su");
// open input/output facilities
OutputStreamWriter osw = new OutputStreamWriter(p.getOutputStream());
BufferedReader in = new BufferedReader(
new InputStreamReader(p.getInputStream()) );
// output the command
osw.write("mount -o rw,remount /system");
osw.flush();
// read the response
while ((line = in.readLine()) != null) {
Log.i("UPDATE", "output mount rw " + line);
}
// output the command
osw.write("cp " + fpath + " /system/app/myapp.apk");
osw.flush();
// read the response
while ((line = in.readLine()) != null) {
Log.i("UPDATE", "output cp " + line);
}
// output the command
osw.write("mount -o ro,remount system");
osw.flush();
// read the response
while ((line = in.readLine()) != null) {
Log.i("UPDATE", "output mount ro " + line);
}
} catch (Exception e) {
Log.e("UPDATE", "error in executing shell commands: " + e.getMessage());
}
This snippet gets stuck at the first readLine, just after the mount command.
Questions:
Why does it stuck there? Shouldn't i expect something to read from the input stream?
It just doesn't work even if i remove the readLines. Filesystem is not remount'd and file is obviously not copied. Why?
There's a way to avoid the superuser prompt asking for permissions? My app got to run on a screenless system. I cannot get a confirm by an user.
There's a better way to do what i need?
Thank you
There's a better way to do what i need?
Copying the APK will not install it. Use pm instead of cp.
There's a way to avoid the superuser prompt asking for permissions?
This is up to the su app, so if you need one that automatically grants permissions without asking or remembers the permissions.

How to get the build.prop values?

How do I get the build.prop values that are found in /system/build.prop without root access? How do I edit them?
You can probably consider using SystemProperties.get("someKey") as suggested by #kangear in your application using reflection like:
public String getSystemProperty(String key) {
String value = null;
try {
value = (String) Class.forName("android.os.SystemProperties")
.getMethod("get", String.class).invoke(null, key);
} catch (Exception e) {
e.printStackTrace();
}
return value;
}
And then you can use it any where like:
getSystemProperty("someKey");
Try This
static String GetFromBuildProp(String PropKey) {
Process p;
String propvalue = "";
try {
p = new ProcessBuilder("/system/bin/getprop", PropKey).redirectErrorStream(true).start();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
propvalue = line;
}
p.destroy();
} catch (IOException e) {
e.printStackTrace();
}
return propvalue;
}
Does System.getProperty() help? As an alternative, you can execute getprop in a Process and retrieve its output.
Such as:
SystemProperties.get("ro.rksdk.version")
use android.os.Build class, see http://developer.android.com/reference/android/os/Build.html, but you can not edit it without root access.
I have checked multiple devices including some Samsung and LG devices as well as a Nexus 4, latest one was the Nvidia Shield Tablet with Android 6.0.
On all devices ll on /system/build.prop gave me this result(of course with varying size and date of build.prop):
-rw-r--r-- root root 3069 2015-10-13 21:48 build.prop
This means that anyone and any app without any permissions can read the file. Root would only be required for writing the non "ro."-values. You could just create a new BufferedReader(new FileReader("/system/build.prop")) and read all lines.
Advantages of this approach:
no need for reflection (SystemProperties.get)
no need to spawn a Process and executing getprop
Disadvantages:
does not contain all system properties (some values e.g. are set at boot only available at runtime)
not handy for getting a specific value compared to SystemProperties.get
On the setting page of your file manager, set home as /system, then you could browse system folders and copy build.prop and paste to sdcard. I'm still trying to root my phone but I have no problem tweaking on the way (no pun).
To read properties using reflection on the hidden API :
static public String getprop(String key){
try { Class c = Class.forName("android.os.SystemProperties");
try { Method method = c.getDeclaredMethod("get", String.class);
try { return (String) method.invoke(null, key);
} catch (IllegalAccessException e) {e.printStackTrace();}
catch (InvocationTargetException e) {e.printStackTrace();}
} catch (NoSuchMethodException e) {e.printStackTrace();}
} catch (ClassNotFoundException e) {e.printStackTrace();}
return null;
}
To edit them (Root required) manually, you should extract them with adb :
adb pull /system/build.prop
Edit them on the computer, then "install" the new build.prop :
adb push build.prop /sdcard/
adb shell
mount -o rw,remount -t rootfs /system
cp /sdcard/build.prop /system/
chmod 644 /system/build.prop
Would be safer to keep an original build.prop copy.

Android Not Granting Dump Permission

For the purposes of monitoring Battery usage etc. I have code that executes a few dumpsys calls, reads and parses the output to extract data that I am interested in.
dumpsys battery, dumpsys statusbar, and dumpsys power all give me an error message for output like "Permission Denial: can't dump Battery service from pid..."
Also, when the application is launched there is an item in the log tagged with "PackageManager" statingNot granting permission android.permissionDUMP to package.... (protectionLevel = 3 ...)"
However, dumpsys cpuinfo and dumpsys netstat work and give me the correct output, which seems to be inconsistent.
I am able to generate dumpsys battery and the like from the adb shell, but when I try to call it programmatically it does not work.
I have tried running this on a HTC Nexus One phone as well as the emulator and get the same results for each. The weird thing is that this code worked on my Nexus One a day ago (before I upgraded from 2.2 to 2.3), and now it does not. Is this because of the upgrade?
An example of the code I am trying to run is as follows:
String command = "dumpsys battery";
try {
String s = null;
Process process = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(process.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(process.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
How do I get the dumpsys to give me the correct output programmatically and how to I get the dump permission to be granted?
*The Nexus One is not rooted and I would like to get this working without having to root it for the purposes of my project
Thank you for your help
Regular applications cannot get the DUMP permission. It is reserved to system applications.
android.permission.Dump is protected by system, signature, and development permission protection levels. Line 1993 of the source shows you this. If your APK is signed with the framework cert, is in the priv-app directory, or debuggable (see below) you can use the pm service to grant the permission, but otherwise the code specifically prevents what you're asking for (line 2624 of source).
Debuggable APKs can be created through setting the debuggable attribute on a buildType via build.gradle. Sample Android DSL:
android {
...
buildTypes {
debug {
debuggable true
...
}
quality_assurance {
debuggable true
}
...
}
If your handset had been rooted, 'dumpsys activity' will work on Android2.3:
private static void dumpIT0(String sCmd) {
try {
String s = null;
String command = "su -c " + sCmd;
Process process = Runtime.getRuntime().exec(command);
BufferedReader stdInput = new BufferedReader(new InputStreamReader(
process.getInputStream()));
BufferedReader stdError = new BufferedReader(new InputStreamReader(
process.getErrorStream()));
// read the output from the command
System.out.println("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
System.out.println(s);
}
// read any errors from the attempted command
System.out.println("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
System.out.println(s);
}
} catch (IOException e) {
Log.e(TAG, "IOException: " + e);
}
}
sCmd = "dumpsys activity";

Categories

Resources