Setting up JNA in Android Studio - android

I try to import jna.jar into my project since JNA is a very useful tool to call Native library which is base on JNI.
OS: Windows 10
IDE: Android Studio 1.5.1
JDK: 1.8.0_73
NDK: r10e
What I have done
(AS = Android Studio)
Create a new project by AS with API18.
Download jna.jar from their GitHub.
https://github.com/java-native-access/jna
copy jna.jar into project folder.
JNATest\app\libs\jna.jar
In AS, right-click on the icon of jna.jar, choose Add as Library
Wait for few seconds, check the File->Project Structure->app->Dependencies. We do have the jna.jar. (Same as app\build.gradle)
build gradle
Implement JAVA code about JNA in MainActivity.java
Run app on real device Sony Z3 (arm)
Crash by CLibrary.Instance.printf("Hello, JNA");
Error Message on Android Monitor
E/AndroidRuntime: FATAL EXCEPTION: main
Process: i3d.jnatest, PID: 1068
java.lang.UnsatisfiedLinkError: Native library (com/sun/jna/android-arm/libjnidispatch.so) not found in resource path (.)
at com.sun.jna.Native.loadNativeDispatchLibraryFromClasspath(Native.java:866)
at com.sun.jna.Native.loadNativeDispatchLibrary(Native.java:826)
at com.sun.jna.Native.<clinit>(Native.java:140)
..
... so on
Java code
package i3d.jnatest;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import com.sun.jna.Library;
import com.sun.jna.Native;
public class MainActivity extends AppCompatActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
CLibrary.Instance.printf("Hello, JNA");
}
public interface CLibrary extends Library
{
CLibrary Instance = (CLibrary) Native.loadLibrary("msvcrt", CLibrary.class);
void printf(String format, Object... args);
}
}
Question
According to error message, I miss /android-arm/libjnidispatch.so in runtime.
Did I put the wrong place for jna.jar?
How should I get and use /android-arm/libjnidispatch.so?
I am a newbie about Android Studio, so maybe misunderstanding something key-point.

For Android, reference the JNA library adding #aar at the end of the string instead of downloading the JNA jar:
https://github.com/java-native-access/jna/blob/master/www/FrequentlyAskedQuestions.md#jna-on-android

Put the .so file in the following directory (when using android studio): yourproject\app\src\main\jniLibs\armeabi-v7a\libjnidispatch.so
Update I: (up to version <= 4.3.0) Since some of you asked where to find the *.so file:
On the official JNA site you will find all the supported architectures (30+) for download:
https://github.com/java-native-access/jna/tree/master/lib/native
Download the jar of the architecture you'd like and open it with some zip tool. In there you'll find the libjnidispatch.so file (of course only for unix architectures. For windows its a dll)
Update II: (starting from version >= 4.4.0)
Use the jna-X.X.0.aar file, supplied by the JNA project
As mentioned in a comment - starting from version 4.4.0 JNA publishes an AAR to maven central with all the libjnidispatch.so's in it. Users have had better luck using gradle than straight maven here, which doesn't always select or properly handle aars.

I found this comment in a file in the library github repo - "If you're using Google's Eclipse plugin then you must manually remove libjnidispatch.so from jna.jar/lib/armeabi and add it into your project's libs/armeabi directory."
Since this file was created in 2012 and Android Studio was still in very early phase and not super popular by that time, I assume it might be a valid note for Eclipse and also for Android Studio. I suggest you try it.

Related

Build an android apk from Unity3d project working with C/C++ dll

I made a Unity3d project working with C/C++ Dll.
So first I made the dll in Visual studio.
// mydll.cpp
#define EXPORT_API __declspec(dllexport)
extern "C" {
int EXPORT_API add(int a, int b)
{
return a+b;
}
}
And I added this dll into my Unity3D project and called
// C# script in Unity3D
public class TestDll : MonoBehaviour {
[DllImport("mydll")]
private static extern int add (int a, int b);
void Start() {
int a = add (100, 200);
}
}
This code works well and I got the correct result in Unity3D editor.
So I built this project to android platform and got an apk.
I installed and run this apk on my android device but the app doesn't work.
The app didn't run the Dll function.
Whats the matter? I tried to find out the solution in Google and here, but didn't get anything, yet.
Please help me.
Thanks.
Your dll must be in Plugins folder for Windows, it can work for Editor too. for Android you must replace in Plugins/Android folder. Build and write me ok
LearnCocos2D's comment is accurate.
To get Unity to DllImport() a shared library on Android, you must use an NDK compiler and specify a compile config for your target Android platform. Moreover, Unity requires you to specify the architecture of the Android platform in the build settings, eg.. "arm v7" vs "arm64".
As an aside, in Unity 2019.4 - selecting "Load on Startup" in the inspector page of my .so elicits a "DLLNotFoundException".
Overview of this: https://docs.unity3d.com/2019.4/Documentation/Manual/AndroidNativePlugins.html
NDK's CMake guide for getting you started on compiling correctly: https://developer.android.com/ndk/guides/cmake

How to setup alljoyn sdk in android?

I am trying to setup two android devices to communicate with each other through wifi. Some of the links I have gone through suggest alljoyn sdk in order to accomplish this.
There is an sdk download but there is no documentation for how to setup environment.
Here is how to set up an AllJoyn SDK development environment with android studio:
Download the SDK from this page. Go for Android Core SDK - release (or debug).
Create a new blank android project.
Create directory <project>/app/src/main/jniLibs and <project>/app/src/main/jniLibs/armeabi.
From alljoyn-15.09.00-rel/java/jar copy alljoyn.jar and from alljoyn-15.09.00-rel/java/lib copy liballjoyn_java.so. The directory to copy from might differ depending on the current version and your release/debug choice.
Put alljoyn.jar in /jniLibs and put liballjoyn_java.so in /jniLibs/armeabi. Should look like this
Right click project -> Open Module Settings -> app -> Dependencies.
With the green [+] button, add a file dependency.
Navigate to <project>/app/src/main/jniLibs/alljoyn.jar and select that jar.
This will add a line in your gradle (compile files('src/main/jniLibs/alljoyn.jar')) that will allow for code completion etc.
In the file where you want to use alljoyn code, include this snippet
/* Load the native alljoyn_java library. */
static {
System.loadLibrary("alljoyn_java");
}
for example:
public class MainActivity extends AppCompatActivity {
/* Load the native alljoyn_java library. */
static {
System.loadLibrary("alljoyn_java");
}
#Override
public void onCreate(Bundle savedInstanceState) {
...
}
}
You can now use the alljoyn SDK. Import classes with
import org.alljoyn.bus.BusAttachment;
import org.alljoyn.bus.BusException;
import org.alljoyn.bus.BusListener;
etc.
If you're more of an eclipse guy, check this official documentation page on how to setup an eclipse environment.

What is the minimum number of steps to get full javadoc support with the new default project options?

With the new SDK Tools and ADT versions 22.6.2, the default options for creating a new project with a blank activity produces a project which uses Fragments and refers to a library project (a new one for each project) named appcompat_v7_x.
The relevant parts of the stub code for the main activity are:
package com.myname.miniandroid;
import android.support.v7.app.ActionBarActivity;
import android.support.v7.app.ActionBar;
import android.support.v4.app.Fragment;
.....
.....
public class MainActivity extends ActionBarActivity {
#Override
protected void onCreate(Bundle savedInstanceState) {
....
}
public static class PlaceholderFragment extends Fragment {
......
......
}
}
.
We can see that it uses a Fragment and an ActionBarActivity. The automatically created library project has both the v4 and the v7 jars in its libs folder, the main project has just the v4 jar. As built by default, hovering over either of these classes gives no javadoc information.
To get such support I've had to :
1) insert a file android-support-v7-appcompat.jar.properties into the libs folder of my automatically created appcompat_v7_4 library project. It contains the lines:
doc=c:\\dev\\tools\\android-sdk-windows4.4\\docs\\reference
src=C:\\dev\\tools\\android-sdk-windows4.4\\extras\\android\\support\\v7\\appcompat\\src
(Both lines seem to be necessary)
2) insert a file anndroid-support-v4.jar.properties into the libs folder of the main project. It contains the line:
src=C:\\dev\\tools\\android-sdk-windows4.4\\extras\\android\\support\\v4\\src
3) Close and reopen both projects and clean all projects.
I've got a brand new installation of Eclipse Kepler and an up to date installation of the SDK.
I feel that there must be a quicker way of getting set up to start a new project with the recommended default options. If anyone can tell me what it is, I would be most grateful.
You have use the "New" button in the upper left corner, select Android Application Project, choose the name, icon...
When you have done, you should have a working "Hello world" app.
If you want to add external libraries this is the answer: https://stackoverflow.com/a/3643015/3203988

google play game service error -> 'Could not find class...GameHelper '

import com.google.example.games.basegameutils.GameHelper;
public class MyAppName extends Cocos2dxActivity implements GameHelper.GameHelperListener {
....
.....
public static GameHelper gameHelper;
#Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
gameHelper = new GameHelper(this);
.....
error point: gameHelper = new GameHelper(this);
error Message : Could not find class 'com.google.example.games.basegameutils.GameHelper', referenced from method com.company.MyAppName.MyAppName.onCreate
How do I fix this?
On BaseGameUtils, go to Project Properties | Android. Verify that it's targeting a valid Android target that's present on your SDK (anything with API level >= 8 should work).
Also on the project properties screen for BaseGameUtils, check that the "Is Library" checkbox is checked.
Check that BaseGameUtil is referencing google-play-services_lib as a library. (Project Properties | Android | References).
Check that your project is referencing BaseGameUtil as a library (same).
Hope this helps!
Did you define Basegameutils as a library project and include it as a reference ?
The doc that accompanies the sample is fairly good.
In the latest BaseGameUtils project (I downloaded from google github on Aug 13, 2014), the source files are not under the src/ folder. so you will need to Properties->Java Build Path->Add folder and select the java folders.
If the project then compiles without error for the BaseGameUtils, great! I also encountered some other compilation errors and solved it by update the Google Play services to the latest version in SDK manager.
Hope it helps.

Monodroid issue with jar binding zubhium sdk

Iam trying to bind a jar(zubhium sdk jar) file to my mono droid project. I have followed their guide on xamarins website and created a new binding project which I reference I my mono droid project.
I am having some issues with package names. I get the following error:
Error 3 package com.zubhium.interfaces does not exist
com.zubhium.interfaces.ZubhiumListener
C:\Users\jbp\Desktop\ny\CmsApp.Droid\obj\Debug\android\src\mono\com\zubhium\interfaces\ZubhiumListenerImplementor.java 8 25 CmsApp.Droid
from the genrated source:
package mono.com.zubhium.interfaces;
public class ZubhiumListenerImplementor
extends java.lang.Object
implements
mono.android.IGCUserPeer,
com.zubhium.interfaces.ZubhiumListener
And that is because when the project is wrapped it automaticly adds mono(.com.zubhium....) to the package name. I cant find how to remove this mono or if i can set a rule to add this part.
I tried to put <attr path="/api/package[#name='com.zubhium.interfaces']" name="managedName">mono.com.zubhium.interfaces</attr>
in the xmldata.xml file but that did not work.
Do you guys have any sugestions?
Regards
package com.zubhium.interfaces does not exist
When you bind a .jar library and reference the binding project from another project, you need to also add the .jar to your Application project and set its Build action to AndroidJavaLibrary.
Failure to do so means that the .jar won't be added to the javac $CLASSPATH, resulting in javac compilation errors when compiling the Android Callable Wrapper (as you saw), and that the .jar won't included into your final .apk. Both of these are Badâ„¢.
And that is because when the project is wrapped it automaticly adds mono(.com.zubhium....) to the package name.
That's for an "Implementor" type; you can ignore it. It's used as part of the implementation of events. If you look at the generated C# code, there should be:
[global::Android.Runtime.Register ("mono/com/zubhium/interfaces/ZubhiumListenerImplementor")]
internal sealed class ZubhiumListenerImplementor : Java.Lang.Object, IZubhiumListener {
// ...
}
The mono.com.zubhium.interfaces.ZubhiumListenerImplementor is the ACW for the internal ZubhiumListenerImplementor type.
You can't rename this type; it's an internal construct that isn't controlled via metadata.

Categories

Resources