11/02/2017 |
Minor update: The main process is now created using the ProcessBuilder. |
25/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!. |
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.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import androidx.appcompat.app.AppCompatActivity;
// import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.EditText;
public class MainActivity extends AppCompatActivity {
/* Called when the activity is first created. */
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 reader = new BufferedReader(new InputStreamReader(pr.getInputStream()));
while ((read = reader.read(buffer1)) > 0) {
output.append(buffer1, 0, read);
t.append(output.toString() + "\n");
}
reader.close();
BufferedReader errReader = new BufferedReader(new InputStreamReader(pr.getErrorStream()));
while ((read = errReader.read(buffer1)) > 0) {
output.append(buffer1, 0, read);
t.append(output.toString() + "\n");
}
errReader.close();
}
catch (Exception e) {
t.append("Exception " + e.getMessage());
e.printStackTrace();
}
}
@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");
Process process = null;
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 */
// You can use the ProcessBuilder or just call 'exec'.
//ProcessBuilder prb = new ProcessBuilder ("." + data_dir + filename);
//process = prb.start();
process = Runtime.getRuntime().exec("." + data_dir + filename);
log_text.append("process started\n\n");
/* Open streams to this process. It should be running now */
/* and waiting for input. */
BufferedWriter writer = new BufferedWriter(new OutputStreamWriter(process.getOutputStream()));
BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream()));
/* 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: " + reader.readLine() + "\n\n");
/* Make sure the Ada process terminates: */
writer.write("exit" + '\n');
writer.flush();
log_text.append("Received: " + reader.readLine() + "\n\n");
} catch (IOException e) {
/* TODO Auto-generated catch block */
log_text.append("io exception: " + e.getMessage());
e.printStackTrace();
} catch (InterruptedException e) {
/* TODO Auto-generated catch block */
log_text.append("interrupted exception: " + e.getMessage());
e.printStackTrace();
} catch (Exception e) {
log_text.append("exception: " + e.getMessage());
e.printStackTrace();
}
}
}