Android app更新适配安卓10、11版本

您所在的位置:网站首页 oppo11升级安卓10 Android app更新适配安卓10、11版本

Android app更新适配安卓10、11版本

2024-07-10 06:19| 来源: 网络整理| 查看: 265

Android app内部更新适配安卓10、11版本 前言

​ App内部更新现在基本每个app中都有,由于安卓各大应用市场不统一,不像Ios那样只有一个应用商城。并且现在安卓已经更新到11版本了,中间有几个版本还需对App内部更新做适配,所以说这里记录一下。本笔记目前适配Android11版本。本文只讲下载和安装的核心,不对更新版本的校验和更新弹出框做优化,有需要的可以自行添加。这里参考了android两位大神的文章https://blog.csdn.net/lmj623565791/article/details/72859156?spm=1001.2014.3001.5502、https://guolin.blog.csdn.net/article/details/105419420。

在这里插入图片描述

6.0版本之前

其实在6.0版本之前是什么都不要做的,直接将apk文件下载到sd卡目录中再调用如下代码就可以了

File file = new File(Environment.getExternalStorageDirectory(), "testandroid7-debug.apk"); Intent intent = new Intent(Intent.ACTION_VIEW); intent.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive"); startActivity(intent); 6.0-7.0之间

到了6.0之后如果将文件存储到sd的目录和读取sd卡下载好的文件中需要申请READ_EXTERNAL_STORAGE和WRITE_EXTERNAL_STORAGE这两个读写权限。就是Environment.开头调用的这些目录。除了sdcard/Android/data/你的包名下/…这是你app的私有目录无需申请权限。

7.0之后

在官方7.0的以上的系统中,尝试传递 file://URI可能会触发FileUriExposedException。而你用之前的sd获得的路径恰好就是这种,接下来说说解决方案:

在清单文件AndroidManifest.xml配置如下

name是固定的

authorities是应用的唯一标识一般用应用的包名再拼上一些随便的字符,

exported=false固定的,

grantUriPermissions=true固定的

meta中的name固定的

resource这边需要再res下创建一个xml文件夹,在xml文件夹下创建一个文件,文件内容如下

可配置标签说明

代表设备的根目录new File("/"); 代表context.getFilesDir() 代表context.getCacheDir() 代表Environment.getExternalStorageDirectory() 代表context.getExternalFilesDirs() 代表getExternalCacheDirs()

因为我这里用的的sdcard/Android/data/你的包名下/updateApp/updateApp.apk所以无需请求权限,但是这个目录下的文件是会计算到你应用的大小中的并且应用一卸载这里面的内容也会跟着卸载。

安装apk稍作修改

private fun getUriForFile(file:File) = if(Build.VERSION.SDK_INT >= 24) getUriForFile24(file) else Uri.fromFile(file) private fun getUriForFile24(file:File) = FileProvider.getUriForFile(this,"$packageName.fileprovider",file) private fun setIntentDataAndType(intent: Intent,type:String,file: File,writeAble:Boolean) { if(Build.VERSION.SDK_INT >= 24){ intent.setDataAndType(getUriForFile(file),type) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) if(writeAble) { intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) } }else { intent.setDataAndType(Uri.fromFile(file),type) } }

调用安装

File file = new File(Environment.getExternalStorageDirectory(), "testandroid7-debug.apk"); Intent intent = new Intent(Intent.ACTION_VIEW); // 调用上面的方法 setIntentDataAndType(intent, "application/vnd.android.package-archive",file,true); startActivity(intent); 10.0之后

其实安卓10之后增加了作用域访问权限,已经不能使用之前的那种File(路径)的方式去访问sd卡下的路径了,专门有需要使用contentResolver结合MediaStore去访问,这里不展开讲解。可以去看郭神的文章https://guolin.blog.csdn.net/article/details/105419420而我们为了规避掉这个事情,还是上面的将apk的包下载到自己应用下的目录就可以无需做任何改动。

我也尝试将apk下载到download下,下载可以,但是我不知道怎么取出来,所以放弃了。有知道的大佬可以告知我一声。

代码示例 package com.qmc.update import android.content.Intent import android.net.Uri import android.os.Build import android.os.Bundle import android.util.Log import android.widget.Toast import androidx.appcompat.app.AppCompatActivity import androidx.core.content.FileProvider import pub.devrel.easypermissions.EasyPermissions import java.io.File import java.io.FileOutputStream import java.net.HttpURLConnection import java.net.URL class MainActivity : AppCompatActivity(),EasyPermissions.PermissionCallbacks { val TAG = this.javaClass.simpleName override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) downLoadApp() } private fun downLoadApp() { Thread { val url = URL("http://192.168.1.120:3001/yanyue/updateApp.apk") val httpURLConnection = url.openConnection() as HttpURLConnection httpURLConnection.requestMethod = "GET" httpURLConnection.connect() try { val responseCode = httpURLConnection.responseCode if (responseCode == HttpURLConnection.HTTP_OK) { val inputStream = httpURLConnection.inputStream val downLoadPath = getExternalFilesDir(null)?.absolutePath + File.separator + "/updateApp" val file = File(downLoadPath) if(!file.exists()) { file.mkdir() } val outputStream = FileOutputStream("$downLoadPath/update.apk") val byteArray = ByteArray(1024) var count: Int do { count = inputStream.read(byteArray) if (count != -1) { outputStream.write(byteArray, 0, count) } else { inputStream.close() outputStream.close() break } } while (true) inputStream.close() outputStream.close() val updateFile = File("$downLoadPath/update.apk") if(file.exists()){ runOnUiThread { val installIntent = Intent(Intent.ACTION_VIEW) setIntentDataAndType(installIntent,"application/vnd.android.package-archive",updateFile,true) startActivity(installIntent) } } else { Log.e(TAG, "downLoadApp: 文件不存在") } } } catch (e: Exception) { Log.e(TAG, "downLoadApp: ${e.message}") } }.start() } private fun getUriForFile(file:File) = if(Build.VERSION.SDK_INT >= 24) getUriForFile24(file) else Uri.fromFile(file) private fun getUriForFile24(file:File) = FileProvider.getUriForFile(this,"$packageName.fileprovider",file) private fun setIntentDataAndType(intent: Intent,type:String,file: File,writeAble:Boolean) { if(Build.VERSION.SDK_INT >= 24){ intent.setDataAndType(getUriForFile(file),type) intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION) if(writeAble) { intent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION) } }else { intent.setDataAndType(Uri.fromFile(file),type) } } override fun onPermissionsDenied(requestCode: Int, perms: MutableList) { Toast.makeText(this,"权限拒绝",Toast.LENGTH_SHORT).show() } override fun onPermissionsGranted(requestCode: Int, perms: MutableList) { downLoadApp() } override fun onRequestPermissionsResult( requestCode: Int, permissions: Array, grantResults: IntArray ) { super.onRequestPermissionsResult(requestCode, permissions, grantResults) EasyPermissions.onRequestPermissionsResult(requestCode,permissions,grantResults,this) } }

在这里插入图片描述

注意在清单文件中添加网络权限!!!



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3