# cd <SDK-directory> # 반드시 해당 SDK디렉토리에서 실행해주어야 정상적인 SDK update가 수행됨. # ./tools/android update sdk --no-ui
#include <android/native_activity.h> #if defined(__cplusplus) extern "C" { #endif void ANativeActivity_onCreate(ANativeActivity *s_native_activity, void *s_saved_state, size_t s_saved_state_size); #if defined(__cplusplus) } #endif void ANativeActivity_onCreate(ANativeActivity *s_native_activity, void *s_saved_state, size_t s_saved_state_size) { /* ... */ }
# include <EGL/egl.h> # include <GLES/gl.h> # include <android/native_activity.h> # include <android/log.h> # include <android/looper.h> # include <android/sensor.h> # include <android/configuration.h> # include <android_native_app_glue.h> struct saved_state { /* ... */ }; struct engine { struct android_app* app; ASensorManager* sensorManager; const ASensor* accelerometerSensor; ASensorEventQueue* sensorEventQueue; /* .... */ }; #if defined(__cplusplus) extern "C" { #endif void android_main(struct android_app *s_app); #if defined(__cplusplus) } #endif void android_main(struct android_app *s_app) { struct engine s_engine; app_dummy(); /* static library를 현재의 shared object 에 link 시에 링크가 생략될 수 있기 때문에 이를 방지하는 차원에서 그냥 호출 */ (void)memset((void *)(&s_engine), 0, sizeof(s_engine)); s_app->userData = &s_engine; s_app->onAppCmd = <handler>; s_app->onInputEvent = <handler>; /* ... */ s_engine.app = s_app; /* ... */ for(;;) { int s_ident; int s_events; struct android_poll_source *s_source; for(;;) { s_ident = ALooper_pollAll(0 /* 0 or (-1) */, NULL, &s_events, (void *)(&s_source)); if(s_ident < 0) { break; } if(s_ident == LOOPER_ID_USER) { /* ... */ } if(s_app->destroyRequested != 0) { return; } } } }
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.minzkn.pgl.hwport" android:versionCode="1" android:versionName="1.0"> <uses-sdk android:minSdkVersion="9" /> <!-- Tell the system this app requires OpenGL ES 1.0. --> <uses-feature android:glEsVersion="0x00010000" android:required="true" /> <application android:label="@string/app_name" android:hasCode="false"> <activity android:name="android.app.NativeActivity" android:label="@string/app_name"> <meta-data android:name="android.app.lib_name" android:value="hwport_activity" /> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
LOCAL_PATH:=$(call my-dir) # ---- def_hwport_cflags:=-Wall# def_hwport_cflags+=-W# def_hwport_cflags+=-Wshadow# def_hwport_cflags+=-Wcast-qual# def_hwport_cflags+=-Wcast-align# def_hwport_cflags+=-Wpointer-arith# def_hwport_cflags+=-Wbad-function-cast# def_hwport_cflags+=-Wstrict-prototypes# def_hwport_cflags+=-Wmissing-prototypes# def_hwport_cflags+=-Wmissing-declarations# def_hwport_cflags+=-Wnested-externs# def_hwport_cflags+=-Winline# def_hwport_cflags+=-Wwrite-strings# def_hwport_cflags+=-Wchar-subscripts# def_hwport_cflags+=-Wformat# def_hwport_cflags+=-Wformat-security# def_hwport_cflags+=-Wimplicit# def_hwport_cflags+=-Wmain# def_hwport_cflags+=-Wmissing-braces# def_hwport_cflags+=-Wnested-externs# def_hwport_cflags+=-Wparentheses# def_hwport_cflags+=-Wredundant-decls# def_hwport_cflags+=-Wreturn-type# def_hwport_cflags+=-Wsequence-point# def_hwport_cflags+=-Wsign-compare# def_hwport_cflags+=-Wswitch# def_hwport_cflags+=-Wuninitialized# def_hwport_cflags+=-Wunknown-pragmas# def_hwport_cflags+=-Wcomment# def_hwport_cflags+=-Wundef# def_hwport_cflags+=-Wunused# def_hwport_cflags+=-Wstrict-aliasing# #def_hwport_cflags+=-Wunreachable-code# def_hwport_cflags+=-Wconversion# #def_hwport_cflags+=-Wpadded# def_hwport_cflags+=-D_REENTRANT# Thread-Safe 를 위한 def_hwport_cflags+=-D_LARGEFILE_SOURCE -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -D_LFS64_LARGEFILE=1# 대용량 파일을 다루기 위한 def_hwport_cflags+=-U_FORTIFY_SOURCE -D_FORTIFY_SOURCE=0# libc 호환성을 높이기 위한... def_hwport_c_includes:=$(LOCAL_PATH)/include# def_hwport_ldlibs:=-ldl -llog -landroid# 대부분 이정도 링크는 해줘야 함. def_hwport_ldlibs+=-lEGL -lGLESv3# OpenGL ES library link #def_hwport_ldlibs+=-ljnigraphics# JNI graphics 방식을 사용하는 경우 필요 # ---- include $(CLEAR_VARS) LOCAL_MODULE:=gbox_shared# LOCAL_CFLAGS:=$(def_hwport_cflags)# LOCAL_C_INCLUDES:=$(def_hwport_c_includes)# LOCAL_SRC_FILES:=$(abspath $(wildcard $(LOCAL_PATH)/source.gbox/main.c))# LOCAL_LDLIBS:=$(def_hwport_ldlibs)# LOCAL_SHARED_LIBRARIES:=gbox hwport_pgl# include $(BUILD_EXECUTABLE) # ---- include $(CLEAR_VARS) LOCAL_MODULE:=gbox_static# LOCAL_CFLAGS:=$(def_hwport_cflags)# LOCAL_C_INCLUDES:=$(def_hwport_c_includes)# LOCAL_SRC_FILES:=$(abspath $(wildcard $(LOCAL_PATH)/source/*.c $(LOCAL_PATH)/source.gbox/*.c))# LOCAL_LDLIBS:=$(def_hwport_ldlibs)# include $(BUILD_EXECUTABLE) # ---- include $(CLEAR_VARS) LOCAL_MODULE:=gbox_activity# LOCAL_CFLAGS:=-Ddef_hwport_android_native_activity_module_name='"gbox"' $(def_hwport_cflags)# LOCAL_C_INCLUDES:=$(def_hwport_c_includes)# LOCAL_SRC_FILES:=$(abspath $(wildcard $(LOCAL_PATH)/source.gbox/main.c))# LOCAL_LDLIBS:=$(def_hwport_ldlibs)# include $(BUILD_SHARED_LIBRARY) # ---- include $(CLEAR_VARS) LOCAL_MODULE:=gbox# LOCAL_CFLAGS:=-Ddef_hwport_android_native_activity_main=1 $(def_hwport_cflags)# LOCAL_C_INCLUDES+=$(def_hwport_c_includes)# LOCAL_SRC_FILES:=$(abspath $(filter-out $(LOCAL_PATH)/source.gbox/main.c,$(wildcard $(LOCAL_PATH)/source.gbox/*.c)))# LOCAL_LDLIBS:=$(def_hwport_ldlibs)# LOCAL_SHARED_LIBRARIES:=hwport_pgl# LOCAL_STATIC_LIBRARIES:=android_native_app_glue# include $(BUILD_SHARED_LIBRARY) # ---- include $(CLEAR_VARS) LOCAL_MODULE:=hwport_pgl# LOCAL_CFLAGS:=$(def_hwport_cflags)# LOCAL_C_INCLUDES:=$(def_hwport_c_includes)# LOCAL_SRC_FILES:=$(abspath $(wildcard $(LOCAL_PATH)/source/*.c))# LOCAL_LDLIBS:=$(def_hwport_ldlibs)# include $(BUILD_SHARED_LIBRARY) # ---- $(call import-module,android/native_app_glue) # ---- # End of Android.mk
// Context 를 인자값을 받아서 Signature 의 값을 얻는다. char* getSignaiture(JNIEnv *env, jobject context) { jstring packageName; jobject packageManagerObj; jobject packageInfoObj; jclass contextClass = env->GetObjectClass( context); jmethodID getPackageNameMid = env->GetMethodID( contextClass, "getPackageName", "()Ljava/lang/String;"); jmethodID getPackageManager = env->GetMethodID( contextClass, "getPackageManager", "()Landroid/content/pm/PackageManager;"); jclass packageManagerClass = env->FindClass("android/content/pm/PackageManager"); jmethodID getPackageInfo = env->GetMethodID( packageManagerClass, "getPackageInfo", "(Ljava/lang/String;I)Landroid/content/pm/PackageInfo;"); jclass packageInfoClass = env->FindClass("android/content/pm/PackageInfo"); jfieldID signaturesFid = env->GetFieldID( packageInfoClass, "signatures", "[Landroid/content/pm/Signature;"); jclass signatureClass = env->FindClass("android/content/pm/Signature"); jmethodID signatureToByteArrayMid = env->GetMethodID( signatureClass, "toByteArray", "()[B"); jclass messageDigestClass = env->FindClass("java/security/MessageDigest"); jmethodID messageDigestUpdateMid = env->GetMethodID( messageDigestClass, "update", "([B)V"); jmethodID getMessageDigestInstanceMid = env->GetStaticMethodID( messageDigestClass, "getInstance", "(Ljava/lang/String;)Ljava/security/MessageDigest;"); jmethodID digestMid = env->GetMethodID( messageDigestClass,"digest", "()[B"); jclass base64Class = env->FindClass("android/util/Base64"); jmethodID encodeToStringMid = env->GetStaticMethodID( base64Class,"encodeToString", "([BI)Ljava/lang/String;"); packageName = (jstring)env->CallObjectMethod( context, getPackageNameMid); packageManagerObj = env->CallObjectMethod(context, getPackageManager); // PackageManager.GET_SIGNATURES = 0x40 packageInfoObj = env->CallObjectMethod( packageManagerObj,getPackageInfo, packageName, 0x40); jobjectArray signatures = (jobjectArray)env->GetObjectField( packageInfoObj, signaturesFid); //int signatureLength = env->GetArrayLength(signatures); jobject signatureObj = env->GetObjectArrayElement(signatures, 0); jobject messageDigestObj = env->CallStaticObjectMethod(messageDigestClass, getMessageDigestInstanceMid, env->NewStringUTF("SHA1")); env->CallVoidMethod(messageDigestObj, messageDigestUpdateMid, env->CallObjectMethod( signatureObj,signatureToByteArrayMid)); // Base64.DEFAULT = 0 그렇기 때문에 맨 마지막 인자값은 0이다. jstring signatureHash = (jstring)env->CallStaticObjectMethod( base64Class, encodeToStringMid,env->CallObjectMethod( messageDigestObj, digestMid, signatureObj), 0); return (char*)env->GetStringUTFChars(signatureHash,0); }
/* Copyright (C) JAEHYUK CHO All rights reserved. Code by JaeHyuk Cho <mailto:minzkn@minzkn.com> */ Atom s_atom; hwport_uint32_t s_value[4]; s_value[0] = (hwport_uint32_t)0xa0000000u; /* 0x00000000u ~ 0xffffffffu */ s_atom = XInternAtom(s_xlib_demo->m_display, "_NET_WM_WINDOW_OPACITY", False); (void)XChangeProperty( s_xlib_demo->m_display, s_xlib_demo->m_window[hwport_xlib_demo_background_window], s_atom, XA_CARDINAL, (int)(sizeof(s_value[0]) << 3), PropModeReplace, (const unsigned char *)(&s_value[0]), 1); XSync(s_xlib_demo->m_display, False);