一般再访问sd卡前都要获取sd卡的路径,以防止不同的厂商有不同的路径配置。Android提供了Environment类来获取系统当前sd卡路径。

Log.d(TAG, Environment.getExternalStorageDirectory().getAbsolutePath());

以手上的三星手机为例,打印出来的结果是

533    09-20    14:29:47.850    D    32105    32105    sdtest          : /storage/emulated/0

adb shell连上手机确认下路径

 root@degasveltechn:/proc/32105 # cat mounts
cat mounts
...
/dev/block/platform/soc.2/by-name/USER /data ext4 rw,seclabel,nosuid,nodev,noatime,discard,journal_checksum,journal_asyn
c_commit,noauto_da_alloc,data=ordered 0 0
...
/data/media /storage/emulated/0 sdcardfs rw,nosuid,nodev,relatime,uid=1023,gid=1023,derive=legacy,reserved=20MB 0 0

/storage/emulated/0 目录是以sdcardfs方式挂载到目录/data/media,/data目录是系统目录,由此可见

Environment.getExternalStorageDirectory()

获取到的是机身内部SD卡的地址,并不是真正外部SD卡的地址。android系统是区分内部SD卡和外部SD卡两种,一般内部SD卡是内部ROM存储空间的一部分切割出来的,逻辑的意义大于物理。

当我们想用如下方法访问SD卡的时候

 File sd = new File(Environment.getExternalStorageDirectory(), "text.txt");
try {
sd.createNewFile();
} catch (IOException e) {
e.printStackTrace();
}

会发现再createNewFile()的时候程序抛出了一个IO异常,系统调用open的时候被返回EACCES文件访问权限错误了。

1036  09-20 14:46:28.850  W 32368 32368 System.err: java.io.IOException: open failed: EACCES (Permission denied)
1037 09-20 14:46:28.850 W 32368 32368 System.err: at java.io.File.createNewFile(File.java:946)
1053 09-20 14:46:28.850 W 32368 32368 System.err: Caused by: libcore.io.ErrnoException: open failed: EACCES (Permission denied

因为我们没有在AndroidManifest.xml里面加入权限使用的声明

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

Android对于SD卡目录的访问权限限制并不是直接通过控制linux内核文件权限rwx标志位来限制应用访问,而是间接通过package management service控制一个文件

/data/system/packages.list

来实现,我们先看下未加入uses-permission声明的时候,该文件的内容是什么

cat /data/system/packages.list | grep sdtest
com.example.sdtest 10155 1 /data/data/com.example.sdtest default none

当前拥有的组权限是none,再增加了user-permission声明之后,再看文件内容变成了

cat /data/system/packages.list | grep sdtest
com.example.sdtest 10155 1 /data/data/com.example.sdtest default 1028,1015

新增了1028和1015组权限。

而1028正好是sdcard_r,因而就间接拥有了SD卡的访问权限。

sd卡的访问的更多相关文章

  1. android 读取SD卡文件

    SD卡作为手机的扩展存储设备,在手机中充当硬盘角色,可以让我们手机存放更多的数据以及多媒体等大体积文件.因此查看SD卡的内存就跟我们查看硬盘的剩余空间一样,是我们经常操作的一件事,那么在Android ...

  2. 【译】如何在 Android 5.0 上获取 SD卡 的读写权限

    因为最近项目需要,涉及到 SD卡 的读写操作,然而申请 <!-- 读写权限 --> <uses-permission android:name="android.permi ...

  3. 无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

    1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name= ...

  4. system权限无法访问外挂SD卡

    总结Android应用system权限无法访问SD卡问题 包括android1.6 解决方案http://hi.baidu.com/yunlongchn/item/7d6636d8547317ffca ...

  5. SD卡之二:SD总线访问模式

    SD 卡是以命令.回应.数据流进行通讯. 1.命令:命令的长度是48位,命令以'0'开始,第2位为'1'表示主机发往SD卡的命令,最后以CRC和结束位'1'结尾. 2.回应:回应的长度是48位或者13 ...

  6. RAM、DRAM、SD卡

    catalogue . ROM.RAM.DRAM.SRAM和FLASH的区别 . 内存工作原理 . DRAM基本结构与原理 . SD卡基本结构与原理 1. ROM.RAM.DRAM.SRAM和FLAS ...

  7. Android 数据库SQLite 写入SD卡

    如果手机没有root,数据库文件是无法查看到的,不方便调试. 最好的办法是把数据库写进SD卡. 修改的地方有两处: 1.在你的helper类中把数据库文件名称 DATABASE_NAME 由原来的一个 ...

  8. Android中使用SQLiteOpenHelper管理SD卡中的数据库

    使用Android中自带的SQLiteOpenHelper可以完成数据库的创建与管理,但有两点局限: (1)数据库创建在内存卡中,大小受限,创建位置位于/data/data/应用程序名/databas ...

  9. sd 卡驱动--基于高通平台

    点击打开链接 内容来自以下博客: http://blog.csdn.net/qianjin0703/article/details/5918041 Linux设备驱动子系统第二弹 - SD卡 (有介绍 ...

随机推荐

  1. 最新flowable研究学习及其汉化flowable6.3中文

    flowable 是activiti的分支,现在感觉比activiti要强大一些,官网是 https://flowable.org/ 下载最新的6.31版本. 放到tomcat下面,汉化需要对flow ...

  2. 代码重复率检查工具jsinspect

    检查重复代码,去掉冗余代码. 安装: npm install -g jsinspect 用法:jsinspect [options] <paths ...> 检测复制粘贴和结构类似的Jav ...

  3. openjudge-2的100次方阶乘

    开始进行的第一天 #include <stdio.h> #include <string.h> int main() { int n; scanf("%d" ...

  4. 原生js实现轮播图原理

    轮播图的原理1.图片移动实现原理:利用浮动将所有所有照片依次排成一行,给这一长串图片添加一个父级的遮罩,每次只显示一张图,其余的都隐藏起来.对图片添加绝对定位,通过控制left属性,实现照片的移动. ...

  5. lintcode671 循环单词

    循环单词   The words are same rotate words if rotate the word to the right by loop, and get another. Cou ...

  6. java学习笔记-9.违例差错控制

      1.违例规范是告诉程序员这个方法可能抛出哪些类型的异常.他的格式在方法声明中,位于自变量(参数)列表的后面,如void f() throws tooBig, tooSmall, divZero { ...

  7. 【转载】JAVA常见面试题及解答(精华)

     JAVA常见面试题及解答(精华)       1)transient和volatile是java关键字吗?(瞬联) 如果用transient声明一个实例变量,当对象存储时,它的值不需要维持.例如: ...

  8. SIG蓝牙mesh笔记2_mesh组成

    目录 SIG 蓝牙 mesh 组成 mesh网络概述 网络和子网 设备和节点 devices & nodes 入网 mesh中的几个概念 智能插座例子 SIG 蓝牙 mesh 组成 mesh网 ...

  9. es6从零学习(四):Class的继承

    es6从零学习(四):Class的继承 一:继承的方式 1.Class 可以通过extends关键字实现继承 class Point { } class ColorPoint extends Poin ...

  10. Coprime Sequence(前后缀GCD)

    Description Do you know what is called ``Coprime Sequence''? That is a sequence consists of $n$ posi ...