歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> 如何從Python代碼中直接訪問Android的Service

如何從Python代碼中直接訪問Android的Service

日期:2017/3/1 9:41:14   编辑:Linux編程

在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