Skip to content

Instantly share code, notes, and snippets.

@gnail737
Last active August 29, 2015 14:00
Show Gist options
  • Select an option

  • Save gnail737/9ad7fc93142513398889 to your computer and use it in GitHub Desktop.

Select an option

Save gnail737/9ad7fc93142513398889 to your computer and use it in GitHub Desktop.
My test code to run native ARM C binaries on Android
/*******************************************************************************************************************
To use the following code you need to create a Java based android Project and cross-compile a test C executable on Linux/PC/Mac
and Copy it to Asset Folder of your Android Project. Instruction on Cross-Compile can be found in
http://www.kandroid.org/ndk/docs/STANDALONE-TOOLCHAIN.html
and
http://www.ikravets.com/computer-life/programming/2014/01/18/an-android-cross-compiling-environment-on-windowsunix-like-systems-using-ndk
The code used to run binary and fetch output from stdout is copied from stackoverflow post -
http://stackoverflow.com/questions/4703131/is-it-possible-to-run-a-native-arm-binary-on-a-non-rooted-android-phone
and
http://gimite.net/en/index.php?Run%20native%20executable%20in%20Android%20App
http://kevinboone.net/android_native.html
********************************************************************************************************************/
package com.example.hellonativecode;
import java.io.BufferedReader;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import android.app.Activity;
import android.content.Context;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.util.Log;
import android.widget.TextView;
public class MainActivity extends Activity {
/** Called when the activity is first created. */
static final String TAG = "com.example.hellonativecode.MainActivity";
static final String exeFileName = "hello";
static String nativePath = "";
NativeWorker nw;
TextView tv;
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
/* Create a TextView and set its content.
*/
copyFile(exeFileName, nativePath, this, true);
tv = new TextView(this);
nw = new NativeWorker();
nw.start();
setContentView(tv);
}
private static void copyFile(String assetPath, String localPath, Context context, boolean doCopy) {
try {
InputStream in = context.getAssets().open(assetPath);
//FileOutputStream out = new FileOutputStream(localPath);
FileOutputStream out = context.openFileOutput(assetPath, Context.MODE_PRIVATE);
nativePath = context.getFilesDir()+"/"+assetPath;
int read;
if (doCopy) {
byte[] buffer = new byte[4096];
while ((read = in.read(buffer)) > 0) {
out.write(buffer, 0, read);
}
}
out.close();
in.close();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
class NativeWorker extends Thread {
@Override
public void run() {
final StringBuffer output = new StringBuffer();
Process nativeApp = null;
try {
nativeApp = Runtime.getRuntime().exec("/system/bin/chmod 777 "+nativePath);
nativeApp.waitFor();
Thread.sleep(2000);
nativeApp = Runtime.getRuntime().exec(nativePath);
} catch (IOException e) {
Log.i(TAG, "Binary with name " + nativePath + " not found!!!");
e.printStackTrace();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (nativeApp != null) {
BufferedReader reader = new BufferedReader(new InputStreamReader(nativeApp.getInputStream()));
int read;
char[] buffer = new char[4096];
//output = new StringBuffer();
try {
while ((read = reader.read(buffer)) > 0) {
output.append(buffer, 0, read);
}
reader.close();
// Waits for the command to finish.
nativeApp.waitFor();
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
Log.e(TAG, "Our spawned Process is Interrupted !!");
e.printStackTrace();
}
String nativeOutput = output.toString();
Log.e(TAG, "here is the result : "+nativeOutput);
}
//run this at the end to signal mainthread our processing is done
boolean hdl = new Handler(Looper.getMainLooper(), new Handler.Callback() {
@Override
public boolean handleMessage(Message msg) {
tv.setText(new String(output));
return true;
}
}).sendEmptyMessage(0);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment