I have an Android application that only runs on ARM CPUs. This is due to the fact that I have included an ARM executable in the APK. However, after quite a bit of searching, I have been unable to find any way to indicate (in a manifest file or something similar) that the application will not run on other architectures.
Normally, applications that want to include native code include a shared library. In this case, the app only shows up in the Play Store for users with a compatible CPU. However, using a shared library is not an option for my app.
Is there some place in the project's manifest file or somewhere else that I can explicitly indicate the CPU architectures the app supports?
However, using a shared library is not an option for my app.
In theory, it should be. Create a do-nothing little JNI-compatible library with the NDK, and only build it for architectures that your packaged-in binary supports (e.g., ARMv5 and ARMv7). You probably don't even have to use the library (though I'd set up a Java class that references it to be safe, at least during initial testing). That should be enough to trigger Play Store filters, even if you never actually invoke the code at runtime.
IOW, use the NDK stuff just for filtering.
Personally, I'd rewrite your command-line binary to be a NDK-built JNI-compatible library, for performance reasons, but that's just me.
This is may be what you are looking for
TextView tv_showArch_View = (TextView)findViewById(R.id.ShowCPUArch);
String CPU_ABI = Build.CPU_ABI;
tv_showArch_View.setText(CPU_ABI);
It returned to me
ARMeabi for Emulator running on ARM processor
and
X86 for Emulator running on Intel processor
For More detailed information you can go thru Google's Official Documentation
Related
I have an app that relies on some ARM 32-bit native libraries along with my own native library. Due to the new 64-bit requirement I need to have both 32- and 64-bit libraries in my APK, but I do not have access to the source code of those libraries so cannnot compile them to satisfy this demand.
I looked for 64-bit versions of the libraries I rely on and am sure they don't exist. Is it possible to somehow translate binaries from 32-bit to 64-bit or create fake libraries that won't be loaded at all?
No this is not possible. Your problem is similar to:
Linking 32-bit library to 64-bit program
Sadly the already bad solution for this type of problem, which is interprocess communication between an 32bit and a 64bit application will not work since the application which runs the native code needs to be 64bit.
This solution won't work anymore too see the statement at the bottom.
So you have only the following options:
Contact the publisher / owner of the library and request 64bit binaries.
Look for another library which might replace the current one.
Recode the needed functionality yourself. You might wanna disassemble the original library for that.
Run the 32bit library on a Server and make the app communicate with the Server. May be super slow and it requires an permanet internet connection.
I am pretty sure that providing "Fake" 64bit binaries will violate the ToS of the PlayStore so even if it get's accepted in first place it your app might get removed at any time.
But if you are willing to take the risk you can create you own 64bit version of the library you just need to make sure the linker is satisfied.
I have an .so file which I pulled from an Android APK (Not my app, so I don't have access to the source, just the library)
I want to use this shared object on my 32 bit Ubuntu machine, and call some functions from it (Preferably with Python) . Is it possible to convert an Android .so to a Linux .so?
Or is there any simple solution to accessing the functions in the .so without resorting to a hefty virtual machine or something?
Thanks
Most likely not. It's very probably the Android you pull it from is running on the ARM architecture, and therefore the .so library was compiled for that architecture.
Unless your desktop machine is also on the ARM architecture (it's most likely x86 and it would have to be specific such as ARMv7) the .so binary will be incompatible on your desktop.
Depending on what the .so library actually is, you may be able to grab the source code and compile it for your x86 machine.
Disclaimer: Even if you obtain a library compiled for the same architecture as your desktop (from x86 phone), there is no guarantee it will work. It may rely on other libraries provided only by Android, and this may be the start of a very deep rabbit hole.
From what I understand, native code on Android is code that works directly with the processor of a specific device. So if I wanted to take advantage of a certain processor I would use native code.
But what happens if I want to make an app that contains native code, but targets multiple processors?
Do I have to make multiple apps, one for each architecture? Or is there a way to put multiple version of the native code in one app picking the one matching the processor of the device it runs on?
The Android Native Development Kit is a suite of cross compilers and support libraries which can be used to produce shared object (.so) files targeting one or more of the officially supported Android architectures.
The Android application package (.apk) specialized zip file format allows inclusion of distinct native libraries for more than one architecture.
If you refer to the NDK documentation, you will see that there is a project configuration file which you can use to specify which architecture(s) your native code should be compiled to support.
This is usually referred to as cross compiling. Ie, you need a compiler than compiles X, your current code, for Y. It generates code for CPU Y, not X as is the usual case.
You need to target multiple CPU architecture only if you are developing a NDK application.
Create a file named "Application.mk" under the jni folder. Add this parameter
APP_ABI=
Example :
APP_ABI:=x86 armv7eabi mips
or you can all do this
APP_ABI:=all ( in which it would create the apk for all supported architecture)
but doing this you would generate a FAT binary and google play will take care of filtering the corresponding apk for different underlying architecture when the user installs your app.
As clearly stated in NDK documentation,
The new .apk will embed your shared libraries, and they will be extracted automatically at installation time by the system when you install the package on a target device.
Now, suppose I included only a subset of all possible libraries, say only the armeabi one. Trying to install on an x86 device will result in the following error:
Installation error: INSTALL_FAILED_CPU_ABI_INCOMPATIBLE
Is it possible to disable platform checking and proceed anyway, since the application is able to fallback to a pure Java implementation of the native code?
My guess would be that it is not, however I believe including a nearly/effectively empty library for other platforms of interest would solve your problem at limited effort or package size impact.
I don't know for a fact that you'd actually need a valid .so for an architecture to pass the test, as opposed to a dummy file in the right folder with the right extension (assuming you never try to load it).
But even if you do need a valid one, you could just build the hello-jni sample for all architectures or something like that. Having a jni function you can call that returns if the library is usable or a stand-in might also be a simple way of solving the detection problem.
I am working on a project in which I need to include NGSpice simulation library in an Android application and of course be able to use it.
I tried including the NGSpice windows DLL in my android application using SWIG and Android NDK, but it turned out that it is not even possible, so now I started to think about building NGSpice as a shared library for linux.
And now my question is, can I use the linux shared library for NGSpice as it is in my Android application, or does it need to built differently somehow to work on my Android application.
Thanks.
No. Android typically has two key differences from a traditional linux:
1) It uses the Bionic C library and dynamic linker, instead of a more traditional set such as glibc.
2) Android is typically run on an ARM or 32-bit x86 processor (or in rare cases MIPS), while your desktop Linux library might be either 64-bit or 32-bit x86 code.
If you build a .so compatible with the architecture of the machine and with bionic's system library functions and dynamic linker, then it should be workable.
Alternatively, if you have something for a compatible architecture but the wrong libc, it may be possible to write your own loader to get it into memory in working form on a secured device, or on a rooted device it is possible to run a more traditional linux userspace (typically Debian derived) in a chroot. But neither of these would be easy to integrate into an Android application - for the latter you'd almost definitely have to pass work over via interprocess communication, and that might prove easier in the former case as well.
Your only really endorsed solution is to rebuild the library from source, using either the ndk build system, or an ndk-generated "stand alone toolchain" and the library's current build system.