我们先来看下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 Alarmsdrwxrwx--x root     sdcard_r          2015-10-20 15:40 Androiddrwxrwx--- root     sdcard_r          2015-12-03 10:17 Camera360drwxrwx--- root     sdcard_r          2015-11-16 17:24 DCIMdrwxrwx--- root     sdcard_r          2015-10-29 13:48 Downloaddrwxrwx--- root     sdcard_r          2015-10-19 17:08 Moviesdrwxrwx--- root     sdcard_r          2015-10-21 18:55 Musicdrwxrwx--- root     sdcard_r          1980-01-01 08:06 Notificationsdrwxrwx--- root     sdcard_r          2015-11-25 13:49 Picturesdrwxrwx--- root     sdcard_r          1980-01-01 08:06 Podcastsdrwxrwx--- root     sdcard_r          1980-01-01 08:06 Ringtonesdrwxrwx--- root     sdcard_r          2015-12-03 11:21 baidudrwxrwx--- root     sdcard_r          1980-01-01 08:00 elogdrwxrwx--- root     sdcard_r          2015-12-03 10:51 libsdrwxrwx--- root     sdcard_r          2015-12-03 11:21 soufundrwxrwx--- 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 0tmpfs /dev tmpfs rw,seclabel,nosuid,relatime,mode=755 0 0devpts /dev/pts devpts rw,seclabel,relatime,mode=600 0 0proc /proc proc rw,relatime 0 0sysfs /sys sysfs rw,seclabel,relatime 0 0selinuxfs /sys/fs/selinux selinuxfs rw,relatime 0 0debugfs /sys/kernel/debug debugfs rw,relatime 0 0none /acct cgroup rw,relatime,cpuacct 0 0none /sys/fs/cgroup tmpfs rw,seclabel,relatime,mode=750,gid=1000 0 0none /sys/fs/cgroup/memory cgroup rw,relatime,memory 0 0tmpfs /mnt/asec tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0tmpfs /mnt/obb tmpfs rw,seclabel,relatime,mode=755,gid=1000 0 0none /dev/memcg cgroup rw,relatime,memory 0 0none /dev/cpuctl cgroup rw,relatime,cpu 0 0tmpfs /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,就可以正常使用了。


更多相关文章

  1. Pycharm安装PyQt5的详细教程
  2. 【阿里云镜像】切换阿里巴巴开源镜像站镜像——Debian镜像
  3. Android屏幕分辨率正确获取及PX,DPI,DP,SP等的对应关系
  4. android 获取唯一标识
  5. android拍照与读取相册
  6. Android(安卓)热点开关状态的判断和获取热点ssid
  7. Android软键盘适配问题
  8. Android--SoLoader,android动态加载so库
  9. Android(安卓)命令行编译、打包生成apk文件

随机推荐

  1. Android消息机制
  2. android在EditText中插入表情图片
  3. android 自定义控件学习之三 控件布局常
  4. Android中LocationManager的简单使用,获
  5. Android(安卓)Zip文件解压缩代码
  6. Android中Uri的使用
  7. ANDROID 应用退出
  8. Android利用Fiddler进行网络数据抓包
  9. AndFix解析——(上)
  10. 如何编程实现开启或者关闭GPS