Android6.0引入的动态权限控制(Runtime Permissions),Android7.0又引入“私有目录被限制访问”,“StrictMode API 政策” 安卓 8.0 未知来源
1.资源文件 添加xml 文件夹,添加filepaths 文件
<?xml version="1.0" encoding="utf-8"?> <resources> <paths> <external-path path="" name="download" /> </paths> </resources>
2.定义广播接收器,接收下载完成,AndroidMainifest 添加注册
public class UpdateBroadcastReceiver extends BroadcastReceiver { @SuppressLint("NewApi") @Override public void onReceive(Context context, Intent intent) { long dwonloadID = intent.getLongExtra( DownloadManager.EXTRA_DOWNLOAD_ID, -1); Intent install = new Intent(context, UpdateActivity.class); install.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); install.putExtra(DownloadManager.EXTRA_DOWNLOAD_ID, dwonloadID); context.startActivity(install); } }
<receiver android:name=".receiver.UpdateBroadcastReceiver"> <intent-filter> <action android:name="android.intent.action.DOWNLOAD_COMPLETE" /> </intent-filter> </receiver>
3.FileProvider 注册
<provider android:name="android.support.v4.content.FileProvider" android:authorities="com.zonesun.erp.jxygzzj.fileProvider" android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/filepaths" /> </provider>
4.安装界面
public class UpdateActivity extends BaseActivity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); checkIsAndroidO(); } /** * 判断是否是8.0,8.0需要处理未知应用来源权限问题,否则直接安装 */ private void checkIsAndroidO() { if (Build.VERSION.SDK_INT >= 26) { //来判断应用是否有权限安装apk boolean installAllowed = getPackageManager().canRequestPackageInstalls(); //有权限 if (installAllowed) { //安装apk installApk(); } else { //无权限 申请权限 // ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.REQUEST_INSTALL_PACKAGES}, 5); Uri packageURI = Uri.parse("package:" + getPackageName()); //注意这个是8.0新API Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI); startActivityForResult(intent, 8); } } else { installApk(); } } @Override public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); Toast.makeText(UpdateActivity.this, "show", Toast.LENGTH_SHORT).show(); switch (requestCode) { case 5: //有注册权限且用户允许安装 if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) { installApk(); } else { //将用户引导至安装未知应用界面。 Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES); startActivityForResult(intent, 6); } break; } } /** * 安装APK */ private void installApk() { Intent intent = new Intent(Intent.ACTION_VIEW); String apkName=context.getSharedPreferences("downloadcomplete", 0).getString("apk",""); LogUtils.v("installApk", apkName); File file = new File(Environment.getExternalStorageDirectory() + "/" + Environment.DIRECTORY_DOWNLOADS, apkName); if (file == null) { T.showLong(UpdateActivity.this, R.string.qxlzdazbaz); return; } LogUtils.v("installApk", Build.VERSION.SDK_INT); if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // Uri apkUri = // FileProvider.getUriForFile(context, "com.zonesun.erp.jxygzzj.fileProvider", file); Uri apkUri = FileProvider.getUriForFile(this, "com.zonesun.erp.jxygzzj.fileProvider", file); LogUtils.v("installApk", apkUri.toString()); intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); intent.setDataAndType(apkUri, "application/vnd.android.package-archive"); } else { intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); Uri uri = Uri.fromFile(file); LogUtils.v("installApk", uri.toString()); intent.setDataAndType(uri, "application/vnd.android.package-archive"); } startActivity(intent); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); switch (requestCode) { case 8: installApk(); break; } } @Override public boolean onKeyDown(int keyCode, KeyEvent event) { // TODO Auto-generated method stub if (keyCode == KeyEvent.KEYCODE_BACK) { } return super.onKeyDown(keyCode, event); } }
注册
<activity android:name=".activity.UpdateActivity" android:screenOrientation="portrait" android:theme="@style/AppTheme" />
downloadmanger 下载
public void download(Context context, String apkURL, String name) { SharedPreferences preferences = context.getSharedPreferences( "downloadcomplete", 0); SharedPreferences.Editor editor = preferences.edit(); editor.putString("apk", name); editor.commit(); DownloadManager downloadManager = (DownloadManager) context.getSystemService(Context.DOWNLOAD_SERVICE); Uri uri = Uri.parse(apkURL); DownloadManager.Request request = new DownloadManager.Request(uri); request.setDestinationInExternalPublicDir(Environment.DIRECTORY_DOWNLOADS, name);//表示设置下载地址为sd卡的Trinea文件夹,文件名为参数name try { request.setDescription(context.getString(R.string.app_describe)); } catch (Exception e) { e.printStackTrace(); } request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_VISIBLE_NOTIFY_COMPLETED); request.setMimeType("application/vnd.android.package-archive"); request.allowScanningByMediaScanner(); request.setVisibleInDownloadsUi(true); final long refernece = downloadManager.enqueue(request);
}
参考: