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()
}
}