Write output of android shell command to a file - android

I am trying to write output of atrace to sdcard. I am using
getRuntime().exec()("atrace gfx > /storage/sdcard0/trace.txt")
in the app.App is signed as a system app and the command is working fine from terminal.But no file is created when running it from the app.

I solved it by reading data from inputstream and writing it to a file
try {
Process p = Runtime.getRuntime().exec("atrace -t 5 gfx");
p.waitFor();
BufferedReader reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = reader.readLine();
File myFile = new File("/storage/sdcard0/trac.txt");
FileOutputStream f = null;
try {
f = new FileOutputStream(myFile);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
PrintWriter pw = new PrintWriter(f);
while (line != null) {
pw.println(line);
//Toast.makeText(getBaseContext(), line, Toast.LENGTH_LONG).show();
line = reader.readLine();
}
pw.flush();
pw.close();
f.close();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}

Related

Android Studio Shell Command From App To Execute [duplicate]

I'm trying to execute this command from the application emulator terminal (you can find it in google play) in this app i write su and press enter, so write:
screenrecord --time-limit 10 /sdcard/MyVideo.mp4
and press again enter and start the recording of the screen using the new function of android kitkat.
so, i try to execute the same code from java using this:
Process su = Runtime.getRuntime().exec("su");
Process execute = Runtime.getRuntime().exec("screenrecord --time-limit 10 /sdcard/MyVideo.mp4");
But don't work because the file is not created. obviously i'm running on a rooted device with android kitkat installed. where is the problem? how can i solve? because from terminal emulator works and in Java not?
You should grab the standard input of the su process just launched and write down the command there, otherwise you are running the commands with the current UID.
Try something like this:
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
outputStream.writeBytes("screenrecord --time-limit 10 /sdcard/MyVideo.mp4\n");
outputStream.flush();
outputStream.writeBytes("exit\n");
outputStream.flush();
su.waitFor();
}catch(IOException e){
throw new Exception(e);
}catch(InterruptedException e){
throw new Exception(e);
}
A modification of the code by #CarloCannas:
public static void sudo(String...strings) {
try{
Process su = Runtime.getRuntime().exec("su");
DataOutputStream outputStream = new DataOutputStream(su.getOutputStream());
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
outputStream.close();
}catch(IOException e){
e.printStackTrace();
}
}
(You are welcome to find a better place for outputStream.close())
Usage example:
private static void suMkdirs(String path) {
if (!new File(path).isDirectory()) {
sudo("mkdir -p "+path);
}
}
Update:
To get the result (the output to stdout), use:
public static String sudoForResult(String...strings) {
String res = "";
DataOutputStream outputStream = null;
InputStream response = null;
try{
Process su = Runtime.getRuntime().exec("su");
outputStream = new DataOutputStream(su.getOutputStream());
response = su.getInputStream();
for (String s : strings) {
outputStream.writeBytes(s+"\n");
outputStream.flush();
}
outputStream.writeBytes("exit\n");
outputStream.flush();
try {
su.waitFor();
} catch (InterruptedException e) {
e.printStackTrace();
}
res = readFully(response);
} catch (IOException e){
e.printStackTrace();
} finally {
Closer.closeSilently(outputStream, response);
}
return res;
}
public static String readFully(InputStream is) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
int length = 0;
while ((length = is.read(buffer)) != -1) {
baos.write(buffer, 0, length);
}
return baos.toString("UTF-8");
}
The utility to silently close a number of Closeables (Soсket may be no Closeable) is:
public class Closer {
// closeAll()
public static void closeSilently(Object... xs) {
// Note: on Android API levels prior to 19 Socket does not implement Closeable
for (Object x : xs) {
if (x != null) {
try {
Log.d("closing: "+x);
if (x instanceof Closeable) {
((Closeable)x).close();
} else if (x instanceof Socket) {
((Socket)x).close();
} else if (x instanceof DatagramSocket) {
((DatagramSocket)x).close();
} else {
Log.d("cannot close: "+x);
throw new RuntimeException("cannot close "+x);
}
} catch (Throwable e) {
Log.x(e);
}
}
}
}
}
Process p;
StringBuffer output = new StringBuffer();
try {
p = Runtime.getRuntime().exec(params[0]);
BufferedReader reader = new BufferedReader(
new InputStreamReader(p.getInputStream()));
String line = "";
while ((line = reader.readLine()) != null) {
output.append(line + "\n");
p.waitFor();
}
}
catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
String response = output.toString();
return response;
Late reply, but it will benefit someone. You can use the sh command in the exec() method.
Here is my example:
try {
File workingDirectory = new File(getApplicationContext().getFilesDir().getPath());
Process shProcess = Runtime.getRuntime().exec("sh", null, workingDirectory);
try{
PrintWriter outputExec = new PrintWriter(new OutputStreamWriter(shProcess.getOutputStream()));
outputExec.println("PATH=$PATH:/data/data/com.bokili.server.nginx/files;export LD_LIBRARY_PATH=/data/data/com.bokili.server.nginx/files;nginx;exit;");
outputExec.flush();
} catch(Exception ignored){ }
shProcess.waitFor();
} catch (IOException ignored) {
} catch (InterruptedException e) {
try{ Thread.currentThread().interrupt(); }catch(Exception ignored){}
} catch (Exception ignored) { }
What have I done with this?
First I call the shell, then I change (set) the necessary environments in it, and finally I start my nginx with it.
This works on unrooted devices too.
Greetings.

Saving application logs to a text file does not work

I want save my android application logs on a text file and send it via email in order to handling exceptions and feedback. I implemented following codes in my application, but logs text file contains nothing and is empty after executing code.
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
StringBuilder logString = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
logString.append(line);
}
File logFile = new File("sdcard/log.txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.append(logString);
buf.newLine();
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
I used Log.i, Log.e and Log.w for writing log messages to logcat in my whole application.
I would be grateful if anyone guide me to addressing my problem.
Try This,
public static void appendLog(String text) {
if (true) {
File root = android.os.Environment.getExternalStorageDirectory();
File dir = new File(root.getAbsolutePath() + "/YourAppName");
dir.mkdir();
File logFile = new File(dir, "YourAppName.txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
}
try {
// BufferedWriter for performance, true to set append to file
// flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
true));
buf.append(text
+ " - "
+ new SimpleDateFormat("MM/dd/yyyy HH:mm:ss")
.format(new Date()));
buf.newLine();
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
and Used this method instead of Log.i, Log.e and Log.w in your application

Can't create file in the internal storage

i am trying to create a file in the internal storage, i followed the steps in android developers website but when i run the below code there is no file created
please let me know what i am missing in the code
code:
File file = new File(this.getFilesDir(), "myfile");
try {
file.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
FileOutputStream fOut = null;
try {
fOut = openFileOutput("myfile",Context.MODE_PRIVATE);
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
fOut.write("SSDD".getBytes());
} catch (IOException e) {
e.printStackTrace();
}
try {
fOut.close();
} catch (IOException e) {
e.printStackTrace();
}
By default these files are private and are accessed by only your application and get deleted , when user delete your application
For saving file:
public void writeToFile(String data) {
try {
FileOutputStream fou = openFileOutput("data.txt", MODE_APPEND);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(fou);
outputStreamWriter.write(data);
outputStreamWriter.close();
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
For loading file:
public String readFromFile() {
String ret = "";
try {
InputStream inputStream = openFileInput("data.txt");
if ( inputStream != null ) {
InputStreamReader inputStreamReader = new InputStreamReader(inputStream);
BufferedReader bufferedReader = new BufferedReader(inputStreamReader);
String receiveString = "";
StringBuilder stringBuilder = new StringBuilder();
while ( (receiveString = bufferedReader.readLine()) != null ) {
stringBuilder.append(receiveString);
}
inputStream.close();
ret = stringBuilder.toString();
}
}
catch (FileNotFoundException e) {
Log.e("login activity", "File not found: " + e.toString());
} catch (IOException e) {
Log.e("login activity", "Can not read file: " + e.toString());
}
return ret;
}
Try to get the path for storing files were the app has been installed.The below snippet will give app folder location and add the required permission as well.
File dir = context.getExternalFilesDir(null)+"/"+"folder_name";
If you are handling files that are not intended for other apps to use, you should use a private storage directory on the external storage by calling getExternalFilesDir(). This method also takes a type argument to specify the type of subdirectory (such as DIRECTORY_MOVIES). If you don't need a specific media directory, pass null to receive the root directory of your app's private directory.
Probably, this would be the best practice.
Use this method to create folder
public static void appendLog(String text, String fileName) {
File sdCard=new File(Environment.getExternalStorageDirectory().getPath());
if(!sdCard.exists()){
sdCard.mkdirs();
}
File logFile = new File(sdCard, fileName + ".txt");
if (logFile.exists()) {
logFile.delete();
}
try {
logFile.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}
try {
//BufferedWriter for performance, true to set append to file flag
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile, true));
buf.write(text);
buf.newLine();
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
}
In this method, you have to pass your data string as a first parameter and file name which you want to create as second parameter.

java.io.FileNotFoundException for text file

I have a txt file in the root folder of my Android project called KARIN.txt. I am trying to reach it by FileReader but I am having the following error:
java.io.FileNotFoundException: /KARIN.txt: open failed: ENOENT (No such file or directory)
How I am trying to reach that file is as following:
BufferedReader br = new BufferedReader(new FileReader("KARIN.txt"));
I am confused that why it is not allowing me to read the file.
If KARIN.txt is built into your project you should put it in the assets folder and access it via the AssetManager.
public String loadFile(String file){
AssetManager am = getActivity().getAssets();
InputStreamReader ims = null;
BufferedReader reader = null;
String data = "File not available!";
try {
ims = new InputStreamReader(am.open(file), "UTF-8");
reader = new BufferedReader(ims);
} catch (IOException e) {
e.printStackTrace();
}
if(ims != null){
try {
String mLine = reader.readLine();
data = "";
while(mLine != null){
data+= mLine;
mLine = reader.readLine();
}
} catch (IOException e) {
e.printStackTrace();
} finally{
if (reader != null) {
try {
reader.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
return data;
}

How to keep on appending logs while writing into File in SDCard?

I have written a method to print Logs in file. This is working. My only concern is that the logs are been replaced by new logs. Is there any way to keep logs appending ??
public static void printLog(Context context){
String filename = context.getExternalFilesDir(null).getPath() + File.separator + "my_app.log";
String command = "logcat -d *:V";
Log.d(TAG, "command: " + command);
try{
Process process = Runtime.getRuntime().exec(command);
BufferedReader in = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line = null;
try{
File file = new File(filename);
file.createNewFile();
FileWriter writer = new FileWriter(file);
while((line = in.readLine()) != null){
writer.write(line + "\n");
}
writer.flush();
writer.close();
}
catch(IOException e){
e.printStackTrace();
}
}
catch(IOException e){
e.printStackTrace();
}
}
Try this:
public static void printLog(String logData) {
try {
File logFile = new File(Environment.getExternalStorageDirectory(),
"yourLog.txt");
if (!logFile.exists()) {
try {
logFile.createNewFile();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
try {
BufferedWriter buf = new BufferedWriter(new FileWriter(logFile,
true));
buf.append(logData);
buf.newLine();
buf.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (Exception e) {
e.printStackTrace();
}
}
You are not writing the file in Append mode.
Use new FileWriter(file,true) instead of new FileWriter(file)
More easy way to write to your sdcard:
try {
FileWriter f = new FileWriter(Environment.getExternalStorageDirectory()+
"/mytextfile.txt", true);
f.write("Hello World");
f.flush();
f.close();
}
The boolean in the constructor of FileWriter says its only allowed to append:
http://developer.android.com/reference/java/io/FileWriter.html#FileWriter(java.io.File, boolean)

Categories

Resources