android操作apk的方法总结

APK相关操作总结:

  • 将raw下文件复制到sdcard根目录
  • 判断apk是否已经安装
  • 打开未知来源安装权限设置
  • 跳转去安装apk文件
  • 打开已经安装的apk文件
  • 点击打开或者安装apk

    /**
     * 将raw下文件复制到sdcard根目录
     */
    private fun copyApkToPath(fileName: String): String? {
        val curFilePath = "$copyApkPath/$fileName"
        LegoLog.i(curFilePath)
//        val curFilePath = Environment.getExternalStorageDirectory().absolutePath + "/" + fileName
        val file = File(curFilePath)
        var assetFileStream: InputStream? = null

         assetFileStream = resources.openRawResource(R.raw.intelligentpatrol)
        if (assetFileStream == null) {
            return null
        }
        return if (!file.exists()) {
            val out = FileOutputStream(file)
            val buffer = ByteArray(1024)
            var read: Int = assetFileStream.read(buffer)
            while (read != -1) {
                out.write(buffer, 0, read)
                read = assetFileStream.read(buffer)
            }

            LegoLog.i(logTag + "目标文件复制成功$fileName")
            curFilePath
        } else {
            LegoLog.i(logTag + "需要复制的文件已存在!$fileName")
            curFilePath
        }
    }

    /**
     * 判断apk是否已经安装
     */
    private fun isAvailable(context: Context, packageName: String): Boolean {
        if (curHashMap.isEmpty() || (curHashMap.isNotEmpty() && !curHashMap.containsKey(packageName))) {
            val packageManager: PackageManager = context.packageManager
            // 获取所有已安装程序的包信息
            val pinfo = packageManager.getInstalledPackages(0)
            for (i in pinfo.indices) {
                // 循环判断是否存在指定包名
                if (pinfo[i].packageName.equals(packageName, ignoreCase = true)) {
                    val hasInstallVersion: String? =
                        context.packageManager.getPackageInfo(packageName, 0).versionName

                    val hasInstallVersionCode: Long =
                        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
                            context.packageManager.getPackageInfo(packageName, 0).longVersionCode
                        } else {
                            context.packageManager.getPackageInfo(
                                packageName,
                                0
                            ).versionCode.toLong()
                        }
                    LegoLog.i(logTag + "输出当前获取应用的版本名:$hasInstallVersion")
                    LegoLog.i(logTag + "输出当前获取应用的版本号:$hasInstallVersionCode")
                    when (packageName) {
                        qzpkg -> {
                            if (hasInstallVersionCode >= qzCurVersionCode.toLong()) {
                                curHashMap[qzpkg] = true
                                deleteApkPath(qzfileName)
                            }
                        }
                        ...
                    }
                }
            }
        }
        return curHashMap[packageName] ?: false
    }

    /**
     *    打开未知来源安装权限设置
     */
    @RequiresApi(Build.VERSION_CODES.O)
    private fun startInstallPermissionSettingActivity() {
        val packageURI =
            Uri.parse("package:" + this.packageName) //设置包名,可直接跳转当前软件的设置页面
        val intent =
            Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI)
        try {
            this.startActivity(intent)
        } catch (e: Throwable) {
            showToast("打开安装软件权限界面错误")
        }
    }

    /**
     * 跳转去安装apk文件
     */
    private fun openInstallApk(curfilePath: String) {
        LegoLog.i(logTag + "已经复制成功的文件的路径$curfilePath")
        val install = Intent(Intent.ACTION_VIEW)
        install.flags = Intent.FLAG_ACTIVITY_NEW_TASK
        val apkFile = File(curfilePath)
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O && !this.packageManager.canRequestPackageInstalls()) {
            AlertDialog.Builder()
                .message("安装应用需要打开未知来源权限,请去设置中开启权限")
                .okButtonText("确定")
                .build().apply {
                    setOkBtnClickListener {
                        startInstallPermissionSettingActivity()
                    }
                    show(this@CurMainActivity)
                }
        } else {
            var fileIntent = Intent("android.intent.action.VIEW")
            fileIntent.addCategory("android.intent.category.DEFAULT")
            fileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            val uri: Uri
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                uri = FileProvider.getUriForFile(
                    this.applicationContext,
                    "com.test.mobilepoliceaffair.fileprovider",
                    apkFile
                )
                fileIntent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
            } else {
                fileIntent = Intent(Intent.ACTION_VIEW)
                uri = Uri.fromFile(apkFile)
                fileIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
            }
            fileIntent.setDataAndType(uri, "application/vnd.android.package-archive")

            try {
                this.startActivity(Intent.createChooser(fileIntent, "选择应用"))
            } catch (e: ActivityNotFoundException) {
                showToast("无法安装!")
            }
        }
    }

    /**
     * 打开已经安装的apk文件
     */
    private fun openApkClass(pkg: String, cls: String) {
        try {
            val i = Intent().apply {
                component = ComponentName(
                    pkg,
                    cls
                )
                putExtras(Bundle().apply {
                    putString("record_code", curbah)//备案号
                    putString("user", Gson().toJson(curUser))//用户信息
                    putString("regcon_syscode", PortalCode.log_syscode)//日志需要增加的systemcode
                    LegoLog.i(logTag + Gson().toJson(curUser))
                })
            } //启动指定包名应用
            startActivity(i)
        } catch (e: Exception) {
            LegoLog.i(logTag, "打开已安装的apk失败" + e.message)
            if (curHashMap.containsKey(pkg)) {
                LegoLog.i(logTag, "删除curHaspMap中的存在记录")
                curHashMap.remove(pkg)
            }
            val tipsDialog: TipsDialog = WarningBuilder(this)
                    .tipMsgColor(resources.getColor(R.color.colorAccent))
                    .build()
            tipsDialog.tipMsg("打开Apk失败")
                    .explainText("打开已安装的apk失败" + e.message)
                    .okButtonText("再次尝试")
                    .okButtonClickListener {
                        when (cls) {
                            qzclass -> {
                                openOrInstallApk(qzfileName, qzpkg, qzclass)
                            }
                            ...
                            else -> LegoLog.i(logTag, "不是目标文件安装")
                        }
                        tipsDialog.dismiss()
                    }
            tipsDialog.show(this)
        }
    }

    /**
     * 点击打开或者安装apk
     */
    fun openOrInstallApk(fileName: String, pkgName: String, clsName: String) {
        showLoading("请稍后...")
        if (!BuildConfig.DEBUG && curUser == null) {
            hideLoading()

            val tipsDialog = WarningBuilder(this)
                    .tipMsgColor(resources.getColor(R.color.colorAccent))
                    .build()
            tipsDialog.tipMsg("用户异常")
                    .explainText("当前用户信息异常,请联系管理员")
            tipsDialog.show(this)
            return
        }
        if (isAvailable(MainApplication.applicationContext, pkgName)) {

            hideLoading()
            openApkClass(pkgName, clsName)
        } else {
            copyApkToPath(fileName)?.let {
                hideLoading()
                openInstallApk(it)
            }
            hideLoading()
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值