美文网首页
Android下载apk到本地,并安装

Android下载apk到本地,并安装

作者: 因为我的心 | 来源:发表于2023-12-13 15:20 被阅读0次

1、效果图

效果图.png

注意:

  • 1、声明权限,并动态获取权限
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />

    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
    <!--在SDCard中创建与删除文件权限-->
    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
        tools:ignore="ProtectedPermissions" />
    <uses-permission android:name="android.permission.VIBRATE" />
  • 2、Application中添加requestLegacyExternalStorage
  <application
        android:allowBackup="true"
        android:dataExtractionRules="@xml/data_extraction_rules"
        android:fullBackupContent="@xml/backup_rules"
        android:icon="@mipmap/ic_launcher"
        android:name=".MyApplication"
        android:label="@string/app_name"
        android:roundIcon="@mipmap/ic_launcher_round"
        android:supportsRtl="true"
        android:theme="@style/AppTheme"
        android:requestLegacyExternalStorage="true"
        android:networkSecurityConfig="@xml/network_security_config"
        >
  • 3、network_security_config.xml
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true" />
</network-security-config>

2、使用

   //------------APP内部下载和安装--------------
            var url = "https://chatplus.buzz/download/chatplus-android.apk"
            //var url = "https://storage-asura.ruigushop.com/wms/client/73500430201577474/wmstest0.5.221017.apk"

           //获取本地的下载路径
           var localPath = FileUtils.getApkFilePath(MyApplication.instance, url)
           //获取文件名
           var fileName = FileUtils.getFileName(MyApplication.instance, url)

            var filePath = localPath+fileName
            LogUtils.debugInfo("-----filePath: ${filePath}---文件名:${fileName}")
            val file = File(filePath)
           if (file.exists()){
               //文件存在
               progressBar.text = "100%"
               progressBar.progress = 100.0
               //下载完成,去安装apk
               var intent =  FileUtils.openApkFile(context, File(filePath))
               intent?.let {
                   startActivity(context,it,null)
               }
           }else{
               //文件不存在
               RequestNetDialog.showDialog(activity)
               mainScope.launch {
                   downLoad(
                       tag = "appDown",
                       url = url,
                       savePath = localPath,
                       saveName = fileName,
                       reDownload = true,
                       loadListener = object : OnDownLoadListener {
                           override fun onDownLoadPrepare(key: String) {

                           }

                           override fun onDownLoadError(key: String, throwable: Throwable) {
                               RequestNetDialog.hideDialog()
                               LogUtils.debugInfo("---下载报错------key:${throwable.toString()}")
                           }

                           override fun onDownLoadSuccess(key: String, path: String, size: Long) {
                               LogUtils.debugInfo("---下载完成------key:${key}")
                               //下载完成,去安装apk
                               var intent =  FileUtils.openApkFile(context, File(filePath))
                               intent?.let {
                                   startActivity(context,it,null)
                               }

                           }



                           override fun onDownLoadPause(key: String) {

                           }

                           override fun onUpdate(
                               key: String,
                               progress: Int,
                               read: Long,
                               count: Long,
                               done: Boolean
                           ) {
                               RequestNetDialog.hideDialog()
                               progressBar.text = "${progress}%"
                               progressBar.progress = progress.toDouble()
                               LogUtils.debugInfo("---下载进度------progress:${progress}")
                           }

                       })
               }
           }

3、获取app本地路径

package com.asura.android.tmspda.util;

import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Build;
import android.os.Environment;

import androidx.core.content.FileProvider;

import com.asura.android.tmspda.MyApplication;

import java.io.File;

public class FileUtils {

    /**
     * 获取app本地的路径
     *
     * @param context
     * @param downLoadUrl
     * @return
     */
    public static String getApkFilePath(Context context, String downLoadUrl) {
        if (Environment.getExternalStorageState().equals(
                Environment.MEDIA_MOUNTED)) {
            File external = MyApplication.Companion.getInstance().getExternalFilesDir(null);
            if (external != null) {
                return external.getAbsolutePath();
            }
        }
        return MyApplication.Companion.getInstance().getFilesDir().getAbsolutePath();
    }


    /**
     * 获取下载的文件名字
     *
     * @param context
     * @param downLoadUrl
     * @return
     */
    public static String getFileName(Context context, String downLoadUrl) {
        String fileName = "";
        if (downLoadUrl.endsWith(".apk")) {
            int index = downLoadUrl.lastIndexOf("/");
            if (index != -1) {
                fileName = downLoadUrl.substring(index);
            } else {
                fileName = context.getPackageName() + ".apk";
            }
        } else {
            fileName = "";
        }
        return fileName;
    }

    /**
     * 安装apk
     *
     * @param context
     * @param outputFile
     * @return
     */
    public static Intent openApkFile(Context context, File outputFile) {
        Intent intent = new Intent();
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
        intent.setAction(Intent.ACTION_VIEW);
        Uri uri;
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            uri = FileProvider.getUriForFile(context, context.getPackageName() + ".provider.fileprovider", outputFile);
        } else {
            uri = Uri.fromFile(outputFile);
        }
        intent.setDataAndType(uri, "application/vnd.android.package-archive");
        return intent;
    }
}

4、XML中声明FileProvider

  <provider
            android:name=".base.FileProvider"
            android:authorities="${applicationId}.provider.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true">
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/provider_paths" />
        </provider>

5、provider_paths.xml

<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">
    <external-path name="external_files" path="."/>
</paths>

6、FileProvider.java

/**
 * @Author lyy
 */
public class FileProvider extends androidx.core.content.FileProvider {
}

相关文章

网友评论

      本文标题:Android下载apk到本地,并安装

      本文链接:https://www.haomeiwen.com/subject/tcnbgdtx.html