diff --git a/.idea/assetWizardSettings.xml b/.idea/assetWizardSettings.xml
deleted file mode 100644
index 1d1e989..0000000
--- a/.idea/assetWizardSettings.xml
+++ /dev/null
@@ -1,57 +0,0 @@
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/caches/build_file_checksums.ser b/.idea/caches/build_file_checksums.ser
index 4efb1d7..4f4e779 100644
Binary files a/.idea/caches/build_file_checksums.ser and b/.idea/caches/build_file_checksums.ser differ
diff --git a/.idea/encodings.xml b/.idea/encodings.xml
index c2bae49..97626ba 100644
--- a/.idea/encodings.xml
+++ b/.idea/encodings.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.idea/markdown-navigator.xml b/.idea/markdown-navigator.xml
new file mode 100644
index 0000000..7758d01
--- /dev/null
+++ b/.idea/markdown-navigator.xml
@@ -0,0 +1,83 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/misc.xml b/.idea/misc.xml
index c0f68ed..e0d5b93 100644
--- a/.idea/misc.xml
+++ b/.idea/misc.xml
@@ -5,27 +5,31 @@
-
+
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
index 94a25f7..35eb1dd 100644
--- a/.idea/vcs.xml
+++ b/.idea/vcs.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/.travis.yml b/.travis.yml
index 939e9e3..7b0adca 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,12 +1,12 @@
language: android
jdk: oraclejdk8
before_install:
-- yes | sdkmanager "platforms;android-27"
+- yes | sdkmanager "platforms;android-28"
env:
global:
- - ANDROID_API_LEVEL=27
- - ANDROID_BUILD_TOOLS_VERSION=27.0.3
+ - ANDROID_API_LEVEL=28
+ - ANDROID_BUILD_TOOLS_VERSION=28.0.3
- TRAVIS_SECURE_ENV_VARS=true
android:
diff --git a/LICENSE b/LICENSE
index 1861d82..5dc1cac 100644
--- a/LICENSE
+++ b/LICENSE
@@ -1,23 +1,21 @@
+The MIT License (MIT)
- The MIT License (MIT)
- Copyright (c) 2017 Jenly Yu
- https://github.com/jenly1314
+Copyright (c) 2018 Jenly Yu
- Permission is hereby granted, free of charge, to any person obtaining
- a copy of this software and associated documentation files
- (the "Software"), to deal in the Software without restriction, including
- without limitation the rights to use, copy, modify, merge, publish,
- distribute, sublicense, and/or sell copies of the Software, and to permit
- persons to whom the Software is furnished to do so, subject to the
- following conditions:
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
- The above copyright notice and this permission notice shall be included
- in all copies or substantial portions of the Software.
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- DEALINGS IN THE SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
\ No newline at end of file
diff --git a/README.md b/README.md
index 01bed42..a73a1f7 100644
--- a/README.md
+++ b/README.md
@@ -9,7 +9,8 @@
[![License](https://img.shields.io/badge/license-MIT-blue.svg)](https://opensource.org/licenses/mit-license.php)
[![Blog](https://img.shields.io/badge/blog-Jenly-9933CC.svg)](http://blog.csdn.net/jenly121)
-AppUpdater for Android 是一个专注于App更新一键傻瓜式集成的开源库,主要包括app-updater和app-dialog。
+AppUpdater for Android 是一个专注于App更新,一键傻瓜式集成App版本升级的开源库。(无需担心通知栏适配;无需担心重复点击下载;无需担心App安装等问题;这些AppUpdater都已帮您处理好。)
+ 核心库主要包括app-updater和app-dialog。
> 下载更新和弹框提示分开,是因为这本来就是两个逻辑。完全独立开来能有效的解耦。
* app-updater 主要负责后台下载更新App,无需担心下载时各种配置相关的细节,一键傻瓜式升级。
* app-dialog 主要是提供常用的Dialog和DialogFragment,简化弹框提示,样式支持高度自定义。
@@ -36,7 +37,7 @@ AppUpdater for Android 是一个专注于App更新一键傻瓜式集成的开源
com.king.app
app-updater
- 1.0
+ 1.0.1
pom
@@ -44,27 +45,27 @@ AppUpdater for Android 是一个专注于App更新一键傻瓜式集成的开源
com.king.app
app-dialog
- 1.0
+ 1.0.1
pom
```
### Gradle:
```gradle
//app-updater
- compile 'com.king.app:app-updater:1.0'
+ compile 'com.king.app:app-updater:1.0.1'
//app-dialog
- compile 'com.king.app:app-dialog:1.0'
+ compile 'com.king.app:app-dialog:1.0.1'
```
### Lvy:
```lvy
//app-updater
-
+
//app-dialog
-
+
```
diff --git a/app-dialog/bintray.gradle b/app-dialog/bintray.gradle
index 94c2c6a..04e46f0 100644
--- a/app-dialog/bintray.gradle
+++ b/app-dialog/bintray.gradle
@@ -4,7 +4,8 @@ publish {
userOrg = 'jenly'//bintray.com用户名
groupId = 'com.king.app'//jcenter上的路径
artifactId = 'app-dialog'//项目名称
- publishVersion = '1.0'//版本号
+ publishVersion = app_version.versionName//版本号
desc = 'AppDialog for Android'//描述
website = 'https://github.com/jenly1314/AppUpdater'//网站
+ licences = ['MIT']//开源协议
}
\ No newline at end of file
diff --git a/app-dialog/build.gradle b/app-dialog/build.gradle
index cc80d34..b838768 100644
--- a/app-dialog/build.gradle
+++ b/app-dialog/build.gradle
@@ -2,16 +2,15 @@ apply plugin: 'com.android.library'
apply from: 'bintray.gradle'
android {
- compileSdkVersion 27
-
+ compileSdkVersion build_versions.compileSdk
+ buildToolsVersion build_versions.buildTools
defaultConfig {
- minSdkVersion 15
- targetSdkVersion 27
- versionCode 1
- versionName "1.0"
-
+ minSdkVersion build_versions.minSdk
+ targetSdkVersion build_versions.targetSdk
+ versionCode app_version.versionCode
+ versionName app_version.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@@ -23,15 +22,21 @@ android {
}
}
+ lintOptions {
+ abortOnError false
+ warning 'InvalidPackage'
+ }
+
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testImplementation deps.test.junit
+ androidTestImplementation deps.test.runner
+ androidTestImplementation deps.test.espresso
+ //support
+ compileOnly deps.support.appcompat
- compileOnly 'com.android.support:appcompat-v7:27.1.1'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
diff --git a/app-dialog/src/main/java/com/king/app/dialog/AppDialog.java b/app-dialog/src/main/java/com/king/app/dialog/AppDialog.java
index b25f000..8b14d96 100644
--- a/app-dialog/src/main/java/com/king/app/dialog/AppDialog.java
+++ b/app-dialog/src/main/java/com/king/app/dialog/AppDialog.java
@@ -32,6 +32,12 @@ public enum AppDialog {
//-------------------------------------------
+ /**
+ * 通过{@link AppDialogConfig} 创建一个视图
+ * @param context
+ * @param config 弹框配置 {@link AppDialogConfig}
+ * @return
+ */
public View createAppDialogView(Context context,AppDialogConfig config){
View view = null;
if(config!=null){
@@ -99,6 +105,11 @@ public enum AppDialog {
//-------------------------------------------
+ /**
+ * 显示DialogFragment
+ * @param fragmentManager
+ * @return
+ */
public String showDialogFragment(FragmentManager fragmentManager,AppDialogConfig config){
AppDialogFragment dialogFragment = AppDialogFragment.newInstance(config);
String tag = dialogFragment.getTag() !=null ? dialogFragment.getTag() : dialogFragment.getClass().getSimpleName();
@@ -107,6 +118,12 @@ public enum AppDialog {
return tag;
}
+ /**
+ * 显示DialogFragment
+ * @param fragmentManager
+ * @param dialogFragment
+ * @return
+ */
public String showDialogFragment(FragmentManager fragmentManager,DialogFragment dialogFragment){
String tag = dialogFragment.getTag() !=null ? dialogFragment.getTag() : dialogFragment.getClass().getSimpleName();
showDialogFragment(fragmentManager,dialogFragment,tag);
@@ -114,6 +131,13 @@ public enum AppDialog {
return tag;
}
+ /**
+ * 显示DialogFragment
+ * @param fragmentManager
+ * @param dialogFragment
+ * @param tag
+ * @return
+ */
public String showDialogFragment(FragmentManager fragmentManager,DialogFragment dialogFragment, String tag) {
dialogFragment.show(fragmentManager,tag);
mTag = tag;
@@ -122,36 +146,82 @@ public enum AppDialog {
//-------------------------------------------
+ /**
+ * 显示弹框
+ * @param context
+ * @param config 弹框配置 {@link AppDialogConfig}
+ */
public void showDialog(Context context,AppDialogConfig config){
- showDialog(context,createAppDialogView(context,config));
+ showDialog(context,config,true);
+ }
+
+ /**
+ * 显示弹框
+ * @param context
+ * @param config 弹框配置 {@link AppDialogConfig}
+ * @param isCancel 是否可取消(默认为true,false则拦截back键)
+ */
+ public void showDialog(Context context,AppDialogConfig config,boolean isCancel){
+ showDialog(context,createAppDialogView(context,config),R.style.app_dialog,DEFAULT_WIDTH_RATIO,isCancel);
}
+ /**
+ * 显示弹框
+ * @param context
+ * @param contentView 弹框内容视图
+ */
public void showDialog(Context context,View contentView){
showDialog(context,contentView,DEFAULT_WIDTH_RATIO);
}
+ /**
+ * 显示弹框
+ * @param context
+ * @param contentView 弹框内容视图
+ * @param isCancel 是否可取消(默认为true,false则拦截back键)
+ */
public void showDialog(Context context,View contentView,boolean isCancel){
showDialog(context,contentView,R.style.app_dialog,DEFAULT_WIDTH_RATIO,isCancel);
}
+ /**
+ * 显示弹框
+ * @param context
+ * @param contentView 弹框内容视图
+ * @param widthRatio 宽度比例,根据屏幕宽度计算得来
+ */
public void showDialog(Context context,View contentView,float widthRatio){
showDialog(context,contentView,widthRatio,true);
}
+ /**
+ * 显示弹框
+ * @param context
+ * @param contentView 弹框内容视图
+ * @param widthRatio 宽度比例,根据屏幕宽度计算得来
+ * @param isCancel 是否可取消(默认为true,false则拦截back键)
+ */
public void showDialog(Context context,View contentView,float widthRatio,boolean isCancel){
showDialog(context,contentView,R.style.app_dialog,widthRatio,isCancel);
}
+ /**
+ * 显示弹框
+ * @param context
+ * @param contentView 弹框内容视图
+ * @param resId Dialog样式
+ * @param widthRatio 宽度比例,根据屏幕宽度计算得来
+ */
public void showDialog(Context context, View contentView, @StyleRes int resId, float widthRatio){
showDialog(context,contentView,resId,widthRatio,true);
}
/**
- *
+ * 显示弹框
* @param context
- * @param contentView
+ * @param contentView 弹框内容视图
* @param resId Dialog样式
- * @param widthRatio
+ * @param widthRatio 宽度比例,根据屏幕宽度计算得来
* @param isCancel 是否可取消(默认为true,false则拦截back键)
*/
public void showDialog(Context context, View contentView, @StyleRes int resId, float widthRatio,final boolean isCancel){
diff --git a/app-dialog/src/main/java/com/king/app/dialog/AppDialogConfig.java b/app-dialog/src/main/java/com/king/app/dialog/AppDialogConfig.java
index cdb4c32..a2f619b 100644
--- a/app-dialog/src/main/java/com/king/app/dialog/AppDialogConfig.java
+++ b/app-dialog/src/main/java/com/king/app/dialog/AppDialogConfig.java
@@ -8,38 +8,60 @@ import android.view.View;
* @author Jenly Jenly
*/
public class AppDialogConfig {
-
+ /**
+ * 布局ID
+ */
private @LayoutRes int layoutId = R.layout.app_dialog;
-
+ /**
+ * 标题视图ID
+ */
private @IdRes int titleId = R.id.tvDialogTitle;
-
+ /**
+ * 内容视图ID
+ */
private @IdRes int contentId = R.id.tvDialogContent;
-
+ /**
+ * 取消视图ID(左边按钮)
+ */
private @IdRes int cancelId = R.id.btnDialogCancel;
-
+ /**
+ * 确定视图ID(右边按钮)
+ */
private @IdRes int okId = R.id.btnDialogOK;
-
+ /**
+ * 按钮中间分割线ID
+ */
private @IdRes int line = R.id.line;
-
+ /**
+ * 标题文本
+ */
private CharSequence title;
-
+ /**
+ * 内容文本
+ */
private CharSequence content;
-
+ /**
+ * 取消按钮文本
+ */
private CharSequence cancel;
-
+ /**
+ * 确定按钮文本
+ */
private CharSequence ok;
-
+ /**
+ * 是否隐藏取消按钮,如果取消则底部只显示一个按钮
+ */
private boolean isHideCancel;
private View.OnClickListener onClickCancel;
private View.OnClickListener onClickOk;
- public int getLayoutId() {
+ public @LayoutRes int getLayoutId() {
return layoutId;
}
- public AppDialogConfig setLayoutId(int layoutId) {
+ public AppDialogConfig setLayoutId(@LayoutRes int layoutId) {
this.layoutId = layoutId;
return this;
}
@@ -48,43 +70,43 @@ public class AppDialogConfig {
return titleId;
}
- public AppDialogConfig setTitleId(int titleId) {
+ public AppDialogConfig setTitleId(@IdRes int titleId) {
this.titleId = titleId;
return this;
}
- public int getContentId() {
+ public @IdRes int getContentId() {
return contentId;
}
- public AppDialogConfig setContentId(int contentId) {
+ public AppDialogConfig setContentId(@IdRes int contentId) {
this.contentId = contentId;
return this;
}
- public int getCancelId() {
+ public @IdRes int getCancelId() {
return cancelId;
}
- public AppDialogConfig setCancelId(int cancelId) {
+ public AppDialogConfig setCancelId(@IdRes int cancelId) {
this.cancelId = cancelId;
return this;
}
- public int getOkId() {
+ public @IdRes int getOkId() {
return okId;
}
- public AppDialogConfig setOkId(int okId) {
+ public AppDialogConfig setOkId(@IdRes int okId) {
this.okId = okId;
return this;
}
- public int getLine() {
+ public @IdRes int getLine() {
return line;
}
- public AppDialogConfig setLine(int line) {
+ public AppDialogConfig setLine(@IdRes int line) {
this.line = line;
return this;
}
diff --git a/app-dialog/src/main/java/com/king/app/dialog/fragment/BaseDialogFragment.java b/app-dialog/src/main/java/com/king/app/dialog/fragment/BaseDialogFragment.java
index 4e9b2b3..50863b6 100644
--- a/app-dialog/src/main/java/com/king/app/dialog/fragment/BaseDialogFragment.java
+++ b/app-dialog/src/main/java/com/king/app/dialog/fragment/BaseDialogFragment.java
@@ -1,5 +1,7 @@
package com.king.app.dialog.fragment;
+import android.app.Dialog;
+import android.content.Context;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
@@ -11,13 +13,18 @@ import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
+import android.view.WindowManager;
import android.widget.TextView;
+import com.king.app.dialog.R;
+
/**
* @author Jenly Jenly
*/
public abstract class BaseDialogFragment extends DialogFragment {
+ protected static final float DEFAULT_WIDTH_RATIO = 0.85f;
+
private View mRootView;
@Nullable
@@ -31,6 +38,21 @@ public abstract class BaseDialogFragment extends DialogFragment {
return mRootView;
}
+ @Override
+ public void onActivityCreated(Bundle savedInstanceState) {
+ super.onActivityCreated(savedInstanceState);
+ super.getDialog().getWindow().getAttributes().windowAnimations = R.style.app_dialog_animation;
+ getDialog().setCanceledOnTouchOutside(false);
+ setDialogWindow(getContext(),getDialog(),DEFAULT_WIDTH_RATIO);
+ }
+
+ private void setDialogWindow(Context context, Dialog dialog, float widthRatio){
+ Window window = dialog.getWindow();
+ WindowManager.LayoutParams lp = window.getAttributes();
+ lp.width = (int)(context.getResources().getDisplayMetrics().widthPixels * widthRatio);
+ window.setAttributes(lp);
+ }
+
protected View getRootView(){
return mRootView;
}
diff --git a/app-dialog/src/main/res/drawable/app_dialog_bg.xml b/app-dialog/src/main/res/drawable/app_dialog_bg.xml
index 0c984ca..ea1fd30 100644
--- a/app-dialog/src/main/res/drawable/app_dialog_bg.xml
+++ b/app-dialog/src/main/res/drawable/app_dialog_bg.xml
@@ -4,9 +4,9 @@
+ android:bottomLeftRadius="@dimen/app_dialog_radius"
+ android:bottomRightRadius="@dimen/app_dialog_radius"
+ android:topLeftRadius="@dimen/app_dialog_radius"
+ android:topRightRadius="@dimen/app_dialog_radius" />
\ No newline at end of file
diff --git a/app-dialog/src/main/res/layout/app_dialog.xml b/app-dialog/src/main/res/layout/app_dialog.xml
index f5431f5..f5d09a8 100644
--- a/app-dialog/src/main/res/layout/app_dialog.xml
+++ b/app-dialog/src/main/res/layout/app_dialog.xml
@@ -14,7 +14,7 @@
android:minHeight="40dp"
android:padding="6dp"
android:lines="1"
- android:textSize="16sp"
+ android:textSize="@dimen/app_dialog_title_text_size"
android:textColor="@color/app_dialog_title_color"
android:text="@string/app_dialog_title"/>
diff --git a/app-dialog/src/main/res/values/colors.xml b/app-dialog/src/main/res/values/colors.xml
index 9bd2129..7605999 100644
--- a/app-dialog/src/main/res/values/colors.xml
+++ b/app-dialog/src/main/res/values/colors.xml
@@ -1,10 +1,13 @@
+ #FF4081
+
#333333
#666666
#333333
- #FF4081
+ @color/colorAccent
#d2d2d2
+
diff --git a/app-dialog/src/main/res/values/dimens.xml b/app-dialog/src/main/res/values/dimens.xml
index 6e2c5b3..90f2a0a 100644
--- a/app-dialog/src/main/res/values/dimens.xml
+++ b/app-dialog/src/main/res/values/dimens.xml
@@ -1,5 +1,10 @@
- 0.4dp
+ 0.5dp
+ 10dp
+
+ 16sp
+ 16sp
+ 18sp
\ No newline at end of file
diff --git a/app-updater/bintray.gradle b/app-updater/bintray.gradle
index 68d83b5..75eff66 100644
--- a/app-updater/bintray.gradle
+++ b/app-updater/bintray.gradle
@@ -5,7 +5,8 @@ publish {
userOrg = 'jenly'//bintray.com用户名
groupId = 'com.king.app'//jcenter上的路径
artifactId = 'app-updater'//项目名称
- publishVersion = '1.0'//版本号
+ publishVersion = app_version.versionName//版本号
desc = 'AppUpdater for Android'//描述
website = 'https://github.com/jenly1314/AppUpdater'//网站
+ licences = ['MIT']//开源协议
}
\ No newline at end of file
diff --git a/app-updater/build.gradle b/app-updater/build.gradle
index 2d08d8b..952d0f8 100644
--- a/app-updater/build.gradle
+++ b/app-updater/build.gradle
@@ -2,16 +2,15 @@ apply plugin: 'com.android.library'
apply from: 'bintray.gradle'
android {
- compileSdkVersion 27
-
+ compileSdkVersion build_versions.compileSdk
+ buildToolsVersion build_versions.buildTools
defaultConfig {
- minSdkVersion 15
- targetSdkVersion 27
- versionCode 1
- versionName "1.0"
-
+ minSdkVersion build_versions.minSdk
+ targetSdkVersion build_versions.targetSdk
+ versionCode app_version.versionCode
+ versionName app_version.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
}
@@ -23,13 +22,19 @@ android {
}
}
+ lintOptions {
+ abortOnError false
+ warning 'InvalidPackage'
+ }
+
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
+ testImplementation deps.test.junit
+ androidTestImplementation deps.test.runner
+ androidTestImplementation deps.test.espresso
+ //support
+ compileOnly deps.support.appcompat
- compileOnly 'com.android.support:appcompat-v7:27.1.1'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
}
diff --git a/app-updater/src/main/java/com/king/app/updater/AppUpdater.java b/app-updater/src/main/java/com/king/app/updater/AppUpdater.java
index 9b6228b..877465b 100644
--- a/app-updater/src/main/java/com/king/app/updater/AppUpdater.java
+++ b/app-updater/src/main/java/com/king/app/updater/AppUpdater.java
@@ -9,6 +9,7 @@ import android.os.IBinder;
import android.support.annotation.DrawableRes;
import android.support.annotation.NonNull;
import android.text.TextUtils;
+import android.util.Log;
import com.king.app.updater.callback.UpdateCallback;
import com.king.app.updater.constant.Constants;
@@ -21,13 +22,21 @@ import com.king.app.updater.util.PermissionUtils;
* @author Jenly Jenly
*/
public class AppUpdater {
-
+ /**
+ * {@link #mContext}不强制要求是{@link Activity},但能传{@link Activity}尽量传。AppUpdater本应该只专注于App更新,尽量不涉及动态权限相关的处理。如果mContext传的是{@link Activity},则默认会校验一次动态权限。
+ */
private Context mContext;
-
+ /**
+ * 配置信息
+ */
private UpdateConfig mConfig;
-
+ /**
+ * 更新回调
+ */
private UpdateCallback mCallback;
-
+ /**
+ * http管理接口,可自定义实现。如:使用okHttp
+ */
private IHttpManager mHttpManager;
private ServiceConnection mServiceConnection;
@@ -59,10 +68,15 @@ public class AppUpdater {
*/
public void start(){
if(mConfig!=null && !TextUtils.isEmpty(mConfig.getUrl())){
- //mContext不强制要求是Activity,能传Activity尽量传。AppUpdater本应该只专注于App更新,尽量不涉及动态权限相关的处理。如果mContext不强制要求是Activity是Activity默认会优先校验一次动态权限。
+ //如果mContext是Activity,则默认会校验一次动态权限。
if(mContext instanceof Activity){
PermissionUtils.INSTANCE.verifyReadAndWritePermissions((Activity) mContext,Constants.RE_CODE_STORAGE_PERMISSION);
}
+
+ if(mConfig.isShowNotification() && !PermissionUtils.INSTANCE.isNotificationEnabled(mContext)){
+ Log.w(Constants.TAG,"Notification permission not enabled.");
+ }
+
startDownloadService();
}else{
throw new NullPointerException("url = null");
diff --git a/app-updater/src/main/java/com/king/app/updater/UpdateConfig.java b/app-updater/src/main/java/com/king/app/updater/UpdateConfig.java
index 3152e9e..7e25b04 100644
--- a/app-updater/src/main/java/com/king/app/updater/UpdateConfig.java
+++ b/app-updater/src/main/java/com/king/app/updater/UpdateConfig.java
@@ -1,6 +1,7 @@
package com.king.app.updater;
+import android.content.Context;
import android.os.Parcel;
import android.os.Parcelable;
import android.support.annotation.DrawableRes;
@@ -24,20 +25,35 @@ public class UpdateConfig implements Parcelable {
*/
private String mFilename;
+ /**
+ * 是否显示通知栏
+ */
private boolean isShowNotification = true;
/**
* 下载完成后是否自动弹出安装
*/
private boolean isInstallApk = true;
-
+ /**
+ * 通知栏图标:默认取app图标
+ */
private int mNotificationIcon;
+ /**
+ * 通知栏ID
+ */
private int mNotificationId = Constants.DEFAULT_NOTIFICATION_ID;
+ /**
+ * 通知栏渠道ID
+ */
private String mChannelId;
-
+ /**
+ * 通知栏渠道名称
+ */
private String mChannelName;
-
+ /**
+ * 默认{@link Context#getPackageName() + ".fileProvider"}
+ */
private String mAuthority;
/**
* 下载失败是否支持点击通知栏重复下载
diff --git a/app-updater/src/main/java/com/king/app/updater/service/DownloadService.java b/app-updater/src/main/java/com/king/app/updater/service/DownloadService.java
index 6204bf7..236cee2 100644
--- a/app-updater/src/main/java/com/king/app/updater/service/DownloadService.java
+++ b/app-updater/src/main/java/com/king/app/updater/service/DownloadService.java
@@ -77,7 +77,7 @@ public class DownloadService extends Service {
startDownload(config,null,null);
}
}else{
- Log.w(Constants.TAG,"已经在下载中,请勿重复下载。");
+ Log.w(Constants.TAG,"Please do not repeat the download.");
}
}
@@ -105,7 +105,7 @@ public class DownloadService extends Service {
}
if(isDownloading){
- Log.w(Constants.TAG,"已经在下载中,请勿重复下载。");
+ Log.w(Constants.TAG,"Please do not repeat the download.");
return;
}
@@ -154,6 +154,9 @@ public class DownloadService extends Service {
return context.getCacheDir().getAbsolutePath();
}
+ /**
+ * 停止服务
+ */
private void stopService(){
mCount = 0;
stopSelf();
@@ -300,17 +303,9 @@ public class DownloadService extends Service {
}
}
-
- @Override
- public boolean onUnbind(Intent intent) {
- Log.d(Constants.TAG,"onUnbind");
- return super.onUnbind(intent);
- }
-
@Override
public void onDestroy() {
isDownloading = false;
- Log.d(Constants.TAG,"onDestroy");
super.onDestroy();
}
diff --git a/app-updater/src/main/java/com/king/app/updater/util/PermissionUtils.java b/app-updater/src/main/java/com/king/app/updater/util/PermissionUtils.java
index c5a8807..f6cd5b8 100644
--- a/app-updater/src/main/java/com/king/app/updater/util/PermissionUtils.java
+++ b/app-updater/src/main/java/com/king/app/updater/util/PermissionUtils.java
@@ -1,15 +1,24 @@
package com.king.app.updater.util;
import android.Manifest;
+import android.annotation.TargetApi;
import android.app.Activity;
+import android.app.AppOpsManager;
+import android.app.NotificationManager;
+import android.content.Context;
+import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.os.Build;
import android.support.annotation.NonNull;
import android.support.v4.app.ActivityCompat;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+
/**
* @author Jenly Jenly
*/
-public enum PermissionUtils {
+public enum PermissionUtils {
INSTANCE;
@@ -18,12 +27,18 @@ public enum PermissionUtils {
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_PHONE_STATE};
+ /**
+ * 校验权限
+ * @param activity
+ * @param requestCode
+ * @return
+ */
public boolean verifyReadAndWritePermissions(@NonNull Activity activity,int requestCode){
int readResult = checkPermission(activity,Manifest.permission.READ_EXTERNAL_STORAGE);
int writeResult = checkPermission(activity,Manifest.permission.WRITE_EXTERNAL_STORAGE);
int readPhoneState = checkPermission(activity,Manifest.permission.READ_PHONE_STATE);
- if( readResult != PackageManager.PERMISSION_GRANTED || writeResult != PackageManager.PERMISSION_GRANTED || readPhoneState != PackageManager.PERMISSION_GRANTED){
+ if(readResult != PackageManager.PERMISSION_GRANTED || writeResult != PackageManager.PERMISSION_GRANTED || readPhoneState != PackageManager.PERMISSION_GRANTED){
ActivityCompat.requestPermissions(activity,PERMISSIONS_STORAGE,requestCode);
return false;
}
@@ -33,4 +48,45 @@ public enum PermissionUtils {
public int checkPermission(@NonNull Activity activity,@NonNull String permission){
return ActivityCompat.checkSelfPermission(activity,permission);
}
+
+ /**
+ * 获取通知权限
+ * @param context
+ */
+ public boolean isNotificationEnabled(Context context) {
+
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {
+ NotificationManager notificationManager = (NotificationManager)context.getSystemService(Context.NOTIFICATION_SERVICE);
+ if (notificationManager.getImportance() == NotificationManager.IMPORTANCE_NONE) {
+ return false;
+ }
+ }
+
+ if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT){
+ String CHECK_OP_NO_THROW = "checkOpNoThrow";
+ String OP_POST_NOTIFICATION = "OP_POST_NOTIFICATION";
+
+ AppOpsManager mAppOps = (AppOpsManager) context.getSystemService(Context.APP_OPS_SERVICE);
+ ApplicationInfo appInfo = context.getApplicationInfo();
+ String pkg = context.getApplicationContext().getPackageName();
+ int uid = appInfo.uid;
+
+ try {
+ Class appOpsClass = Class.forName(AppOpsManager.class.getName());
+ Method checkOpNoThrowMethod = appOpsClass.getMethod(CHECK_OP_NO_THROW, Integer.TYPE, Integer.TYPE, String.class);
+ Field opPostNotificationValue = appOpsClass.getDeclaredField(OP_POST_NOTIFICATION);
+
+ int value = (Integer) opPostNotificationValue.get(Integer.class);
+ return ((Integer) checkOpNoThrowMethod.invoke(mAppOps, value, uid, pkg) == AppOpsManager.MODE_ALLOWED);
+
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+
+ return false;
+ }
+
+ return true;
+ }
+
}
diff --git a/app/build.gradle b/app/build.gradle
index 808d354..414c9d9 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -1,15 +1,19 @@
apply plugin: 'com.android.application'
android {
- compileSdkVersion 27
+ compileSdkVersion build_versions.compileSdk
+ buildToolsVersion build_versions.buildTools
+
defaultConfig {
applicationId "com.king.appupdater"
- minSdkVersion 15
- targetSdkVersion 27
- versionCode 1
- versionName "1.0"
+ minSdkVersion build_versions.minSdk
+ targetSdkVersion build_versions.targetSdk
+ versionCode app_version.versionCode
+ versionName app_version.versionName
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+
}
+
buildTypes {
release {
minifyEnabled false
@@ -20,11 +24,13 @@ android {
dependencies {
implementation fileTree(include: ['*.jar'], dir: 'libs')
- implementation 'com.android.support:appcompat-v7:27.1.1'
- implementation 'com.android.support.constraint:constraint-layout:1.1.2'
- testImplementation 'junit:junit:4.12'
- androidTestImplementation 'com.android.support.test:runner:1.0.2'
- androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
+ testImplementation deps.test.junit
+ androidTestImplementation deps.test.runner
+ androidTestImplementation deps.test.espresso
+ //support
+ implementation deps.support.appcompat
+ implementation deps.support.constraintlayout
+
implementation project(':app-updater')
implementation project(':app-dialog')
}
diff --git a/app/release/app-release.apk b/app/release/app-release.apk
index c702d17..322dec7 100644
Binary files a/app/release/app-release.apk and b/app/release/app-release.apk differ
diff --git a/app/release/output.json b/app/release/output.json
index 9f0c959..bd004be 100644
--- a/app/release/output.json
+++ b/app/release/output.json
@@ -1 +1 @@
-[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
+[{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":2,"versionName":"1.0.1","enabled":true,"outputFile":"app-release.apk","fullName":"release","baseName":"release"},"path":"app-release.apk","properties":{}}]
\ No newline at end of file
diff --git a/app/src/main/java/com/king/appupdater/MainActivity.java b/app/src/main/java/com/king/appupdater/MainActivity.java
index fe60dea..ae549e6 100644
--- a/app/src/main/java/com/king/appupdater/MainActivity.java
+++ b/app/src/main/java/com/king/appupdater/MainActivity.java
@@ -29,7 +29,6 @@ public class MainActivity extends AppCompatActivity {
public final String TAG = this.getClass().getSimpleName();
private String mUrl = "https://raw.githubusercontent.com/jenly1314/AppUpdater/master/app/release/app-release.apk";
-// private String mUrl = "https://pro-app-qn.fir.im/1ddfe25998acd3d861d746101e6e079e1611b666.apk?attname=app-release.apk_1.2.apk";
private ProgressBar progressBar;
@@ -154,11 +153,7 @@ public class MainActivity extends AppCompatActivity {
.setOnClickOk(new View.OnClickListener() {
@Override
public void onClick(View v) {
- new AppUpdater.Builder()
- .serUrl(mUrl)
- .setFilename("AppUpdater.apk")
- .build(getContext())
- .start();
+ new AppUpdater(getContext(),mUrl).start();
AppDialog.INSTANCE.dismissDialog();
}
});
@@ -180,14 +175,12 @@ public class MainActivity extends AppCompatActivity {
public void onClick(View v) {
new AppUpdater.Builder()
.serUrl(mUrl)
- .setFilename(Environment.getExternalStorageDirectory() + "/.AppUpdater")
- .setFilename("AppUpdater.apk")
.build(getContext())
.start();
AppDialog.INSTANCE.dismissDialog();
}
});
- AppDialog.INSTANCE.showDialog(getContext(),AppDialog.INSTANCE.createAppDialogView(getContext(),config),false);
+ AppDialog.INSTANCE.showDialog(getContext(),AppDialog.INSTANCE.createAppDialogView(getContext(),config),true);
}
/**
@@ -214,6 +207,7 @@ public class MainActivity extends AppCompatActivity {
public void onClick(View v) {
new AppUpdater.Builder()
.serUrl(mUrl)
+ .setFilename(Environment.getExternalStorageDirectory() + "/.AppUpdater")
.setFilename("AppUpdater.apk")
.build(getContext())
.start();
diff --git a/build.gradle b/build.gradle
index fee5b64..97c430d 100644
--- a/build.gradle
+++ b/build.gradle
@@ -1,15 +1,17 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
-
+
+ apply from: 'versions.gradle'
+ addRepos(repositories)
repositories {
google()
jcenter()
}
dependencies {
- classpath 'com.android.tools.build:gradle:3.1.2'
+ classpath 'com.android.tools.build:gradle:3.2.1'
- classpath 'com.novoda:bintray-release:0.8.1'
+ classpath 'com.novoda:bintray-release:0.9'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
@@ -33,5 +35,8 @@ allprojects {
charSet 'UTF-8'
links "http://docs.oracle.com/javase/8/docs/api"
}
+
+ options.addStringOption('Xdoclint:none', '-quiet')
+ failOnError false
}
}
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
index 8ac7ca2..46f9ecd 100644
--- a/gradle/wrapper/gradle-wrapper.properties
+++ b/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
-#Mon Jun 25 18:24:14 CST 2018
+#Thu Jan 10 09:17:54 CST 2019
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-4.4-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-4.6-all.zip
diff --git a/settings.gradle b/settings.gradle
index c0a46f6..c9fbda6 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -1 +1 @@
-include ':app', ':app-updater', ':app-updater', ':app-dialog'
+include ':app', ':app-updater', ':app-dialog'
diff --git a/versions.gradle b/versions.gradle
new file mode 100644
index 0000000..b2180eb
--- /dev/null
+++ b/versions.gradle
@@ -0,0 +1,49 @@
+//App
+def app_version = [:]
+app_version.versionCode = 2
+app_version.versionName = "1.0.1"
+ext.app_version = app_version
+
+//build version
+def build_versions = [:]
+build_versions.minSdk = 15
+build_versions.targetSdk = 28
+build_versions.compileSdk = 28
+build_versions.buildTools = "28.0.3"
+ext.build_versions = build_versions
+
+// App dependencies
+def versions = [:]
+//support
+versions.supportLibrary = "28.0.0"
+versions.constraintLayout = "1.1.3"
+
+//test
+versions.junit = "4.12"
+versions.runner = "1.0.2"
+versions.espresso = "3.0.2"
+ext.versions = versions
+
+ext.deps = [:]
+
+//support
+def support = [:]
+support.appcompat = "com.android.support:appcompat-v7:$versions.supportLibrary"
+support.constraintlayout = "com.android.support.constraint:constraint-layout:$versions.constraintLayout"
+deps.support = support
+
+//test
+def test = [:]
+test.junit = "junit:junit:$versions.junit"
+test.runner = "com.android.support.test:runner:$versions.runner"
+test.espresso = "com.android.support.test.espresso:espresso-core:$versions.espresso"
+deps.test = test
+
+
+ext.deps = deps
+
+def addRepos(RepositoryHandler handler) {
+ handler.google()
+ handler.jcenter()
+}
+ext.addRepos = this.&addRepos
\ No newline at end of file