这几天在做Android应用的远程更新功能,将下载的更新包放在移动设备上指定的文件夹。
用的是 Environment.getExternalStorageDirectory() 这种方法。然后在获取的文件夹中新建一个hkapp文件夹,用来存放下载的apk文件。
那么,这个hkapp文件究竟是在那块存储区域呢?
一開始,看看网上的API,已经这种方法的字面意思。想当然地以为它就是获取SD卡上的文件夹,而不是手机的内部存储。
当然。除了望文生义之外,似乎还有确凿的证据支持我的观点。那就是在执行的时候报错,提示权限不足,也就是要配置訪问外部存储的权限:
plain copy
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
嗯,看上去就是在获取SD卡了...
我有两个手机:
1. 华为C8812,带SD卡,接上电脑之后显示有两个存储设备,而且识别为磁盘。当中。H盘是手机自带的,而I盘就是后来放进去的SD卡。
在程序中用了getExternalStorageDirectory()方法之后,发现hkapp目录的实际位置是在I盘,也就是SD卡上,OK,看上去这个getExternalStorageDirectory方法确实是获取了SD卡。而不是手机自带的存储。
2. 华为C8817,不带SD卡,接上电脑之后仅仅显示一个设备,而且,是作为设备总体来识别,而不单单是个磁盘。
在这个C8817上执行程序之前。我是有点小操心的,由于这个手机没有SD卡啊,会不会执行到一半报错呢?那么实际的情况是,确实报错了,但报的是没有权限訪问外部存储的错,于是也把权限加上去:
plain copy
- <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"></uses-permission>
- <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"></uses-permission>
然后就想了,给了你权限又有什么用呢?反正你终究是没有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.