Recently, there was a need to get the MAC address of the Android device on the JNI layer. Google circled it and did not see the implementation method. So I had to write it myself.
The basic idea is to call the android Java-layer API through JNI to obtain the MAC address of wifi. Theoretically, all JavaCodeCan be translated into JNI code, so it can be implemented.
First, let's take a look at the Java implementation code obtained from the MAC address:
PublicString getlocalmacaddress (context ){
Wifimanager WiFi = (wifimanager) Context. getsystemservice (context. wifi_service );
Wifiinfo info = wifi. getconnectioninfo ();
ReturnInfo. getmacaddress ();
}
The code is quite simple. There are only two objects: wifimanager and wifiinfo. Therefore, it is not complicated to translate this into JNI code.
Obtain the wifimanager object in JNI first:
/*
* Get the wifimanager object
* Parameter: jctxobj is the context object.
*/
Jobject getwifimanagerobj (jnienv * ENV, jclass clz, jobject jctxobj)
{
Logi ( "Gotwifimangerobj" );
// Obtain the value of context. wifi_service
// Jstring jstr_wifi_serveice = env-> newstringutf ("WiFi ");
Jclass jctxclz = env-> findclass ( "Android/content/context" );
Jfieldid fid_wifi_service = env-> getstaticfieldid (jctxclz, "Wifi_service" ,"Ljava/lang/string ;" );
Jstring jstr_wifi_serveice = (jstring) ENV-> getstaticobjectfield (jctxclz, fid_wifi_service );
Jclass jclz = env-> getobjectclass (jctxobj );
Jmethodid mid_getsystemservice = env-> getmethodid (jclz, "Getsystemservice" , "(Ljava/lang/string;) ljava/lang/object ;" );
Jobject wifimanager = env-> callobjectmethod (jctxobj, mid_getsystemservice, jstr_wifi_serveice );
// Because jclass inherits from jobject, it needs to be released;
// Jfieldid and jmethodid are memory addresses, which are not allocated in our code and do not need to be released.
Env-> deletelocalref (jctxclz );
Env-> deletelocalref (jclz );
Env-> deletelocalref (jstr_wifi_serveice );
Return Wifimanager;
}
Then, get the wifiinfo object:
/*
* Get the wifiinfo object
* Parameter: wifimgrobj is a wifimanager object.
*/
Jobject getwifiinfoobj (jnienv * ENV, jobject wifimgrobj)
{
Logi ("Getwifiinfoobj");
If(Wifimgrobj = NULL ){
ReturnNULL;
}
Jclass jclz = env-> getobjectclass (wifimgrobj );
Jmethodid mid = env-> getmethodid (jclz,"Getconnectioninfo","() Landroid/NET/WiFi/wifiinfo ;");
Jobject wifiinfo = env-> callobjectmethod (wifimgrobj, mid );
Env-> deletelocalref (jclz );
ReturnWifiinfo;
}
Now the last step is only needed. Call the getmacaddress () method of wifiinfo:
/*
* Obtain the MAC address
* Parameter: wifiinfoobj, wifiinfo object
*/
Char * Getmacaddress (jnienv * ENV, jobject wifiinfoobj)
{
Logi ( "Getmacaddress ...." );
If (Wifiinfoobj = NULL ){
Return NULL;
}
Jclass jclz = env-> getobjectclass (wifiinfoobj );
Jmethodid mid = env-> getmethodid (jclz, "Getmacaddress" , "() Ljava/lang/string ;" );
Jstring jstr_mac = (jstring) ENV-> callobjectmethod (wifiinfoobj, mid );
If (Jstr_mac = NULL ){
Env-> deletelocalref (jclz );
Return NULL;
}
Const Char * TMP = env-> getstringutfchars (jstr_mac, null );
Char * MAC = (Char *) Malloc (strlen (TMP) + 1 );
Memcpy (MAC, TMP, strlen (TMP) + 1 );
Env-> releasestringutfchars (jstr_mac, TMP );
Env-> deletelocalref (jclz );
Return Mac;
}
You only need to concatenate these three processes.
Jobject wifimanagerobj = getwifimanagerobj (ENV, clz, jctxobj );
Jobject wifiinfoobj = getwifiinfoobj (ENV, wifimanagerobj );
Char * MAC = getmacaddress (ENV, wifiinfoobj );
Complete source code:
Http://download.csdn.net/detail/niosm/4409938