Reputation: 129
So, I have this native code that I built for different CPUs. I don't want to load as a library, I want to execute the binaries through runtime.exec(...).
Is there a way of placing them in some place where Android will take care of the CPU qualifiers? Or do I have to make different APKs?
Upvotes: 0
Views: 3001
Reputation: 1
I also tried using libiperf3
. So file as suggested by @Alex Cohn but still get the permission denied error.
Error Output: Iperf3:error - unable to create a new stream: permission denied
I got the same error when I was trying to execute /data/local/tmp/iperf3
binary using adb shell.
However, when ran chmod 777
, I was able to run it successfully. The issue is the app cannot execute it no matter where I put the binary.
Upvotes: 0
Reputation: 61
Android Q+
(Personally tested with Android 11
). Since got released new policy changes towards android system safety, you can't execute normally your binary executables just from /data/data/package/files/...
folders.
W^X violation details: https://developer.android.com/about/versions/10/behavior-changes-10#execute-permission
Solution:
1. Add your executables to the native libraries folder in Android studio eg. app/libs/armeabi/executable
.
2. Also add this line to your manifest (Application layer):
<Application
...
android:extractNativeLibs="true">
...
</application>
If you are using newer version of the Gradle plugin, you may face issues when your executable not being packaged into apk or extracted in.
/data/app/package/lib/.../...
You need then trick Android Gradle plugin a bit.
Solution:
1. Create a folder structure in your file explorer lib/armeabi/executable
(I use armeabi just as an example, it can be your architecture)
2. Now zip this lib
folder and rename it to yournaming.jar
3. Copy and paste in your Android Studio libs
directory
4. Go to your build.grade(app)
, in dependencies
section add following line
for compiling .jar
.
dependencies {
implementation fileTree(dir: 'libs', include: '*.jar')
...
}
5 Build your .apk
and check with analyze tool
, folder should be now created in .apk
itself
If all these steps done, now can try do exec command to run binary executable from android app:
try {
// creating exec process
Process process =
Runtime.getRuntime().exec(getApplicationInfo().nativeLibraryDir +
"/executable");
// reading and printing executable outcome
byte[] buffer = new byte[2048];
process.waitFor();
process.getInputStream().read(buffer, 0 , buffer.length);
System.out.println(new String(buffer));
} catch (IOException | InterruptedException e)
{
e.printStackTrace();
}
Hopefully helped to solve your case
Upvotes: 5
Reputation: 57183
Making different APKs is sometimes a good choice, to reduce the download size. Just think about it, hundreds of thousands of people will be downloading these extra megabytes from the Play Store with every update! There are some strategies for creating and maintaining such split APK's: it's important to keep the version numbers in proper order. See https://stackoverflow.com/a/20029256/192373 and the improvement by Ashwin S Ashok below.
Whether you choose to split the APK's, or keep a monolithic one, feel free to use my "patent": put your executables into libs/armeabi-v7a
(or other subfolder, according to target ABI) , and give them names that all start with lib and end with .so (e.g. lib_vim_.so
). This will turn on the installation magic, and the appropriate files will be unpacked (and updated) into your /data/package/lib
folder with executable permissions.
Upvotes: 5