Run bash script from android app - android

I want to change the value of variable in xml. The value is based on another file which read by editXml.sh. So I need to run the editXml.sh before app is compiled.
I try to run the script in MainActivity with code as follows:
onCreate() {
......
execScript();
}
execScript(){
try{
Runtime rt = Runtime.getRuntime();
Process proc = rt.exec("sh /.../editXml.sh");
} catch(Throwable t)
{
t.printStackTrace();
}
}
The editXml.sh is in my local, but the code doesn't work when I run app in Android studio.(Works on local) Should I put my script in the app? And which part of the app? Any suggestion?

Try this. I've tested this code and it works.
Let's you script named script.sh.
Put file script.sh to you project's /res/raw folder.
Use code below.
Build apk. Unpack apk (this is usual zip-archive) and make sure file /res/raw/script.sh exists there.
Install apk on device and start it.
public static void executeCommandAndGetOutput(String command){
BufferedReader reader = null;
String result = "";
try {
Process p = Runtime.getRuntime().exec(command);
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null){
result += line + "\n";
}
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
if(reader != null)
try {
reader.close();
} catch (Exception e) {
e.printStackTrace();
}
}
Log.i("Test", result);
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
String pathToScript = getDir("my_scripts", 0).getAbsolutePath() + File.separator + "script.sh";
// Unpacking script to local filesystem
InputStream in = getResources().openRawResource(R.raw.script);
FileOutputStream out = null;
try {
out = new FileOutputStream(pathToScript);
byte[] buff = new byte[1024];
int read = 0;
while ((read = in.read(buff)) > 0) {
out.write(buff, 0, read);
}
}
catch(Exception e){
}
finally {
try {
in.close();
out.close();
} catch (Exception e) {
e.printStackTrace();
}
}
// Make script executable
executeCommand("chmod 775 " + pathToScript);
// Execute script
executeCommand("sh " + pathToScript);
}
public static String getSystemCommandOutput(String command){
BufferedReader reader = null;
String result = "";
try {
Process p = Runtime.getRuntime().exec(command);
reader = new BufferedReader(new InputStreamReader(p.getInputStream()));
String line = null;
while ((line = reader.readLine()) != null){
result += line + "\n";
}
p.waitFor();
} catch (Exception e) {
e.printStackTrace();
} finally {
closeQuietly(reader);
}
return result;
}

You can put script at raw resources and then unpack it to Context.getDir(...) folder and run from there with absolute path.
Also you need to run "chmod 775" (chmod +x) for this file before executing.
Example about copying a file from raw: Copying raw file into SDCard? You can copy to app folder (Context.getDir(...)) instead of sdcard

console output:
58:07.979 8935-8935/cc.softwarefactory.lokki.android E/MainActivity﹕ onCreate
12:58:08.234 8935-8935/cc.softwarefactory.lokki.android E/MainActivity﹕ PATH: /data/data/cc.softwarefactory.lokki.android/app_my_scripts/editxml.sh
12:58:08.258 8935-8935/cc.softwarefactory.lokki.android E/MainActivity﹕ result:
12:58:08.287 8935-8935/cc.softwarefactory.lokki.android E/MainActivity﹕ result: not found
I changed
Log.i("Test", result) to Log.e(TAG,"result: " + result);

Related

compiling cpp files on runtime Android Studio

I am making a compiling app with my custom made a language. This app will change the custom made language code automatically to a CPP code. So all I need to do is compile the CPP code on runtime.
I got stuck compiling a CPP file in my app.
I have already checked out using dexmaker and image-playground, but I had problems with the Gradle-build. They are somewhat old projects and I'm not really sure how to use it so I passed that one.
So I am trying to use the command line tool with the android studio. I have saved my CPP file and can use it I think. Below includes my file i/o code. This is my code.
Code:
public class Code_cpp extends AppCompatActivity {
private Context context;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.code_cpp);
TextView textView = (TextView) findViewById(R.id.view);
textView.setMovementMethod(new ScrollingMovementMethod());
context = this;
}
public void savebutton(View v) {
final EditText edit = (EditText) findViewById(R.id.edit_text);
TextView textView = (TextView) findViewById(R.id.view);
Log.v("EditText", edit.getText().toString());
String messageString = edit.getText().toString();
writeToFile(messageString,context);
Toast.makeText(getApplicationContext(), "saved", Toast.LENGTH_LONG).show();
}
private void writeToFile(String data,Context context) {
try {
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(context.openFileOutput("config.cpp", Context.MODE_PRIVATE));
outputStreamWriter.write(data);
outputStreamWriter.close();
Log.e("Success", "File write Success ");
}
catch (IOException e) {
Log.e("Exception", "File write failed: " + e.toString());
}
}
public void loadbutton(View v){
String msg = readFromFile(context);
TextView textView = (TextView) findViewById(R.id.view);
textView.setText(msg);
}
private String readFromFile(Context context) {
String ret = "";
try {
InputStream inputStream = context.openFileInput("config.cpp");
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).append("\n");
}
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;
}
public void run(View v){
try {
Process process = Runtime.getRuntime().exec("g++ config.cpp;./a.out");
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
int read;
char[] buffer = new char[4096];
StringBuffer output = new StringBuffer();
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
process.waitFor();
//return output.toString();
String result=output.toString();
TextView textView = (TextView) findViewById(R.id.view);
textView.setText(result);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
I get an error when I click the run button
Caused by: java.io.IOException: Cannot run program "g++": error=13, Permission denied
I don't want to root my phone because I don't want to use this app just on my phone but with other phones too when I download it. Do I have to try another way to compile this? Why do I get permission denied errors?

make android source using adb shell command "cat"

I want to use shell command, 'cat'.
I want to copy the "abc.jpg" file..But It didn't operate.
What is the problem? Thank you.
public void onClick(View v) {
Runtime runtime = Runtime.getRuntime();
Process process;
try {
String cmd = "cat /sdcard/0/Pikicast/abc.jpg>/sdcard/0/apk_backups/abc.jpg";
process = runtime.exec(cmd);
BufferedReader br = new BufferedReader(new InputStreamReader(process.getInputStream()));
String line;
while ((line = br.readLine()) != null) {
Log.i("test",line);
}
} catch (Exception e) {
e.fillInStackTrace();
Log.e("Process Manager", "Unable to execute top command");
}
}
I have modified your code a little. Kindly try this.
String[] command = {"cat","/sdcard/0/Pikicast/abc.jpg>/sdcard/0/apk_backups/abc.jpg"};
StringBuilder cmdReturn = new StringBuilder();
try {
ProcessBuilder processBuilder = new ProcessBuilder(command);
Process process = processBuilder.start();
InputStream inputStream = process.getInputStream();
int c;
while ((c = inputStream.read()) != -1) {
cmdReturn.append((char) c);
}
prompt.setText(cmdReturn.toString());
Log.w("test",cmdReturn);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
Log.e("Process Manager", "Unable to execute top command");
}

CSV file cannot be accessed via BufferedReader in Android

I am trying to read a CSV file using BufferedReader in android. My program works perfectly fine in Java but when I try read those data from Android following error I get.
01-31 17:09:58.466: W/System.err(15912): java.io.FileNotFoundException:
/Users/sabbir/Documents/workspace/TestCSV/src/file/input.csv: open failed: ENOENT (No
such file or directory)
Following code I am using here.
public double getLongitudes() {
BufferedReader br = null;
String line = "";
String cvsSplitBy = ";";
String[] nextLine;
double longitudes = 0;
try {
br = new BufferedReader(
new FileReader(
"/Users/sabbir/Documents/workspace/TestCSV/src/file/input.csv"));
while ((line = br.readLine()) != null) {
// use comma as separator
String[] country = line.split(cvsSplitBy);
longitudes = Double.parseDouble(country[5]);
Log.d("worked", "worked");
// System.out.println("Latitude " + longitudes);
}
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (br != null) {
try {
br.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
System.out.println("Done");
return (longitudes);
}}
Any idea why its happening ??
The path /Users/sabbir/Documents/workspace/TestCSV/src/file/input.csv is invalid. This looks like the path to a file on your computer rather than your Android device. You need to push the file to your device or your emulated device and access it from there. Even the Android emulator will not read files directly from your computer's filesystem.
Proper way to store your CSV in Android is:
("/sdcard/Android/data/filename.csv");
The .csv file needs to be in your project resources. You can copy the file into assets folder and read it this way
AssetInputStream asset_stream = (AssetInputStream)getAssets().open("input.csv");
InputStreamReader reader = new InputStreamReader(asset_stream);
BufferedReader br = new BufferedReader(reader);
This is one method that has worked for me before.
Another method would be to put the file into res/raw folder and access it
InputStream file = getResources().openRawResource(R.raw.inputfile);
You can also refer to https://stackoverflow.com/a/3851429/3092829
Hope this helps!
So i have solved my problem.
public class ReadCSV {
BufferedReader br = null;
String line = "";
String cvsSplitBy = ";";
String[] nextLine;
String[] country;
AssetInputStream asset_stream = null;
public String[] getLatitude() {
try {
asset_stream = (AssetInputStream) MainActivity.getContext()
.getAssets().open("Input.csv");
} catch (IOException e) {
e.printStackTrace();
}
InputStreamReader reader = new InputStreamReader(asset_stream);
Log.d("logg", "log" + reader);
br = new BufferedReader(reader);
Log.d("logg", "log" + br);
try {
while ((line = br.readLine()) != null) {
country = line.split(cvsSplitBy);
}
} catch (NumberFormatException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
return country;
}
As you can see I am trying to get my latitude by returning it through country. But when I trying get it from another fragment class through this,
String[] lat;
lat = csv.getLatitude();
Log.d("", "" + lat);
Why I don't get latitude back ?

How can I send the log file of the android device via email from inside my app?

as an error report I want to send the device and/or application log to a email account. For that I prepared a button in my view. Can someone help me with that, how can I retrieve the log files?
Thanks
String separator = System.getProperty("line.separator");
try {
Process process = Runtime.getRuntime().exec("logcat -d");
BufferedReader bufferedReader = new BufferedReader(
new InputStreamReader(process.getInputStream()));
String line;
while ((line = bufferedReader.readLine()) != null) {
log.append(line);
log.append(separator);
}
} catch (Exception e) {
}
Here's a slightly improved version, adapted from Ramesh (thanks). The main difference is to do your own buffering. It's fast.
private void extractLogToFile()
{
// Make file name.
String fullName = ...;
// Extract to file.
File file = new File (fullName);
InputStreamReader reader = null;
FileWriter writer = null;
try
{
// get input stream
String cmd = "logcat -d -v time";
Process process = Runtime.getRuntime().exec(cmd);
reader = new InputStreamReader (process.getInputStream());
// write output stream
writer = new FileWriter (file);
char[] buffer = new char[10000];
do
{
int n = reader.read (buffer, 0, buffer.length);
if (n == -1)
break;
writer.write (buffer, 0, n);
} while (true);
reader.close();
writer.close();
}
catch (IOException e)
{
if (writer != null)
try {
writer.close();
} catch (IOException e1) {
}
if (reader != null)
try {
reader.close();
} catch (IOException e1) {
}
e.printStackTrace();
return;
}
}

How to access written files without having root permissions?

I have this code for write and read to file ZIZI.txt:
//=============== Write To File ZIZI.txt ===============================================
private void writeFileToInternalStorage() {
String eol = System.getProperty("line.separator");
BufferedWriter writer = null;
try {
writer = new BufferedWriter(new OutputStreamWriter(openFileOutput(
"ZIZI.txt", MODE_WORLD_WRITEABLE)));
writer.write("This is a test1." + eol);
writer.write("This is a test2." + eol);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (writer != null) {
try {
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(getBaseContext(),"OK Save", Toast.LENGTH_SHORT).show();
}
//================ Read From File ZIZI.txt ===========================================
private void readFileFromInternalStorage() {
String FF="";
String eol = System.getProperty("line.separator");
BufferedReader input = null;
try {
input = new BufferedReader(new InputStreamReader(openFileInput("ZIZI.txt")));
String line;
StringBuffer buffer = new StringBuffer();
while ((line = input.readLine()) != null) {
FF+=line+eol;
buffer.append(line + eol);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (input != null) {
try {
input.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
Toast.makeText(getBaseContext(),FF, Toast.LENGTH_SHORT).show();
}
I see with DDMS that the File is in: \data\data\setup.myProject\files\ZIZI.txt
But I can't see this file in my phone (because I don't have root permissions)
I want to write and read from my SD card or from any folder that I can see in my
phone. How to change the code for this?
Have you never used the Android Developers website?
Try Dev Guide -> Data Storage -> Using the External Storage
You need to specify the entire path to your file, using either getFilesDir for internal storage or getExternalFilesDir() for external storage. For example:
openFileInput(getExternalFilesDir(null) + "/" + "ZIZI.txt");

Categories

Resources