getUriForDownloadedFile(long downloadId)这个方法可以返回文件的Uri地址也就是content形式的,对于Android N来说不能直接通过分享一个file path在应用直接进行文件的分享,必须通过content也就是uri的形式进行文件的分享。
通过File类型进行文件分享对于文件的权限是不能进行动态控制的,这样就会造成很多的安全性问题,但是通过Uri的形式进行文件分享是能够保证文件的安全的,通过share一个Uri,接收者可以动态的申请获取另外一个应用的访问权限,进行文件访问。
Google一直想在文件分享上面做到安全,从Android N开始如果分享file://...给另外一个应用将会收到FileUriExposedException(https://developer.android.com/reference/android/os/FileUriExposedException.html)
这个异常在接受分享的应用没有对分享路径访问权限的时候,比如分享一个storage存储的文件,但是没有READ_EXTETAL_STORAGE,或者分享应用data/data下面存储的文件。
当将应用的target改成24或者更高的版本的时候,分享一个file://时将会抛出这个异常。
如果是自己新建的一个文件想要分享给其他的应用可以通过FileProvider提供的方法转换为Uri然后分享给另外的应用。
在Android N以前我们获取文件下载名称就是通过DownloadManager中的COLUMN_LOCAL_FILENAME得到的,但是这个Column在Android N开始这个Column被遗弃了。所以在Android N开始我们可以使用Column-COLUMN_LOCAL_URI来获取文件存储的uri。另外DownloadManager在api 11开始提供了getUriForDownloadFile(long downloadId)放来获取下载文件的uri。
COLUMN_LOCAL_Filename COLUMN_LOCAL_URI dm.getUriForDownloadFile PackageInstaller 接受类型
4.4 /sto.../ing_2.apk
file:///storag...string_2.apk
file:///storag...tring_2.apk
file
5.0 /data....bin
content://....loads/22
content://....ownloads/22
file
M /stora...tring_2.apk
file:///....alstring_2.apk
content://....nloads/12
file
N
file://...olo.pluralstring_2.apk
content://...s/21
content
在Android 4.4上面getUriForDownloadFile()得到的uri地址和COLUMN_LOCAL_URI的值是一样的,得到的uri类型是file类型的。
在Android5.0上面得到的getUriForDownloadFile()和COLUMN_LOCAL_URI的值是一样的,但是类型是content类型的。
在AndroidM上面getUriForDownloadFile()得到的类型是content类型的,但是COLUMN_LOCAL_URI得到的是file类型的,两个的值是不同的。
在AndroidN上getUriForDownloadFile()的值是content类型的uri,COLUMN_LOCAL_URI的值是file类型的。
由于在Android N上面因为权限问题不能通过file进行文件的分享,所以在Android N上面文件下载以后如果直接获取COLUMN_LOCAL_URI的值然后调用package installer进行安装,首先可以通过FileProvider的getUriForFile()生成一个content类型的uri,然后通知packageInstaller进行安装。但是content类型的uri在Android N之前是不支持的,所以在Android N之前不能转换成uri。
AppsOrange中的自动安装调用PackageManager中自动安装方式的时只能接受file类型的Uri,这个和直接调用PackageInstaller进行安装是不同的。