如何从C++代码直接访问android framework层的WifiService
16lz
2021-01-26
说到底,Java层的service就是就C++层的binder的封装,所以从原理上来讲通过C++代码直接访问android framework层的service是完全可能的,这篇文章以访问WifiService为例,讲解如何去实现这个功能。
费话少说,直接上代码:
WifiTest.cpp
#include #include #include #include #include #include #include #include //#include #include #include using namespace android;#define WIFI_SERVICE "wifi"const String16 WIFI_DESCRIPTOR("android.net.wifi.IWifiManager");class ScanResult{private: ScanResult& operator=(const ScanResult& o);public: ScanResult(const ScanResult& o): mSsid(o.mSsid),mBssid(o.mBssid),mCaps(o.mCaps),mLevel(o.mLevel),mFrequency(o.mFrequency),mTimestamp(o.mTimestamp) { } ScanResult(String8 ssid,String16 bssid,String16 caps,int level,int freq,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 startScan(int forceActive) = 0; virtual int getScanResults(List &list) = 0; virtual bool setWifiEnabled(bool enable) = 0;};class BpWifiService: public android::BpInterface{ enum { FIRST_CALL_TRANSACTION = 1, TRANSACTION_getConfiguredNetworks = (android::IBinder::FIRST_CALL_TRANSACTION + 0), TRANSACTION_addOrUpdateNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 1), TRANSACTION_removeNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 2), TRANSACTION_enableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 3), TRANSACTION_disableNetwork = (android::IBinder::FIRST_CALL_TRANSACTION + 4), TRANSACTION_pingSupplicant = (android::IBinder::FIRST_CALL_TRANSACTION + 5), TRANSACTION_startScan = (android::IBinder::FIRST_CALL_TRANSACTION + 6), TRANSACTION_getScanResults = (android::IBinder::FIRST_CALL_TRANSACTION + 7), TRANSACTION_disconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 8), TRANSACTION_reconnect = (android::IBinder::FIRST_CALL_TRANSACTION + 9), TRANSACTION_reassociate = (android::IBinder::FIRST_CALL_TRANSACTION + 10), TRANSACTION_getConnectionInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 11), TRANSACTION_setWifiEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 12), TRANSACTION_getWifiEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 13), TRANSACTION_setCountryCode = (android::IBinder::FIRST_CALL_TRANSACTION + 14), TRANSACTION_setFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 15), TRANSACTION_getFrequencyBand = (android::IBinder::FIRST_CALL_TRANSACTION + 16), TRANSACTION_isDualBandSupported = (android::IBinder::FIRST_CALL_TRANSACTION + 17), TRANSACTION_saveConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 18), TRANSACTION_getDhcpInfo = (android::IBinder::FIRST_CALL_TRANSACTION + 19), TRANSACTION_acquireWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 20), TRANSACTION_updateWifiLockWorkSource = (android::IBinder::FIRST_CALL_TRANSACTION + 21), TRANSACTION_releaseWifiLock = (android::IBinder::FIRST_CALL_TRANSACTION + 22), TRANSACTION_initializeMulticastFiltering = (android::IBinder::FIRST_CALL_TRANSACTION + 23), TRANSACTION_isMulticastEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 24), TRANSACTION_acquireMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 25), TRANSACTION_releaseMulticastLock = (android::IBinder::FIRST_CALL_TRANSACTION + 26), TRANSACTION_setWifiApEnabled = (android::IBinder::FIRST_CALL_TRANSACTION + 27), TRANSACTION_getWifiApEnabledState = (android::IBinder::FIRST_CALL_TRANSACTION + 28), TRANSACTION_getWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 29), TRANSACTION_setWifiApConfiguration = (android::IBinder::FIRST_CALL_TRANSACTION + 30), TRANSACTION_startWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 31), TRANSACTION_stopWifi = (android::IBinder::FIRST_CALL_TRANSACTION + 32), TRANSACTION_addToBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 33), TRANSACTION_clearBlacklist = (android::IBinder::FIRST_CALL_TRANSACTION + 34), TRANSACTION_getWifiServiceMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 35), TRANSACTION_getWifiStateMachineMessenger = (android::IBinder::FIRST_CALL_TRANSACTION + 36), TRANSACTION_getConfigFile = (android::IBinder::FIRST_CALL_TRANSACTION + 37), TRANSACTION_captivePortalCheckComplete = (android::IBinder::FIRST_CALL_TRANSACTION + 38), };public: BpWifiService(const android::sp& impl): android::BpInterface(impl) { } void startScan(int forceActive) { android::Parcel 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 &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;itransact(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 sm = android::defaultServiceManager(); android::sp binder; android::sp wifi; binder = sm->getService(android::String16(WIFI_SERVICE)); if (binder == 0) { return 1; } wifi = android::interface_cast(binder); wifi->setWifiEnabled(true);printf("+++++scan start");wifi->startScan(1);for(int i=0;i<10;i++){usleep(1*1000*1000);List list;wifi->getScanResults(list);if(list.size() > 0) { for(List::iterator it = list.begin();it != list.end();++it) { (*it).dump(); } break; }} return(0);}
基本的思路很简单:
先通过:
android::defaultServiceManager()->getService(android::String16(WIFI_SERVICE));
获取binder接口,再通过Parcel读与binder,具体的实现可以参考IWifiManager.java的代码。
编译后运行以上的代码可以得到类似以下的输出:
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
完整代码下载:
http://download.csdn.net/detail/i2cbus/7613361
更多相关文章
- android GridView 长按事件不管用
- android studio 快捷键(本文持续更新)
- JNI和NDK编程(一)
- Android实现蒙板效果
- RoboGuice logo Android上的Guice RoboGuice
- Android与PC客户端进行Socket通信的一些问题
- 【Android】代码开启/关闭GPS
- android 调试跟踪framework层代码
- Android(安卓)JNI代码