前言:你的apk文件即使有文件读取权限,若想安装下载后的app,我们需要将apk文件暴露给系统安装进程
apk安装所需权限
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.REPLACE_EXISTING_PACKAGE"/> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/><!-- 8.0必要权限 -->第一步、
在AndroidManifest.xml添加文件提供者
<provider android:name="android.support.v4.content.FileProvider" android:authorities="${applicationId}.fileProvider" --------${applicationId}为你的报包名 .fileProvider内容提供者的名字 android:grantUriPermissions="true" android:exported="false"> <!-- 元数据 --> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> ----------file_paths 见第二步 </provider>第二步、
在xml文件夹中创建file_paths.xml (res\xml\file_paths.xml)
<?xml version="1.0" encoding="utf-8"?> <resources> <external-files-path path="/download" name="download"/> </resources><external-files-path>代表的是/storage/emulated/0/Android/data/你的包名/files/目录、与Context.getExternalFilesDir()方法获得的相同
所以上面的意思就是将Context.getExternalFilesDir()+“/download"文件夹下面的数据暴露给系统
具体地址,根据你的需求来定
<files-path name="name" path="path" /> 物理路径相当于Context.getFilesDir() + /path/ <cache-path name="name" path="path" /> 物理路径相当于Context.getCacheDir() + /path/ <external-path name="name" path="path" /> 物理路径相当于Environment.getExternalStorageDirectory() + /path/ <external-files-path name="name" path="path" /> 物理路径相当于Context.getExternalFilesDir(String) + /path/ <external-cache-path name="name" path="path" /> 物理路径相当于Context.getExternalCacheDir() + /path/第三步(正式安装)、
eg:假如我的文件放在了Context.getExternalFilesDir()+"/download"+"/test.apk"
则:
Intent intent = new Intent(Intent.ACTION_VIEW); String filePath=Context.getExternalFilesDir()+"/download"+"/test.apk"; File file = new File(filePath); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); if (Build.VERSION.SDK_INT >= 24) {//大于7.0使用此方法 Uri apkUri =FileProvider.getUriForFile(context, "你的包名.fileProvider", file);///-----ide文件提供者名 //添加这一句表示对目标应用临时授权该Uri所代表的文件 intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); }else {//小于7.0就简单了 // 由于没有在Activity环境下启动Activity,设置下面的标签 intent.setDataAndType(Uri.fromFile(file),"application/vnd.android.package-archive"); } startActivity(intent);