Kivy A to Z -- 如何在Kivy中获取SD卡或者U盘的插拔事件

Kivy只是一个图形库,在Android平台上,有很多功能需要自己扩展,其中如何监听SD卡或者U盘的插拔事件就是一个问题。但是实际上解决起来也还是比较简单。


在Android平台上,用vold来替代linux下的udev来进行热插拔设备的管理。通过local socket server把热插拔设备的事件广播给正在监听的设备,所以要在Kivy中获取U盘或者SD卡的事件,只需要通过local socket client来监听vold的发送的事件,监听的路径为/dev/socket/vold,具体的实现方式如下:



import socket
import select

s = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
s.connect('/dev/socket/vold')
print 'start select!'
while True:
    ss = select.select([s,],[],[],20)
    data = s.recv(1024)
    for msg in data.split('\x00'):
        print msg

当接上SD卡时,会得到下面的打印:

'605 Volume sdcard /sdcard state changed from 2 (Pending) to 1 (Idle-Unmounted)'
'630 Volume sdcard /sdcard disk inserted (253:0)'
'605 Volume sdcard /sdcard state changed from 1 (Idle-Unmounted) to 3 (Checking)'
'605 Volume sdcard /sdcard state changed from 3 (Checking) to 4 (Mounted)'

当拔下SD卡时,会得到下面的打印:

'605 Volume sdcard /sdcard state changed from 4 (Mounted) to 5 (Unmounting)'
'605 Volume sdcard /sdcard state changed from 5 (Unmounting) to 1 (Idle-Unmounted)'
'631 Volume sdcard /sdcard disk removed (253:0)'
'605 Volume sdcard /sdcard state changed from 1 (Idle-Unmounted) to 0 (No-Media)'
'605 Volume sdcard /sdcard state changed from 0 (No-Media) to 2 (Pending)'

具体的代码的意义可以看system/vold/ResponseCode.h,如:

    static const int VolumeDiskInserted            = 630;
    static const int VolumeDiskRemoved             = 631;

    static const int VolumeStateChange              = 605;


要监听SD卡的挂载事件可以解析如下的字符串:

'605 Volume sdcard /sdcard state changed from 3 (Checking) to 4 (Mounted)'
要监听SD卡的拔出事件可以解析如下的字符串:

'605 Volume sdcard /sdcard state changed from 4 (Mounted) to 5 (Unmounting)'


具体的解析字符串的工作比较简单,可以用正则表达式来进行解析。



但是如果你直接在Kivy下执行上面的代码,会发现socket.AF_UNIX未定义,具体的原因可以看:

https://github.com/kivy/python-for-android/issues/163


目前的解决方法是直接在pyconfig.h中定义HAVE_SYS_UN_H,然后再重新编译python。




你可能感兴趣的:(Kivy A to Z -- 如何在Kivy中获取SD卡或者U盘的插拔事件)