在Kivy中,通过pyjnius扩展能够间接调用Java代码,而pyjnius利用的是Java的反射机制。可是在Python对象和Java对象中转来转去总让人感觉到十分别扭。好在android提供了binder这个进程间通信的功能,Java中的Service也是基于Binder的C++代码封装来实现进程间通信的,这也为从Python代码中绕开pyjnius直接訪问Java代码提供了可能,既然Java的Service是基于C++的封装来实现的,也相同能够在Python中封装相同的C++代码,这篇文章解说了怎样通过binder在Python代码中直接訪问Java的Service。如WifiService。

binder_wrap.h

#ifndef BINDER_WRAP_H
#define BINDER_WRAP_H #ifdef __cplusplus
extern "C" {
#endif typedef int (*vector_visitor)(const char16_t* str16,int length,void *data);
typedef int (*fnOnTransact)(uint32_t code,const void *data,void *reply,uint32_t flags,void *userData);
int server_create(const char *name,const char *descriptor,fnOnTransact onTrans,void *data); void* binder_getbinder(const char *name);
int binder_releasebinder(void* binder);
int binder_listServices(vector_visitor visitor,void *data);
int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,size_t size);
int binder_transact(void* binder,int code,const void *data,void* reply,int flags);
void* parcel_new();
int parcel_destroy(void* parcel);
int parcel_writeInterfaceToken(void* parcel,const char *interface);
int parcel_writeInt32(void *parcel,int val);
int parcel_writeCString(void *parcel,const char* str);
int parcel_writeString16(void *parcel,const char16_t* str, size_t len); int parcel_readInt32(void *parcel);
long parcel_readInt64(void *parcel);
int parcel_readString16(void *parcel,char16_t* str, size_t len);
int parcel_readInplace(void *parcel,void* data, int len);
int parcel_readExceptionCode(void *parcel);
int parcel_dataAvail(void *parcel); #ifdef __cplusplus
}
#endif #endif

binder_wrap.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 <binder/Parcel.h> #include "binder_wrap.h" using namespace android; void* binder_getbinder(const char *name)
{
android::sp<android::IServiceManager> sm = android::defaultServiceManager();
sp<IBinder> *binder = new sp<IBinder>();
do {
*binder = sm->getService(android::String16(name));
if (binder != 0)
{
break;
}
usleep(500000); // 0.5 s
} while(true);
return reinterpret_cast<void *>(binder);
} int binder_releasebinder(void* binder)
{
sp<IBinder> *bp = reinterpret_cast<sp<IBinder> *>(binder); if(bp == 0)
{
return 0;
} delete bp; return 1;
} //Vector<String16> listServices() = 0;
int binder_listServices(vector_visitor visitor,void *data)
{
android::sp<android::IServiceManager> sm = android::defaultServiceManager(); Vector<String16> list = sm->listServices(); for (int i=0;i<list.size();i++)
{
visitor(list[i].string(),list[i].size(),data);
} return list.size();
} int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,size_t size)
{
sp<IBinder> *bp = reinterpret_cast<sp<IBinder> *>(binder); if(bp == 0)
{
return 0;
} if (descriptor == NULL || size <= 0)
{
return 0;
} String16 des = (*bp)->getInterfaceDescriptor(); if (size > des.size())
{
size = des.size();
} memcpy(descriptor,des.string(),size*2); return size;
} //int binder_transact(void* binder,int code,const Parcel& data,Parcel* reply,int flags = 0)
int binder_transact(void* binder,int code,const void *data,void* reply,int flags)
{
sp<IBinder> *bp = reinterpret_cast<sp<IBinder> *>(binder); if(bp == 0 || data == 0 || reply == 0)
{
return 0;
}
return (*bp)->transact(code,*(Parcel*)data,(Parcel*)reply,flags);
} void* parcel_new()
{
return (void*)new Parcel();
} int parcel_destroy(void* parcel)
{
if(parcel == 0)
{
return 0;
}
delete (Parcel*)parcel;
return 1;
} int parcel_writeInterfaceToken(void* parcel,const char *interface)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
}
return p->writeInterfaceToken(String16(interface));
} int parcel_writeInt32(void *parcel,int val)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
} return p->writeInt32(val);
} int parcel_writeCString(void *parcel,const char* str)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
}
return p->writeCString(str);
} int parcel_writeString16(void *parcel,const char16_t* str, size_t len)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
} if (str == 0 || len <= 0)
{
return 0;
} return p->writeString16(str,len);
} int parcel_readInt32(void *parcel)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
}
return p->readInt32();
} long parcel_readInt64(void *parcel)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
}
return p->readInt64();
} int parcel_readString16(void *parcel,char16_t* str, size_t len)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
} if (str == NULL || len <= 0)
{
return 0;
} String16 str16 = p->readString16(); if (len > str16.size())
{
len = str16.size();
} memcpy(str,str16.string(),len*2); return len;
} int parcel_readExceptionCode(void *parcel)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
}
return p->readExceptionCode();
} int parcel_readInplace(void *parcel,void* data, int len)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
} if (len >= 0 && len <= (int32_t)p->dataAvail())
{
const void *d = p->readInplace(len);
memcpy(data,d,len);
return len;
}
return 0;
} int parcel_dataAvail(void *parcel)
{
Parcel *p = reinterpret_cast<Parcel *>(parcel); if(p == 0)
{
return 0;
} return p->dataAvail(); }

正如代码中所看到的,这里对C++的IBinder和Parcel两个对象进行了封装,而Java的Service的底层实现也正是对这两个类进行封装的结果,详细的能够看

frameworks\base\core\jni\android_util_Binder.cpp

的代码。

再来看下怎样在Python中使用这些代码,这里用cython来封装这些C接口:

binder.pyx

cdef extern from "utils/Unicode.h":
ctypedef short char16_t
ctypedef unsigned int uint32_t cdef extern from "Python.h":
ctypedef short Py_UNICODE
ctypedef size_t Py_ssize_t
object PyString_FromStringAndSize(const char *v, Py_ssize_t len)
int PyString_AsStringAndSize(object obj, char **buffer, Py_ssize_t *length)
object PyUnicode_FromUnicode(const Py_UNICODE *u, Py_ssize_t size)
Py_UNICODE* PyUnicode_AS_UNICODE(object)
Py_ssize_t PyUnicode_GetSize(object)
void Py_INCREF(object)
void Py_DECREF(object) cdef extern from "binder_wrap.h":
ctypedef int (*vector_visitor)(const char16_t* str16,int length,void *data)
int binder_listServices(vector_visitor visitor,void *data)
ctypedef int (*fnOnTransact)(uint32_t code,const void *data,void *reply,uint32_t flags,void *userData)
int server_create(const char *name,const char *descriptor,fnOnTransact onTrans,void *data)
void* binder_getbinder(const char *name)
int binder_releasebinder(void* binder)
int binder_getInterfaceDescriptor(void *binder,char16_t *descriptor,int size)
int binder_transact(void* binder,int code,const void *data,void* reply,int flags) void* parcel_new()
int parcel_destroy(void* parcel)
int parcel_writeInterfaceToken(void* parcel,const char *interface)
int parcel_writeInt32(void *parcel,int val)
int parcel_writeCString(void *parcel,const char* str)
int parcel_writeString16(void *parcel,const char16_t* str, size_t len) int parcel_readInt32(void *parcel)
int parcel_readInt64(void *parcel)
int parcel_readString16(void *parcel,char16_t* str, size_t len)
int parcel_readExceptionCode(void *parcel)
int parcel_readInplace(void *parcel,void* data, int len) int parcel_dataAvail(void *parcel) cdef int visitor(const char16_t* str16,int length,void *data):
arr = <object>data
o = PyUnicode_FromUnicode(<Py_UNICODE*>str16,length)
arr.append(o) def listServices():
arr = []
Py_INCREF(arr)
binder_listServices(visitor,<void *>arr)
Py_DECREF(arr)
return arr cdef class Binder:
cdef void *ptr
def __cinit__(self,char *name): #, sp[IBinder] service):
self.ptr = binder_getbinder(name) def __dealloc__(self):
binder_releasebinder(self.ptr) def getInterfaceDescriptor(self):
cdef char16_t descriptor[256]
cdef int ret
ret = binder_getInterfaceDescriptor(self.ptr,descriptor,sizeof(descriptor))
if not ret:
return None
return PyUnicode_FromUnicode(<Py_UNICODE*>descriptor,ret) def transact(self,int code,data,reply,int flags):
cdef int dataPtr = data.getNativePtr()
cdef int replyPtr = reply.getNativePtr()
binder_transact(self.ptr,code,<void *>dataPtr,<void*>replyPtr,flags)
return reply cdef class Parcel:
cdef void *ptr
cdef int nativePtr
def __cinit__(self,unsigned int nativePtr=0): #, sp[IBinder] service):
self.nativePtr = nativePtr
if not nativePtr:
self.ptr = parcel_new()
else:
self.ptr = <void *>nativePtr def __dealloc__(self):
if not self.nativePtr:
parcel_destroy(self.ptr) def getNativePtr(self):
return <int>self.ptr def writeInterfaceToken(self,const char *interface):
return parcel_writeInterfaceToken(<void *>self.ptr,interface) def writeInt(self,int val):
self.writeInt32(val)
def writeInt32(self,int val):
return parcel_writeInt32(<void *>self.ptr,val) def writeCString(self,const char* cstr):
return parcel_writeCString(<void *>self.ptr,cstr) def writeString16(self,ustr):
cdef char16_t *un
cdef int size
if isinstance(ustr,unicode):
un = <char16_t*>PyUnicode_AS_UNICODE(ustr)
size = PyUnicode_GetSize(ustr)
return parcel_writeString16(<void *>self.ptr,un,size) def readInt32(self):
return parcel_readInt32(self.ptr)
def readInt(self):
return self.readInt32() def readInt64(self):
return parcel_readInt64(self.ptr) def readExceptionCode(self):
return parcel_readExceptionCode(self.ptr) def readString16(self):
cdef char16_t str16[256]
cdef int ret
ret = parcel_readString16(self.ptr,str16,sizeof(str16))
if not ret:
return None
return PyUnicode_FromUnicode(<Py_UNICODE*>str16,ret) def readByteArray(self):
return self.createByteArray() def createByteArray(self):
length = self.readInt()
print 'createByteArray:',length
return self.readInplace(length) # int parcel_readInplace(void *parcel,void* data, size_t len)
def readInplace(self,length):
cdef char arr[512]
ret = parcel_readInplace(self.ptr,arr,length)
if ret == length:
return PyString_FromStringAndSize(arr,length)
else:
return None # int parcel_dataAvail(void *parcel)
def dataAvail(self):
return parcel_dataAvail(self.ptr) def createTypedArrayList(self,creator):
N = self.readInt()
if N <= 0:
return None
arr = []
for i in range(N):
if self.readInt() == 0:
continue
else:
result = creator.createFromParcel(self)
arr.append(result)
return arr @classmethod
def obtain(cls):
return Parcel()
@classmethod
def recycle(cls):
pass

好,再来看看怎样来实现訪问WifiService的功能:

WifiService.py

from binder import Binder,Parcel

WIFI_SERVICE = "wifi";
DESCRIPTOR = "android.net.wifi.IWifiManager";
FIRST_CALL_TRANSACTION = 1
TRANSACTION_getConfiguredNetworks = (FIRST_CALL_TRANSACTION + 0);
TRANSACTION_addOrUpdateNetwork = (FIRST_CALL_TRANSACTION + 1);
TRANSACTION_removeNetwork = (FIRST_CALL_TRANSACTION + 2);
TRANSACTION_enableNetwork = (FIRST_CALL_TRANSACTION + 3);
TRANSACTION_disableNetwork = (FIRST_CALL_TRANSACTION + 4);
TRANSACTION_pingSupplicant = (FIRST_CALL_TRANSACTION + 5);
TRANSACTION_startScan = (FIRST_CALL_TRANSACTION + 6);
TRANSACTION_getScanResults = (FIRST_CALL_TRANSACTION + 7);
TRANSACTION_disconnect = (FIRST_CALL_TRANSACTION + 8);
TRANSACTION_reconnect = (FIRST_CALL_TRANSACTION + 9);
TRANSACTION_reassociate = (FIRST_CALL_TRANSACTION + 10);
TRANSACTION_getConnectionInfo = (FIRST_CALL_TRANSACTION + 11);
TRANSACTION_setWifiEnabled = (FIRST_CALL_TRANSACTION + 12);
TRANSACTION_getWifiEnabledState = (FIRST_CALL_TRANSACTION + 13);
TRANSACTION_setCountryCode = (FIRST_CALL_TRANSACTION + 14);
TRANSACTION_setFrequencyBand = (FIRST_CALL_TRANSACTION + 15);
TRANSACTION_getFrequencyBand = (FIRST_CALL_TRANSACTION + 16);
TRANSACTION_isDualBandSupported = (FIRST_CALL_TRANSACTION + 17);
TRANSACTION_saveConfiguration = (FIRST_CALL_TRANSACTION + 18);
TRANSACTION_getDhcpInfo = (FIRST_CALL_TRANSACTION + 19);
TRANSACTION_acquireWifiLock = (FIRST_CALL_TRANSACTION + 20);
TRANSACTION_updateWifiLockWorkSource = (FIRST_CALL_TRANSACTION + 21);
TRANSACTION_releaseWifiLock = (FIRST_CALL_TRANSACTION + 22);
TRANSACTION_initializeMulticastFiltering = (FIRST_CALL_TRANSACTION + 23);
TRANSACTION_isMulticastEnabled = (FIRST_CALL_TRANSACTION + 24);
TRANSACTION_acquireMulticastLock = (FIRST_CALL_TRANSACTION + 25);
TRANSACTION_releaseMulticastLock = (FIRST_CALL_TRANSACTION + 26);
TRANSACTION_setWifiApEnabled = (FIRST_CALL_TRANSACTION + 27);
TRANSACTION_getWifiApEnabledState = (FIRST_CALL_TRANSACTION + 28);
TRANSACTION_getWifiApConfiguration = (FIRST_CALL_TRANSACTION + 29);
TRANSACTION_setWifiApConfiguration = (FIRST_CALL_TRANSACTION + 30);
TRANSACTION_startWifi = (FIRST_CALL_TRANSACTION + 31);
TRANSACTION_stopWifi = (FIRST_CALL_TRANSACTION + 32);
TRANSACTION_addToBlacklist = (FIRST_CALL_TRANSACTION + 33);
TRANSACTION_clearBlacklist = (FIRST_CALL_TRANSACTION + 34);
TRANSACTION_getWifiServiceMessenger = (FIRST_CALL_TRANSACTION + 35);
TRANSACTION_getWifiStateMachineMessenger = (FIRST_CALL_TRANSACTION + 36);
TRANSACTION_getConfigFile = (FIRST_CALL_TRANSACTION + 37);
TRANSACTION_captivePortalCheckComplete = (FIRST_CALL_TRANSACTION + 38); mRemote = Binder(WIFI_SERVICE) def transact(TRANSACTION):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
mRemote.transact(TRANSACTION, _data, _reply, 0)
_reply.readExceptionCode()
return _reply.readInt32() def getConfiguredNetworks():
pass
def addOrUpdateNetwork():
pass
def removeNetwork():
pass
def enableNetwork(netId,disableOthers):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
_data.writeInt32(netId)
if disableOthers:
_data.writeInt32(1)
else:
_data.writeInt32(0)
mRemote.transact(TRANSACTION_enableNetwork, _data, _reply, 0)
_reply.readExceptionCode()
return _reply.readInt32() != 0
def disableNetwork(netId):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
_data.writeInt32(netId)
mRemote.transact(TRANSACTION_disableNetwork, _data, _reply, 0)
_reply.readExceptionCode()
return _reply.readInt32() != 0 def pingSupplicant():
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
mRemote.transact(TRANSACTION_pingSupplicant, _data, _reply, 0)
_reply.readExceptionCode()
return _reply.readInt32() != 0 def startScan(forceActive):
_data = Parcel()
_reply = Parcel()
ret = 0
try:
_data.writeInterfaceToken(DESCRIPTOR)
if forceActive:
_data.writeInt(1)
else:
_data.writeInt(0)
mRemote.transact(TRANSACTION_startScan, _data, _reply, 0)
ret = _reply.readExceptionCode()
finally:
_reply.recycle()
_data.recycle()
return ret == 0 class ScanResult:
def __init__(self,ssid,bssid,caps,level,frequency,timestamp):
self.ssid = ssid
self.bssid = bssid
self.caps = caps
self.level = level
self.frequency = frequency
self.timestamp = timestamp
@classmethod
def createFromParcel(cls,reply):
has_ssid = reply.readInt32()
ssid = None
if has_ssid:
ssid_lengt = reply.readInt()
ssid = reply.readByteArray()
BSSID = reply.readString16()
caps = reply.readString16()
level = reply.readInt()
frequency = reply.readInt()
timestamp = reply.readInt64() print 'BSSID:',BSSID
print 'caps:',caps
print 'level:',level
print 'frequency:',frequency
print 'timestamp:',timestamp
return ScanResult(ssid,BSSID,caps,level,frequency,timestamp) def getScanResults():
_data = Parcel.obtain()
_reply = Parcel.obtain()
_result = None
try:
_data.writeInterfaceToken(DESCRIPTOR)
mRemote.transact(TRANSACTION_getScanResults, _data, _reply, 0)
if 0 != _reply.readExceptionCode():
return None
_result = _reply.createTypedArrayList(ScanResult)
finally:
_reply.recycle()
_data.recycle()
return _result def disconnect():
return transact(TRANSACTION_disconnect) != 0 def reconnect():
return transact(TRANSACTION_reconnect) != 0 def reassociate():
return transact(TRANSACTION_reassociate) != 0 """
class WifiInfo:
def __init__():
pass
@classmethod
def createFromParcel(cls,r):
info = WifiInfo();
info.networkId = r.readInt32()
info.rssi = r.readInt32()
info.linkSpeed = r.readInt32()
if r.readByte() == 1:
info.setInetAddress(InetAddress.getByAddress(in.createByteArray()))
if r.readInt() == 1:
info.mWifiSsid = WifiSsid.CREATOR.createFromParcel(r)
info.mBSSID = r.readString16()
info.mMacAddress = r.readString16()
info.mMeteredHint = r.readInt32() != 0
""" def getConnectionInfo():
pass
def setWifiEnabled(enable):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
if enable:
_data.writeInt32(1)
else:
_data.writeInt32(0)
mRemote.transact(TRANSACTION_setWifiEnabled, _data,_reply,0)
_reply.readExceptionCode()
_result = (0!=_reply.readInt32())
return _result; def getWifiEnabledState():
return transact(TRANSACTION_getWifiEnabledState) def setCountryCode(country,persist):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
if isinstance(country,str):
country = unicode(contry)
_data.writeString16(country)
if persist:
_data.writeInt32(1)
else:
_data.writeInt32(0)
mRemote.transact(TRANSACTION_setCountryCode, _data,_reply,0)
_reply.readExceptionCode()
_result = (0!=_reply.readInt32())
return _result; def setFrequencyBand(band, persist):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
if isinstance(country,str):
country = unicode(contry)
_data.writeInt32(band)
if persist:
_data.writeInt32(1)
else:
_data.writeInt32(0)
mRemote.transact(TRANSACTION_setFrequencyBand, _data,_reply,0)
_reply.readExceptionCode()
_result = (0!=_reply.readInt32())
return _result; def getFrequencyBand():
return transact(TRANSACTION_getFrequencyBand) def isDualBandSupported():
return transact(TRANSACTION_isDualBandSupported) != 0
def saveConfiguration():
pass def get_readable_address(addr):
return "%d:%d:%d:%d"%(addr&0xff,(addr>>8)&0xff,(addr>>16)&0xff,(addr>>24)&0xff) def getDhcpInfo():
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
mRemote.transact(TRANSACTION_getDhcpInfo, _data,_reply,0)
_reply.readExceptionCode()
if 0 == _reply.readInt32():
return None ipAddress = get_readable_address(reply.readInt32());
gateway = get_readable_address(reply.readInt32());
netmask = get_readable_address(reply.readInt32());
dns1 = get_readable_address(reply.readInt32());
dns2 = get_readable_address(reply.readInt32());
serverAddress = get_readable_address(reply.readInt32());
leaseDuration = get_readable_address(reply.readInt32()); info = (ipAddress,gateway,netmask,dns1,dns2,serverAddress,leaseDuration)
print "ipAddress %s,\ngateway %s,\nnetmask %s,\ndns1 %s,\ndns2 %s,\nserverAddress %s,\nleaseDuration %s"%info
return info def acquireWifiLock():
pass
def updateWifiLockWorkSource():
pass
def releaseWifiLock():
pass
def initializeMulticastFiltering():
pass
def isMulticastEnabled():
pass
def acquireMulticastLock():
pass
def releaseMulticastLock():
pass
def setWifiApEnabled(wifiConfig,enable):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
if wifiConfig:
_data.writeInt32(1)
wifiConfig.writeToParcel(_data)
else:
_data.writeInt32(0)
if enable:
_data.writeInt32(1)
else:
_data.writeInt32(0) mRemote.transact(TRANSACTION_setWifiApEnabled, _data,_reply,0)
_reply.readExceptionCode() def getWifiApEnabledState():
return transact(TRANSACTION_getWifiApEnabledState) def getWifiApConfiguration():
pass
def setWifiApConfiguration():
pass
def startWifi():
return transact(TRANSACTION_startWifi)
def stopWifi():
return transact(TRANSACTION_stopWifi)
def addToBlacklist(bssid):
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
if isinstance(bssid,str):
bssid = unicode(bssid)
_data.writeString16(bssid)
mRemote.transact(TRANSACTION_addToBlacklist, _data,_reply,0)
_reply.readExceptionCode() def clearBlacklist():
return transact(TRANSACTION_clearBlacklist)
def getWifiServiceMessenger():
pass
def getWifiStateMachineMessenger():
pass
def getConfigFile():
_data = Parcel()
_reply = Parcel()
_data.writeInterfaceToken(DESCRIPTOR)
mRemote.transact(TRANSACTION_getConfigFile, _data,_reply,0)
_reply.readExceptionCode()
return _reply.readString16() def captivePortalCheckComplete():
return transact(TRANSACTION_captivePortalCheckComplete) != 0

眼下并没有实现全部的WifiService的功能,可是像startScan。getScanResults,setWifiEnabled,getWifiEnabledState,getDhcpInfo,setWifiApEnabled这些基本的接口已经实现了,其他接口没有实现并不是是由于不能实现,而是比較繁琐,临时未实现而己,后面会不断的完好。

再来看下測试代码:

test.py

import WifiService

WifiService.setWifiEnabled(True)

WifiService.startScan(True)

print WifiService.pingSupplicant()
print WifiService.getConfigFile() for i in range(10):
time.sleep(1.0)
result = WifiService.getScanResults()
if result:
print result
break

运行后将会打印出搜索到的Wifi信息。

另外就是代码的编译问题了。

代码必须在android的源码下进行编译。我试过在ndk上进行编译,经过一番努力,通过链接事先编译好的C++ binder库。也成功编译通过,可是程序不能正常执行。这应该是预先编译出来的库和ndk的库存在兼容性问题造成的。也许通过在ndk上编译binder库能够避免这个问题。可是眼下还没有作过尝试。 可是编译出来的代码应该能够执行在各个不同的版本号,我在4.0和4.2版本号的设备上作了简单的測试,事实证明在4.2上编译的代码能够在4.0上执行,可是考虑到android的诸多版本号,各个版本号多多少少有些兼容性问题,更具体的还必须比較各个版本号的binder代码。并通过測试才干得到结果。

Kivy A to Z -- 怎样从python代码中直接訪问Android的Service的更多相关文章

  1. pycharm运行Pytest,有没有将Pytest写入Python代码中的区别

    初学pytest. 将pytest写进Python代码中 不同运行方式都可正常运行     =======================**********************========= ...

  2. python代码中判断版本

    在python代码中判断python版本: if sys.version_info < (3, 0): lib.make_flows.argtypes = [c_char_p, c_char_p ...

  3. 怎样从C++代码直接訪问android framework层的WifiService

    说究竟,Java层的service就是就C++层的binder的封装.所以从原理上来讲通过C++代码直接訪问android framework层的service是全然可能的,这篇文章以訪问WifiSe ...

  4. 如何在创建hive表格的python代码中导入外部文件

    业务场景大概是这样的,我要对用户博文进行分词(这个步骤可以看这篇文章如何在hive调用python的时候使用第三方不存在的库-how to use external python library in ...

  5. Python 面试中可能会被问到的30个问题

    第一家公司问的题目 1 简述解释型和编译型编程语言? 解释型语言编写的程序不需要编译,在执行的时候,专门有一个解释器能够将VB语言翻译成机器语言,每个语句都是执行的时候才翻译.这样解释型语言每执行一次 ...

  6. Python代码中func(*args, **kwargs)

    这是Python函数可变参数 args及kwargs *args表示任何多个无名参数,它是一个tuple **kwargs表示关键字参数,它是一个dict 测试代码如下: def foo(*args, ...

  7. python代码中pass的用法

    我们有时会在方法中写一些注释代码,用来提示这个方法是干嘛的之类,看下面代码: class Game_object: def __init__(self, name): self.name = name ...

  8. 解决python代码中含有中文报错

    python中写入中文时报错如下图所示: 依照网上解决方法:在py文件中加入:#encoding=utf-8 然后继续报错如下图所示: 解决方法: 在py文件中加入: import sysreload ...

  9. 生成.m文件的python代码中出现的错误

    错误代码 import tempfile import subprocess import shlex import os import numpy as np import scipy.io scr ...

随机推荐

  1. CF Rook, Bishop and King

    http://codeforces.com/contest/370/problem/A 题意:车是走直线的,可以走任意多个格子,象是走对角线的,也可以走任意多个格子,而国王可以走直线也可以走对角线,但 ...

  2. jar包中的类如何读取包内和包外的配置文件

    最近将代码打包成jar包,关于如何处理读取配置文件的问题特此记录一下. out.properties a.jar -com -a.class -in.properties 如上所示,out.prope ...

  3. 【NOIP 2012 国王游戏】 贪心+高精度

    题目描述 恰逢 H 国国庆,国王邀请 n 位大臣来玩一个有奖游戏.首先,他让每个大臣在左.右 手上面分别写下一个整数,国王自己也在左.右手上各写一个整数.然后,让这 n 位大臣排 成一排,国王站在队伍 ...

  4. Show username instead of "System Account" in SharePoint 2010

    Problems: When I load my local SharePoint site, the account always show as "System Account" ...

  5. 优化 Android 线程和后台任务开发

    在 Android 开发中,你不应该做任何阻碍主线程的事情.但这究竟意味着什么呢?在这次海湾 Android 开发者大会讲座中,Ari Lacenski 认为对于长时间运行或潜在的复杂任务要特别小心. ...

  6. Android 获得屏幕的宽高度

    在View构造函数中获得屏幕的宽高 public class GameView extends View { public GameView(Context context) { Display d ...

  7. [Quick-x]制作新手引导高亮区域方法之二:裁剪模式

    demo下载:https://github.com/chenquanjun/Quick-x-HighlightArea 2.裁剪模式 (1)创建裁剪对象 , , ) --非高亮区域颜色 local b ...

  8. Python sh库学习 上篇

    官方文档有句话"allows you to call any program",并且:helps you write shell scripts in Python by givi ...

  9. Understanding Network Class Loaders

    By Qusay H. Mahmoud, October 2004     When Java was first released to the public in 1995 it came wit ...

  10. Google Chrome中的高性能网络(二)

    Chrome Predictor的预测功能优化 Chrome会随着使用变得更快. 它这个特性是通过一个单例对象Predictor来实现的.这个对象在浏览器内核进程(Browser Kernel Pro ...