Android 总结外置 内置SD卡路径问题

我们先来看下android5.1 init.rc中

    mkdir /mnt/shell/emulated 0700 shell shell
    mkdir /storage/emulated 0555 root root
    mkdir /storage/sdcard1 0000 system system
    mkdir /storage/usbotg 0700 system system
    mkdir /mnt/media_rw/usbotg 0700 media_rw media_rw
    mkdir /mnt/media_rw/sdcard1 0700 media_rw media_rw

    export EXTERNAL_STORAGE /storage/emulated/legacy
    export PRIMARY_STORAGE /storage/sdcard0
    export SECONDARY_STORAGE /storage/sdcard1
    export EMULATED_STORAGE_SOURCE /mnt/shell/emulated
    export EMULATED_STORAGE_TARGET /storage/emulated

    # Support legacy paths
    symlink /storage/emulated/legacy /sdcard
    symlink /storage/emulated/legacy /mnt/sdcard
    symlink /mnt/shell/emulated/0 /storage/emulated/legacy
    symlink /storage/emulated/legacy /storage/sdcard0

下面这段是fuse功能,将storage/sdcard1 转到/mnt/media_rw/sdcard1 并且拥有权限

# virtual sdcard daemon running as media_rw (1023)
service sdcard /system/bin/sdcard -u 1023 -g 1023 -l /data/media /mnt/shell/emulated
    class late_start

    chown system system /data/etc/storage.config

# fusewrapped external sdcard daemon running as media_rw (1023)
service fuse_sdcard1 /system/bin/sdcard -u 1023 -g 1023 -w 1023 -d /mnt/media_rw/sdcard1 /storage/sdcard1
    class late_start

 service fuse_usbotg /system/bin/sdcard -u 1023 -g 1023  -d   /mnt/media_rw/usbotg /storage/usbotg 
    class late_start


再来看Environment.getExternalStorageDirectory其实这个获得的内部SD卡的路径,只是Android把它理解成了外部存储。

它的路径就是storage/sdcard0,进入目录看,群组的权限是都有的。它的群组是sdcard_r。在APK中,加入相关权限会加入这个群组。也就拥有这些文件夹的读写权限了。

drwxrwx--- root     sdcard_r          1980-01-01 08:06 Alarms
drwxrwx--x root     sdcard_r          2015-10-20 15:40 Android
drwxrwx--- root     sdcard_r          2015-12-03 10:17 Camera360
drwxrwx--- root     sdcard_r          2015-11-16 17:24 DCIM
drwxrwx--- root     sdcard_r          2015-10-29 13:48 Download
drwxrwx--- root     sdcard_r          2015-10-19 17:08 Movies
drwxrwx--- root     sdcard_r          2015-10-21 18:55 Music
drwxrwx--- root     sdcard_r          1980-01-01 08:06 Notifications
drwxrwx--- root     sdcard_r          2015-11-25 13:49 Pictures
drwxrwx--- root     sdcard_r          1980-01-01 08:06 Podcasts
drwxrwx--- root     sdcard_r          1980-01-01 08:06 Ringtones
drwxrwx--- root     sdcard_r          2015-12-03 11:21 baidu
drwxrwx--- root     sdcard_r          1980-01-01 08:00 elog
drwxrwx--- root     sdcard_r          2015-12-03 10:51 libs
drwxrwx--- root     sdcard_r          2015-12-03 11:21 soufun
drwxrwx--- root     sdcard_r          2015-12-03 10:17 system

上面是Android原生的,我们公司也是这个方式。


但是我试了华为p8,就不是了。它在设置里面有一个默认存储,当你设置外部SD卡后,这个接口得到的是外部SD卡的路径。

华为这个路径是storage/sdcard1,但是当你插上usb的时候,外部存储又会unmount,导致你微信里面使用的图片都无法使用。这也是我在编写应用的时候老是异常的原因,是获取的sd卡被卸载了。


但是在设置里面选取默认储存,然后Environment.getExternalStorageDirectory返回外部存储地址还是内部存储地址是一个比较好的选择,像我们的平台如果有外部的SD卡,对于应用来说都没有借口知道其路径。只能直接使用storage/sdcard1


如果默认存储是外部sd卡的话,又想获取内部存储的路径怎么办呢?

如果是系统应用可以从storageManager中getVolumList可以获取所有的Volume,后去Volume去看它是不是Primary的,如果是就是内部存储。也可以直接使用getPrimaryVolume获取内存存储的Volume,但是一般的APK调不到这函数。

一般apk应该可以使用mount命令这种方式查看内部存储和外部存储的信息。

rootfs / rootfs ro,relatime 0 0
tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0
devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0
proc /proc proc rw,relatime 0 0
sysfs /sys sysfs rw,seclabel,relatime 0 0
selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0
debugfs /sys/kernel/debug debugfs rw,relatime 0 0
none /acct cgroup rw,relatime,cpuacct 0 0
none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0
none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0
tmpfs /mnt/asec tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
tmpfs /mnt/obb tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0
none /dev/memcg cgroup rw,relatime,memory 0 0
none /dev/cpuctl cgroup rw,relatime,cpu 0 0
tmpfs /tmp tmpfs rw,seclabel,relatime 0 0
/dev/block/platform/comip-mmc.1/by-name/system /system ext4 ro,seclabel,relatime,data=ordered 0 0
/dev/block/platform/comip-mmc.1/by-name/cache /cache ext4 rw,seclabel,nosuid,nodev,noatime,data=ordered 0 0
/dev/block/platform/comip-mmc.1/by-name/userdata /data ext4 rw,seclabel,nosuid,nodev,noatime,noauto_da_alloc,data=ordered 0 0
/dev/block/platform/comip-mmc.1/by-name/amt /amt ext4 rw,seclabel,relatime,data=ordered 0 0
/dev/fuse /mnt/shell/emulated fuse rw,nosuid,nodev,noexec,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/sdcard1 fuse rw,nosuid,nodev,noexec,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
/dev/fuse /storage/usbotg fuse rw,nosuid,nodev,noexec,relatime,user_id=1023,group_id=1023,default_permissions,allow_other 0 0
上面就是mount命令打出来的信息,可以看到3个fuse文件系统,这个手机上没有外部SD卡,就没有外部SD卡的挂载信息了,内部的SD卡其实就是data分区的一部分。


所以我觉得在我用华为手机开发应用的时候,应该先将默认存储设层内置的,然后再去编写APK,获取的路径应该就是storage/sdcard0,就可以正常使用了。



  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值