├── .gitignore
├── .idea
├── caches
│ └── build_file_checksums.ser
├── codeStyles
│ └── Project.xml
├── gradle.xml
├── misc.xml
├── modules.xml
├── runConfigurations.xml
└── vcs.xml
├── README.md
├── app
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
│ ├── androidTest
│ └── java
│ │ └── androidkun
│ │ └── com
│ │ └── versionupdate
│ │ └── ExampleInstrumentedTest.java
│ ├── main
│ ├── AndroidManifest.xml
│ ├── java
│ │ └── androidkun
│ │ │ └── com
│ │ │ └── versionupdate
│ │ │ └── MainActivity.java
│ └── res
│ │ ├── layout
│ │ └── activity_main.xml
│ │ ├── mipmap-hdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-mdpi
│ │ ├── app_icon_small.png
│ │ └── ic_launcher.png
│ │ ├── mipmap-xhdpi
│ │ ├── app_icon.png
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxhdpi
│ │ └── ic_launcher.png
│ │ ├── mipmap-xxxhdpi
│ │ └── ic_launcher.png
│ │ ├── values-w820dp
│ │ └── dimens.xml
│ │ └── values
│ │ ├── colors.xml
│ │ ├── dimens.xml
│ │ ├── strings.xml
│ │ └── styles.xml
│ └── test
│ └── java
│ └── androidkun
│ └── com
│ └── versionupdate
│ └── ExampleUnitTest.java
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── versionupdatelibrary
├── .gitignore
├── build.gradle
├── proguard-rules.pro
└── src
├── androidTest
└── java
│ └── androidkun
│ └── com
│ └── versionupdatelibrary
│ └── ExampleInstrumentedTest.java
├── main
├── AndroidManifest.xml
├── java
│ └── androidkun
│ │ └── com
│ │ └── versionupdatelibrary
│ │ ├── Activity
│ │ └── TranslucentActivity.java
│ │ ├── db
│ │ ├── DBHelper.java
│ │ ├── ThreadDao.java
│ │ └── ThreadDaoImpl.java
│ │ ├── download
│ │ ├── DownloadCallBack.java
│ │ ├── DownloadTask.java
│ │ ├── DownloadThread.java
│ │ └── InitThread.java
│ │ ├── entity
│ │ ├── Config.java
│ │ ├── FileBean.java
│ │ ├── ThreadBean.java
│ │ └── VersionUpdateConfig.java
│ │ ├── service
│ │ └── VersionUpdateService.java
│ │ └── utils
│ │ └── MD5Util.java
└── res
│ ├── layout
│ ├── activity_translucent.xml
│ └── layout_notifi.xml
│ ├── mipmap-xhdpi
│ ├── close.png
│ ├── ic_continue.png
│ ├── ic_launcher.png
│ └── ic_pause.png
│ ├── values-w820dp
│ └── dimens.xml
│ ├── values-zh
│ └── strings.xml
│ ├── values
│ ├── dimens.xml
│ └── strings.xml
│ └── xml
│ └── provider_paths.xml
└── test
└── java
└── androidkun
└── com
└── versionupdatelibrary
└── ExampleUnitTest.java
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea/workspace.xml
5 | /.idea/libraries
6 | .DS_Store
7 | /build
8 | /captures
9 | .externalNativeBuild
10 |
--------------------------------------------------------------------------------
/.idea/caches/build_file_checksums.ser:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/.idea/caches/build_file_checksums.ser
--------------------------------------------------------------------------------
/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/gradle.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/.idea/runConfigurations.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # XVersionUpdate
2 | ## 快速实现版本更新功能
3 | 
4 | ## 1.添加依赖
5 |
6 | compile 'com.androidkun:xversionupdate:1.0.6'
7 |
8 | ## 2.调用APII实现版本更新
9 |
10 | VersionUpdateConfig.getInstance()//获取配置实例
11 | .setContext(MainActivity.this)//设置上下文
12 | .setDownLoadURL(url)//设置文件下载链接
13 | .setNewVersion("1.0.1")//设置即将下载的APK的版本号,避免重复下载
14 | .setFileSavePath(savePath)//设置文件保存路径(可不设置)
15 | .setNotificationIconRes(R.mipmap.app_icon)//设置通知图标
16 | .setNotificationSmallIconRes(R.mipmap.app_icon_small)//设置通知小图标
17 | .setNotificationTitle("版本升级Demo")//设置通知标题
18 | .startDownLoad();//开始下载
19 |
20 | ## 接下来就不用再做任何处理了,会自动弹出通知显示下载进度并下载完成后会自动跳到安装页面。
21 |
--------------------------------------------------------------------------------
/app/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 24
5 | buildToolsVersion "24.0.3"
6 | defaultConfig {
7 | applicationId "androidkun.com.versionupdate"
8 | minSdkVersion 16
9 | targetSdkVersion 24
10 | versionCode 1
11 | versionName "1.0"
12 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
13 | }
14 | buildTypes {
15 | release {
16 | minifyEnabled false
17 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
18 | }
19 | }
20 | }
21 |
22 | dependencies {
23 | compile fileTree(include: ['*.jar'], dir: 'libs')
24 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
25 | exclude group: 'com.android.support', module: 'support-annotations'
26 | })
27 | compile 'com.android.support:appcompat-v7:24.0.0-beta1'
28 | testCompile 'junit:junit:4.12'
29 | compile project(':versionupdatelibrary')
30 | }
31 |
--------------------------------------------------------------------------------
/app/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\AndroidStudio\AndroidStudio\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/app/src/androidTest/java/androidkun/com/versionupdate/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdate;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("androidkun.com.versionupdate", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
--------------------------------------------------------------------------------
/app/src/main/java/androidkun/com/versionupdate/MainActivity.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdate;
2 |
3 | import android.os.Bundle;
4 | import android.support.v7.app.AppCompatActivity;
5 | import android.view.View;
6 |
7 | import androidkun.com.versionupdatelibrary.entity.VersionUpdateConfig;
8 |
9 | public class MainActivity extends AppCompatActivity{
10 |
11 |
12 | private String url = "http://112.29.152.47/imtt.dd.qq.com/16891/7693A213D6163F3C2B1505130BBCFB08.apk?mkey=5a0930034113e38d&f=1907&c=0&fsname=com.happyelements.AndroidAnimal.qq_1.50_50.apk&csr=1bbd&p=.apk";
13 |
14 | @Override
15 | protected void onCreate(Bundle savedInstanceState) {
16 | super.onCreate(savedInstanceState);
17 | setContentView(R.layout.activity_main);
18 | }
19 |
20 | public void update(View view){
21 | VersionUpdateConfig.getInstance()//获取配置实例
22 | .setContext(MainActivity.this)//设置上下文
23 | .setDownLoadURL(url)//设置文件下载链接
24 | .setNewVersion("1.50")//设置即将下载的APK的版本号
25 | .setNotificationIconRes(R.mipmap.app_icon)//设置通知大图标
26 | .setNotificationSmallIconRes(R.mipmap.app_icon_small)//设置通知小图标
27 | .setNotificationTitle("版本升级Demo")//设置通知标题
28 | .startDownLoad();//开始下载
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/app_icon_small.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-mdpi/app_icon_small.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/app_icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-xhdpi/app_icon.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/colors.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | #3F51B5
4 | #303F9F
5 | #FF4081
6 |
7 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VersionUpdate
3 |
4 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/test/java/androidkun/com/versionupdate/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdate;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | jcenter()
6 | }
7 | dependencies {
8 | classpath 'com.android.tools.build:gradle:2.2.3'
9 | classpath 'com.novoda:bintray-release:0.3.4'
10 |
11 | // NOTE: Do not place your application dependencies here; they belong
12 | // in the individual module build.gradle files
13 | }
14 | }
15 |
16 | allprojects {
17 | repositories {
18 | jcenter()
19 | }
20 | tasks.withType(Javadoc) {
21 | options{
22 | encoding "UTF-8"
23 | charSet 'UTF-8'
24 | links "http://docs.oracle.com/javase/7/docs/api"
25 | }
26 | }
27 | }
28 |
29 | task clean(type: Delete) {
30 | delete rootProject.buildDir
31 | }
32 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 |
3 | # IDE (e.g. Android Studio) users:
4 | # Gradle settings configured through the IDE *will override*
5 | # any settings specified in this file.
6 |
7 | # For more details on how to configure your build environment visit
8 | # http://www.gradle.org/docs/current/userguide/build_environment.html
9 |
10 | # Specifies the JVM arguments used for the daemon process.
11 | # The setting is particularly useful for tweaking memory settings.
12 | org.gradle.jvmargs=-Xmx1536m
13 |
14 | # When configured, Gradle will run in incubating parallel mode.
15 | # This option should only be used with decoupled projects. More details, visit
16 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
17 | # org.gradle.parallel=true
18 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Mon Dec 28 10:00:20 PST 2015
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # Attempt to set APP_HOME
46 | # Resolve links: $0 may be a link
47 | PRG="$0"
48 | # Need this for relative symlinks.
49 | while [ -h "$PRG" ] ; do
50 | ls=`ls -ld "$PRG"`
51 | link=`expr "$ls" : '.*-> \(.*\)$'`
52 | if expr "$link" : '/.*' > /dev/null; then
53 | PRG="$link"
54 | else
55 | PRG=`dirname "$PRG"`"/$link"
56 | fi
57 | done
58 | SAVED="`pwd`"
59 | cd "`dirname \"$PRG\"`/" >/dev/null
60 | APP_HOME="`pwd -P`"
61 | cd "$SAVED" >/dev/null
62 |
63 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
64 |
65 | # Determine the Java command to use to start the JVM.
66 | if [ -n "$JAVA_HOME" ] ; then
67 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
68 | # IBM's JDK on AIX uses strange locations for the executables
69 | JAVACMD="$JAVA_HOME/jre/sh/java"
70 | else
71 | JAVACMD="$JAVA_HOME/bin/java"
72 | fi
73 | if [ ! -x "$JAVACMD" ] ; then
74 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
75 |
76 | Please set the JAVA_HOME variable in your environment to match the
77 | location of your Java installation."
78 | fi
79 | else
80 | JAVACMD="java"
81 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
82 |
83 | Please set the JAVA_HOME variable in your environment to match the
84 | location of your Java installation."
85 | fi
86 |
87 | # Increase the maximum file descriptors if we can.
88 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
89 | MAX_FD_LIMIT=`ulimit -H -n`
90 | if [ $? -eq 0 ] ; then
91 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
92 | MAX_FD="$MAX_FD_LIMIT"
93 | fi
94 | ulimit -n $MAX_FD
95 | if [ $? -ne 0 ] ; then
96 | warn "Could not set maximum file descriptor limit: $MAX_FD"
97 | fi
98 | else
99 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
100 | fi
101 | fi
102 |
103 | # For Darwin, add options to specify how the application appears in the dock
104 | if $darwin; then
105 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
106 | fi
107 |
108 | # For Cygwin, switch paths to Windows format before running java
109 | if $cygwin ; then
110 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
111 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
112 | JAVACMD=`cygpath --unix "$JAVACMD"`
113 |
114 | # We build the pattern for arguments to be converted via cygpath
115 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
116 | SEP=""
117 | for dir in $ROOTDIRSRAW ; do
118 | ROOTDIRS="$ROOTDIRS$SEP$dir"
119 | SEP="|"
120 | done
121 | OURCYGPATTERN="(^($ROOTDIRS))"
122 | # Add a user-defined pattern to the cygpath arguments
123 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
124 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
125 | fi
126 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
127 | i=0
128 | for arg in "$@" ; do
129 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
130 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
131 |
132 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
133 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
134 | else
135 | eval `echo args$i`="\"$arg\""
136 | fi
137 | i=$((i+1))
138 | done
139 | case $i in
140 | (0) set -- ;;
141 | (1) set -- "$args0" ;;
142 | (2) set -- "$args0" "$args1" ;;
143 | (3) set -- "$args0" "$args1" "$args2" ;;
144 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
145 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
146 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
147 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
148 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
149 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
150 | esac
151 | fi
152 |
153 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
154 | function splitJvmOpts() {
155 | JVM_OPTS=("$@")
156 | }
157 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
158 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
159 |
160 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
161 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app', ':versionupdatelibrary'
2 |
--------------------------------------------------------------------------------
/versionupdatelibrary/.gitignore:
--------------------------------------------------------------------------------
1 | /build
2 |
--------------------------------------------------------------------------------
/versionupdatelibrary/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.library'
2 | apply plugin: 'com.novoda.bintray-release'//添加
3 |
4 | android {
5 | compileSdkVersion 28
6 | buildToolsVersion "28.0.3"
7 |
8 | defaultConfig {
9 | minSdkVersion 16
10 | targetSdkVersion 28
11 | versionCode 1
12 | versionName "1.0"
13 |
14 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
15 |
16 | }
17 | buildTypes {
18 | release {
19 | minifyEnabled false
20 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
21 | }
22 | }
23 | lintOptions {
24 | checkReleaseBuilds false
25 | abortOnError false
26 | }
27 | }
28 |
29 | dependencies {
30 | compile fileTree(dir: 'libs', include: ['*.jar'])
31 | androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
32 | exclude group: 'com.android.support', module: 'support-annotations'
33 | })
34 | compile 'com.android.support:appcompat-v7:24.0.0-beta1'
35 | testCompile 'junit:junit:4.12'
36 | }
37 |
38 | publish {
39 | userOrg = 'androidkun'
40 | groupId = 'com.androidkun'
41 | artifactId = 'xversionupdate'
42 | publishVersion = '1.0.6'
43 | desc = 'A quick update version of the framework for Android.'
44 | website = 'https://github.com/AndroidKun/XVersionUpdate'
45 | }
46 |
47 |
--------------------------------------------------------------------------------
/versionupdatelibrary/proguard-rules.pro:
--------------------------------------------------------------------------------
1 | # Add project specific ProGuard rules here.
2 | # By default, the flags in this file are appended to flags specified
3 | # in D:\AndroidStudio\AndroidStudio\sdk/tools/proguard/proguard-android.txt
4 | # You can edit the include path and order by changing the proguardFiles
5 | # directive in build.gradle.
6 | #
7 | # For more details, see
8 | # http://developer.android.com/guide/developing/tools/proguard.html
9 |
10 | # Add any project specific keep options here:
11 |
12 | # If your project uses WebView with JS, uncomment the following
13 | # and specify the fully qualified class name to the JavaScript interface
14 | # class:
15 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview {
16 | # public *;
17 | #}
18 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/androidTest/java/androidkun/com/versionupdatelibrary/ExampleInstrumentedTest.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary;
2 |
3 | import android.content.Context;
4 | import android.support.test.InstrumentationRegistry;
5 | import android.support.test.runner.AndroidJUnit4;
6 |
7 | import org.junit.Test;
8 | import org.junit.runner.RunWith;
9 |
10 | import static org.junit.Assert.*;
11 |
12 | /**
13 | * Instrumentation test, which will execute on an Android device.
14 | *
15 | * @see Testing documentation
16 | */
17 | @RunWith(AndroidJUnit4.class)
18 | public class ExampleInstrumentedTest {
19 | @Test
20 | public void useAppContext() throws Exception {
21 | // Context of the app under test.
22 | Context appContext = InstrumentationRegistry.getTargetContext();
23 |
24 | assertEquals("androidkun.com.versionupdatelibrary.test", appContext.getPackageName());
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
15 |
16 |
18 |
19 |
20 |
21 |
26 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/Activity/TranslucentActivity.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.Activity;
2 |
3 | import android.Manifest;
4 | import android.app.Activity;
5 | import android.app.AlertDialog;
6 | import android.content.DialogInterface;
7 | import android.content.Intent;
8 | import android.content.pm.PackageManager;
9 | import android.net.Uri;
10 | import android.os.Build;
11 | import android.os.Bundle;
12 | import android.provider.Settings;
13 | import android.support.annotation.RequiresApi;
14 | import android.support.v4.app.ActivityCompat;
15 | import android.support.v4.content.ContextCompat;
16 | import android.view.KeyEvent;
17 | import android.widget.Toast;
18 |
19 |
20 | import java.util.ArrayList;
21 | import java.util.List;
22 |
23 | import androidkun.com.versionupdatelibrary.R;
24 | import androidkun.com.versionupdatelibrary.entity.VersionUpdateConfig;
25 |
26 | /***
27 | * 透明的Activity 用于运行权限检测
28 | */
29 | public class TranslucentActivity extends Activity implements
30 | ActivityCompat.OnRequestPermissionsResultCallback {
31 | /**
32 | * 需要进行检测的权限数组
33 | */
34 | protected String[] needPermissions = {
35 | Manifest.permission.WRITE_EXTERNAL_STORAGE,
36 | Manifest.permission.READ_EXTERNAL_STORAGE
37 | };
38 |
39 | private static final int PERMISSON_REQUESTCODE = 0;
40 |
41 | //未知来源app安装权限
42 | private static final int InstallPermission = 10022;
43 | /**
44 | * 判断是否需要检测,防止不停的弹框
45 | */
46 | private boolean isNeedCheck = true;
47 |
48 | @Override
49 | protected void onCreate(Bundle savedInstanceState) {
50 | super.onCreate(savedInstanceState);
51 | setContentView(R.layout.activity_translucent);
52 | }
53 |
54 | @Override
55 | protected void onResume() {
56 | super.onResume();
57 | if (isNeedCheck) {
58 | checkPermissions(needPermissions);
59 | }
60 | }
61 |
62 | /**
63 | * @since 2.5.0
64 | */
65 | private void checkPermissions(String... permissions) {
66 | List needRequestPermissonList = findDeniedPermissions(permissions);
67 | if (null != needRequestPermissonList
68 | && needRequestPermissonList.size() > 0) {
69 | ActivityCompat.requestPermissions(this,
70 | needRequestPermissonList.toArray(
71 | new String[needRequestPermissonList.size()]),
72 | PERMISSON_REQUESTCODE);
73 | } else {
74 | //权限已授权 检查未知来源apk安装权限
75 | checkInstallProcess();
76 | // VersionUpdateConfig.getInstance().passCheck();
77 | // finish();
78 | }
79 | }
80 |
81 | /**
82 | * 获取权限集中需要申请权限的列表
83 | *
84 | * @param permissions
85 | * @return
86 | * @since 2.5.0
87 | */
88 | private List findDeniedPermissions(String[] permissions) {
89 | List needRequestPermissonList = new ArrayList();
90 | for (String perm : permissions) {
91 | if (ContextCompat.checkSelfPermission(this,
92 | perm) != PackageManager.PERMISSION_GRANTED
93 | || ActivityCompat.shouldShowRequestPermissionRationale(
94 | this, perm)) {
95 | needRequestPermissonList.add(perm);
96 | }
97 | }
98 | return needRequestPermissonList;
99 | }
100 |
101 | /**
102 | * 检测是否说有的权限都已经授权
103 | *
104 | * @param grantResults
105 | * @return
106 | * @since 2.5.0
107 | */
108 | private boolean verifyPermissions(int[] grantResults) {
109 | for (int result : grantResults) {
110 | if (result != PackageManager.PERMISSION_GRANTED) {
111 | return false;
112 | }
113 | }
114 | return true;
115 | }
116 |
117 | @Override
118 | public void onRequestPermissionsResult(int requestCode,
119 | String[] permissions, int[] paramArrayOfInt) {
120 | if (requestCode == PERMISSON_REQUESTCODE) {
121 | if (!verifyPermissions(paramArrayOfInt)) {
122 | showMissingPermissionDialog();
123 | isNeedCheck = false;
124 | }else{
125 | checkInstallProcess();
126 | }
127 | }
128 | }
129 |
130 | /**
131 | * 显示提示信息
132 | *
133 | * @since 2.5.0
134 | */
135 | private void showMissingPermissionDialog() {
136 | AlertDialog.Builder builder = new AlertDialog.Builder(this);
137 | builder.setTitle(R.string.notifyTitle);
138 | builder.setMessage(R.string.notifyMsg);
139 |
140 | // 拒绝, 退出应用
141 | builder.setNegativeButton(R.string.cancel,
142 | new DialogInterface.OnClickListener() {
143 | @Override
144 | public void onClick(DialogInterface dialog, int which) {
145 | finish();
146 | }
147 | });
148 |
149 | builder.setPositiveButton(R.string.setting,
150 | new DialogInterface.OnClickListener() {
151 | @Override
152 | public void onClick(DialogInterface dialog, int which) {
153 | startAppSettings();
154 | }
155 | });
156 |
157 | builder.setCancelable(false);
158 |
159 | builder.show();
160 | }
161 |
162 | /**
163 | * 启动应用的设置
164 | *
165 | * @since 2.5.0
166 | */
167 | private void startAppSettings() {
168 | Intent intent = new Intent(
169 | Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
170 | intent.setData(Uri.parse("package:" + getPackageName()));
171 | startActivity(intent);
172 | isNeedCheck = true;
173 | }
174 |
175 |
176 | //检查是否有8.0未知来源安装权限
177 | private void checkInstallProcess() {
178 | boolean haveInstallPermission;
179 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
180 | //先获取是否有安装未知来源应用的权限
181 | haveInstallPermission = getPackageManager().canRequestPackageInstalls();
182 | if (!haveInstallPermission) {//没有权限
183 | AlertDialog.Builder alert = new AlertDialog.Builder(this);
184 | alert.setTitle("更新提示").setMessage("安装应用需要打开未知来源权限,请去设置中开启权限").setPositiveButton("确定",
185 | new DialogInterface.OnClickListener() {
186 |
187 | @Override
188 | public void onClick(DialogInterface dialog, int which) {
189 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
190 | startInstallPermissionSettingActivity();
191 | }
192 | }
193 | }).setNegativeButton("取消", new DialogInterface.OnClickListener() {
194 | @Override
195 | public void onClick(DialogInterface dialog, int which) {
196 | Toast.makeText(TranslucentActivity.this, "没有权限,已停止更新", Toast.LENGTH_LONG).show();
197 | if(VersionUpdateConfig.getInstance().getStrongUpdate()==1){
198 | //直接退出app
199 | android.os.Process.killProcess(android.os.Process.myPid());// 杀死该应用进程
200 | System.exit(0);
201 | }else {
202 | finish();
203 | }
204 | }
205 | });
206 | alert.create();
207 | alert.show();
208 | return;
209 | }
210 | }
211 | //权限已授权 开始下载
212 | VersionUpdateConfig.getInstance().passCheck();
213 | finish();
214 | }
215 |
216 | @RequiresApi(api = Build.VERSION_CODES.O)
217 | private void startInstallPermissionSettingActivity() {
218 | Uri packageURI = Uri.parse("package:" + getPackageName());
219 | //注意这个是8.0新API
220 | Intent intent = new Intent(Settings.ACTION_MANAGE_UNKNOWN_APP_SOURCES, packageURI);
221 | startActivityForResult(intent, InstallPermission);
222 | }
223 |
224 | @Override
225 | protected void onActivityResult(int requestCode, int resultCode, Intent data) {
226 | super.onActivityResult(requestCode, resultCode, data);
227 | if(requestCode==InstallPermission){//未知来源app安装权限
228 | if(resultCode == RESULT_OK){
229 | //获取未知来源apk安装权限
230 | VersionUpdateConfig.getInstance().passCheck();
231 | finish();
232 | }else{
233 | Toast.makeText(TranslucentActivity.this, "没有权限,已停止更新", Toast.LENGTH_LONG).show();
234 | if(VersionUpdateConfig.getInstance().getStrongUpdate()==1){
235 | //直接退出app
236 | finish();
237 | System.exit(0);
238 | }else {
239 | finish();
240 | }
241 | }
242 | }
243 | }
244 |
245 | @Override
246 | public boolean onKeyDown(int keyCode, KeyEvent event) {
247 | if (keyCode == KeyEvent.KEYCODE_BACK) {
248 | this.finish();
249 | return true;
250 | }
251 | return super.onKeyDown(keyCode, event);
252 | }
253 | }
254 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/db/DBHelper.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.db;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | * Created by Kun on 2017/5/22.
9 | * GitHub: https://github.com/AndroidKun
10 | * CSDN: http://blog.csdn.net/a1533588867
11 | * Description:
12 | */
13 |
14 | public class DBHelper extends SQLiteOpenHelper{
15 |
16 | private static final String DB_NAME = "db_download";
17 | private static DBHelper dbHelper = null;
18 |
19 | public static DBHelper getInstance(Context context){
20 | if(dbHelper == null) dbHelper = new DBHelper(context);
21 | return dbHelper;
22 | }
23 |
24 | private DBHelper(Context context){
25 | super(context,DB_NAME,null,1);
26 | }
27 |
28 | @Override
29 | public void onCreate(SQLiteDatabase db) {
30 | String sql = "create table thread_info (_id integer primary key autoincrement," +
31 | "thread_id integer,url text,start integer,end integer,finished integer)";
32 | db.execSQL(sql);
33 | }
34 |
35 | @Override
36 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
37 |
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/db/ThreadDao.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.db;
2 |
3 | import java.util.List;
4 |
5 | import androidkun.com.versionupdatelibrary.entity.ThreadBean;
6 |
7 | /**
8 | * Created by Kun on 2017/5/22.
9 | * GitHub: https://github.com/AndroidKun
10 | * CSDN: http://blog.csdn.net/a1533588867
11 | * Description:
12 | */
13 |
14 | public interface ThreadDao {
15 | /**
16 | * 插入下载线程信息
17 | * @param threadBean
18 | */
19 | void insertThread(ThreadBean threadBean);
20 |
21 | /**
22 | * 更新下载线程信息
23 | * @param url
24 | * @param thread_id
25 | * @param finished
26 | */
27 | void updateThread(String url, int thread_id, int finished);
28 |
29 | /**
30 | * 删除下载线程
31 | * @param url
32 | */
33 | void deleteThread(String url);
34 |
35 | /**
36 | * 获取下载线程
37 | * @param url
38 | * @return
39 | */
40 | List getThreads(String url);
41 |
42 | /**
43 | * 判断下载线程是否存在
44 | * @param url
45 | * @param thread_id
46 | * @return
47 | */
48 | boolean isExists(String url, int thread_id);
49 | }
50 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/db/ThreadDaoImpl.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.db;
2 |
3 | import android.content.Context;
4 | import android.database.Cursor;
5 | import android.database.sqlite.SQLiteDatabase;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import androidkun.com.versionupdatelibrary.entity.ThreadBean;
11 |
12 | /**
13 | * Created by Kun on 2017/5/22.
14 | * GitHub: https://github.com/AndroidKun
15 | * CSDN: http://blog.csdn.net/a1533588867
16 | * Description:
17 | */
18 |
19 | public class ThreadDaoImpl implements ThreadDao{
20 | private DBHelper dbHelper;
21 |
22 | public ThreadDaoImpl(Context context){
23 | dbHelper = DBHelper.getInstance(context);
24 | }
25 |
26 | @Override
27 | public synchronized void insertThread(ThreadBean threadBean) {
28 | SQLiteDatabase db = dbHelper.getWritableDatabase();
29 | db.execSQL("insert into thread_info ( thread_id, url, start ,end, finished) values (?,?,?,?,?)"
30 | ,new Object[]{threadBean.getId(),threadBean.getUrl(),threadBean.getStart(),threadBean.getEnd(),threadBean.getFinished()});
31 | db.close();
32 | }
33 |
34 | @Override
35 | public synchronized void updateThread(String url, int thread_id, int finished) {
36 | SQLiteDatabase db = dbHelper.getWritableDatabase();
37 | db.execSQL("update thread_info set finished = ? where url = ? and thread_id = ?"
38 | ,new Object[]{finished,url,thread_id});
39 | db.close();
40 | }
41 |
42 | @Override
43 | public void deleteThread(String url) {
44 | SQLiteDatabase db = dbHelper.getWritableDatabase();
45 | db.execSQL("delete from thread_info where url = ?",new Object[]{url});
46 | db.close();
47 | }
48 |
49 | @Override
50 | public List getThreads(String url) {
51 | SQLiteDatabase db = dbHelper.getReadableDatabase();
52 | Cursor cursor = db.rawQuery("select * from thread_info where url = ?",new String[]{url});
53 | List threadBeanList = new ArrayList<>();
54 | while (cursor.moveToNext()){
55 | ThreadBean bean = new ThreadBean();
56 | bean.setId(cursor.getInt(cursor.getColumnIndex("thread_id")));
57 | bean.setUrl(cursor.getString(cursor.getColumnIndex("url")));
58 | bean.setStart(cursor.getInt(cursor.getColumnIndex("start")));
59 | bean.setEnd(cursor.getInt(cursor.getColumnIndex("end")));
60 | bean.setFinished(cursor.getInt(cursor.getColumnIndex("finished")));
61 | threadBeanList.add(bean);
62 | }
63 | cursor.close();
64 | db.close();
65 | return threadBeanList;
66 | }
67 |
68 | @Override
69 | public boolean isExists(String url, int thread_id) {
70 | SQLiteDatabase db = dbHelper.getReadableDatabase();
71 | Cursor cursor = db.rawQuery("select * from thread_info where url = ? and thread_id = ?", new String[]{url,thread_id+""});
72 | boolean exists = cursor.moveToNext();
73 | cursor.close();
74 | db.close();
75 | return exists;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/download/DownloadCallBack.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.download;
2 |
3 | import androidkun.com.versionupdatelibrary.entity.ThreadBean;
4 |
5 | /**
6 | * Created by Kun on 2017/5/22.
7 | * GitHub: https://github.com/AndroidKun
8 | * CSDN: http://blog.csdn.net/a1533588867
9 | * Description:下载进度回调
10 | */
11 |
12 | public interface DownloadCallBack {
13 | /**
14 | * 暂停回调
15 | * @param threadBean
16 | */
17 | void pauseCallBack(ThreadBean threadBean);
18 | /**
19 | * 停止下载回调
20 | * @param threadBean
21 | */
22 | void closeCallBack(ThreadBean threadBean);
23 | /**
24 | * 下载进度
25 | * @param length
26 | */
27 | void progressCallBack(int length);
28 |
29 | /**
30 | * 线程下载完毕
31 | * @param threadBean
32 | */
33 | void threadDownLoadFinished(ThreadBean threadBean);
34 | }
35 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/download/DownloadTask.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.download;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 |
6 | import java.util.ArrayList;
7 | import java.util.List;
8 |
9 | import androidkun.com.versionupdatelibrary.db.ThreadDao;
10 | import androidkun.com.versionupdatelibrary.db.ThreadDaoImpl;
11 | import androidkun.com.versionupdatelibrary.entity.Config;
12 | import androidkun.com.versionupdatelibrary.entity.FileBean;
13 | import androidkun.com.versionupdatelibrary.entity.ThreadBean;
14 | import androidkun.com.versionupdatelibrary.service.VersionUpdateService;
15 |
16 |
17 | /**
18 | * Created by Kun on 2017/5/22.
19 | * GitHub: https://github.com/AndroidKun
20 | * CSDN: http://blog.csdn.net/a1533588867
21 | * Description:
22 | */
23 | public class DownloadTask implements DownloadCallBack {
24 |
25 | private Context context;
26 | private FileBean fileBean;
27 | private ThreadDao dao;
28 | private int downloadThreadCount;
29 |
30 | /**
31 | * 总下载完成进度
32 | */
33 | private int finishedProgress = 0;
34 | /**
35 | * 下载线程信息集合
36 | */
37 | private List threads;
38 | /**
39 | * 下载线程集合
40 | */
41 | private List downloadThreads = new ArrayList<>();
42 |
43 | public DownloadTask(Context context, FileBean fileBean, int downloadThreadCount) {
44 | this.context = context;
45 | this.fileBean = fileBean;
46 | dao = new ThreadDaoImpl(context);
47 | this.downloadThreadCount = downloadThreadCount;
48 | //初始化下载线程
49 | initDownThreads();
50 | }
51 |
52 | private void initDownThreads() {
53 | //查询数据库中的下载线程信息
54 | threads = dao.getThreads(fileBean.getUrl());
55 | if(threads.size()==0){//如果列表没有数据 则为第一次下载
56 | //根据下载的线程总数平分各自下载的文件长度
57 | int length = fileBean.getLength()/downloadThreadCount;
58 | for(int i = 0; i500 || finishedProgress==fileBean.getLength()){
134 | fileBean.setFinished(finishedProgress);
135 | /* EventMessage message = new EventMessage(3,fileBean);
136 | EventBus.getDefault().post(message);*/
137 | Intent intent = new Intent(Config.ACTION_REFRESH);
138 | speed = (int) (speed/(time*0.001));
139 | intent.putExtra("Speed",speed);
140 | intent.putExtra("FileBean",fileBean);
141 | context.sendBroadcast(intent);
142 | curTime = System.currentTimeMillis();
143 | speed = 0;
144 | }
145 | }
146 |
147 | @Override
148 | public synchronized void threadDownLoadFinished(ThreadBean threadBean) {
149 | for(ThreadBean bean:threads){
150 | if(bean.getId() == threadBean.getId()){
151 | //从列表中将已下载完成的线程信息移除
152 | threads.remove(bean);
153 | break;
154 | }
155 | }
156 | if(threads.size()==0){//如果列表size为0 则所有线程已下载完成
157 | //删除数据库中的信息
158 | dao.deleteThread(fileBean.getUrl());
159 | //发送下载完成事件
160 | /* EventMessage message = new EventMessage(2,fileBean);
161 | EventBus.getDefault().post(message);*/
162 | Intent intent = new Intent(Config.ACTION_FININSHED);
163 | intent.putExtra("FileBean",fileBean);
164 | context.sendBroadcast(intent);
165 | }
166 | }
167 |
168 | public FileBean getFileBean() {
169 | return fileBean;
170 | }
171 |
172 | }
173 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/download/DownloadThread.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.download;
2 |
3 | import java.io.File;
4 | import java.io.InputStream;
5 | import java.io.RandomAccessFile;
6 | import java.net.HttpURLConnection;
7 | import java.net.URL;
8 |
9 | import androidkun.com.versionupdatelibrary.entity.Config;
10 | import androidkun.com.versionupdatelibrary.entity.FileBean;
11 | import androidkun.com.versionupdatelibrary.entity.ThreadBean;
12 |
13 | /**
14 | * Created by Kun on 2017/5/22.
15 | * GitHub: https://github.com/AndroidKun
16 | * CSDN: http://blog.csdn.net/a1533588867
17 | * Description:下载线程
18 | */
19 |
20 | public class DownloadThread extends Thread {
21 |
22 | private FileBean fileBean;
23 | private ThreadBean threadBean;
24 | private DownloadCallBack callback;
25 | private Boolean isPause = false;
26 | private Boolean isClose = false;
27 |
28 | public DownloadThread(FileBean fileBean,ThreadBean threadBean, DownloadCallBack callback) {
29 | this.fileBean = fileBean;
30 | this.threadBean = threadBean;
31 | this.callback = callback;
32 | }
33 |
34 | public void setPause(Boolean pause) {
35 | isPause = pause;
36 | }
37 |
38 | public void setClose(boolean close) {
39 | isClose = close;
40 | }
41 | @Override
42 | public void run() {
43 | HttpURLConnection connection = null;
44 | RandomAccessFile raf = null;
45 | InputStream inputStream = null;
46 | try {
47 | URL url = new URL(threadBean.getUrl());
48 | connection = (HttpURLConnection) url.openConnection();
49 | connection.setConnectTimeout(10000);
50 | connection.setRequestMethod("GET");
51 | //设置下载起始位置
52 | int start = threadBean.getStart() + threadBean.getFinished();
53 | connection.setRequestProperty("Range","bytes="+start+"-"+threadBean.getEnd());
54 | //设置写入位置
55 | File file = new File(Config.downLoadPath,fileBean.getFileName());
56 | raf = new RandomAccessFile(file,"rwd");
57 | raf.seek(start);
58 | //开始下载
59 | if(connection.getResponseCode() == HttpURLConnection.HTTP_PARTIAL){
60 | inputStream = connection.getInputStream();
61 | byte[] bytes = new byte[1024];
62 | int len = -1;
63 | while ((len = inputStream.read(bytes))!=-1){
64 | raf.write(bytes,0,len);
65 | //将加载的进度回调出去
66 | callback.progressCallBack(len);
67 | //保存进度
68 | threadBean.setFinished(threadBean.getFinished()+len);
69 | //在下载暂停的时候将下载进度保存到数据库
70 | if(isClose){
71 | callback.closeCallBack(threadBean);
72 | return;
73 | }
74 | if(isPause){
75 | callback.pauseCallBack(threadBean);
76 | return;
77 | }
78 |
79 | }
80 | //下载完成
81 | callback.threadDownLoadFinished(threadBean);
82 | }
83 |
84 | } catch (Exception e) {
85 | e.printStackTrace();
86 | } finally {
87 | try {
88 | inputStream.close();
89 | raf.close();
90 | connection.disconnect();
91 | }catch (Exception e){
92 | e.printStackTrace();
93 | }
94 | }
95 | }
96 |
97 | }
98 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/download/InitThread.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.download;
2 |
3 | import android.content.Context;
4 | import android.content.Intent;
5 | import android.text.TextUtils;
6 | import android.util.Log;
7 |
8 | import java.io.File;
9 | import java.io.RandomAccessFile;
10 | import java.net.HttpURLConnection;
11 | import java.net.URL;
12 |
13 | import androidkun.com.versionupdatelibrary.R;
14 | import androidkun.com.versionupdatelibrary.entity.Config;
15 | import androidkun.com.versionupdatelibrary.entity.FileBean;
16 | import androidkun.com.versionupdatelibrary.utils.MD5Util;
17 |
18 |
19 | /**
20 | * Created by Kun on 2017/5/22.
21 | * GitHub: https://github.com/AndroidKun
22 | * CSDN: http://blog.csdn.net/a1533588867
23 | * Description:
24 | */
25 |
26 | public class InitThread extends Thread {
27 |
28 | private Context context;
29 | private FileBean fileBean;
30 |
31 | public InitThread(Context context, FileBean fileBean) {
32 | this.context = context;
33 | this.fileBean = fileBean;
34 | }
35 |
36 | @Override
37 | public void run() {
38 | HttpURLConnection connection = null;
39 | RandomAccessFile randomAccessFile = null;
40 | try {
41 | URL url = new URL(fileBean.getUrl());
42 | connection = (HttpURLConnection) url.openConnection();
43 | connection.setConnectTimeout(10000);
44 | connection.setRequestMethod("GET");
45 | int fileLength = -1;
46 | if (connection.getResponseCode() == HttpURLConnection.HTTP_OK) {
47 | fileLength = connection.getContentLength();
48 | }
49 | if (fileLength <= 0) {
50 | Intent intent = new Intent(Config.ACTION_ERROR);
51 | intent.putExtra("error", context.getString(R.string.error_url));
52 | context.sendBroadcast(intent);
53 | return;
54 | }
55 | //判断当前版本的APK是否下载过
56 | File downLoadedFile = new File(Config.downLoadPath, fileBean.getFileName());
57 | if (downLoadedFile.exists()) {
58 | String versionNameFromApk = MD5Util.getVersionNameFromApk(context, downLoadedFile.getPath());
59 | Log.w("AAA", "versionNameFromApk:" + versionNameFromApk + "curVersion:" + fileBean.getVersion());
60 | if (!TextUtils.isEmpty(versionNameFromApk) &&
61 | !TextUtils.isEmpty(fileBean.getVersion()) &&
62 | versionNameFromApk.equals(fileBean.getVersion())) {
63 | Intent intent = new Intent(Config.ACTION_FININSHED);
64 | intent.putExtra("FileBean", fileBean);
65 | context.sendBroadcast(intent);
66 | return;
67 | }
68 | }
69 |
70 | File dir = new File(Config.downLoadPath);
71 | if (!dir.exists()) {
72 | dir.mkdir();
73 | }
74 | File file = new File(dir, fileBean.getFileName());
75 | randomAccessFile = new RandomAccessFile(file, "rwd");
76 | randomAccessFile.setLength(fileLength);
77 | fileBean.setLength(fileLength);
78 |
79 | Intent intent = new Intent(Config.ACTION_START);
80 | intent.putExtra("FileBean", fileBean);
81 | context.sendBroadcast(intent);
82 | } catch (Exception e) {
83 | e.printStackTrace();
84 | }
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/entity/Config.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.entity;
2 |
3 | import android.os.Environment;
4 |
5 | /**
6 | * Created by Kun on 2017/5/22.
7 | * GitHub: https://github.com/AndroidKun
8 | * CSDN: http://blog.csdn.net/a1533588867
9 | * Description:配置文件
10 | */
11 |
12 | public class Config {
13 | /**
14 | * 通知栏标题
15 | */
16 | public static String notificationTitle ;
17 | /**
18 | * 是否是强制更新 强制更新:1.是,0,否
19 | */
20 | public static int strongUpdate = 0;
21 | /**
22 | * 通知栏小图标
23 | */
24 | public static int notificaionSmallIconResId = 0;
25 | /**
26 | * 通知栏图标
27 | */
28 | public static int notificaionIconResId = 0;
29 | /**
30 | * 文件下载地址
31 | */
32 | public static String downLoadPath = Environment.getExternalStorageDirectory().getAbsolutePath()
33 | + "/downloads/";
34 |
35 | /**
36 | * 开始下载
37 | */
38 | public final static String ACTION_START = "ACTION_START";
39 | /**
40 | * 暂停下载
41 | */
42 | public final static String ACTION_PAUSE = "ACTION_PAUSE";
43 | /**
44 | * 下载完成
45 | */
46 | public final static String ACTION_FININSHED = "ACTION_FININSHED";
47 | /**
48 | * 取消下载
49 | */
50 | public final static String ACTION_CLOSE = "ACTION_CLOSE";
51 | /**
52 | * 刷新下载进度
53 | */
54 | public final static String ACTION_REFRESH = "ACTION_REFRESH";
55 | /**
56 | * 下载失败
57 | */
58 | public final static String ACTION_ERROR = "ACTION_ERROR";
59 | }
60 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/entity/FileBean.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by Kun on 2017/5/22.
7 | * GitHub: https://github.com/AndroidKun
8 | * CSDN: http://blog.csdn.net/a1533588867
9 | * Description:下载文件信息
10 | */
11 |
12 | public class FileBean implements Serializable{
13 |
14 | private int id;
15 | private String fileName;
16 | private String url;
17 | private String version;
18 | private int length;
19 | private int finished;
20 |
21 | public FileBean(){
22 |
23 | }
24 |
25 | public FileBean(int id, String fileName, String url, int length, int finished) {
26 | this.id = id;
27 | this.fileName = fileName;
28 | this.url = url;
29 | this.length = length;
30 | this.finished = finished;
31 | }
32 |
33 | public int getId() {
34 | return id;
35 | }
36 |
37 | public void setId(int id) {
38 | this.id = id;
39 | }
40 |
41 | public String getFileName() {
42 | return fileName;
43 | }
44 |
45 | public void setFileName(String fileName) {
46 | this.fileName = fileName;
47 | }
48 |
49 | public String getUrl() {
50 | return url;
51 | }
52 |
53 | public void setUrl(String url) {
54 | this.url = url;
55 | }
56 |
57 | public void setVersion(String version) {
58 | this.version = version;
59 | }
60 |
61 | public String getVersion() {
62 | return version;
63 | }
64 |
65 | public int getLength() {
66 | return length;
67 | }
68 |
69 | public void setLength(int length) {
70 | this.length = length;
71 | }
72 |
73 | public int getFinished() {
74 | return finished;
75 | }
76 |
77 | public void setFinished(int finished) {
78 | this.finished = finished;
79 | }
80 | }
81 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/entity/ThreadBean.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.entity;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | * Created by Kun on 2017/5/22.
7 | * GitHub: https://github.com/AndroidKun
8 | * CSDN: http://blog.csdn.net/a1533588867
9 | * Description:下载线程信息
10 | */
11 |
12 | public class ThreadBean implements Serializable{
13 |
14 | private int id;
15 | private String url;
16 | private int start;
17 | private int end;
18 | private int finished;
19 |
20 | public ThreadBean(){
21 |
22 | }
23 |
24 | public ThreadBean(int id, String url, int start, int end, int finished) {
25 | this.id = id;
26 | this.url = url;
27 | this.start = start;
28 | this.end = end;
29 | this.finished = finished;
30 | }
31 |
32 | public int getId() {
33 | return id;
34 | }
35 |
36 | public void setId(int id) {
37 | this.id = id;
38 | }
39 |
40 | public String getUrl() {
41 | return url;
42 | }
43 |
44 | public void setUrl(String url) {
45 | this.url = url;
46 | }
47 |
48 | public int getStart() {
49 | return start;
50 | }
51 |
52 | public void setStart(int start) {
53 | this.start = start;
54 | }
55 |
56 | public int getEnd() {
57 | return end;
58 | }
59 |
60 | public void setEnd(int end) {
61 | this.end = end;
62 | }
63 |
64 | public int getFinished() {
65 | return finished;
66 | }
67 |
68 | public void setFinished(int finished) {
69 | this.finished = finished;
70 | }
71 | }
72 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/entity/VersionUpdateConfig.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.entity;
2 |
3 | import android.app.Activity;
4 | import android.content.Context;
5 | import android.content.Intent;
6 | import android.os.Build;
7 |
8 | import androidkun.com.versionupdatelibrary.Activity.TranslucentActivity;
9 | import androidkun.com.versionupdatelibrary.service.VersionUpdateService;
10 | import androidkun.com.versionupdatelibrary.utils.MD5Util;
11 |
12 |
13 | /**
14 | * Created by Kun on 2017/5/22.
15 | * GitHub: https://github.com/AndroidKun
16 | * CSDN: http://blog.csdn.net/a1533588867
17 | * Description:
18 | */
19 |
20 | public class VersionUpdateConfig {
21 |
22 | private static VersionUpdateConfig config = new VersionUpdateConfig();
23 | private FileBean fileBean;
24 | private Context context;
25 |
26 | private VersionUpdateConfig() {
27 |
28 | }
29 |
30 | public static VersionUpdateConfig getInstance() {
31 | return config;
32 | }
33 |
34 | /**
35 | * 设置上下文
36 | *
37 | * @param context
38 | * @return
39 | */
40 | public VersionUpdateConfig setContext(Context context) {
41 | this.context = context;
42 | return config;
43 | }
44 |
45 | /**
46 | * 设置文件保存路径
47 | *
48 | * @param path
49 | * @return
50 | */
51 | public VersionUpdateConfig setFileSavePath(String path) {
52 | Config.downLoadPath = path;
53 | return config;
54 | }
55 | /**
56 | * 设置强制更新
57 | * @param strongUpdate 1.是,0,否
58 | * @return
59 | */
60 | public VersionUpdateConfig setStrongUpdate(int strongUpdate) {
61 | Config.strongUpdate = strongUpdate;
62 | return config;
63 | }
64 |
65 | public int getStrongUpdate(){
66 | return Config.strongUpdate;
67 | }
68 |
69 | /**
70 | * 设置通知标题
71 | */
72 | public VersionUpdateConfig setNotificationTitle(String title) {
73 | Config.notificationTitle = title;
74 | return config;
75 | }
76 |
77 | /**
78 | * 设置通知图标
79 | */
80 | public VersionUpdateConfig setNotificationIconRes(int resId) {
81 | Config.notificaionIconResId = resId;
82 | return config;
83 | }
84 |
85 | /**
86 | * 设置通知小图标
87 | */
88 | public VersionUpdateConfig setNotificationSmallIconRes(int resId) {
89 | Config.notificaionSmallIconResId = resId;
90 | return config;
91 | }
92 |
93 | /**
94 | * 设置下载链接
95 | *
96 | * @param url
97 | * @return
98 | */
99 | public VersionUpdateConfig setDownLoadURL(String url) {
100 | fileBean = new FileBean(0, MD5Util.MD5(url) + ".apk", url, 0, 0);
101 | return config;
102 | }
103 |
104 | /**
105 | * 设置新包的版本号 用于区分是否下载过此包
106 | *
107 | * @param version 新包的版本号
108 | * @return
109 | */
110 | public VersionUpdateConfig setNewVersion(String version) {
111 | if (fileBean == null) {
112 | throw new NullPointerException("url cannot be null, you must call setDownLoadURL() before setNewVersion().");
113 | }
114 | fileBean.setVersion(version);
115 | return config;
116 | }
117 |
118 |
119 |
120 | /**
121 | * 开始下载
122 | */
123 | public void startDownLoad() {
124 | if (context == null) {
125 | throw new NullPointerException("context cannot be null, you must first call setContext().");
126 | }
127 | if (fileBean == null) {
128 | throw new NullPointerException("url cannot be null, you must first call setDownLoadURL().");
129 | }
130 |
131 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
132 | ((Activity) context).startActivity(new Intent(context, TranslucentActivity.class));
133 | } else {
134 | passCheck();
135 | }
136 | }
137 |
138 | public void passCheck() {
139 | Intent startIntent = new Intent(context, VersionUpdateService.class);
140 | startIntent.setAction(VersionUpdateService.ACTION_START);
141 | startIntent.putExtra("FileBean", fileBean);
142 | context.startService(startIntent);
143 | }
144 |
145 |
146 | }
147 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/service/VersionUpdateService.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.service;
2 |
3 | import android.app.Notification;
4 | import android.app.NotificationManager;
5 | import android.app.PendingIntent;
6 | import android.app.Service;
7 | import android.content.BroadcastReceiver;
8 | import android.content.Context;
9 | import android.content.Intent;
10 | import android.content.IntentFilter;
11 | import android.net.ConnectivityManager;
12 | import android.net.NetworkInfo;
13 | import android.net.Uri;
14 | import android.os.Build;
15 | import android.os.IBinder;
16 | import android.support.annotation.Nullable;
17 | import android.support.v4.app.NotificationCompat;
18 | import android.support.v4.content.FileProvider;
19 | import android.text.TextUtils;
20 | import android.util.Log;
21 | import android.widget.RemoteViews;
22 | import android.widget.Toast;
23 |
24 | import java.io.File;
25 | import java.lang.reflect.Method;
26 | import java.text.DecimalFormat;
27 | import java.util.ArrayList;
28 | import java.util.List;
29 | import java.util.concurrent.ExecutorService;
30 | import java.util.concurrent.Executors;
31 |
32 | import androidkun.com.versionupdatelibrary.R;
33 | import androidkun.com.versionupdatelibrary.download.DownloadTask;
34 | import androidkun.com.versionupdatelibrary.download.InitThread;
35 | import androidkun.com.versionupdatelibrary.entity.Config;
36 | import androidkun.com.versionupdatelibrary.entity.FileBean;
37 |
38 |
39 | /**
40 | * Created by Kun on 2017/5/22.
41 | * GitHub: https://github.com/AndroidKun
42 | * CSDN: http://blog.csdn.net/a1533588867
43 | * Description:
44 | */
45 |
46 | public class VersionUpdateService extends Service {
47 | public static final String ACTION_START = "ACTION_START";
48 | public static final String ACTION_PAUSE = "ACTION_PAUSE";
49 | /**
50 | * 下载任务集合
51 | */
52 | private List downloadTasks = new ArrayList<>();
53 | public static ExecutorService executorService = Executors.newCachedThreadPool();
54 |
55 | private DownLoadBroadcastReceiver receiver;
56 |
57 | private FileBean curFileBean;
58 | /**
59 | * 网络状态
60 | */
61 | private boolean netWorkStatus;
62 |
63 | /**
64 | * 手动暂停下载
65 | */
66 | private boolean isUserPause;
67 |
68 | @Override
69 | public void onCreate() {
70 | super.onCreate();
71 | receiver = new DownLoadBroadcastReceiver();
72 | IntentFilter intentFilter = new IntentFilter();
73 | intentFilter.addAction(Config.ACTION_START);
74 | intentFilter.addAction(Config.ACTION_REFRESH);
75 | intentFilter.addAction(Config.ACTION_FININSHED);
76 | intentFilter.addAction(Config.ACTION_PAUSE);
77 | intentFilter.addAction(Config.ACTION_ERROR);
78 | intentFilter.addAction(Config.ACTION_CLOSE);
79 | intentFilter.addAction(BUTTON_ACTION);
80 | intentFilter.addAction(BUTTON_CLOSE_ACTION);
81 | intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
82 | registerReceiver(receiver, intentFilter);
83 | }
84 |
85 | @Override
86 | public int onStartCommand(Intent intent, int flags, int startId) {
87 | if (intent.getAction().equals(ACTION_START)) {
88 | isDownLoading = true;
89 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
90 | curFileBean = fileBean;
91 |
92 | for (DownloadTask downloadTask : downloadTasks) {
93 | if (downloadTask.getFileBean().getUrl().equals(fileBean.getUrl())) {
94 | //如果下载任务中以后该文件的下载任务 则直接返回
95 | return super.onStartCommand(intent, flags, startId);
96 | }
97 | }
98 | executorService.execute(new InitThread(getBaseContext(), fileBean));
99 | } else if (intent.getAction().equals(ACTION_PAUSE)) {
100 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
101 | DownloadTask pauseTask = null;
102 | for (DownloadTask downloadTask : downloadTasks) {
103 | if (downloadTask.getFileBean().getUrl().equals(fileBean.getUrl())) {
104 | downloadTask.pauseDownload();
105 | pauseTask = downloadTask;
106 | break;
107 | }
108 | }
109 | //将下载任务移除
110 | downloadTasks.remove(pauseTask);
111 | }
112 | return super.onStartCommand(intent, flags, startId);
113 | }
114 |
115 |
116 | @Nullable
117 | @Override
118 | public IBinder onBind(Intent intent) {
119 | return null;
120 | }
121 |
122 | @Override
123 | public void onDestroy() {
124 | super.onDestroy();
125 | unregisterReceiver(receiver);
126 | }
127 |
128 | private NotificationManager notificationManager;
129 | private RemoteViews remoteView;
130 | private NotificationCompat.Builder builder;
131 | private final int notificationId = 100001;
132 | private boolean isDownLoading = false;
133 | private final String BUTTON_ACTION = "BUTTON_ACTION";
134 | private final String BUTTON_CLOSE_ACTION = "BUTTON_CLOSE_ACTION";
135 |
136 | /**
137 | * 发送通知
138 | */
139 | private void sendDefaultNotification() {
140 | remoteView = new RemoteViews(getPackageName(), R.layout.layout_notifi);
141 | if (TextUtils.isEmpty(Config.notificationTitle)) {
142 | remoteView.setTextViewText(R.id.textView, getString(R.string.notification_title));
143 | } else {
144 | remoteView.setTextViewText(R.id.textView, Config.notificationTitle);
145 | }
146 | if (Config.notificaionIconResId != 0) {
147 | remoteView.setImageViewResource(R.id.icon, Config.notificaionIconResId);
148 | }
149 | Intent buttonAction = new Intent(BUTTON_ACTION);
150 | PendingIntent pendingIntent = PendingIntent.getBroadcast(this, 1, buttonAction, PendingIntent.FLAG_UPDATE_CURRENT);
151 | remoteView.setOnClickPendingIntent(R.id.btn1, pendingIntent);
152 |
153 | Intent closeAction = new Intent(BUTTON_CLOSE_ACTION);
154 | PendingIntent closeIntent = PendingIntent.getBroadcast(this, 1, closeAction, PendingIntent.FLAG_UPDATE_CURRENT);
155 | remoteView.setOnClickPendingIntent(R.id.btnClose, closeIntent);
156 |
157 | builder = new NotificationCompat.Builder(this);
158 | if(Config.notificaionSmallIconResId == 0) {
159 | builder.setSmallIcon(R.mipmap.ic_launcher);
160 | }else{
161 | builder.setSmallIcon(Config.notificaionSmallIconResId);
162 | }
163 | builder.setTicker(getString(R.string.notification_ticker));
164 | builder.setContent(remoteView);
165 | builder.setAutoCancel(true);
166 | builder.setOngoing(true);
167 | builder.setPriority(Notification.PRIORITY_MAX);
168 | notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
169 | notificationManager.notify(notificationId, builder.build());
170 | }
171 |
172 | private void updataNofication(int progress, int size, String speed) {
173 | if (isDownLoading) {
174 | remoteView.setImageViewResource(R.id.btn1, R.mipmap.ic_pause);
175 | } else {
176 | remoteView.setImageViewResource(R.id.btn1, R.mipmap.ic_continue);
177 | }
178 | remoteView.setProgressBar(R.id.progressBar, 100, progress, false);
179 | DecimalFormat df = new DecimalFormat("#.##");
180 | remoteView.setTextViewText(R.id.textSize, df.format(b2mbDouble(size)) + "");
181 | remoteView.setTextViewText(R.id.textSpeed, speed + "kb/s");
182 | notificationManager.notify(notificationId, builder.build());
183 | }
184 |
185 | public double b2mbDouble(long b) {
186 | return b * 1.0 / 1024 / 1024;
187 | }
188 |
189 | /**
190 | * 关闭通知
191 | */
192 | private void cancleNotification() {
193 | notificationManager.cancel(notificationId);
194 | }
195 |
196 |
197 | private class DownLoadBroadcastReceiver extends BroadcastReceiver {
198 | @Override
199 | public void onReceive(Context context, Intent intent) {
200 | String action = intent.getAction();
201 | if (action.equals(Config.ACTION_START)) {
202 | isDownLoading = true;
203 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
204 | //开始下载
205 | DownloadTask downloadTask = new DownloadTask(VersionUpdateService.this, fileBean, 3);
206 | downloadTasks.add(downloadTask);
207 | if (notificationManager == null) {
208 | sendDefaultNotification();
209 | }
210 | } else if (action.equals(Config.ACTION_FININSHED)) {
211 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
212 | DownloadTask task = null;
213 | for (DownloadTask downloadTask : downloadTasks) {
214 | if(downloadTask.getFileBean().getUrl().equals(fileBean.getUrl())){
215 | task = downloadTask;
216 | break;
217 | }
218 | }
219 | if(task!=null){
220 | downloadTasks.remove(task);
221 | }
222 | installPage(fileBean);
223 | cancleNotification();
224 | curFileBean = null;
225 | } else if (action.equals(Config.ACTION_REFRESH)) {
226 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
227 | DecimalFormat df = new DecimalFormat("#.##");
228 | int progress = (int) (fileBean.getFinished() * 1.0f / fileBean.getLength() * 1.0f*100);
229 | int speed = intent.getIntExtra("Speed", 0);
230 | String format = df.format(speed * 1.0 / 1024);
231 | updataNofication(progress, fileBean.getLength(), format);
232 | } else if (action.equals(Config.ACTION_PAUSE)) {
233 | isDownLoading = false;
234 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
235 | int progress = (int) (fileBean.getFinished() * 1.0f / fileBean.getLength() * 1.0f*100);
236 | updataNofication(progress, fileBean.getLength(), "0");
237 | }else if(action.equals(BUTTON_CLOSE_ACTION)){//点击取消下载按钮
238 | if(curFileBean!=null){
239 | File file = new File(Config.downLoadPath,curFileBean.getFileName());
240 | DownloadTask task = null;
241 | for (DownloadTask downloadTask : downloadTasks) {
242 | if(downloadTask.getFileBean().getUrl().equals(curFileBean.getUrl())){
243 | downloadTask.closeDownload();
244 | task = downloadTask;
245 | break;
246 | }
247 | }
248 | if(task!=null){
249 | downloadTasks.remove(task);
250 | }else{
251 | DownloadTask downloadTask = new DownloadTask(VersionUpdateService.this, curFileBean, 3);
252 | downloadTask.closeDownload();
253 | }
254 | }
255 | }else if(action.equals(Config.ACTION_CLOSE)){//取消下载
256 | FileBean fileBean = (FileBean) intent.getSerializableExtra("FileBean");
257 | File file = new File(Config.downLoadPath,fileBean.getFileName());
258 | if(file.exists()){
259 | file.delete();
260 | }
261 | cancleNotification();
262 | }else if (action.equals(BUTTON_ACTION)) {
263 | if(!netWorkStatus){
264 | Toast.makeText(context,"请检查网络",Toast.LENGTH_SHORT).show();
265 | return;
266 | }
267 | if (isDownLoading) {
268 | isUserPause = true;
269 | Intent startIntent = new Intent(context, VersionUpdateService.class);
270 | startIntent.setAction(VersionUpdateService.ACTION_PAUSE);
271 | startIntent.putExtra("FileBean", curFileBean);
272 | startService(startIntent);
273 | } else {
274 | isUserPause = false;
275 | Intent startIntent = new Intent(context, VersionUpdateService.class);
276 | startIntent.setAction(VersionUpdateService.ACTION_START);
277 | startIntent.putExtra("FileBean", curFileBean);
278 | startService(startIntent);
279 | }
280 | }else if(action.equals(Config.ACTION_ERROR)){
281 | Toast.makeText(context, intent.getStringExtra("error"),Toast.LENGTH_SHORT).show();
282 | }else{
283 | if(curFileBean == null) return;
284 | ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
285 | NetworkInfo mobNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
286 | NetworkInfo wifiNetInfo = connectivityManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
287 |
288 | if (!mobNetInfo.isConnected() && !wifiNetInfo.isConnected()) {
289 | //网络连接已断开
290 | netWorkStatus = false;
291 | if(!isDownLoading) return;
292 | Intent startIntent = new Intent(context, VersionUpdateService.class);
293 | startIntent.setAction(VersionUpdateService.ACTION_PAUSE);
294 | startIntent.putExtra("FileBean", curFileBean);
295 | startService(startIntent);
296 | } else {
297 | netWorkStatus = true;
298 | //网络连接已连接
299 | if(isDownLoading || isUserPause) return;
300 | Intent startIntent = new Intent(context, VersionUpdateService.class);
301 | startIntent.setAction(VersionUpdateService.ACTION_START);
302 | startIntent.putExtra("FileBean", curFileBean);
303 | startService(startIntent);
304 |
305 | }
306 | }
307 | }
308 | }
309 |
310 | /**
311 | * 自动安装
312 | */
313 | private void installPage(FileBean filebean) {
314 | String filePath = Config.downLoadPath + "/" + filebean.getFileName();
315 | File file = new File(filePath);
316 | if (!file.exists()) {
317 | throw new NullPointerException(
318 | "The package cannot be found");
319 | }
320 | Intent install = new Intent(Intent.ACTION_VIEW);
321 | // 调用系统自带安装环境
322 | if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
323 | install.setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
324 | Uri contentUri = FileProvider.getUriForFile(this, getPackageName()+".fileprovider", file);
325 | install.setDataAndType(contentUri, "application/vnd.android.package-archive");
326 | } else {
327 | install.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
328 | install.setDataAndType(Uri.fromFile(file), "application/vnd.android.package-archive");
329 | }
330 | getApplicationContext().startActivity(install);
331 | collapseStatusBar();
332 | }
333 |
334 | /**
335 | * 收起通知栏
336 | */
337 | public void collapseStatusBar() {
338 | try {
339 | Object statusBarManager = getSystemService("statusbar");
340 | Method collapse;
341 | if (Build.VERSION.SDK_INT <= 16) {
342 | collapse = statusBarManager.getClass().getMethod("collapse");
343 | } else {
344 | collapse = statusBarManager.getClass().getMethod("collapsePanels");
345 | }
346 | collapse.invoke(statusBarManager);
347 | } catch (Exception localException) {
348 | localException.printStackTrace();
349 | }
350 | }
351 | }
352 |
353 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/java/androidkun/com/versionupdatelibrary/utils/MD5Util.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary.utils;
2 |
3 | import android.content.Context;
4 | import android.content.pm.PackageInfo;
5 | import android.content.pm.PackageManager;
6 |
7 | import java.security.MessageDigest;
8 |
9 | /**
10 | * Created by Kun on 2017/11/13.
11 | * GitHub: https://github.com/AndroidKun
12 | * CSDN: http://blog.csdn.net/a1533588867
13 | * Description:MD5工具
14 | */
15 |
16 | public class MD5Util {
17 |
18 | public final static String MD5(String pwd) {
19 | char md5String[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
20 | 'A', 'B', 'C', 'D', 'E', 'F' };
21 | try {
22 | byte[] btInput = pwd.getBytes();
23 |
24 | MessageDigest mdInst = MessageDigest.getInstance("MD5");
25 |
26 | mdInst.update(btInput);
27 |
28 | byte[] md = mdInst.digest();
29 |
30 | int j = md.length;
31 | char str[] = new char[j * 2];
32 | int k = 0;
33 | for (int i = 0; i < j; i++) { // i = 0
34 | byte byte0 = md[i]; //95
35 | str[k++] = md5String[byte0 >>> 4 & 0xf]; // 5
36 | str[k++] = md5String[byte0 & 0xf]; // F
37 | }
38 | return new String(str);
39 | } catch (Exception e) {
40 | return null;
41 | }
42 | }
43 |
44 | /**
45 | * 从一个apk文件去获取该文件的版本信息
46 | *
47 | * @param context
48 | * 本应用程序上下文
49 | * @param archiveFilePath
50 | * APK文件的路径。如:/sdcard/download/XX.apk
51 | * @return
52 | */
53 | public static String getVersionNameFromApk(Context context, String archiveFilePath) {
54 | PackageManager pm = context.getPackageManager();
55 | PackageInfo packInfo = pm.getPackageArchiveInfo(archiveFilePath, PackageManager.GET_ACTIVITIES);
56 | if(packInfo!=null) {
57 | return packInfo.versionName;
58 | }
59 | return null;
60 | }
61 |
62 |
63 | }
64 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/layout/activity_translucent.xml:
--------------------------------------------------------------------------------
1 |
2 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/layout/layout_notifi.xml:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
16 |
17 |
23 |
24 |
30 |
31 |
37 |
38 |
41 |
46 |
51 |
56 |
62 |
68 |
69 |
70 |
71 |
77 |
78 |
79 |
85 |
86 |
87 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/mipmap-xhdpi/close.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/versionupdatelibrary/src/main/res/mipmap-xhdpi/close.png
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_continue.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_continue.png
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_pause.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/AndroidKun/XVersionUpdate/569a28d67b85d469f424d896db2629c68d01e784/versionupdatelibrary/src/main/res/mipmap-xhdpi/ic_pause.png
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/values-w820dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 64dp
6 |
7 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/values-zh/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VersionUpdateDemo
3 | 正在下载...
4 | 总体积:
5 | 下载速度:
6 | 开始下载
7 |
8 | 提示
9 | 当前应用缺少必要权限。\n\n请点击\"设置\"-\"权限\"-打开所需权限。
10 | 设置
11 | 取消
12 | 确定
13 | 下载连接无效
14 |
15 |
16 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 16dp
4 | 16dp
5 |
6 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 | VersionUpdateDemo
3 | downloading...
4 | Size:
5 | Speed:
6 | Start downloading
7 |
8 | Notity
9 | The current application is missing the necessary permissions.\n\nPlease click\"Setting\"-\"permissions\"-
10 | open required permissions。
11 | Setting
12 | Cancel
13 | Sure
14 | Download connection invalid
15 |
16 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/main/res/xml/provider_paths.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
--------------------------------------------------------------------------------
/versionupdatelibrary/src/test/java/androidkun/com/versionupdatelibrary/ExampleUnitTest.java:
--------------------------------------------------------------------------------
1 | package androidkun.com.versionupdatelibrary;
2 |
3 | import org.junit.Test;
4 |
5 | import static org.junit.Assert.*;
6 |
7 | /**
8 | * Example local unit test, which will execute on the development machine (host).
9 | *
10 | * @see Testing documentation
11 | */
12 | public class ExampleUnitTest {
13 | @Test
14 | public void addition_isCorrect() throws Exception {
15 | assertEquals(4, 2 + 2);
16 | }
17 | }
--------------------------------------------------------------------------------