说到底,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



更多相关文章

  1. android GridView 长按事件不管用
  2. android studio 快捷键(本文持续更新)
  3. JNI和NDK编程(一)
  4. Android实现蒙板效果
  5. RoboGuice logo Android上的Guice RoboGuice
  6. Android与PC客户端进行Socket通信的一些问题
  7. 【Android】代码开启/关闭GPS
  8. android 调试跟踪framework层代码
  9. Android(安卓)JNI代码

随机推荐

  1. Duplicate files copied in APK META-INF
  2. Android利用TTF文件设置字体
  3. android 从webview中读取缓存的图片
  4. 【转载】Using SQLite from Shell in And
  5. Android移植--启动篇
  6. Android手动切换屏幕方向
  7. Android依赖库版本不一致
  8. Android(安卓)ListView实现任意layout
  9. AndroidFragment切换
  10. Android中JNI开发(二)Android.mk写法