Android app在后台静默升级,安装成功之后自动打开app

2024-05-12 18:48

本文主要是介绍Android app在后台静默升级,安装成功之后自动打开app,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、使用Android自带的DownloadManager远程下载APK;

    val handler = Handler()private fun downLoadApk(apkUrl: String) {//创建request对象val request: DownloadManager.Request =DownloadManager.Request(Uri.parse(apkUrl))//显示还是隐藏 隐藏加权限:DOWNLOAD_WITHOUT_NOTIFICATION//request.setNotificationVisibility(DownloadManager.Request.VISIBILITY_HIDDEN)//设置通知栏的标题request.setTitle("下载")//设置通知栏的messagerequest.setDescription("正在下载.....")//设置下载文件类型request.setMimeType("application/vnd.android.package-archive")//设置文件存放目录request.setDestinationInExternalFilesDir(this,Environment.DIRECTORY_DOWNLOADS,"update.apk")//获取系统服务val downloadManager = getSystemService(DOWNLOAD_SERVICE) as DownloadManager//进行下载val id = downloadManager.enqueue(request)val runnable = object : Runnable {override fun run() {val cursor = downloadManager.query(DownloadManager.Query().setFilterById(id))cursor?.apply {if (moveToFirst()) {val title =getString(getColumnIndex(DownloadManager.COLUMN_TITLE))val uri =getString(getColumnIndex(DownloadManager.COLUMN_LOCAL_URI))val current =getInt(getColumnIndex(DownloadManager.COLUMN_BYTES_DOWNLOADED_SO_FAR))val total =getInt(getColumnIndex(DownloadManager.COLUMN_TOTAL_SIZE_BYTES))LogUtil.e(current.toString())//获取下载状态信息if (getInt(getColumnIndex(DownloadManager.COLUMN_STATUS)) == DownloadManager.STATUS_SUCCESSFUL) {//下载完成handler.removeCallbacksAndMessages(null)LogUtil.e("下载完成:$uri")val file = File(uri.substring(7)RootUtil.sinlenceInstallApk(file)}}}cursor?.close()handler.postDelayed(this, 1000)}}handler.postDelayed(runnable, 1000)}

二,下载完之后,通过封装的RootUtils工具类安装重启

object RootsUtils {/*** 判断手机是否有root权限*/private fun sysHasRootPerssion(): Boolean {var printWriter: PrintWriter?var process: Process? = nulltry {process = Runtime.getRuntime().exec("su")printWriter = PrintWriter(process.outputStream)printWriter.flush()printWriter.close()val value = process.waitFor()return returnResult(value)} catch (e: Exception) {e.printStackTrace()} finally {process?.destroy()}return false}/*** root下执行cmd的返回值*/private fun returnResult(value: Int): Boolean {// 代表成功return when (value) {0 -> {true}1 -> { // 失败false}else -> { // 未知情况false}}}/*** root下静默安装*/private fun rootSlienceInstallApk(apkPath: String): Boolean {var printWriter: PrintWriter?var process: Process? = nulltry {process = Runtime.getRuntime().exec("su")printWriter = PrintWriter(process.outputStream)printWriter.println("pm install -r $apkPath")printWriter.flush()printWriter.close()execLinuxCommand()val value = process.waitFor()return returnResult(value)} catch (e: Exception) {e.printStackTrace()} finally {process?.destroy()}return false}/*** 通过Linux延时执行重启*/private fun execLinuxCommand() {val cmd = "sleep 1; am start -n com.xx.xxx/.LunchActivity"//Runtime对象val runtime = Runtime.getRuntime()try {val localProcess = runtime.exec("su")val localOutputStream = localProcess.outputStreamval localDataOutputStream = DataOutputStream(localOutputStream)localDataOutputStream.writeBytes(cmd)localDataOutputStream.flush()LogUtil.e("设备准备重启")} catch (e: IOException) {e.printStackTrace()}}fun rootInstallApk(file: File) {if (!sysHasRootPerssion()) {LogUtil.e("系统尚无Root权限")return}LogUtil.i("系统有Root权限")if (!file.exists()) {LogUtil.e("尚无APK文件")return}//静默安装if (rootSlienceInstallApk(file.path)) {LogUtil.d("静默安装成功")} else {LogUtil.e("静默安装失败!!!")}}
}

三、使用的是Android7.1已经root的,经过反复测试,是可以静默安装并且安装成功之后自动重启成功的;

四、单个应用,在安装成功app之后,这个App的进程都被杀掉了,根本收不到广播重启打开了,如果非要使用广播打开的话,需要另外做一个无UI的App,做成双守护进程,把版本升级任务都交给它,通过它重启打开已安装的App,广播代码如下;

class BootReceiver : BroadcastReceiver() {override fun onReceive(context: Context, intent: Intent) {val action = intent.actionintent.dataString?.substring(8)?.apply {LogUtil.d("BootReceiver onReceive():接收到Intent.getAction() = " + intent.action + " , 包名 = " + intent.dataString)/*** 接收安装广播* android.intent.action.PACKAGE_ADDED*/if (action == Intent.ACTION_PACKAGE_ADDED) {LogUtil.d("BootReceiver onReceive():安装了:" + this + "包名的程序")}/*** 接收卸载广播* android.intent.action.PACKAGE_REMOVED*/if (action == Intent.ACTION_PACKAGE_REMOVED) {LogUtil.d("BootReceiver onReceive():卸载了:" + this + "包名的程序")}/*** 接收更新广播* android.intent.action.PACKAGE_REPLACED*/if (action == Intent.ACTION_PACKAGE_REPLACED) {LogUtil.d("BootReceiver onReceive():更新了:" + this + "包名的程序,context.getPackageName()=" + context.packageName)//更新的软件包名是否和我的工程一致if (this == context.packageName) {//更新完后打开val it = Intent()it.setClassName(this, "$this.xxxActivity") //启动类it.action = "android.intent.action.MAIN" //首个启动类actionit.addCategory("android.intent.category.LAUNCHER") //放入程序列表//it.addCategory("android.intent.category.HOME");                           //作为桌面,Home键打开,可做启动默认程序it.addCategory("android.intent.category.DEFAULT") //隐式打开,如果没main可有,如果main可有可无it.flags = Intent.FLAG_ACTIVITY_NEW_TASKcontext.startActivity(it)}}/*** 接收重启广播* android.intent.action.PACKAGE_REPLACED*/if (action == Intent.ACTION_PACKAGE_RESTARTED) {LogUtil.d("BootReceiver onReceive():重启了:" + this + "包名的程序")}/*** 接收开机广播* android.intent.action.BOOT_COMPLETED*/if (action == Intent.ACTION_BOOT_COMPLETED) {LogUtil.d("BootReceiver onReceive():仪器开机,开启了:" + this + "包名的程序")}}}
}
        <receiverandroid:name=".install.BootReceiver"android:label="@string/app_name"> <!-- app open/delete/upgrade/completed receiver --><intent-filter><action android:name="android.intent.action.PACKAGE_ADDED" /> <!-- add --><action android:name="android.intent.action.PACKAGE_REPLACED" /> <!-- update --><action android:name="android.intent.action.PACKAGE_REMOVED" /> <!-- delete --><action android:name="android.intent.action.PACKAGE_RESTARTED" /> <!-- restart --><action android:name="android.intent.action.BOOT_COMPLETED" /> <!-- completed --><data android:scheme="package" /></intent-filter></receiver>

五、在静默安装之后执行重启代码

    /*** 执行此命令后:BootReceiver 监听到Intent.ACTION_PACKAGE_REPLACED,然后自启动* */fun rootStartApk(packageName: String, activityName: String): Boolean {val isSuccess = falsevar process: Process? = nulltry {process = Runtime.getRuntime().exec("su")val printWriter = PrintWriter(process.outputStream)printWriter.println("am start -n $packageName/.$activityName")printWriter.flush()printWriter.close()val value = process.waitFor()return returnResult(value)} catch (e: java.lang.Exception) {e.printStackTrace()} finally {process?.destroy()}return isSuccess}

 

这篇关于Android app在后台静默升级,安装成功之后自动打开app的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/983447

相关文章

Python使用国内镜像加速pip安装的方法讲解

《Python使用国内镜像加速pip安装的方法讲解》在Python开发中,pip是一个非常重要的工具,用于安装和管理Python的第三方库,然而,在国内使用pip安装依赖时,往往会因为网络问题而导致速... 目录一、pip 工具简介1. 什么是 pip?2. 什么是 -i 参数?二、国内镜像源的选择三、如何

Android 悬浮窗开发示例((动态权限请求 | 前台服务和通知 | 悬浮窗创建 )

《Android悬浮窗开发示例((动态权限请求|前台服务和通知|悬浮窗创建)》本文介绍了Android悬浮窗的实现效果,包括动态权限请求、前台服务和通知的使用,悬浮窗权限需要动态申请并引导... 目录一、悬浮窗 动态权限请求1、动态请求权限2、悬浮窗权限说明3、检查动态权限4、申请动态权限5、权限设置完毕后

解决jupyterLab打开后出现Config option `template_path`not recognized by `ExporterCollapsibleHeadings`问题

《解决jupyterLab打开后出现Configoption`template_path`notrecognizedby`ExporterCollapsibleHeadings`问题》在Ju... 目录jupyterLab打开后出现“templandroidate_path”相关问题这是 tensorflo

Python安装时常见报错以及解决方案

《Python安装时常见报错以及解决方案》:本文主要介绍在安装Python、配置环境变量、使用pip以及运行Python脚本时常见的错误及其解决方案,文中介绍的非常详细,需要的朋友可以参考下... 目录一、安装 python 时常见报错及解决方案(一)安装包下载失败(二)权限不足二、配置环境变量时常见报错及

Android里面的Service种类以及启动方式

《Android里面的Service种类以及启动方式》Android中的Service分为前台服务和后台服务,前台服务需要亮身份牌并显示通知,后台服务则有启动方式选择,包括startService和b... 目录一句话总结:一、Service 的两种类型:1. 前台服务(必须亮身份牌)2. 后台服务(偷偷干

MySQL8.2.0安装教程分享

《MySQL8.2.0安装教程分享》这篇文章详细介绍了如何在Windows系统上安装MySQL数据库软件,包括下载、安装、配置和设置环境变量的步骤... 目录mysql的安装图文1.python访问网址2javascript.点击3.进入Downloads向下滑动4.选择Community Server5.

Go Mongox轻松实现MongoDB的时间字段自动填充

《GoMongox轻松实现MongoDB的时间字段自动填充》这篇文章主要为大家详细介绍了Go语言如何使用mongox库,在插入和更新数据时自动填充时间字段,从而提升开发效率并减少重复代码,需要的可以... 目录前言时间字段填充规则Mongox 的安装使用 Mongox 进行插入操作使用 Mongox 进行更

C语言中自动与强制转换全解析

《C语言中自动与强制转换全解析》在编写C程序时,类型转换是确保数据正确性和一致性的关键环节,无论是隐式转换还是显式转换,都各有特点和应用场景,本文将详细探讨C语言中的类型转换机制,帮助您更好地理解并在... 目录类型转换的重要性自动类型转换(隐式转换)强制类型转换(显式转换)常见错误与注意事项总结与建议类型

CentOS系统Maven安装教程分享

《CentOS系统Maven安装教程分享》本文介绍了如何在CentOS系统中安装Maven,并提供了一个简单的实际应用案例,安装Maven需要先安装Java和设置环境变量,Maven可以自动管理项目的... 目录准备工作下载并安装Maven常见问题及解决方法实际应用案例总结Maven是一个流行的项目管理工具

MySql9.1.0安装详细教程(最新推荐)

《MySql9.1.0安装详细教程(最新推荐)》MySQL是一个流行的关系型数据库管理系统,支持多线程和多种数据库连接途径,能够处理上千万条记录的大型数据库,本文介绍MySql9.1.0安装详细教程,... 目录mysql介绍:一、下载 Mysql 安装文件二、Mysql 安装教程三、环境配置1.右击此电脑