歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> 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.htm

Python腳本獲取Linux系統信息 http://www.linuxidc.com/Linux/2013-08/88531.htm

在Ubuntu下用Python搭建桌面算法交易研究環境 http://www.linuxidc.com/Linux/2013-11/92534.htm

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(); 

     

}

更多詳情見請繼續閱讀下一頁的精彩內容: http://www.linuxidc.com/Linux/2014-08/105192p2.htm

Copyright © Linux教程網 All Rights Reserved