这几天在做Android应用的远程更新功能,将下载的更新包放在移动设备上指定的目录。用的是 Environment.getExternalStorageDirectory() 这个方法,然后在获取的目录中新建一个hkapp文件夹,用来存放下载的apk文件。
那么,这个hkapp文件到底是在那块存储区域呢?
一开始,看看网上的API,已经这个方法的字面意思,想当然地以为它就是获取SD卡上的目录,而不是手机的内部存储。当然,除了望文生义之外,似乎还有确凿的证据支持我的观点,那就是在运行的时候报错,提示权限不足,也就是要配置访问外部存储的权限:
嗯,看上去就是在获取SD卡了...
我有两个手机:
1. 华为C8812,带SD卡,接上电脑之后显示有两个存储设备,并且识别为磁盘,其中,H盘是手机自带的,而I盘就是后来放进去的SD卡。
在程序中用了getExternalStorageDirectory()方法之后,发现hkapp文件夹的实际位置是在I盘,也就是SD卡上,OK,看上去这个getExternalStorageDirectory方法确实是获取了SD卡,而不是手机自带的存储。
2. 华为C8817,不带SD卡,接上电脑之后只显示一个设备,并且,是作为设备整体来识别,而不单单是个磁盘。
在这个C8817上运行程序之前,我是有点小担心的,因为这个手机没有SD卡啊,会不会运行到一半报错呢?那么实际的情况是,确实报错了,但报的是没有权限访问外部存储的错,于是也把权限加上去:
然后就想了,给了你权限又有什么用呢?反正你终究是没有SD卡在里面,必然要继续报错嘛。于是重新运行,发现整个下载过程一切正常,没有报错!hkapp文件夹也正常建立了,但位置是在我原本以为的”内部存储“中,apk文件也顺利地进去了。
那么,到这里,有点错乱了,这个”getExternalStorageDirectory()“ 到底是获取外部存储还是内部存储呢?
其实这两个存储都是外部储存,真正的内部储存位置是data/data/包名
官方推荐 使用getExternalFilesDir(String)
or getExternalCacheDir()。
并且不需要申请权限
使用
getExternalFilesDir(String)
存储数据时候,系统在删除应用时,会把里面的数据也清楚,这样的话,里面的内容就不会长期留在手机里。
Return the primary external storage directory. This directory may not currently be accessible if it has been mounted by the user on their computer, has been removed from the device, or some other problem has happened. You can determine its current state with getExternalStorageState()
.
Note: don't be confused by the word "external" here. This directory can better be thought as media/shared storage. It is a filesystem that can hold a relatively large amount of data and that is shared across all applications (does not enforce permissions). Traditionally this is an SD card, but it may also be implemented as built-in storage in a device that is distinct from the protected internal storage and can be mounted as a filesystem on a computer.
On devices with multiple users (as described by UserManager
), each user has their own isolated external storage. Applications only have access to the external storage for the user they're running as.
In devices with multiple "external" storage directories, this directory represents the "primary" external storage that the user will interact with. Access to secondary storage is available through
Applications should not directly use this top-level directory, in order to avoid polluting the user's root namespace. Any files that are private to the application should be placed in a directory returned byContext.getExternalFilesDir
, which the system will take care of deleting if the application is uninstalled. Other shared files should be placed in one of the directories returned bygetExternalStoragePublicDirectory(String)
.
Writing to this path requires the WRITE_EXTERNAL_STORAGE
permission, and starting in read access requires the READ_EXTERNAL_STORAGE
permission, which is automatically granted if you hold the write permission.
Starting in KITKAT
, if your application only needs to store internal data, consider using getExternalFilesDir(String)
or getExternalCacheDir()
, which require no permissions to read or write.
This path may change between platform versions, so applications should only persist relative paths.