Giter VIP home page Giter VIP logo

mnupdateapk's Introduction

MNUpdateAPK

Android APK Update Version APK版本更新的下载和安装,适配7.0-11.0下载安装

功能:

1:下载APK
2:安装APK

截图:

如何添加(请认真读完下面步骤和注意事项)

Gradle添加:

1.在Project的build.gradle中添加仓库地址

	allprojects {
		repositories {
			...
			maven { url "https://jitpack.io" }
		}
	}

2.在Module目录下的build.gradle中添加依赖

	dependencies {
        //AndroidX
        implementation 'com.squareup.okhttp3:okhttp:3.11.0'
	    implementation 'com.github.maning0303:MNUpdateAPK:V2.0.5'

        //Suport版本,建议升级AndroidX,不更新
        implementation 'com.squareup.okhttp3:okhttp:3.11.0'
	    implementation 'com.github.maning0303:MNUpdateAPK:V2.0.3'
	}

使用步骤:

1:在Manifest.xml中添加配置

      <!--网络权限问题-->
      <uses-permission android:name="android.permission.INTERNET"/>
      <!--8.0安装需要的权限-->
      <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
      <!--读写权限-->
      <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
      <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
      <!--读写权限Android11-->
      <uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />

2:代码使用

Android 11 适配问题:

1.存储权限需要自行适配
2.安装权限:REQUEST_INSTALL_PACKAGES,11用户授权安装权限后会自动的重启App,所以建议在下载新版本之前优先检查有没有安装权限,就不要再下载完成后检查权限,防止出现需要用户下载两次问题。

本地下载安装:

      //1.先判断有没有安装权限---适配8.0
      //如果不想用封装好的,可以自己去实现8.0适配
      InstallUtils.checkInstallPermission(context, new InstallUtils.InstallPermissionCallBack() {
          @Override
          public void onGranted() {
              //去下载Apk
              downloadApk(...);
          }

          @Override
          public void onDenied() {
              //弹出弹框提醒用户
              AlertDialog alertDialog = new AlertDialog.Builder(context)
                      .setTitle("温馨提示")
                      .setMessage("必须授权才能安装APK,请设置允许安装")
                      .setNegativeButton("取消", null)
                      .setPositiveButton("设置", new DialogInterface.OnClickListener() {
                          @Override
                          public void onClick(DialogInterface dialog, int which) {
                              //打开设置页面
                              InstallUtils.openInstallPermissionSetting(context, new InstallUtils.InstallPermissionCallBack() {
                                  @Override
                                  public void onGranted() {
                                      //去下载Apk
                                      downloadApk(...);
                                  }

                                  @Override
                                  public void onDenied() {
                                      //还是不允许咋搞?
                                      Toast.makeText(context, "不允许安装咋搞?强制更新就退出应用程序吧!", Toast.LENGTH_SHORT).show();
                                  }
                              });
                          }
                      })
                      .create();
              alertDialog.show();
          }
      });

      //2.下载APK
      InstallUtils.with(this)
              //必须-下载地址
              .setApkUrl(Constants.APK_URL_01)
              //非必须-下载保存的文件的完整路径+/name.apk,使用自定义路径需要获取读写权限
              .setApkPath(Constants.APK_SAVE_PATH)
              //非必须-下载回调
              .setCallBack(new InstallUtils.DownloadCallBack() {
                  @Override
                  public void onStart() {
                     //下载开始
                  }
      
                  @Override
                  public void onComplete(String path) {
                     //下载完成
                     InstallUtils.installAPK();
                  }
      
                  @Override
                  public void onLoading(long total, long current) {
                     //下载中
                  }
      
                  @Override
                  public void onFail(Exception e) {
                     //下载失败
                  }
      
                  @Override
                  public void cancle() {
                     //下载取消
                  }
              })
              //开始下载
              .startDownload();
           
              
      //3.安装APK
      InstallUtils.installAPK(context, path, new InstallUtils.InstallCallBack() {
                  @Override
                  public void onSuccess() {
                      //onSuccess:表示系统的安装界面被打开
                      //防止用户取消安装,在这里可以关闭当前应用,以免出现安装被取消
                      Toast.makeText(context, "正在安装程序", Toast.LENGTH_SHORT).show();
                  }
      
                  @Override
                  public void onFail(Exception e) {
                      //安装出现异常,这里可以提示用用去用浏览器下载安装
                  }
              });
              
      //取消下载
      InstallUtils.cancleDownload();
      
      //是否正在下载
      InstallUtils.isDownloading();
      
      //单独设置下载监听
      InstallUtils.setDownloadCallBack(new InstallUtils.DownloadCallBack() {
                  @Override
                  public void onStart() {
                      
                  }
      
                  @Override
                  public void onComplete(String path) {
      
                  }
      
                  @Override
                  public void onLoading(long total, long current) {
      
                  }
      
                  @Override
                  public void onFail(Exception e) {
      
                  }
                  
                  @Override
                  public void cancle() {
                      
                  }
              });
              
              
      //安装APK
      /**
       * 安装APK工具类
       * @param activity       上下文
       * @param filePath      文件路径
       * @param callBack      安装界面成功调起的回调
       */
      InstallUtils.installAPK(activity, path, new InstallUtils.InstallCallBack() {
          @Override
          public void onSuccess() {
              //onSuccess:表示系统的安装界面被打开
              //防止用户取消安装,在这里可以关闭当前应用,以免出现安装被取消
              Toast.makeText(context, "正在安装程序", Toast.LENGTH_SHORT).show();
          }
      
          @Override
          public void onFail(Exception e) {
              Toast.makeText(context, "安装失败:" + e.toString(), Toast.LENGTH_SHORT).show();
          }
      });
      

浏览器下载安装:

     //通过浏览器去下载APK
     InstallUtils.installAPKWithBrower(this, APK_URL);

默认下载路径(支持自定义下载路径):

        
     /Android/data/包名/cache/
     或者
     /data/data/包名/cache/

注意注意注意:

8.0权限问题解决方案:

         //自己去判断
         if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
             //先获取是否有安装未知来源应用的权限
             boolean haveInstallPermission = getPackageManager().canRequestPackageInstalls();
             if (!haveInstallPermission) {
                 //跳转设置开启允许安装
                 Uri packageURI = Uri.parse("package:"+context.getPackageName());
                 Intent intent =new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES,packageURI);
                 startActivityForResult(intent,1000);
                 return;
             }
         }
         //安装APK
         installAPK(...);
        
        
         //------------------------分界线-----------------------
         
         
         //当然这个东西已经封装好了。可以这样使用,详细可以查看Demo
         //先判断有没有安装权限
         InstallUtils.checkInstallPermission(context, new InstallUtils.InstallPermissionCallBack() {
             @Override
             public void onGranted() {
                  //安装APK
                  installAPK(...);
             }
         
             @Override
             public void onDenied() {
                 //弹出弹框提醒用户
                 AlertDialog alertDialog = new AlertDialog.Builder(context)
                         .setTitle("温馨提示")
                         .setMessage("必须授权才能安装APK,请设置允许安装")
                         .setNegativeButton("取消", null)
                         .setPositiveButton("去设置", new DialogInterface.OnClickListener() {
                             @Override
                             public void onClick(DialogInterface dialog, int which) {
                                 //打开安装权限设置页面
                                 InstallUtils.openInstallPermissionSetting(context, new InstallUtils.InstallPermissionCallBack() {
                                     @Override
                                     public void onGranted() {
                                         //安装APK
                                         installAPK(...);
                                     }
         
                                     @Override
                                     public void onDenied() {
                                         //还是不允许咋搞?
                                         Toast.makeText(context, "不允许安装咋搞?强制更新就退出应用程序吧!", Toast.LENGTH_SHORT).show();
                                     }
                                 });
                             }
                         })
                         .create();
                 alertDialog.show();
             }
         });
        

混淆注意:

请添加okhttp3混淆

版本记录:

版本 V2.0.5:
1.优化安装Intent设置FLAG_GRANT_READ_URI_PERMISSION,防止出现权限问题

推荐:

Name Describe
GankMM (Material Design & MVP & Retrofit + OKHttp & RecyclerView ...)Gank.io Android客户端:每天一张美女图片,一个视频短片,若干Android,iOS等程序干货,周一到周五每天更新,数据全部由 干货集中营 提供,持续更新。
MNUpdateAPK Android APK 版本更新的下载和安装,适配7.0,简单方便。
MNImageBrowser 交互特效的图片浏览框架,微信向下滑动动态关闭
MNCalendar 简单的日历控件练习,水平方向日历支持手势滑动切换,跳转月份;垂直方向日历选取区间范围。
MClearEditText 带有删除功能的EditText
MNCrashMonitor Debug监听程序崩溃日志,展示崩溃日志列表,方便自己平时调试。
MNProgressHUD MNProgressHUD是对常用的自定义弹框封装,加载ProgressDialog,状态显示的StatusDialog和自定义Toast,支持背景颜色,圆角,边框和文字的自定义。
MNXUtilsDB xUtils3 数据库模块单独抽取出来,方便使用。
MNVideoPlayer SurfaceView + MediaPlayer 实现的视频播放器,支持横竖屏切换,手势快进快退、调节音量,亮度等。------代码简单,新手可以看一看。
MNZXingCode 快速集成二维码扫描和生成二维码
MNChangeSkin Android夜间模式,通过Theme实现
SwitcherView 垂直滚动的广告栏文字展示。
MNPasswordEditText 类似微信支付宝的密码输入框。
MNSwipeToLoadDemo 利用SwipeToLoadLayout实现的各种下拉刷新效果(饿了吗,京东,百度外卖,美团外卖,天猫下拉刷新等)。

mnupdateapk's People

Contributors

maning0303 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mnupdateapk's Issues

在低版本中用不到provider,但是会报Unable to get provider com.maning.updatelibrary.MNUpdateApkFileProvider

下面是错误log
FATAL EXCEPTION: main
Process: com.msunsoft.nursinghelper, PID: 1761
java.lang.RuntimeException: Unable to get provider com.maning.updatelibrary.MNUpdateApkFileProvider: java.lang.ClassNotFoundException: Didn't find class "com.maning.updatelibrary.MNUpdateApkFileProvider" on path: DexPathList[[zip file "/data/app/com.msunsoft.nursinghelper-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.msunsoft.nursinghelper-1, /system/lib]]
at android.app.ActivityThread.installProvider(ActivityThread.java:4795)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4387)
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4327)
at android.app.ActivityThread.access$1500(ActivityThread.java:135)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:136)
at android.app.ActivityThread.main(ActivityThread.java:5019)
at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:515)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595)
at dalvik.system.NativeStart.main(Native Method)
Caused by: java.lang.ClassNotFoundException: Didn't find class "com.maning.updatelibrary.MNUpdateApkFileProvider" on path: DexPathList[[zip file "/data/app/com.msunsoft.nursinghelper-1.apk"],nativeLibraryDirectories=[/data/app-lib/com.msunsoft.nursinghelper-1, /system/lib]]
at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:56)
at java.lang.ClassLoader.loadClass(ClassLoader.java:497)
at java.lang.ClassLoader.loadClass(ClassLoader.java:457)
at android.app.ActivityThread.installProvider(ActivityThread.java:4780)
at android.app.ActivityThread.installContentProviders(ActivityThread.java:4387) 
at android.app.ActivityThread.handleBindApplication(ActivityThread.java:4327) 
at android.app.ActivityThread.access$1500(ActivityThread.java:135) 
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1256) 
at android.os.Handler.dispatchMessage(Handler.java:102) 
at android.os.Looper.loop(Looper.java:136) 
at android.app.ActivityThread.main(ActivityThread.java:5019) 
at java.lang.reflect.Method.invokeNative(Native Method) 
at java.lang.reflect.Method.invoke(Method.java:515) 
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:779) 
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:595) 
at dalvik.system.NativeStart.main(Native Method) 

模拟器运行出错Unable to get provider com.maning.updatelibrary.MNUpdateApkFileProvider:

模拟器运行时候出现这种错误,clean了会变正常,多运行几次又会出现
Process: com.gntech.develop.gninfomationsys, PID: 11296
java.lang.RuntimeException: Unable to get provider com.maning.updatelibrary.MNUpdateApkFileProvider: java.lang.ClassNotFoundException: Didn't find class "com.maning.updatelibrary.MNUpdateApkFileProvider" on path: DexPathList[zip file "/data/app/com.gntech.develop.gninfomationsys-2/base.apk", zip file "/data/app/com.gntech.develop.gninfomationsys-2/split_lib_slice_3_apk.apk"],nativeLibraryDirectories=[/vendor/lib, [/system/lib]])

是否支持暂停

你好,请问一下,关于暂停功能,有计划支持的日期么?

在低版本安装时报错

在15 版本上安装测试时,会提示 包解析 异常

找了下,放在 cache 目录 需要添加权限。

//参照:APK放到data/data/下面提示解析失败 (http://blog.csdn.net/lonely_fireworks/article/details/27693073)
  private void changeApkFileMode(File file) {
    try {
      //apk放在缓存目录时,低版本安装提示权限错误,需要对父级目录和apk文件添加权限
      String cmd1 = "chmod 777 " + file.getParent();
      Runtime.getRuntime().exec(cmd1);

      String cmd = "chmod 777 " + file.getAbsolutePath();
      Runtime.getRuntime().exec(cmd);
    } catch (IOException e) {
      e.printStackTrace();
    }
  }

java.lang.SecurityException: Permission Denial: reading MNUpdateApkFileProvider

InstallUtils内解读安装包的时候没有加权限FLAG_GRANT_PERSISTABLE_URI_PERMISSION,导致安卓10部分机型会一定几率解析安装包失败,抛无解读权限异常

intent.addFlags(Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION);

我手机是一加8P,差不多3次测试会触发一次,InstallUtils.class被锁死了,没法编译覆盖,所以需要新版本支持

新版本下载安装后 无法自动打开

你好,想请教个问题:
我在使用了你的下载apk并且安装后,新版本安装好没有打开而是直接程序退到主屏幕,我在主屏幕点击应用图标可以打开进入到更新的版本。请问,这个更新安装好无法自动打开是哪些方面的原因呢?
望寄予建议,谢谢!

在release编译模式下,下载完成后,不能开启安装的设置界面

感谢大佬的代码。
我在使用的时候,在正式环境下,下载完成后不能跳转到安装页面
其实准确的说是在 debuggable 为 false的时候,会停在99%(只有在debugable)

  release {
            manifestPlaceholders = [
                    APP_LABEL: "**",
                    APP_ICON : "@mipmap/ic_launcher"

            ]
            signingConfig signingConfigs.config
          .....
            debuggable false
         .....
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }

经过我一天的测试,就是这样,debuggable就不能去安装,true就可以。
混淆我已经保持过了,也不管用

安卓11的回调问题

1.没有安卓11的适配权限 android.permission.MANAGE_EXTERNAL_STORAGE
2.第一次点击下载,下载完成跳到获取系统安装权限页面,返回之后没有走回传,导致安装包自动打开未调起,需要再来一次下载更新步骤才能顺利走完。

在安卓11上第二个问题的表现很糟糕,会导致新用户一个安装包需要下载两次才能更新安装成功

关于安装的一点问题

你跳转到安装页面的时候用的不是startActivityForResult,如果在安装页面解析包出错或者在那个页面无法正常安装的情况下,你要怎么处理

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.