안드로이드를 개발할 때 Framework나 NDK 상에서 앱으로 Intent를 보내고 싶을 경우가 있습니다.
아시다시피 정식으로는 Intent는 Java 영역에서만 보낼 수 있다고 하는데요.
아래와 같이 시스템 커멘드를 이용해서 C 코드 상에서도 Intent를 보낼 수 있는 방법이 있을 것 같습니다.
아니면 C에서 JNI로 자바를 콜백하는 구조로 만들어도 될 것 같습니다.
아래 소스 코드를 참조하세요.
잘안되시면 아래 커맨드 예제에서 --user 0 옵션을 빼거나 추가해보세요.
char cmdbuffer[1024] = {0};
const char *cmd = "am startservice --user 0 -a %s --ei ars_flag 2 --ei invitationType %d --ei mode 1 --es ars_gadget_uuid \"%s\" --ei ars_conn_handle %d --es ars_user_uuid \"%s\" --es ars_username \"%s\"";
sprintf(cmdbuffer, cmd,...);
system(cmdbuffer);
좀더 전문가스러운 방법도 있네요.
class cIntent
{
jclass m_intentClass;
jmethodID m_intentConstructorMethodId;
jmethodID m_intentSetActionMethodId;
jobject m_contextObj;
jmethodID m_sendBroadcastMethodId;
bool m_bIntentEnd;
jobject createNewIntent(char* intentType,Engine*e_pEngine)
{
jstring intentString = e_pEngine->mApp->appThreadEnv->NewStringUTF(intentType);
jobject intentObject = e_pEngine->mApp->appThreadEnv->NewObject(m_intentClass,m_intentConstructorMethodId);
//call intent
e_pEngine->mApp->appThreadEnv->CallVoidMethod(intentObject, m_intentSetActionMethodId, intentString);
return intentObject;
}
//to contenxt
void sendBroadcast(jobject intentObject,Engine*e_pEngine)
{
//LOG_INFO("Broadcasting intent..");
e_pEngine->mApp->appThreadEnv->CallVoidMethod(m_contextObj,m_sendBroadcastMethodId, intentObject);
//LOG_INFO("Intent broadcasted");
}
public:
cIntent()
{
m_intentClass = 0;
m_intentConstructorMethodId = 0;
m_intentSetActionMethodId = 0;
m_contextObj = 0;
m_sendBroadcastMethodId = 0;
m_bIntentEnd = true;
}
~cIntent();
bool Init(Engine*e_pEngine)
{
m_bIntentEnd = true;
jclass activityClass = e_pEngine->mApp->appThreadEnv->GetObjectClass(e_pEngine->mApp->appThreadThis);
jmethodID appGetContextId = e_pEngine->mApp->appThreadEnv->GetMethodID(activityClass, "getApplicationContext", "()Landroid/content/Context;");
if(appGetContextId == 0)
return false;
m_contextObj = e_pEngine->mApp->appThreadEnv->CallObjectMethod(e_pEngine->mApp->appThreadThis, appGetContextId);
if(m_contextObj == 0)
return false;
jclass contextClass = e_pEngine->mApp->appThreadEnv->FindClass("android/content/Context");
if(contextClass == 0)
return false;
jmethodID sendBroadcastMethodId = e_pEngine->mApp->appThreadEnv->GetMethodID(contextClass, "sendBroadcast", "(Landroid/content/Intent;)V");
if(sendBroadcastMethodId == 0)
return false;
m_intentClass = e_pEngine->mApp->appThreadEnv->FindClass("android/content/Intent");
if(m_intentClass == 0)
return false;
m_intentConstructorMethodId = e_pEngine->mApp->appThreadEnv->GetMethodID(m_intentClass, "<init>", "()V");
if(m_intentConstructorMethodId == 0)
return false;
m_intentSetActionMethodId = e_pEngine->mApp->appThreadEnv->GetMethodID(m_intentClass, "setAction", "(Ljava/lang/String;)Landroid/content/Intent;");
if( m_intentSetActionMethodId == 0)
return false;
return true;
}
//char* intent = "com.example.TEST";
void IntentGo(char*e_strMessage,Engine*e_pEngine)
{
m_bIntentEnd = false;
char* intent = e_strMessage;
jobject l_jobject = createNewIntent(intent,e_pEngine);
sendBroadcast(l_jobject ,e_pEngine );
//e_pEngine->mApp->appThreadEnv->DeleteGlobalRef
m_bIntentEnd = true;
}
};