android 下载安装apk详情记载
程序员文章站
2022-06-21 19:14:05
1.权限相关1.1 manifest相关
1.权限相关
1.1 manifest相关
<!-- 打开系统安装界面需要此权限--> <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/> <uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" /> <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<application android:usesCleartextTraffic="true"> 支持明文请求网络,例如http请求
android 7.0以上版本禁止分享本地文件到第三方应用 差不都就是这个意思,反正就是不添加这个provider就不能唤起系统安装进程 <!-- 非androidx 使用这个android.support.v4.content.FileProvider--> <provider android:name="androidx.core.content.FileProvider" android:authorities="com.zznode.zznodesdp.fileprovider" //此处包名+.fileprovider android:exported="false" android:grantUriPermissions="true"> <meta-data android:name="android.support.FILE_PROVIDER_PATHS" android:resource="@xml/file_paths" /> </provider>
在res目录下创建xml文件夹 ,创建file_paths.xml文件
此处是暴露内存所有地址,path具体位置可以设置添加
<?xml version="1.0" encoding="utf-8"?> <paths> <external-path path="." name="file_paths" /> </paths>
2.activity代码
public class SdpActivity extends AppCompatActivity implements EasyPermissions.PermissionCallbacks{ private File apkFile; private ProgressDialog dialog; final String apkUrl = "http://180.168.70.186:8808/apk/app-release.apk"; String phoneNo; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_sdp); Intent intent = getIntent(); Uri data = intent.getData(); phoneNo = data.getQueryParameter("phoneNo"); String[] perms = {Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.READ_EXTERNAL_STORAGE,}; if (EasyPermissions.hasPermissions(this, perms)) { checkInstallApp(); } else { //没有权限进行提示且申请权限 EasyPermissions.requestPermissions(this,"应用需要权限,请允许", 0, perms); } } private void checkInstallApp(){ //拥有权限进行操作 if (checkAppInstalled(this,"com.zznode.esiflutter")){ System.out.println("已经安装sdp"); intentSdp(); }else { //未安装sdp 下载apk showNormalDialog(); } } //跳转到sdp private void intentSdp(){ Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse("zznodesdp://login?phoneNo="+phoneNo)); startActivity(intent); finish(); } @Override public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) { super.onRequestPermissionsResult(requestCode, permissions, grantResults); EasyPermissions.onRequestPermissionsResult(requestCode, permissions, grantResults, this); } private boolean checkAppInstalled(Context context, String pkgName) { if (pkgName== null || pkgName.isEmpty()) { return false; } final PackageManager packageManager = context.getPackageManager(); List<PackageInfo> info = packageManager.getInstalledPackages(0); if(info == null || info.isEmpty()) return false; for ( int i = 0; i < info.size(); i++ ) { if(pkgName.equals(info.get(i).packageName)) { return true; } } return false; } private void showNormalDialog(){ final AlertDialog.Builder normalDialog = new AlertDialog.Builder(this); // normalDialog.setIcon(R.drawable.icon_dialog); normalDialog.setTitle("未安装能力提升APP是否安装?"); normalDialog.setPositiveButton("安装", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { //...To-do downloadAPK(apkUrl); System.out.println("开始更新"); } }); normalDialog.setNegativeButton("取消", new DialogInterface.OnClickListener() { @Override public void onClick(DialogInterface dialog, int which) { intentSdp(); } }); // 显示 normalDialog.show(); } public void downloadAPK(final String apkUrl){ //启动异步任务处理 new AsyncTask<Void, Integer, Void>() { //1主线程显示提示试图 @Override protected void onPreExecute() { dialog = new ProgressDialog(SdpActivity.this); dialog.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL); dialog.show(); apkFile = new File(getExternalFilesDir(null), "update.apk"); } //2分线程,联网请求 @Override protected Void doInBackground(Void... params) { try{ //1 得到链接对象 URL url = new URL(apkUrl); HttpURLConnection connection = (HttpURLConnection) url.openConnection(); connection.setConnectTimeout(5000); connection.setReadTimeout(15000); connection.connect(); int responseCode = connection.getResponseCode(); if(responseCode == 200){ //设置dialog最大进度 dialog.setMax(connection.getContentLength()); InputStream is = connection.getInputStream(); FileOutputStream fos = new FileOutputStream(apkFile); byte[] buffer = new byte[1024]; int len = 0; while ((len = is.read(buffer)) != -1){ fos.write(buffer, 0, len); //在分线程发布进度 publishProgress(len); // dialog.incrementProgressBy(len); } fos.close(); is.close(); } connection.disconnect(); installAPK(); }catch (Exception e){ try {//携带下载链接跳转到浏览器 if (!TextUtils.isEmpty(apkUrl) && apkUrl.contains("http")) { Intent intent = new Intent(); intent.setAction("android.intent.action.VIEW"); Uri content_url = Uri.parse(apkUrl); intent.setData(content_url); startActivity(intent); } } catch (Exception eer) { //异常处理 eer.printStackTrace(); } e.printStackTrace(); } return null; } //3主线程,更新界面 @Override protected void onPostExecute(Void aVoid) { dialog.dismiss(); } //在主线程中更新进度 (在publishProgress之后执行) @Override protected void onProgressUpdate(Integer... values) { dialog.incrementProgressBy(values[0]); } }.execute(); } /** * 启动安装apk */ private void installAPK() { Intent intent = new Intent(Intent.ACTION_VIEW); //判断是否是AndroidN以及更高的版本 if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { intent.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION); //authority值需和manifest中匹配,包名+.fileprovider Uri contentUri = FileProvider.getUriForFile(this, "com.zznode.zznodesdp.fileprovider", apkFile); intent.setDataAndType(contentUri, "application/vnd.android.package-archive"); } else { intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive"); intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK); } startActivity(intent); finish(); } @Override public void onPermissionsGranted(int requestCode, @NonNull List<String> perms) { checkInstallApp(); } @Override public void onPermissionsDenied(int requestCode, @NonNull List<String> perms) { finish(); } }
3.build.gradle中添加依赖
//需要宿主引用 implementation 'pub.devrel:easypermissions:1.2.0'
本文地址:https://blog.csdn.net/kailengchen/article/details/108724756