I have done a couple of the tutorials including the hell from jni one
and another one that calculates the sum of two numbers.
They involved using cygwin and the ndk to create the library so file
and I have a bit of a grasp on how to insert my own libraries into the
libraries layer of Android.
I have now been asked to access the native libraries on Android and
see what I can use them for.
My question is can I do this?
The STABLE-APIS.txt document is a bit vague and mentions the following
as Stable C++ API's in Android 1.5
<cstddef>
<new>
<utility>
<stl_pair.h>
Does that mean I can access them?
If so then how do I go about it? I dont think that following the
tutorials I have already done would be any help?
Any pointers on how to do this or links to tutorials etc.. would be
greatly appreciated
Thanks for that.
I am aware of all of that though and the application is currently very
much java driven.
However I have been asked to explore the NDK to see what Native
libraries can be accessed via the NDK.
Note: I have already followed and completed tutorials on how to use
our own C/C++ code as a native library and load it via the JNI.
So what I'm trying to find out is how I access a Native code library
that is already on the Operating System/device, so how do I access one
of the Stable Api's in the native code and use the methods there?
Essentially what we want to be able to do is open sockets via the NDK
and native code and we were wondering if this is possible and I would
greatly appreciate some guidance on how to achieve this.
Thanks
On 04/13/2010 10:42 AM, draffodx wrote:
> However I have been asked to explore the NDK to see what Native
> libraries can be accessed via the NDK.
>
Any library you want, but you can rely on stable interfaces (which are
defined in header files) only for the libs you mentioned reading in the
stable-apis.txt.
> So what I'm trying to find out is how I access a Native code library
> that is already on the Operating System/device, so how do I access one
> of the Stable Api's in the native code and use the methods there?
>
Use the header files (pre-processor directive #include <...>) for making
the compiler aware of the libraries' functions, have your JNI lib linked
against those libraries by the linker (via NDK: by setting LOCAL_LDLIBS
in your Android.mk). Well, it's just basic C programming w/ using shared
libraries.
> Essentially what we want to be able to do is open sockets via the NDK
> and native code and we were wondering if this is possible and I would
> greatly appreciate some guidance on how to achieve this.
>
Should be easy, since that's normal libc stuff (which is automatically
linked against, so you don't need to do any extra setup). Android is
very POSIX-compatible here, so just check some man pages of your choice.
From a fast googling, this looks promising:
http://beej.us/guide/bgnet/
(Beej's Guide to Network Programming)
-hwh
Thanks for the reply excellent info.
So if I wanted to use the utility stable api my Android.mk in my jni
folder would look like this?
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndk_demo
LOCAL_SRC_FILES := ndk_demo.c
LOCAL_LDLIBS += -utility
include $(BUILD_SHARED_LIBRARY)
Since the libc stuff is automatically linked it doesn't need to appear
in LOCAL_LDLIBS?
But how do I then open a Socket in the native layer via the JNI, as in
where would my code be?
Would I have to write some C++ code in a .c file placed in my jni
folder or would I be able to call directly to a C++ method to create a
socket from a java file?
I know thats probably basic stuff but I'm trying to get my head around
it and understand the basics first
On 04/13/2010 11:14 AM, draffodx wrote:
> Thanks for the reply excellent info.
>
Welcome!
> So if I wanted to use the utility stable api my Android.mk in my jni
> folder would look like this?
>
> LOCAL_PATH := $(call my-dir)
>
> include $(CLEAR_VARS)
>
> LOCAL_MODULE := ndk_demo
> LOCAL_SRC_FILES := ndk_demo.c
>
> LOCAL_LDLIBS += -utility
>
that line would be
LOCAL_LDLIBS += -lutility
(-l is the linker flag for linking against libraries)
> include $(BUILD_SHARED_LIBRARY)
>
> Since the libc stuff is automatically linked it doesn't need to appear
> in LOCAL_LDLIBS?
>
right! :-)
BTW, for debugging, the first library you want to include besides libc
is probably "log" (Android logging), since outputting stuff via
print(f)&Co does not work. To do that, use "-llog" in LOCAL_LDLIBS and
use "#include <log.h>" in your C code.
> But how do I then open a Socket in the native layer via the JNI, as in
> where would my code be?
>
You don't have to go that way, but you can start using this pattern:
#1: start a new Android Java project
#2: define the JNI method(s) you want to call from Java in your Java
code (e.g. "native void sockettest();" for starters).
#3: use the "javah" tool to generate a header file that will contain the
C/C++ function definition for you to use:
javah -classpath /path/to/your/android-apps/bin/ -o ndk_demo.h
com.example.your.android.JNIWrapperClass
#4: include that generated header file (you do not really have to do
that, in fact) in your code, copy function definitions out and fill them
w/ life.
(note that the javah tool uses class files and derives the native
function definition from them, so the classpath above has to point to
the top-level directory where the build mechanism puts the class files)
Start with a simple void() function, i.e. one that does not take
parameters and does not return a value. This way you can start with
learning what you can do with C without JNI specifics getting in your
way. When later dealing with data movement from/to Java, rely on the
fine JNI book which Mustapha gave a link to.
> Would I have to write some C++ code in a .c file placed in my jni
> folder or would I be able to call directly to a C++ method to create a
> socket from a java file?
>
BTW, if you're using C++ instead of plain C, name your source files w/ a
.cpp suffix!
> I know thats probably basic stuff but I'm trying to get my head around
> it and understand the basics first
>
Seems to work, your preliminary examples were pretty much to the point ;-)
-hwh
This is what I have at the minute,
In my java class simply this:
public native void sockettest();
Then the javah created this header file forom that java file:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class com_socket_ndk_NdkSocket */
#ifndef _Included_com_socket_ndk_NdkSocket
#define _Included_com_socket_ndk_NdkSocket
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: com_socket_ndk_NdkSocket
* Method: sockettest
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_com_socket_ndk_NdkSocket_sockettest
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
And I created this C file then called socket.c
#include "com_socket_ndk_NdkSocket.h"
JNIEXPORT jstring JNICALL Java_com_socket_ndk_NdkSocket_sockettest
(JNIEnv * env, jobject) {
//do something with sockets in C code here?
}
And my Android.mk in my jni folder looks like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := socket
LOCAL_SRC_FILES := socket.c
LOCAL_LDLIBS += -llog
include $(BUILD_SHARED_LIBRARY)
So in socket.c and the method sockettest I should try to open a socket
there using C code?
And then call sockettest in my java code?
Do I need to run the Make App from cygwin to create an so file and
load that library?
Again sorry about all the questions and thanks for the help
yes, everything looks just fine at a first glance.
See some small comments below:
On 04/13/2010 01:41 PM, draffodx wrote:
> [...]
> And I created this C file then called socket.c
>
> #include "com_socket_ndk_NdkSocket.h"
>
you'll likely want to also add an
#include <android/log.h>
here, too.
> JNIEXPORT jstring JNICALL Java_com_socket_ndk_NdkSocket_sockettest
> (JNIEnv * env, jobject) {
>
> //do something with sockets in C code here?
>
yes, that's the place for implementation. I'd suggest to start with a
basic call to the logging and then test calling your first JNI function
from Java. So for starting, add the line
__android_log_print(ANDROID_LOG_DEBUG, "Hello from JNI");
to the function's code.
> }
>
> And my Android.mk in my jni folder looks like this:
>
> LOCAL_PATH := $(call my-dir)
>
> include $(CLEAR_VARS)
>
> LOCAL_MODULE := socket
> LOCAL_SRC_FILES := socket.c
>
> LOCAL_LDLIBS += -llog
> include $(BUILD_SHARED_LIBRARY)
>
>
> So in socket.c and the method sockettest I should try to open a socket
> there using C code?
>
Yes, after making sure that everything works so far.
> And then call sockettest in my java code?
>
Yes, so it does get run.
> Do I need to run the Make App from cygwin to create an so file and
> load that library?
>
Yes, put an "Application.mk" file for your project in the NDK dir into
the "app/" folder (into its own directory, let's say you called the
project "SocketTest"), then go to the NDKs root dir (make sure you
initialized the NDK, see docs for that, you basically need to run one
script), then issue
make APP=SocketTest
The <NDK-Root>/app/SocketTest/Application.mk looks like this:
---snip---
APP_PROJECT_PATH := /path/to/project/root/dir
APP_MODULES := socket
---snip---
The project's root dir is the directory hierarchivally located above the
jni/ dir that contains Android.mk and socket.c.
-hwh
Thanks again Hans for the help too.
I now have a skeleton structure with it out putting text to the log.
So I assume now that becuase I've set up an so file that i will have
access to other native libraries?
So I just have to use includes to get what I want?
So as Mustapha says I can use
#include "sys/socket.h"
And then I will be able to use the socket methods that are in
socket.h?
On Apr 13, 1:12 pm, Hans-Werner Hilse <hwhi...@googlemail.com> wrote:
> Hi Mustapha,
>
> On 04/13/2010 02:10 PM, Mustapha Tachouct wrote:
>
> > > JNIEXPORT *void *JNICALL Java_com_socket_ndk_NdkSocket_sockettest(...)
> > > JNIEXPORT *jstring* JNICALL
On 04/13/2010 03:15 PM, draffodx wrote:
> So I just have to use includes to get what I want?
>
For shared libraries other than libc, you also have to add according
LOCAL_LDFLAGS (like for the liblog). But the socket functions should be
in libc, so:
> So as Mustapha says I can use
>
> #include "sys/socket.h"
>
> And then I will be able to use the socket methods that are in
> socket.h?
>
Yes.
-hwh
Now I just have to learn how to code in C!
I am up and running and have been testing out the Stable Api's
available, creating sockets and threads.
But I've been asked to see how we can access non stable API's for
testing purposes.
So for example I would like to get access to the media library and in
particular audio to see if we can record and encode and decode and
play audio at the native layer.
So I was wondering if you could point me in the right direction? I
have tried to use includes but get a file not found error in cygwin
after make APP="project name"
I may have been trying to include files from Framework though, what
folders should I be looking in for what I am allowed to use at the
native layer and in my native code?
Thanks again in advance
LOCAL_LDLIBS += -llog -lAudioTrack -lIAudioRecord -lIAudioFlinger
And in socket.c :
#include <media/IAudioFlinger.h>
#include <media/IAudioRecord.h>
#include <media/AudioTrack.h>
But when I run make APP=socket-ndk I get:
No such file or directory errors
+
cannot find -lAudioTrack
/Michael
> --
> You received this message because you are subscribed to the Google Groups "android-ndk" group.
> To post to this group, send email to andro...@googlegroups.com.
> To unsubscribe from this group, send email to android-ndk...@googlegroups.com.
> For more options, visit this group at http://groups.google.com/group/android-ndk?hl=en.
>
>
/Michael
> That has already made things much clearer, so I only actually have access to
> whats in the lib folder on the NDK?
>
That's what the linker within the NDK is able to access, and to work out
dependencies and symbols correctly, it needs access to the libs. Since
they are not part of the official stable API, they are not necessarily
distributed with the NDK. Such the need to copy them into a) the default
search part, which is what Michael indicated, or b) some other place and
point the linker to it (LOCAL_LDFLAGS += -L/directory/containing/libs
-lthelib).
> And I dont actually have proper access to anything else that devices might
> contain?
>
Technically, you should be able to access it (access the files, link
against and use the libraries). But then - and you seem to be aware of
that - there are no official APIs you can rely on _and_ it might impose
some legal problems (well, I'm not toooo sure about this, it will
certainly depend on the legislation, but it's something to think about,
too).
> So the NDK is completely limited to the Stable Api's it provides?
>
Technically it's a compiler/linker toolchain, a pre-defined make
environment and provides you with everything you need to use the stable
APIs. You can however hack this to compile whatever you want and link
that to whatever you want.
In fact, there are some apps in the Market which in fact do use private
APIs. Consequently they don't run on all devices out there and probably
never will. An example is the ScummVM Android port (I would like to
point to it's source code, but it is buried in the scummvm bugtracker as
a patch in an attachment file, which can only be applied to a certain
ScummVM svn revision).
-hwh
Yes. When I initial wrote the ScummVM port (Android 1.0), there was
*no* way of playing audio through the supported APIs (java or native)
- so I had little choice but to look behind the curtain. I don't
think I would make the same implementation decision now that
AudioTrack is exposed in Java (although I have no plans to remove the
current native code either - it works so far and *is* much easier and
faster to use than calling java functions from C++).
If anyone wants to see how I do audio, graphics, reading apk
resources, plugins, etc in the ScummVM port - feel free to ask. It's
not a particularly good example, since it was originally written
before there was an NDK and uses lots of non-public APIs. Dianne
would hate every bit of it ;)
- Gus
AudioTrack track(AudioSystem::MUSIC, 44100, AudioSystem::PCM_16_BIT, AudioSystem::CHANNEL_OUT_MONO, 4*1024);status_t status = track.initCheck();assert(status==0);short sample[1024];for(int i=0; i<1024; i++){sample[i] = i*65536*32/1024;}track.start();for(;;){track.write(sample, sizeof(sample));}
LOCAL_LDLIBS += -lmedia
In your Android.mk
How did you get the NDK to build this? When I do it I get loads of missing files/directory errors and compilation errors.
Did you take files from the source and put them into the NDK's Build...platforms....folder?
Or did you just place the whole Android source in there? I'm having real trouble getting make APP=appname to build
when I'm trying to get the media/audiotrack.h in my native code
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := testLOCAL_SRC_FILES := test.cppLOCAL_CPPFLAGS += -I/home/jesper/proj/mydroid/frameworks/base/include # todo: fix abs paths...LOCAL_CPPFLAGS += -I/home/jesper/proj/mydroid/system/core/includeLOCAL_LDLIBS += -L/home/jesper/proj/mydroid/out/target/product/generic/system/libLOCAL_LDLIBS += -lmedia -llog
include $(BUILD_SHARED_LIBRARY)
LOCAL_LDLIBS += -L/mydroid/out/target/product/generic/system/lib
And so I still get an error when I try to add -lmedia like:LOCAL_LDLIBS += -lmedia -llog
Did you create that path yourself or am I missing something?
Here is my full Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := socket
LOCAL_SRC_FILES := socket.c
LOCAL_CPPFLAGS += -I/android_source/frameworks/base/include.
LOCAL_CPPFLAGS += -I/android_source/system/core/include
LOCAL_LDLIBS += -L/android_source/out/target/product/generic/system/lib
LOCAL_LDLIBS += -lmedia -llog
include $(BUILD_SHARED_LIBRARY)
And my source is located at
Can someone share me this code using private audio API?
thanks,
> >> android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr oups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/android-ndk?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "android-ndk" group.
> > To post to this group, send email to andro...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr oups.com>
Can someone share me this code using private audio API?
> >> --
>
> >> You received this message because you are subscribed to the Google Groups
> >> "android-ndk" group.
> >> To post to this group, send email to andro...@googlegroups.com.
> >> To unsubscribe from this group, send email to
I've made it clear in most of my posts that nothing I am asking will be used in any sort of commercial or end user application?
Did you change the way to play audio from native code? I cannot find
this code in scummvm 1.1.1
Thanks,
On Apr 16, 9:10 am, Angus Lees <al...@google.com> wrote:
> >> android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr oups.com>
> >> .
> >> For more options, visit this group at
> >>http://groups.google.com/group/android-ndk?hl=en.
>
> > --
> > You received this message because you are subscribed to the Google Groups
> > "android-ndk" group.
> > To post to this group, send email to andro...@googlegroups.com.
> > To unsubscribe from this group, send email to
> > android-ndk...@googlegroups.com<android-ndk%2Bunsubscribe@googlegr oups.com>
This calls into the (uninteresting) ScummVM_audioMixCallback native
function in http://scummvm.svn.sourceforge.net/viewvc/scummvm/scummvm/trunk/backends/platform/android/android.cpp?revision=52791&view=markup
There are no secrets here, this is just a (java) audio playing thread
that calls into a JNI function to get the next batch of audio data
(the JNI function decodes and mixes software midi, mp3 and vorbis but
that is all in ScummVM's core code). The Android Java API is designed
for simplicity rather than performance, but the latency seems ok for
my simple games.
I also encountered some bugs where audio_track.write() would not
necessarily block when the buffer was full, so you can see I detect
short writes and add my own Thread.sleep() to avoid spinning the CPU.
- Gus
Correct - Java is the only portable way to play audio on Android. I
gave some example C++ code much earlier in this thread (in the post
you first replied to) that works without Java on _some_ devices.
- Gus