Hello I have been looking for ways to delete or rename an specific file in the internal storage of the cellphone. Specifically my targets are the files in the waze folder, that are in the root folder of the internal storage. As I said, I look for more information about this but nothing works for me, so I think that my error might be in the path i'm using. Here is my code:
TO RENAME:
file_Path = "/data/data/waze"
File from = new File(file_Path, "currentFileName");
File to = new File(file_Path, "newFilename");
from.renameTo(to); //this method returns me False
TO DELETE:
file_Path ="/data/data/waze/file"
File file = new File(file_Path);
boolean deleted = file.delete();
I try a lot of ways to do this, but this is the one I think is near to get it. So If anyone of you could point me my mistake/s I would thank you! A hug from Costa Rica!
You do not have read or write access to files on internal storage other than your own app's files. You cannot rename or delete files from another app, such as Waze.
The exception is that on rooted devices, you can ask to fork processes with superuser privileges, and those processes would have device-wide read/write access.
For completing #CommonsWare answer, you can check if the device is rooted, then do the methods or something else.
Here is an example,
Taken from : http://www.stealthcopter.com/blog/2010/01/android-requesting-root-access-in-your-app/
Process p;
try {
// Preform su to get root privledges
p = Runtime.getRuntime().exec("su");
// Attempt to write a file to a root-only
DataOutputStream os = new DataOutputStream(p.getOutputStream());
os.writeBytes("echo \"Do I have root?\" >/system/sd/temporary.txt\n");
// Close the terminal
os.writeBytes("exit\n");
os.flush();
try {
p.waitFor();
if (p.exitValue() != 255) {
// TODO Code to run on success
toastMessage("root");
}
else {
// TODO Code to run on unsuccessful
toastMessage("not root");
}
} catch (InterruptedException e) {
// TODO Code to run in interrupted exception
toastMessage("not root");
}
} catch (IOException e) {
// TODO Code to run in input/output exception
toastMessage("not root");
}
Or you can take a look at :
http://su.chainfire.eu/#how
https://github.com/Chainfire/libsuperuser
and also, use the following permission in your manifest too:
<uses-permission android:name="android.permission.ACCESS_SUPERUSER" />
Or a good example is available on Github:
https://github.com/mtsahakis/RootChecker
Related
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;
}
I'm calling C code by JNI in android app.
Every thing is OK in calling, but when I put this code:
FILE* fp = fopen("/storage/sdcard0/input.txt","w+");
if(fp==NULL)
return(*env)->NewStringUTF(env,"n");
else
return(*env)->NewStringUTF(env,"y");
it gets "n". I'm sure that the path is true and I tried this command on my mobile's terminal:
cat /storage/sdcard0/input.txt
and it got me the file's contents.
Edit:
I tried to change the permission of the file by this code but it gave me the same response:
void changePerm()
{
Process chperm;
try {
chperm=Runtime.getRuntime().exec("su");
DataOutputStream os =
new DataOutputStream(chperm.getOutputStream());
os.writeBytes("chmod 777 /storage/sdcard0/input.txt\n");
os.flush();
os.writeBytes("exit\n");
os.flush();
chperm.waitFor();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I also add this permission and no thing changed:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
I take it that the permissions on the file are in fact 0777.
You added android.permission.READ_EXTERNAL_STORAGE, but you try to open for writing
FILE* fp = fopen("/storage/sdcard0/input.txt","w+");
You can get the error by checking for errno and get a message with strerror.
You must either open the file for reading only "r" or add permission for writing WRITE_EXTERNAL_STORAGE
code snippet
void takeSnapShot()
{
Process process = null;
try
{
process = Runtime.getRuntime().exec("/system/bin/screencap -p /sdcard/snapshot/test_2.png" );
try
{
process.waitFor();
} catch (InterruptedException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
} catch (IOException e)
{
// TODO Auto-generated catch block
e.printStackTrace();
}
}
I am gettin an empty file saved whereas If i use the same command through adb shell, i get my screen captured.
Any help will be appreciatable
Edit: my previous answer was mistaken, any app can use the screen capture command.
It might be a permission issue. Are you sure you have permission to write to sdcard?
Check this post, which covers your topic:
How to run android system app without root permisson?
I solved this by adding the following permission to my Manifest.
<uses-permission
android:name="android.permission.READ_FRAME_BUFFER"
tools:ignore="ProtectedPermissions"/>
NOTE: This is a protected permission, my application is a system app and also signed using the platform key.
I am having a hard time figuring out how to write to and read from files on an Android device. The file will be formatted as XML and I already have parsers and data structures built that can format the XML into objects and objects into XML, but the last hurdle is reading the XML from a non-resource file (I know the data structures work because I it works when reading from a resource file) and also writing to a non-resource file. I am terrible at using tools to debug (not sure how to print a stack trace) but I know for a fact the problem is that I cannot read from or write to this files. I have no experience writing to files in Java which may be why I am having a rough time with this.
Write code:
File scoresFile = new File(getExternalFilesDir(null), "scores.xml");
if (!scoresFile.exists())
{
scoresFile.createNewFile();
}
OutputStream os = new FileOutputStream(scoresFile);
os.write(writer.toString().getBytes());
os.flush();
os.close();
Read Code:
XmlPullParserFactory xmlFac = XmlPullParserFactory.newInstance();
XmlPullParser qXML = xmlFac.newPullParser();
InputStream is = null;
File scoresFile = new File(c.getExternalFilesDir(null), "scores.xml");
if (!scoresFile.exists())
{
try {
scoresFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
is = new FileInputStream(scoresFile);
} catch (FileNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
if (is != null)
qXML.setInput(is,null);
else
qXML = c.getResources().getXml(R.xml.scores);
UPDATE: The last if clause in the read section always evaluates to false. So, the InputStream is null... that appears to be the root of my problem.
I would take a look at these two links: Using Internal Storage and Using External Storage
Both link to the same page, just different portions. Really, it depends on whether or not you want to save this file to the devices memory, or to an external medium (such as an SDcard).
Internal - Sandboxed, so that only your app can access it.
External - Anyone can access it.
I created a method for checking whether the android phone is rooted or not. This is done as follows
public int checkrootcommand(String string) {
// TODO Auto-generated method stub
Process exec;
try {
exec = Runtime.getRuntime().exec(new String[]{"su","-c"});
final OutputStreamWriter out = new OutputStreamWriter(exec.getOutputStream());
out.write("exit");
out.flush();
Log.i(SUPER_USER_COMMAND, "su command executed successfully");
return 0; // returns zero when the command is executed successfully
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return 1; //returns one when the command execution fails
}
But the problem is that the method checkrootcommand() is executed first it works perfectly, but when the same method called again the superuser session is still running. Is there any way to end the superuser session once the method is executed??
There is no reliable means of detecting a rooted condition on a device where hardware protections have been overcome by exploiting software vulnerabilities.
At best you can detect the presence of particular toolsets or scan for things that aren't supposed to be there or changes in files that are - but that requires knowledge of what a given installation should look like, and assumes that the OS functionality you are using to make the checks hasn't been modified to hide the changes.
To reliably scan, you need to be sure trusted code runs at a lower level than untrusted code; a rooted device is one where this assurance has been fundamentally broken, or where the end user is trusted more than you the developer are.
In your case, you should kill the process after executing it for the job which is done before returning. The following changes to your code should do the thing.
public int checkrootcommand(String string) {
// TODO Auto-generated method stub
Process exec = null;
try {
exec = Runtime.getRuntime().exec(new String[]{"su","-c"});
final OutputStreamWriter out = new OutputStreamWriter(exec.getOutputStream());
out.write("exit");
out.flush();
Log.i(SUPER_USER_COMMAND, "su command executed successfully");
return 0; // returns zero when the command is executed successfully
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
if (exec != null) {
try {
exec.destroy();
} catch (Exception ignored) {
}
}
}
return 1; //returns one when the command execution fails
}
You may not be able to universally detect whether phone is rooted or not but you should be able to request and then confirm is your app can access root by running id as root e.g., su -c id validate if the command executed successfully and the output contains uid=0 i.e., the uid of the root user.
Method 1 : Application asks for ROOT access :
Add this in your app-level gradle build file :
dependencies {
compile 'eu.chainfire:libsuperuser:201501111220'
}
Now,
System.out.println(Shell.Su.available());
//Outputs true if user-granted else false
Method 2 : Application doesn't asks for ROOT :
boolean deviceisRooted() {
String[] filespaths = {"/system/app/Superuser.apk","/sbin/su", "/system/bin/su","/system/xbin/su"};
for (String xyz : filespaths) {
if (new File(xyz).exists()) return true;
}
return false;
}
System.out.prinln(deviceisRooted());
//Outputs true if device is ROOTED else false
//Doesn't asks user
//Also returns true IF NOT PROPERLY ROOTED (But ROOTED somehow)
Use this code:
Process executor = Runtime.getRuntime().exec("su -c ls /data/data");
executor.waitFor();
int iabd = executor.exitValue();
if(iabd != 0){ /*process exit value is not 0, so user is not root*/ }else{ /* user is root*/ }
You can achieve this from a terminal command and you can run terminal commands within an app.
if [ ! -z "$(/system/bin/ps -A | grep -v grep | grep -c daemonsu)" ]; then echo "device is rooted"; else echo "device is not rooted"; fi
Your application also doesn't require root access this way.