# 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
http://dev.re.kr/72
)
// 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);