11/02/2017 |
Minor update: The main process is now created using the ProcessBuilder. |
18/10/2021 |
Update:
The problem that caused this solution to stop
working on
devices running Android 10 or later has
been solved! This solution now works for old and more recent versions of Android!. |
03/10/2022 | Due to
termination of the xs4all provider web server, this page was moved to http://decijferij.nl/software/Ada
on Android.html |
28/11/2024 |
Improved
Android Studio project. Note that this solution also works for 32-bit Ada compilers for Android ARM. |
with Ada.Text_IO; use Ada.Text_IO;
procedure hello_ada is
begin
loop
declare
Line : String := Get_Line;
begin
Put_Line ("Hello from Ada!, You entered: " & Line);
exit when Line'Length = 4 -- '
and then Line = "exit";
end;
end loop;
end hello_ada;
Now you can build the executable using the command:
arm-android-eabi-gnatmake hello_ada.adb -largs -fPIC -pie
Note that the flags '-largs -fPIC -pie' are optional for older phones
but
required for devices running Android lollipop and later versions
(including wear devices).
package com.hello_ada;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import android.app.Activity;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends Activity {
/* Called when the activity is first created. */
Process process = null;
BufferedReader reader;
BufferedWriter writer;
BufferedReader errReader;
private void logProcess (Process pr, EditText t) throws IOException
{
/* This routine reads the output and error streams from a process */
/* and logs it to an EditText object. */
int read;
char[] buffer1 = new char[4096];
StringBuffer output = new StringBuffer();
try
{
BufferedReader log_reader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((read = log_reader.read(buffer1)) > 0) {
output.append(buffer1, 0, read);
t.append(output.toString() + "\n");
}
log_reader.close();
BufferedReader log_errReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
while ((read = log_errReader.read(buffer1)) > 0) {
output.append(buffer1, 0, read);
t.append(output.toString() + "\n");
}
log_errReader.close();
}
catch (Exception e) {
t.append("logProcess: Exception " + e.getMessage());
e.printStackTrace();
}
}
public String get_result() throws IOException, InterruptedException {
String result = "";
int read;
char[] buffer1 = new char[4096];
StringBuffer output = new StringBuffer();
while (reader.ready() && (read = reader.read(buffer1)) > 0) {
output.append(buffer1, 0, read);
result += output.toString() + "\n";
}
return result;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
EditText log_text = (EditText) findViewById (R.id.editTextTextMultiLine);
log_text.setText("Test native app\n\n");
Context context = getApplicationContext();
PackageManager pm = context.getPackageManager();
try {
ApplicationInfo appInfo = pm.getApplicationInfo("com.hello_ada", PackageManager.GET_SHARED_LIBRARY_FILES);
log_text.append("native lib dir: " + appInfo.nativeLibraryDir + "\n\n");
String data_dir = appInfo.nativeLibraryDir;
String filename = "/libhello_ada.so";
File hello_ada_file = new File(data_dir + filename);
/* Check if the executable exists */
process = Runtime.getRuntime().exec("ls -l " + data_dir + filename);
process.waitFor();
logProcess(process, log_text);
/* Start the Ada process */
process = Runtime.getRuntime().exec("." + data_dir + filename);
/* Open streams to this process. It should be running now */
/* and waiting for input. */
writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
errReader = new BufferedReader(new InputStreamReader(process.getErrorStream()));
// Give the process time to settle
Thread.sleep(100);
log_text.append("\nProcess started\n\n");
/* Now you can send text (or commands!) to the Ada program */
writer.write("Hello from Java!" + '\n');
writer.flush();
/* Read the result */
log_text.append("Received: " + get_result() + "\n\n");
writer.write("Hello again from Java!" + '\n');
writer.flush();
/* Read the result */
log_text.append("Received: " + get_result() + "\n\n");
/* Make sure the Ada process terminates: */
writer.write("exit" + '\n');
writer.flush();
log_text.append("Received: " + get_result() + "\n\n");
} catch (IOException e) {
log_text.append("io exception: " + e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
log_text.append("interrupted exception: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
log_text.append("exception: " + e.getMessage());
e.printStackTrace();
}
}
}