android设备通过USB线缆,使用两种模式与电脑连接:PTP和MTP
PTP模式,android设备被看作一个数码相机,这个功能已经能够在ubuntu 12.04上正常工作。但是仅仅能够访问设备上的DCIM和picture文件夹
MTP模式,是把android的设备视作一个多媒体设备来进行访问,所以能够访问用户空间的所有文件系统,但是这种模式在ubuntu 12.04下面还不支持,需要一些步骤的配置才能正常工作。
下面的教程以nexus 7为例子来配置,使你的电脑(ubuntu12.04)能够通过usb口将nexus 7作为大容量存储设备来进行访问,而且将会自动挂载和移除设备。
1.安装mtp fuse(用户空间文件系统(Filesystem in Userspace,简称FUSE))
1.1选择fuse扩展
很多的fuse扩展都可以用来在你的ubuntu系统上挂载mtp设备:
原始的 mtpfs project 是建立在libmtp库上的
jmtpfs,是mtpfs的重写
go-mtpfs,一种新的有一些限制的mtp
我选择go-mtpfs的原因:
1.比其他的都要稳定
2.连接和改变目录非常块
3.文件传输速度很快
4.文件传输使用的临时空间很小
5.能够直接更改文件的名字
但是也有一些限制:
1.不能传输大于2G的文件
2.文件的时间戳不能保存
3.不能使用其他账户挂载的文件系统
1.2 配置fuse
1.更改/etc/fuse.conf 这个文件的属性 :# sudo chmod a+r /etc/fuse.conf
2.修改文件内容:把“user_allow_other”这一行的注释取消掉
这样做的目的是,能够允许这台电脑上的其他用户挂载文件系统
1.3配置安装go-mtofs
go-mtpfs使用google的go语言编译器,git仓库在:https://github.com/hanwen/go-mtpfs/.
将代码取到本地,然后先安装go的编译器:
sudo apt-get install golang-go
安装libmtp的头文件
sudo apt-get install libmtp-dev
然后在go-mtpfs的源代码目录运行:sudo go install生成go-mtpfs二进制文件,将go-mtpfs拷贝到/usr/loacal/sbin/go-mtpfs就完成了安装
还可以直接下载go-mtpfs的二进制文件,http://hanwen.home.xs4all.nl/public/software/go-mtpfs/
1.4创建挂载点
# sudo mkdir /media/Nexus7
# sudo chmod 777 /media/Nexus7
2.创建udev规则
2.1检测VENDOR_ID和PRODUCT_ID
如果想要在任意模式下都能获取访问Nexus 7的权限,就需要声明所有这些模式下的udev规则
有以下几个模式:
- Recovery mode
- Fastboot mode
- PTP mode (with USB debug on or off)
- MTP mode (with USB debug on or off)
在每个模式下,使用lsusb命令,查看nexus7的Vendor_ID和Product_ID:
#lsusb
Recovery mode(电源+音量上):Bus 002 Device 022: ID 18d1:d001 Google Inc.(选择adb模式下)
Fastboot mode:Bus 002 Device 021: ID 18d1:4e40 Google Inc.
PTP mode(with USB deug on):Bus 002 Device 024: ID 18d1:4e44 Google Inc.
PTP mode(with USB deug off):Bus 002 Device 025: ID 18d1:4e43 Google Inc.
MTP mode(with USB deug on):Bus 002 Device 027: ID 18d1:4e42 Google Inc.
MTP mode(with USB deug off):Bus 002 Device 028: ID 18d1:4e41 Google Inc.
以上这些,蓝色标识的就是Vendor_ID,红色表示的就是Product_ID,要将这些规则写入/etc/udev/rules.d/51-android.rules 这个文件中(见最后)。 51-android.rules这个文件,在我们安装adb驱动的时候曾经创建过,为什么这个文件叫这个名字?因为udev是linux下面的设备管理器,支持即插即用,它允许指定一系列的响应规则,在它侦测到新设备加入的时候,执行他们。
udev要求这些规则存储在/etc/udev/rules.d/50-udev.rules中。udev按照字符排序依次解释这些文件中的规则,如果你希望自己添加的规则在默认规则之后处理,那么文件名必须大于50,比如51
2.2 检测MODEL和MODEL_ID
这个步骤是用来检测nexus 7的插入和拔出,即当你的nexus7使用mtp模式与电脑连接时,自动挂载mtp的文件系统,当你拔出,自动卸载文件系统。
这些udev规则需要建立在设备的MODEL和MODEL_ID能够正常工作。
检测model和model_id的步骤如下:
1.运行udev的监视命令:udevadm monitor --environment --udev
2.用你的nexus7的mtp模式连接电脑
3.等待数秒
4.拔出
gexueyuan@gexueyuan:~$ udevadm monitor --environment --udev
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
UDEV [23855.884828] add /devices/pci0000:00/0000:00:1d.7/usb2/2-4 (usb)
ACTION=add
BUSNUM=002
DEVLINKS=/dev/libmtp-2-4
DEVNAME=/dev/bus/usb/002/030
DEVNUM=030
DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb2/2-4
DEVTYPE=usb_device
ID_BUS=usb
ID_MEDIA_PLAYER=1
ID_MODEL=Nexus_7
ID_MODEL_ENC=Nexus\x207
ID_MODEL_ID=4e41
ID_MTP_DEVICE=1
ID_REVISION=9999
ID_SERIAL=asus_Nexus_7_015d15b4fe2c0200
ID_SERIAL_SHORT=015d15b4fe2c0200
ID_USB_INTERFACES=:ffff00:
ID_VENDOR=asus
ID_VENDOR_ENC=asus
ID_VENDOR_ID=18d1
MAJOR=189
MINOR=157
PRODUCT=18d1/4e41/9999
………………
UDEV [23993.092275] remove /devices/pci0000:00/0000:00:1d.7/usb2/2-4 (usb)
ACTION=remove
BUSNUM=002
DEVLINKS=/dev/libmtp-2-4
DEVNAME=/dev/bus/usb/002/030
DEVNUM=030
DEVPATH=/devices/pci0000:00/0000:00:1d.7/usb2/2-4
DEVTYPE=usb_device
ID_BUS=usb
ID_MEDIA_PLAYER=1
ID_MODEL=Nexus_7
ID_MODEL_ENC=Nexus\x207
ID_MODEL_ID=4e41
ID_MTP_DEVICE=1
ID_REVISION=9999
ID_SERIAL=asus_Nexus_7_015d15b4fe2c0200
………………
在Jelly Bean4.1.2是Nexus
在Jelly Bean4.2+的版本是Nexus_7
在不同的模式下运行还将得到不同的ID_MODEL_ID,这和之前是对应的,mtp模式下,如果usb debug关掉就是4e41,反之是4e42。
现在我们来写51-android.rules 这个文件:
# Bootloader/fastboot nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e40", MODE="0666", OWNER="<gexueyuan>"
#Recovery nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d001", MODE="0666", OWNER="<gexueyuan>"
# MTP mode with USB debug off nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e41", MODE="0666", OWNER="<gexueyuan>"
# MTP mode with USB debug on nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", MODE="0666", OWNER="<gexueyuan>"
# PTP media with USB debug off nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e43", MODE="0666", OWNER="<gexueyuan>"
PTP media with USB debug on nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e44", MODE="0666", OWNER="<gexueyuan>"
# Google Nexus 7 MTP mode : automatic mount when plugged (all android versions)
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e41", ACTION=="add", RUN+="/usr/bin/sudo -b -u gexueyuan /usr/local/sbin/go-mtpfs -allow-other=true /media/Nexus7"
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e42", ACTION=="add", RUN+="/usr/bin/sudo -b -u gexueyuan /usr/local/sbin/go-mtpfs -allow-other=true /media/Nexus7"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e41", ACTION=="add", RUN+="/usr/bin/sudo -b -u gexueyuan /usr/local/sbin/go-mtpfs -allow-other=true /media/Nexus7"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e42", ACTION=="add", RUN+="/usr/bin/sudo -b -u gexueyuan /usr/local/sbin/go-mtpfs -allow-other=true /media/Nexus7"
# # Google Nexus 7 MTP mode : automatic unmount when unplugged (all android versions)
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e41", ACTION=="remove", RUN+="/bin/umount /media/Nexus7"
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e42", ACTION=="remove", RUN+="/bin/umount /media/Nexus7"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e41", ACTION=="remove", RUN+="/bin/umount /media/Nexus7"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e42", ACTION=="remove", RUN+="/bin/umount /media/Nexus7"
上面的规则请使用自己的登录明来替换gexueyuan,然后是重启udev服务。
#sudo service udev restart
现在你的nexus7应该已经可以自动挂载成文件系统了
3.在/etc/fstab中声明
到这里,我们已经达到自动挂载文件系统的目的了,你能够拷贝文件,能够重命名文件,但由于不是真正的文件系统,还面临着以下的问题:
1.不能拷贝大于2G的文件
2.不能创建空文件
3.不能在这个文件系统里面拖拽文件
4.不能直接在这个文件系统打开文件
除此之外,还有一个问题是,不能在文件系统列表里面直接点击箭头来卸载,要解决这一点,我们需要在/etc/fstab里面写入一些声明。
首先运行命令:#mount
...
DeviceFs(Nexus 7) on /media/Nexus7 type fuse.DeviceFs(Nexus 7) (rw,nosuid,nodev,allow_other,user=yourlogin)
然后我们通过这条信息在/etc/fstab结尾来添加一条规则
……
DeviceFs(Nexus\0407) /media/Nexus7 fuse.DeviceFs(Nexus\0407) allow_other,rw,user,noauto 0 0
参考来源:http://bernaerts.dyndns.org/linux/247-ubuntu-automount-nexus7-mtp