In the final analysis, the Java Layer Service is the encapsulation of the C + + layer binder, so it is entirely possible, in principle, to access the service of the Android framework layer directly through C + + code, this article takes a visit to Wifiservice as an example, Explain how to implement this function.
Crap less, directly on the code:
WifiTest.cpp
#include <sys/types.h> #include <unistd.h> #include <grp.h> #include <binder/ipcthreadstate.h > #include <binder/ProcessState.h> #include <binder/IServiceManager.h> #include <utils/log.h># Include <utils/string16.h>//#include <utils/Vector.h> #include <utils/List.h> #include <utils/ Propertymap.h>using namespace Android, #define WIFI_SERVICE "WIFI" Const STRING16 wifi_descriptor (" Android.net.wifi.IWifiManager "), Class scanresult{private:scanresult& operator= (const scanresult& o);p ublic : Scanresult (const scanresult& O): Mssid (O.mssid), Mbssid (O.mbssid), Mcaps (O.mcaps), Mlevel (o.mlevel), MFrequenc Y (o.mfrequency), Mtimestamp (O.mtimestamp) {} scanresult (String8 ssid,string16 bssid,string16 caps,int level,int F req,int64_t timeStamp): Mssid (SSID), Mbssid (BSSID), mcaps (Caps), mlevel (level), Mfrequency (Freq), Mtimestamp ( TimeStamp) {} void Dump () {char temp[130]; int size; MeMset (temp,0,sizeof (temp)); printf ("SSID%s \ n", mssid.string ()); Size = Mbssid.size (); if (Size > sizeof (temp)/2-1) {size = sizeof (temp)/2-1; } Utf16_to_utf8 (Mbssid.string (), size, temp); printf ("Bssid%s \ n", temp); Size = Mcaps.size (); if (Size > sizeof (temp)/2-1) {size = sizeof (temp)/2-1; } Utf16_to_utf8 (Mcaps.string (), size, temp); printf ("SSID%s \ n", temp); printf ("Level%d \ n", mlevel); printf ("Freq%d \ n", mfrequency); printf ("Freq%ld \ n", Mtimestamp); }private:string8 Mssid; String16 Mbssid; String16 Mcaps; int mlevel; int mfrequency; int64_t Mtimestamp;}; Class Iwifiservice:public Android::iinterface {public:declare_meta_interface (wifiservice) virtual void STA Rtscan (int forceactive) = 0; virtual int getscanresults (list<scanresult> &list) = 0; virtual BOOL Setwifienabled (boolenable) = 0;}; Class Bpwifiservice:public android::bpinterface<iwifiservice>{enum {first_call_transaction = 1, Transaction_getconfigurednetworks = (android::ibinder::first_call_transaction + 0), Transaction_addorupdatenetwo RK = (android::ibinder::first_call_transaction + 1), Transaction_removenetwork = (Android::ibinder::first_call_tran Saction + 2), Transaction_enablenetwork = (android::ibinder::first_call_transaction + 3), transaction_disabl Enetwork = (android::ibinder::first_call_transaction + 4), transaction_pingsupplicant = (Android::ibinder::first_ca Ll_transaction + 5), Transaction_startscan = (android::ibinder::first_call_transaction + 6), TRANSACTION_get Scanresults = (android::ibinder::first_call_transaction + 7), Transaction_disconnect = (android::ibinder::first_cal L_transaction + 8), Transaction_reconnect = (android::ibinder::first_call_transaction + 9), Transaction_reas Sociate =(Android::ibinder::first_call_transaction +), Transaction_getconnectioninfo = (Android::ibinder::first_call_tran Saction + one), transaction_setwifienabled = (android::ibinder::first_call_transaction +), Transaction_get Wifienabledstate = (android::ibinder::first_call_transaction +), Transaction_setcountrycode = (android::IBinder: : First_call_transaction + +), Transaction_setfrequencyband = (android::ibinder::first_call_transaction + 15), Transaction_getfrequencyband = (android::ibinder::first_call_transaction + +), transaction_isdualbandsupported = (android::ibinder::first_call_transaction + +), Transaction_saveconfiguration = (android::ibinder::first_call_tr Ansaction + +), Transaction_getdhcpinfo = (android::ibinder::first_call_transaction + +), Transaction_acqu Irewifilock = (android::ibinder::first_call_transaction +), Transaction_updatewifilockworksource = (android::IBi Nder::first_call_transaction +), Transaction_releasewifilock = (android::ibinder::first_call_transaction +), Transaction_initi Alizemulticastfiltering = (android::ibinder::first_call_transaction +), transaction_ismulticastenabled = (androi D::ibinder::first_call_transaction +), Transaction_acquiremulticastlock = (android::ibinder::first_call_transact ION +), Transaction_releasemulticastlock = (android::ibinder::first_call_transaction +), transaction_s etwifiapenabled = (android::ibinder::first_call_transaction +), Transaction_getwifiapenabledstate = (Android::IB Inder::first_call_transaction +), transaction_getwifiapconfiguration = (android::ibinder::first_call_transaction +), Transaction_setwifiapconfiguration = (android::ibinder::first_call_transaction +), Transaction_st Artwifi = (android::ibinder::first_call_transaction +), Transaction_stopwifi = (Android::ibinder::first_call_tra Nsaction + +), TRansaction_addtoblacklist = (android::ibinder::first_call_transaction +), Transaction_clearblacklist = (android: : Ibinder::first_call_transaction +), Transaction_getwifiservicemessenger = (Android::ibinder::first_call_transac tion + +), Transaction_getwifistatemachinemessenger = (android::ibinder::first_call_transaction + +), TRAN Saction_getconfigfile = (android::ibinder::first_call_transaction + notoginseng), Transaction_captiveportalcheckcomplete = ( Android::ibinder::first_call_transaction + +),};p ublic:bpwifiservice (const ANDROID::SP<ANDROID::IBINDER> ;& impl): android::bpinterface<iwifiservice> (impl) {} void Startscan (int forceactive) {android::P arcel data, reply; Data.writeinterfacetoken (Wifi_descriptor); if (forceactive) {data.writeint32 (1); } else {data.writeint32 (0); } Remote ()->transact (Transaction_startscan, data, &reply, 0); } virtual int getscanresults (list<scanresult> &list) {Parcel data, reply; Data.writeinterfacetoken (Wifi_descriptor); Remote ()->transact (transaction_getscanresults, data, &reply, 0); if (0! = Reply.readexceptioncode ()) {return 0; } int count = Reply.readint32 (); for (int i=0;i<count;i++) {String8 SSID; int res = Reply.readint32 (); if (res! = 0) {reply.readint32 (); Reply.readint32 (); int length = Reply.readint32 (); SSID = String8 ((const char*) reply.readinplace (length), length); }//Utf16_to_utf8 (const char16_t* SRC, size_t src_len, char* DST); String16 BSSID = Reply.readstring16 (); String16 caps = Reply.readstring16 (); int level = Reply.readint32 (); int frequency = Reply.readint32 (); int64_t timestamp = Reply.readint64 (); Scanresult result (Ssid,bssid,caps,level,frequency,timestamp); List.push_back (result); } return count; } bool Setwifienabled (bool enable) {Parcel data, reply; Data.writeinterfacetoken (Wifi_descriptor); if (enable) Data.writeint32 (1); else Data.writeint32 (0); Remote ()->transact (transaction_setwifienabled, data,&reply,0); Reply.readexceptioncode (); return 0!=reply.readint32 (); }};implement_meta_interface (Wifiservice, wifi_descriptor) int main (int argc, char *argv[]) {android::sp<android::i servicemanager> sm = android::d Efaultservicemanager (); Android::sp<android::ibinder> Binder; Android::sp<iwifiservice> WiFi; Binder = Sm->getservice (Android::string16 (Wifi_service)); if (binder = = 0) {return 1; WiFi = android::interface_cast<iwifiservice> (binder); Wifi->setwifienabled (True);p rintf ("+++++scan start"); Wifi->startscan (1); for (int i=0;i<10;i++) {usleep (1* 1000*1000); list<scanresult> list;wifi->getscanresults (list); if (list.size () > 0) {for (list<scanresult>::i Terator it = List.begin (); It! = List.end (); ++it) {(*it). dump (); } break; }} return (0);}
The basic idea is simple:
First Pass:
Android::d Efaultservicemanager ()->getservice (Android::string16 (Wifi_service));
Obtain binder interface, and then through parcel read with binder, concrete implementation can refer to Iwifimanager.java code.
Running the above code after compiling can get output similar to the following:
SSID Wifitest
Bssid b8:55:10:84:13:57
SSID [Wpa-psk-ccmp][wpa2-psk-ccmp][wps][ess]
Level-55
Freq 2447
Time Stamp 1073922473
SSID Test
Bssid 08:bd:43:c3:a9:96
SSID [Wpa2-psk-ccmp][wps][ess]
level-66
Freq 2462
Time Stamp 1073922473
Full code Download:
http://download.csdn.net/detail/i2cbus/7613361