How to turn on/off native log cat in ndk at runtime - android

I use this snippet code to turn log on or off
#define DEBUG 1
#if DEBUG
#include <android/log.h>
#define LOG_TAG "native_log"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
#else
# define LOGD(...) do {} while (0) // do nothing
#endif
// use it
LOGD("%s : %d","value", val);
It worked fine by turn DEBUG flag on/off. The problem is I want to do it at run time in java side. What I want like this:
// java
private native void nativeSetDebug(boolean flag);
// jni
JNIEXPORT void JNICALL Java_com_my_package_Native_nativeSetDebug(JNIEnv *env, jobject thiz, jboolean flag){
// what should I do in this method?
}
Since the macros in c++ are replaced by the preprocessor by their value before source file even compiles, so I'm looking for another approach. Is there any ideas?

macro file
extern bool useDebug;
#include <android/log.h>
#define LOG_TAG "native_log"
#define LOGD(...) if(useDebug){__android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)}
C file
bool useDebug = true;
JNIEXPORT void JNICALL Java_com_my_package_Native_nativeSetDebug(JNIEnv *env, jobject thiz, jboolean flag){
useDebug = flag;
}
The extern is important, otherwise each file including the header will define its own variable and they won't be set correctly.

Related

How to get app package name or applicationId using JNI android

For the protection issue of the shared library I will try to get package name using JNI but it will give errors. So, is it possible to get package name or applicationId using JNI? If anyone have example or references for this problem then suggests. Because not any good tutorial or solution available. Else any other way suggest of the protection of the shared library.
Yes, it's possible. Android is based on Linux, we can obtain a lot of information in user space provided by kernel.
In your example, the information stored here /proc/${process_id}/cmdline
We can read this file, and get the application id.
See a simple example
#include <jni.h>
#include <unistd.h>
#include <android/log.h>
#include <stdio.h>
#define TAG "YOURAPPTAG"
extern "C"
JNIEXPORT void JNICALL
Java_com_x_y_MyNative_showApplicationId(JNIEnv *env, jclass type) {
pid_t pid = getpid();
__android_log_print(ANDROID_LOG_DEBUG, TAG, "process id %d\n", pid);
char path[64] = { 0 };
sprintf(path, "/proc/%d/cmdline", pid);
FILE *cmdline = fopen(path, "r");
if (cmdline) {
char application_id[64] = { 0 };
fread(application_id, sizeof(application_id), 1, cmdline);
__android_log_print(ANDROID_LOG_DEBUG, TAG, "application id %s\n", application_id);
fclose(cmdline);
}
}
This works for me:
static jstring get_package_name(
JNIEnv *env,
jobject jActivity
) {
jclass jActivity_class = env->GetObjectClass(jActivity);
jmethodID jMethod_id_pn = env->GetMethodID(
jActivity_class,
"getPackageName",
"()Ljava/lang/String;");
jstring package_name = (jstring) env->CallObjectMethod(
jActivity,
jMethod_id_pn);
return package_name;
}

Error base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}' when create NDK project

I create my first NDK project, that show some text on screen.
I use native method in class NativeLib in java and implement in a class in C.
But I received an error base operand of '->' has non-pointer type 'JNIEnv {aka _JNIEnv}
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#define DEBUG_TAG "MY_NDK_DEMO"
JNIEXPORT jstring JNICALL Java_com_example_helloworld_NativeLib_helloWorld
(JNIEnv * env, jobject obj) {
return (*env)->NewStringUTF("Hello World JNI!");
}
try return env->NewStringUTF("Hello World JNI!");
c++ is different from c
so to make it work
use
env->NewStringUTF("Hy");

Problems with JNI and C++

I did an Opencv's application en windows and now I am using JNI to convert this code to Android but I am having some problems.
In concrete my native code not do nothing.
This is my Java class where I define my native methods:
package com.example.telo3;
import org.opencv.core.Mat;
public class Process {
static {
System.loadLibrary("nativo");
}
public Process(){
dir=inicializar_nativo();
}
public void Procesar(Mat framedetect, Mat framedraw){
procesar_nativo(dir,framedetect.getNativeObjAddr(),framedraw.getNativeObjAddr());
}
private long dir;
private static native long inicializar_nativo();
private static native void procesar_nativo(long thiz, long framedetect, long framedraw);
}
This is my JNI code:
#include "nativo.h"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <stdio.h>
#include "FaceDetector.h"
#include "Draw.h"
#include "Almacena.h"
#include "Runnable.h"
using namespace std;
using namespace cv;
#include <android/log.h>
#define LOG_TAG "NATIVO"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
struct variables {
Almacena almacena;
Draw draw;
FaceDetector face_detector;
};
JNIEXPORT jlong JNICALL Java_com_example_telo3_Process_inicializar_1nativo(
JNIEnv *, jobject) {
long dir = (long) new variables();
return (dir);
}
JNIEXPORT void JNICALL Java_com_example_telo3_Process_procesar_1nativo(JNIEnv *,
jobject, jlong dir, jlong framedetect, jlong framedraw) {
Mat* telo =(Mat*)framedetect;
Mat* telo2= (Mat*)framedraw;
((variables*)dir)->almacena = ((variables*)dir)->face_detector.Detect(*telo);
//almacena = face_detector.Detect(frame_gray);
((variables*)dir)->draw.Dibujar(*telo2,((variables*)dir)->almacena);
//frame_capturado = draw.Dibujar(frame_capturado, almacena);
if( (((variables*)dir)->almacena.get_faces()).size() ==0){
LOGD("no detecto caras");
}
}
I think that I use the Jni correctly but the function Detect not works correctly because when I uses this if return 0.
Looks like a simple typo for me.
Your package is "com.example.telo3"
Your class is "Process"
Your function is "inicializar_nativo()"
So the c++ function has to be declared as
JNIEXPORT jlong JNICALL Java_com_example_telo3_Process_inicializar_nativo(...)
You have declared it as
JNIEXPORT jlong JNICALL Java_com_example_telo3_Process_inicializar_1nativo(...)
Did you get an unsatisfied link exception or such?

JNI, C++ problems

I did an Opencv's application en windows and now I am using JNI to convert this code to Android but I am having some problems.
In concrete my native code not do nothing.
This is my Java class where I define my native methods:
package com.example.telo3;
import org.opencv.core.Mat;
public class Process {
static {
System.loadLibrary("nativo");
}
public Process(){
dir=inicializar_nativo();
}
public void Procesar(Mat framedetect, Mat framedraw){
procesar_nativo(dir,framedetect.getNativeObjAddr(),framedraw.getNativeObjAddr());
}
private long dir;
private static native long inicializar_nativo();
private static native void procesar_nativo(long thiz, long framedetect, long framedraw);
}
This is my JNI code:
#include "nativo.h"
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "opencv2/video/tracking.hpp"
#include <iostream>
#include <stdio.h>
#include "FaceDetector.h"
#include "Draw.h"
#include "Almacena.h"
#include "Runnable.h"
using namespace std;
using namespace cv;
#include <android/log.h>
#define LOG_TAG "NATIVO"
#define LOGD(...) ((void)__android_log_print(ANDROID_LOG_DEBUG, LOG_TAG, __VA_ARGS__))
struct variables {
Almacena almacena;
Draw draw;
FaceDetector face_detector;
};
JNIEXPORT jlong JNICALL Java_com_example_telo3_Process_inicializar_1nativo(
JNIEnv *, jobject) {
long dir = (long) new variables();
return (dir);
}
JNIEXPORT void JNICALL Java_com_example_telo3_Process_procesar_1nativo(JNIEnv *,
jobject, jlong dir, jlong framedetect, jlong framedraw) {
Mat* telo =(Mat*)framedetect;
Mat* telo2= (Mat*)framedraw;
((variables*)dir)->almacena = ((variables*)dir)->face_detector.Detect(*telo);
//almacena = face_detector.Detect(frame_gray);
((variables*)dir)->draw.Dibujar(*telo2,((variables*)dir)->almacena);
//frame_capturado = draw.Dibujar(frame_capturado, almacena);
if( (((variables*)dir)->almacena.get_faces()).size() ==0){
LOGD("no detecto caras");
}
}
I think that I use the Jni correctly but the function Detect not works correctly because when I uses this if return 0.
Is framedetect 0? I made a test app based on this and it worked fine (that is, the jlong was converted to and from just fine, so that shouldn't be the issue).
Try catching the error with ndk-gdb to better understand the problem. Attaching it to the process might a problem though if it crashes straight away, in that case I like to put breakpoint on the java side before the crash, make the execution pause there using the debugger, attach ndk-gdb and continue let the java process continue.
Also I recommend using reinterpret_cast<jlong> and reinterpret_cast<variables*> instead of the C style casts, and save that cast to a separate variable to avoid casting all the time! cleaner code!

android ndk (opencv)

I got a crash when i call my native functions in my android application here is my code :
lib libo=new lib();
public void onPreviewFrame(byte[] data, Camera camera)
{
int s;// where w and h are width and height are the parameters of the camera
s=libo.getdata(data);/: and getdata is my native function
}
my getdata.c :
#include "getdata.h"
JNIEXPORT int JNICALL JAVA_android_video8_libo_som
(JNIEnv* env, jobject obj,jbyte* data)
{
return (data[1]);
}
getdata.h :
#include <jni.h>
#ifndef _Included_android_video8_lib
#define _Included_android_video8_lib
#ifdef __cplusplus
extern "C" {
#endif
JNIEXPORT int JNICALL JAVA_android_video8_libo_som(JNIEnv* env, jobject obj, jbyte*);
#ifdef __cplusplus
}
#endif
#endif
Android.mk :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := opcv
LOCAL_SRC_FILES := getdata.c
include $(BUILD_SHARED_LIBRARY)
and the class where i call the lib :
package android.video8;
public class libo {
static {
System.loadLibrary("opcv");
}
public native static int som(int s);
}
the library is generated without a problem but the exécution of the apps give me a crash
i don't no where ehe error is
thanks
Seems there're some errors in your question. Anyway, you're using wrong prototypes for JNI functions. You should use these signatures:
JNIEXPORT
jint JNICALL JAVA_android_video8_libo_getData(JNIEnv*, jclass, jbyteArray);
JNIEXPORT
jint JNICALL JAVA_android_video8_libo_som(JNIEnv*, jclass, jint);
And use javah tool every time you change native method's prototype.

Categories

Resources