Android compilation calls C code
Preface demand Source
In the past few days, it has no function to help others build a simple android client. The main function is to call the C code to set the Wi-Fi network of the mobile phone, which leads to technical difficulties, how to callC programAchieve what we need.
Solution
I have come up with two solutions for this:
The first solution is to useJNI. What is JNI? JNI is actuallyJava Native InterfaceJava Local interface. It provides several APIs for communication between java and other languages (mainly C and C ++ ).
The second method is to compile the C code to be executedExecutable filesAnd then package the executable file and program together into an APK, and call this executable file when necessary.
Final Choice
Finally, I chose the second solution. The reason is that the second method is relatively simple and operable when I already have executable files. The first solution is to download android NDK, which is a collection of tools and provides dynamic libraries that help developers quickly develop C or C ++, it is very convenient to automatically package so and java applications into apk.
Technical Implementation Executable File
First, you need to get an executable file. Of course, the executable file you want is not as simple as you think, not directly in linux.GccThe C code is required here.Cross-CompilationObtain executable files that can be run on the android server. Here we will not go into details about how to cross-compile the C files. You can search for them online. In addition, NDK is also a good tool.
Resource Storage
The resource storage page here is a small pitfall. When we write a java program, if we want to open a file, we can directly enter the path, for example, if the file to be used is in the project directory, you can directly enter the file name to call it. However, the running environment here is an embedded device, not a PC, which involves a problem, how to store resources.
Here we will talk aboutAsset folderAndRes/raw folderSimilarities and Differences:
Similarities: files in both directories are packaged
IntactWill not be compiled into binary. The files in res/raw are mapped to R. java. You can use the resource ID directly during access, but the files in the assets folder are not mapped to R. java. Res/raw cannot have
Directory structureAnd create a folder under the assets Directory. Resource Acquisition
Let's talk about it here.Res/rawThe following method is used to obtain the input stream for write operations.
1 |
InputStream is =getResources().openRawResource(R.id.filename); |
The next step is how to readAssetsThe following method is also used to obtain the input stream for write operations.
123 |
AssetManager am = null; am = getAssets(); InputStream is = am.open(filename); |
Note:It is said that Assert can only put a single file up1 MBut it is not really specific and has not been verified, if you encounter problems, you should consider this point of attention.
Although the read is successfulShellIf the script is executed, the file should be stored on the mobile phone. If the file is read, it cannot be found on the mobile phone. Therefore, we need an operation to store the file. Here I wrote a function for saving files, which combines methods for getting data from assets.
123456789101112131415 |
public void copyDataToSD(String outFileName)throws IOException{InputStream myInputStream;OutputStream myOutputStream = new FileOutputStream(outFileName);myInputStream = this.getAssets().open(a.out);byte[] buffer = new byte[1024];int length = myInputStream.read(buffer);while (length > 0) {myOutputStream.write(buffer, 0, length);length = myInputStream.read(buffer);}myOutputStream.flush();myInputStream.close();myOutputStream.close();} |
The imported outFileName that I defined is the defined file path and file name.
12 |
private static String EXE_PATH = data/data/com.example.g3wifi/a.out;private static File exe_file; |
Shell Command Execution
Now, everything is ready, and we have nothing to do with it. We need to execute the executable file, because android is based onLinuxTherefore, some basic commands are supported. to execute shell commands in android, follow the format below:
12345678 |
Public void exeC (String cmd) throws IOException {Runtime runtime = Runtime. getRuntime (); Process process = runtime.exe c (cmd); // Process process = runtime.exe c (new String [] {su, reboot }); // you can run two commands. // The result of executing the shell command is BufferedReader ie = new BufferedReader (new InputStreamReader (process. getErrorStream ()));} |