说究竟,Java层的service就是就C++层的binder的封装。所以从原理上来讲通过C++代码直接訪问android framework层的service是全然可能的,这篇文章以訪问WifiService为例,解说怎样去实现这个功能。

费话少说。直接上代码:

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); 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<ScanResult> &list) = 0;
virtual bool setWifiEnabled(bool enable) = 0;
}; class BpWifiService: public android::BpInterface<IWifiService>
{
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<android::IBinder>& impl): android::BpInterface<IWifiService>(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<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::IServiceManager> sm = android::defaultServiceManager();
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);
printf("+++++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>::iterator it = list.begin();it != list.end();++it)
{
(*it).dump();
}
break;
}
} return(0);
}

主要的思路非常easy:

先通过:

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

怎样从C++代码直接訪问android framework层的WifiService的更多相关文章

  1. Kivy A to Z -- 怎样从python代码中直接訪问Android的Service

    在Kivy中,通过pyjnius扩展能够间接调用Java代码,而pyjnius利用的是Java的反射机制.可是在Python对象和Java对象中转来转去总让人感觉到十分别扭.好在android提供了b ...

  2. Android Framework层Power键关机流程(一,Power长按键操作处理)

    一:Android处理Power按键长按操作 在Framework层中,Android4.x对Power键(KeyEvent.KEYCODE_POWER)的操作,我们从PhoneWindowManag ...

  3. Android Framework层Power键关机流程(二,关机流程)

    二,关机流程 从前一篇博文我们知道,当用户长按Power键时会弹出(关机.重启,飞行模式等选项)对话框,我们点击关机,则会弹出关机确认对话框.那么从选项对话框到关机确认对话框又是一个什么流程呢.下面我 ...

  4. Android framework层实现实现wifi无缝切换AP

    http://www.linuxidc.com/Linux/2013-12/93476.htm Android市场上有一款叫Wifijumper的软件,实现相同ssid的多个AP之间根据wifi信号的 ...

  5. Android与WebView的同步和异步訪问机制

    大家都知道.通过WebView,我们能够在Androidclient.用Web开发的方式来开发我们的应用. 假设一个应用就是单纯一个WebView.全部的逻辑都仅仅须要在网页上交互的话,那我们事实上就 ...

  6. 如何调试Android Framework?

    Linus有一句名言广为人知:Read the fucking source code. 但其实,要深入理解某个软件.框架或者系统的工作原理,仅仅「看」代码是远远不够的.就拿Android Frame ...

  7. Android通过HTTP POST带參訪问asp.net网页

    在看了网络上非常多视频关于android通过HTTP POST或者GET方式訪问网页并获取数据的方法. 自己也copy了一份来測试.并通过C#.NET搭建了一个简单的后台,但发现传參时,依照网上的方式 ...

  8. Android开发之使用URL訪问网络资源

    Android开发之使用URL訪问网络资源 URL (UniformResource Locator)对象代表统一资源定位器,它是指向互联网"资源"的指针. 资源能够是简单的文件或 ...

  9. Android中关于JNI 的学习(三)在JNI层訪问Java端对象

    前面两篇文章简介了JNI层跟Java层的一些相应关系,包含方法名,数据类型和方法名称等,相信在理论层面.可以非常好地帮助我们去了解JNI在Native本地开发中的作用,对JNI的一些概念也有了一个初步 ...

随机推荐

  1. 玩游戏(dfs)

    http://acm.sdut.edu.cn/sdutoj/problem.php?action=showproblem&problemid=2566 #include <stdio.h ...

  2. Django day24 cbv和APIView的源码分析 和 resful的规范

    一:cbv的源码分析 1.CBV和FBV的区别: - Class Base View   CBV(基于类的视图) - Function Base View   FBV(基于函数的视图) 2.as_vi ...

  3. DIV+CSS设计时浏览器兼容性

          近期用Div+css做了个企业网站,在浏览器中测试的时候确发现在IE7中显示正常的页面,在ie6中非常混乱,当时第一感觉就想到了兼容问题,可是百思不得其解应该从哪下手,经过一两天的查资料, ...

  4. Too Many open files 问题排查

    问题描述:使用netty做性能测试时,并发过大造成Too Many open files问题 该类错误是因为linux系统对socket连接时需要打开的文件句柄数有限制可以通过ulimit -a 查看 ...

  5. 最近积累的JS 东西,分享一下

    js 关闭页面 var browserName=navigator.appName; if (browserName=="Netscape") { window.open('',' ...

  6. windows phone媒体应用开发

    MediaElement 可以播放许多不同类型的音频和视频媒体. MediaElement 是一个可以在其表面显示视频的矩形区域,也可以播放音频.MediaElement 支持触控输入事件. 使用属性 ...

  7. CSS自定义消息提示

    1.效果 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %> ...

  8. poj1101 the game 广搜

    题目大意: 类似于连连看,问从起点到终点最少需要几条线段. 规则: 1.允许出界. 2.空格的地方才能走. 分析: 题目做下来发现没有卡时间,所以主要还是靠思路.也就是说不用考虑离线算法.直接以每个起 ...

  9. dubbo之本地存根

    本地存根 远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做 ThreadLocal 缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在 ...

  10. OpenCV实现灰度直方图和直方图拉伸

    原文链接:http://blog.csdn.net/xiaowei_cqu/article/details/7600666 如有疑问或者版权问题,请移步原作者或者告知本人. 灰度直方图是数字图像中最简 ...