How to use ScreenCap.cpp on my application? - android

Android Platform has an utility class that's used to take android screenshot . I copied "ScreenCap.cpp" in to JNI folder then build via NDK but failed. The NDK compiler didn't find needed libraries:
#include <binder/IMemory.h>
#include <gui/SurfaceComposerClient.h>
#include <SkImageEncoder.h>
#include <SkBitmap.h>
#include <SkData.h>
#include <SkStream.h>
Here is error log:
jni/ScreenCap.cpp:28:28: fatal error: SkImageEncoder.h: No such file or directory
compilation terminated.
Please tell me how to fix this.
BTW, Is there any solution to capture entire android screen programmatically? I need to capture it at least 10 times per second.
Thanks.

You forgot to include your SkImageEncoder.h into your Local_C_Include. Add this line into your Android.mk file
LOCAL_C_INCLUDES := PATH_TO_SKImageEncoder_HEADER

This question is quite old but I'll try to help just in case.
The problem is that SkImageEncoder.h is not part from NDK but from system's libskia library (not available in the NDK) and, then, should be build together with full system's build process.
If you want this application to run in single device, e.g. you personal device, you should be able to create a working binary by modifying your Android.mk file:
include $(CLEAR_VARS)
LOCAL_MODULE := system_libskia
LOCAL_SRC_FILES := PATH_TO_LIBSKIA/libskia.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := PATH_TO_SKIA_INCLUDE_FOLDER
LOCAL_SHARED_LIBRARIES := system_libskia
You can obtain your device's libskia.so by using running:
adb pull /system/lib/libskia.so
Another possible, but ugly, workaround would be loading libskia.so through dlopen and, then, read all needed symbols from it. This would work for any device as long as symbol's signature remains the same.
Hope this helps.

Related

Failure to build a project using NDK

I'm trying out NDK for the first time, and I'm stuck with building this project. I'm attempting to use the libraries used in Android's screencap recording program to read data from my screen. I understand that I need to use LibGUI, which I've pulled from my phone. Whenever I compile, however, I get this as an error message:
C:/Users/Kevin/Desktop/ScreenCapture//jni/main.cpp:2:34: fatal error: gui/ISurfaceComposer.h: No such file or directory
Which is odd, considering that I have libgui.so included.
What my main file looks like:
#include <stdio.h>
#include <gui/ISurfaceComposer.h>
int main() {
printf("Started!");
return 0;
}
What my Android.mk looks like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgui-prebuilt
LOCAL_SRC_FILES := libgui.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := screencapture
LOCAL_SRC_FILES := main.cpp
LOCAL_SHARED_LIBRARIES := libgui-prebuilt
include $(BUILD_EXECUTABLE)
And I have both the main file and libgui.so in the same folder.
main.cpp:2:34: fatal error: gui/ISurfaceComposer.h: No such file or directory
Your error message indicates that the compiler is unable to find a header file, but your attempted solution is to provide a shared object (.so) library from the phone.
Libraries might help at link time, but before you can link you must successfully compile, and to do that you are going to have to obtain the missing header (perhaps from AOSP sources, as source code it will not be found on the phone) or else recreate it by deducing its contents from clues you collect. Unfortunately, it often isn't possible to take just one internal header out of AOSP, as it will likely depend on many others.
Linking against private system internals also introduces a risk of your program breaking if the private interface between internal components changes between Android versions.
(Normally I would also mention that you are unlikely to be able to record a screen with the NDK in it's normal usage of making a shared library to link into an application process, however your Android.mk seems to indicate you are building an executable - that might work if you can succesfully build it and you run it as a user with sufficient permission such as adb's shell userid or using a root hack)
Add one line for module screencapture:
LOCAL_C_INCLUDES := $(LOCAL_PATH)/
If you haven't folder gui, you need to copy&paste includes headers *.h into folder jni/gui. Always such a requirement about using like that for ndk...
Or second case - using other location of this source for ldlibs:
LOCAL_LDLIBS := -L/full_path_to_source_gui/gui/

compiling non local files using NDK, Linker error

Many related questions have been asked regarding NDK linker errors, but I couldnt clearly found a solution to my situation.
I am trying to extend a sample NDK applicaiton, by adding 4 more local files of my own.
I am including them in the Android.mk file, and including the .h files appropriately.
Here is my Android.mk file.
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgl2jni
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := gl_code.cpp \
sglBandwidthBench.c \
sglBandwidth.c \
common.c \
timer.c
LOCAL_LDLIBS := -llog -lGLESv3 -lEGL
include $(BUILD_SHARED_LIBRARY)
and the .h files inclusion has been proper. but the compilation gives me undefined reference to function x.
I added the files sglBandwidthBench.c sglBandwidth.c common.c timer.c, none of them contain a main function, and the only link is through referecing one of those functions in gl_code.cpp.
how can I link these files together successfully? I couldnt think of any way of specifying it. Any help would be much appreciated.
As you may know, link errors on undefined references are due to one or more method's implemetation not being found by the build system inside the prebuit libraries you provided. So, bottom line, you are probably missing the shared library which contains the implementation for function x.
My advice would be to double-check if you actually have libGLESv3.so under any of your <ndk>\platforms\<android-api-level>\arch-arm\usr\lib directory. Alternatively, check <ndk>\docs\STABLE-APIS.html to see if all the libraries you're using are listed there. If one of them is not, you will either need to upgrade your NDK version or to manually add the missing library to your source code (for that, read section PREBUILT_SHARED_LIBRARY from <ndk>\docs\ANDROID-MK.html).
Hope that this helps!
EDIT: Hi Sai, from what I just learned from your comments, you are trying to call a method implemented in a .c file from inside a .cpp one. So you need to enclose the contents of your gl_code.cpp with the following piece of code:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif

Android NDK won't build library because Bitmap.h is missing?

I'm using the Android NDK to build a library. I had everything working well, but then I needed to change a package name which is referenced in the library. I tried to build the library again once I made the change, by calling ndk-build in its folder, but this is the only output I get and it does not seem to be fully building:
C:\my-app\jni>ndk-build -B
"Compile++ thumb : filters <= filters.cpp
C:/a-fa-outsidelands//jni/filters.cpp:4:28: fatal error: android/bitmap.h: No such file or directory
compilation terminated.
This then leads to an unsatisfied link error when I try to run the application. I'll post my .mk file, but I don't think that should matter because my previous library was working with this .mk file. I'm doing the rebuild (the -B parameter) because it is over a previous build. Any suggestions? Here's my .mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := filters
LOCAL_SRC_FILES := filters.cpp
LOCAL_LDLIBS := -lm -llog -ljnigraphics
include $(BUILD_SHARED_LIBRARY)
Thanks for the help.
What's the android:targetSdkVersion in the app's manifest? IIRC, bitmap.h was not introduced until SDK v8.
EDIT: Was the last successful build on the same machine, with the same NDK version? Does the #include line use <android/bitmap.h> as opposed to "android/bitmap.h"?
EDIT2: Did the targetSdkVersion change since the last build? I found a funny thing: there's no android-10 under android-ndk-xx\platforms. Try creating a blank android-10 folder under android-ndk-xx\platforms and copying the contents of android-9 there. I'm honestly not sure what else to check.
I got the same problem. Then I found this answer.
Android bitmap.h is not found for native code compile
Just ran:
ndk-build APP_PLATFORM=android-8

NDK in JAVA (building problems)

I am trying to connect Unity with simple Java android development and I actually succeeded to get to the part where I can import unity project to android and if needed start it up.
The problem I am facing at the moment is how to pass variables back and forth between those 2 platforms. I found some tutorials and they all suggest to use Android NDK. I am new in this field and got some problems while getting it to work.
I followed this tutorial and got stuck on building the application. I have my Android.mk file but when I run make (make app=ndk-demo) it throws an exception:
"make: *** No targets specified and no makefile found. Stop."
My Android.mk file looks like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ndk-demo
LOCAL_SRC_FILES := $(call all-subdir-java-files)
include $(BUILD_SHARED_LIBRARY)
I have 3 activities in my project, one .h and one .c files. I don't know whether I should include them or all-subdir-java-files does it for me.
In the answer to this question I've described step-by-step instructions how to make a native project. Hope this help you.

android ndk UnsatisfiedLinkError when using a prebuilt shared library

I'm trying to create a shared library that links to another shared library.
Here is my main module Android.mk:
TOP_LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)
LOCAL_PATH := $(TOP_LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION := cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include/ $(LOCAL_PATH)/lib/include
LOCAL_MODULE := SightCore-jni
LOCAL_SRC_FILES := SightDemo.cpp SightCore-jni.cpp
LOCAL_SHARED_LIBRARIES := SightAPI
LOCAL_LDLIBS = -llog
include $(BUILD_SHARED_LIBRARY)
I also have the prebuilt shared library in ./lib directory with its own Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := SightAPI
LOCAL_SRC_FILES := libSightAPI.so
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
The SightCore-jni.cpp source file is the jni interface to the shared library and is loaded using the command
System.loadLibrary("SightCore-jni");
During the ndk-build process I get no compilation or linkage errors.
When I try to run the application and access one of the native methods I get the UnsatsfiedLinkError.
I noticed that if disable the references to the SightAPI in my jni code and put a typo to the LOCAL_STATIC_LIBRARIES := SightAPI line, The build is successful and there is no UnsatisfiedLinkError.
This mean that the jni code I have is good (I'm actually sure it is ok...)
So the observation is as follows:
If I compile the shared library with the prebuilt shared library I get a corrupted .so file.
If I compile the same ndk project without linking to the prebuilt shared library there is no problem loading the shared library from the java side.
Please help me out if you can.
Thanks in advance,
Ita
Found the issue.
Apparently the ndk build system doesn't automatically load referenced shared libraries, even if they are declared in your Android.mk.
I had to call on System.loadLibrary(SightAPI) & System.loadLibrary("SightCore-jni") in order to solve this issue. I would have expected that the only library to load would have been the main library SightCore-jni.
Well..I guess the moral is If you want something done, do it yourself :)
+1 to Roy Samuel for his effort and correct instincts.
I hope this helps anyone.
Cheers
Have you made sure that the cpp function name, that you'd like to use over JNI, is corresponding to the package name of the Java wrapper class where System.loadLibrary("SightCore-jni"); is present?
e.g. If you would like to use the C function, myFunction in the java layer, and suppose your JNI wrapper class is in the package com.my.package.sightcore,
then your C code function name should be like this :
JNIEXPORT JNICALL Java_com_my_package_sightcore_myFunction(JNIEnv * env, jobject thiz, ...)
If you are running your app on your device,
See if the API levels, and hence, the sdk release matches to your device's android version (API level).
Hope this helps. Let me know if you need more clarifications...
This happened to me, and the solution for me was to make sure I was including the proper file libgnustl_shared.so and not libc++_shared.so after I switched compilers. So, just making sure either one of these files is the correct one for your build, and making sure it's been updated with the latest, you shouldn't get this issue any longer.

Categories

Resources