Welcome 微信登录
编程资源 图片资源库 蚂蚁家优选 PDF转换器

首页 / 操作系统 / Linux / 如何从Python代码中直接访问Android的Service

在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。《Python核心编程 第二版》.(Wesley J. Chun ).[高清PDF中文版] http://www.linuxidc.com/Linux/2013-06/85425.htm《Python开发技术详解》.( 周伟,宗杰).[高清PDF扫描版+随书视频+代码] http://www.linuxidc.com/Linux/2013-11/92693.htmPython脚本获取Linux系统信息 http://www.linuxidc.com/Linux/2013-08/88531.htm在Ubuntu下用Python搭建桌面算法交易研究环境 http://www.linuxidc.com/Linux/2013-11/92534.htmbinder_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  #endifbinder_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();      }更多详情见请继续阅读下一页的精彩内容: http://www.linuxidc.com/Linux/2014-08/105192p2.htm