美文网首页
Android 应用升级功能实现

Android 应用升级功能实现

作者: 徘徊0_ | 来源:发表于2019-12-27 17:31 被阅读0次

本文记录实现app应用内升级功能中遇到的问题

常见的app应用内升级常见步骤为:
1,调用后台接口,比对当前版本号查看是否有更新
2,下载最新的apk
3,覆盖安装

问题:安装未知应用权限

先上代码,包含2个方法

  • 判断是否允许应用安装apk权限
  • 没权限的话,跳转打开设置页面
/**
     * 是否允许 安装app
     * @param context
     * @return  true:允许;  false:不允许
     *
     *  注意需要声明该权限
     *   <!--8.0 安装权限-->
     *   <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>
     */
    public static boolean isAgreeInstallPackage(Context context) {
        boolean isAgree = true;
        //8.0以上 需要判断
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
            isAgree = context.getPackageManager().canRequestPackageInstalls();
        }

        return isAgree;
    }

    /**
     * 前往设置,开启 安装apk权限
     * @param context
     */
    public static void openInstallSetting(Activity context) {
        Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES);
        context.startActivityForResult(intent,SetInstallRequestCode);
    }

安装未知应用.png

Android 8.0 以上,安装apk需要注意多了一个 安装未知应用 权限,故需要兼容一下8.0以上,需要注意的是,检测该权限需要注意在AndroidManifest中声明:<uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES"/>

问题:下载完成apk,调起安装页面

先贴上调起apk安装界面的代码

public class InstallApkUtils {

    /**
     * @param apkFile :  需要安装的apk
     * @return 
     * @Description 安装apk
     */
    public static void installApk(Context context,File apkFile) {
        Intent intent = new Intent(Intent.ACTION_VIEW);
        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);//需要开新的任务栈,不然安装完成无法弹出“完成”、“打开”页面
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) { // 7.0+以上版本
            Uri apkUri = FileProvider.getUriForFile(context, BuildConfig.APPLICATION_ID+ ".fileprovider", apkFile);  //包名.fileprovider
            intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
            intent.setDataAndType(apkUri, "application/vnd.android.package-archive");
        } else {
            intent.setDataAndType(Uri.fromFile(apkFile), "application/vnd.android.package-archive");
        }
        context.startActivity(intent);
    }
}

这里需要处理 Android7.0 以上的兼容问题,Android 7.0以上需要通过 FileProvider 来获取 UriFileProvider使用下面会介绍。附上:Google-FileProvider

注意:上面的BuildConfig.APPLICATION_ID其实就是你的包名,我在下面声明FileProvider也使用的是包名

FileProvider使用

1,AndroidManifest.xml 创建一个FileProvider
  <!--${applicationId} 是项目包名-->
   <provider
       android:name="android.support.v4.content.FileProvider"
       android:authorities="${applicationId}.fileprovider"
       android:exported="false"
       android:grantUriPermissions="true">
     <meta-data
         android:name="android.support.FILE_PROVIDER_PATHS"
         android:resource="@xml/file_paths" />
 </provider>

注意:android:authorities="你的包名.fileprovider" 替换,后面的不要动

2,Res 目录下创建 xml文件夹, 创建一个 file_paths.xml
file_paths.png
注意:这个xml,命名只要跟AndroidManifest.xml resource
中的对应即可。(我创建的名字为:file_paths)
<?xml version="1.0" encoding="utf-8"?>
<paths xmlns:android="http://schemas.android.com/apk/res/android">


  <!--代表外部存储区域的根目录下的文件 Environment.getExternalStorageDirectory()/DCIM/camerademo目录-->
  <external-path name="name" path="DCIM/camerademo" />
  <!--代表外部存储区域的根目录下的文件 Environment.getExternalStorageDirectory()/Pictures/camerademo目录-->
  <external-path name="name" path="Pictures/camerademo" />
  
  <!--代表app 私有的存储区域 Context.getFilesDir()目录下的images目录 /data/user/0/com.hm.camerademo/files/images-->
  <files-path name="name" path="images" />
  <!--代表app 私有的存储区域 Context.getCacheDir()目录下的images目录 /data/user/0/com.hm.camerademo/cache/images-->
  <cache-path name="name" path="images" />
  
  
  <!--代表app 外部存储区域根目录下的文件 Context.getExternalFilesDir(Environment.DIRECTORY_PICTURES)目录下的Pictures目录-->
  <!--/storage/emulated/0/Android/data/com.hm.camerademo/files/Pictures-->
  <external-files-path name="name" path="Pictures" />
  <!--代表app 外部存储区域根目录下的文件 Context.getExternalCacheDir目录下的images目录-->
  <!--/storage/emulated/0/Android/data/com.hm.camerademo/cache/images-->
  <external-cache-path name="name" path="images" />

</paths>

比如,我要获取到下面外部存储目录的Uri

String fileName = Environment.getExternalStorageDirectory() +File.separator+"down_apk"+File.separator + "xxxx.apk";

需要在file_paths.xml中添加如下目录,即可:

  <external-path
      name="name"
      path="down_apk"/>

如果报错的话,多半是目录跟File路径不对应,请仔细检查

相关文章

网友评论

      本文标题:Android 应用升级功能实现

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