Browse Source

Merge branch 'developer' of https://gitlab.com/Arisono/SkWeiChat-Baidu

# Conflicts:
#	WeiChat/build.gradle
#	WeiChat/src/main/AndroidManifest.xml
#	WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/datainquiry/adapter/ReportStatisticsMenuListAdapter.java
#	WeiChat/src/main/res/layout/item_grid_data_inquiry_menu.xml
raomeng 8 năm trước cách đây
mục cha
commit
67855be7c7
95 tập tin đã thay đổi với 3508 bổ sung883 xóa
  1. 78 77
      WeiChat/build.gradle
  2. BIN
      WeiChat/libs/asmack-android-8-4.0.7.jar
  3. BIN
      WeiChat/libs/asmack.jar
  4. BIN
      WeiChat/libs/fastjson-1.1.41.jar
  5. BIN
      WeiChat/libs/okhttp-3.4.1.jar
  6. BIN
      WeiChat/libs/pushservice-4.5.5.77.jar
  7. 0 0
      WeiChat/libs/pushservice-5.3.0.99.jar
  8. 320 321
      WeiChat/src/main/AndroidManifest.xml
  9. 8 2
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/contanct/ContactsActivity.java
  10. 1 0
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/crm/VisitReportAddActivity.java
  11. 24 0
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/datainquiry/activity/ReportStatisticsActivity.java
  12. 3 0
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/datainquiry/adapter/DataInquiryMenuGridAdapter.java
  13. 22 22
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/message/ProcessMsgActivity.java
  14. 0 1
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/AddMeetTaskActivity.java
  15. 58 16
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/ApprovalActivity.java
  16. 2 2
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/ExpenseReimbursementActivity.java
  17. 89 16
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/adapter/oa/ApprovalAdapter.java
  18. 5 4
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/model/oa/Approval.java
  19. 1 2
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/model/oa/ApprovalRecord.java
  20. 158 94
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/presenter/ApprovaPresenter.java
  21. 1 1
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/presenter/imp/IApproval.java
  22. 1 1
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/util/OpenFilesUtils.java
  23. 5 3
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/me/MeFragment.java
  24. 12 11
      WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/platform/task/TaskAddErpActivity.java
  25. 25 0
      WeiChat/src/main/java/com/xzjmyk/pm/activity/view/CrashLinearLayoutManager.java
  26. 12 11
      WeiChat/src/main/java/com/xzjmyk/pm/activity/xmpp/XReconnectionManager.java
  27. 25 7
      WeiChat/src/main/java/com/xzjmyk/pm/activity/xmpp/XmppConnectionManager.java
  28. 1 1
      WeiChat/src/main/java/com/xzjmyk/pm/newpedo/service/StepService.java
  29. BIN
      WeiChat/src/main/res/drawable-hdpi/edit_template.png
  30. BIN
      WeiChat/src/main/res/drawable-xhdpi/edit_template.png
  31. BIN
      WeiChat/src/main/res/drawable-xxhdpi/edit_template.png
  32. 2 2
      WeiChat/src/main/res/layout/expense_details_menu.xml
  33. 1 3
      WeiChat/src/main/res/layout/grid_item_simpletext.xml
  34. 8 0
      WeiChat/src/main/res/layout/item_approval_node.xml
  35. 66 0
      WeiChat/src/main/res/layout/item_approval_node_tag.xml
  36. 4 0
      WeiChat/src/main/res/layout/item_approval_tag.xml
  37. 8 10
      WeiChat/src/main/res/layout/item_list_data_inquiry_menu.xml
  38. 150 0
      WeiChat/src/main/res/layout/toast_demo.xml
  39. 1 0
      WeiChat/src/main/res/menu/menu_aproval_set.xml
  40. 1 0
      WeiChat/src/main/res/values/values.xml
  41. 8 17
      app_core/common/build.gradle
  42. 0 25
      app_core/common/proguard-rules.pro
  43. 0 26
      app_core/common/src/androidTest/java/base/android/com/commom/ExampleInstrumentedTest.java
  44. 1 1
      app_core/common/src/main/AndroidManifest.xml
  45. 0 3
      app_core/common/src/main/res/values/strings.xml
  46. 0 17
      app_core/common/src/test/java/base/android/com/commom/ExampleUnitTest.java
  47. 11 17
      app_core/imageload/build.gradle
  48. 9 1
      app_core/imageload/src/main/AndroidManifest.xml
  49. 37 0
      app_core/imageload/src/main/java/com/library/imageloader/BaseImageLoaderStrategy.java
  50. 137 0
      app_core/imageload/src/main/java/com/library/imageloader/ImageLoaderUtil.java
  51. 300 0
      app_core/imageload/src/main/java/com/library/imageloader/iml/GlideImageLoaderStrategy.java
  52. 11 0
      app_core/imageload/src/main/java/com/library/imageloader/listener/ImageSaveListener.java
  53. 14 0
      app_core/imageload/src/main/java/com/library/imageloader/listener/ProgressLoadListener.java
  54. 10 0
      app_core/imageload/src/main/java/com/library/imageloader/listener/SourceReadyListener.java
  55. 164 0
      app_core/imageload/src/main/java/com/library/imageloader/transformation/GlideCircleTransform.java
  56. 90 0
      app_core/imageload/src/main/java/com/library/imageloader/utils/FileUtils.java
  57. 32 0
      app_core/imageload/src/main/java/com/library/imageloader/utils/ImageUtils.java
  58. 96 0
      app_core/imageload/src/main/java/com/library/imageloader/utils/ScreenUtils.java
  59. 36 0
      app_core/imageload/src/main/java/com/library/imageloader/utils/Utils.java
  60. 5 5
      app_core/message/build.gradle
  61. 18 11
      app_core/network/build.gradle
  62. 185 0
      app_core/network/src/main/java/network/app/base/BaseActivity.java
  63. 57 0
      app_core/network/src/main/java/network/app/base/BaseApplication.java
  64. 52 0
      app_core/network/src/main/java/network/app/http/HttpBase.java
  65. 338 0
      app_core/network/src/main/java/network/app/http/HttpClient.java
  66. 9 0
      app_core/network/src/main/java/network/app/http/Method.java
  67. 11 0
      app_core/network/src/main/java/network/app/http/cache/CacheType.java
  68. 170 0
      app_core/network/src/main/java/network/app/http/impl/RetrofitImpl.java
  69. 55 0
      app_core/network/src/main/java/network/app/http/interceptor/CacheInterceptor.java
  70. 99 0
      app_core/network/src/main/java/network/app/http/interceptor/LogInterceptor.java
  71. 31 0
      app_core/network/src/main/java/network/app/http/retrofit/StringConverterFactory.java
  72. 27 0
      app_core/network/src/main/java/network/app/http/retrofit/StringRequestBodyConverter.java
  73. 19 0
      app_core/network/src/main/java/network/app/http/retrofit/StringResponseBodyConverter.java
  74. 10 0
      app_core/network/src/main/java/network/app/http/rx/Result1Listener.java
  75. 11 0
      app_core/network/src/main/java/network/app/http/rx/Result2Listener.java
  76. 8 0
      app_core/network/src/main/java/network/app/http/rx/ResultListener.java
  77. 86 0
      app_core/network/src/main/java/network/app/http/rx/ResultSubscriber.java
  78. 23 0
      app_core/network/src/main/java/network/app/http/rx/RxJavaUtils.java
  79. 45 0
      app_core/network/src/main/java/network/app/http/service/ParamService.java
  80. 26 0
      app_core/network/src/main/java/network/app/http/ssl/TrustAllCerts.java
  81. 14 0
      app_core/network/src/main/java/network/app/http/ssl/TrustAllHostnameVerifier.java
  82. 8 8
      app_third/MPAndroidChart/build.gradle
  83. 8 16
      app_third/lib-zxing/build.gradle
  84. 8 9
      app_third/libbdupdatesdk/build.gradle
  85. 8 9
      app_third/libedittextformlibrary/build.gradle
  86. 8 8
      app_third/libfloatingactionbutton/build.gradle
  87. 8 12
      app_third/library-refreshlayout/build.gradle
  88. 8 8
      app_third/library-swipemenu_lv/build.gradle
  89. 8 6
      app_third/library-viewpager-indicator/build.gradle
  90. 10 9
      app_third/materialdialogs/build.gradle
  91. 8 5
      app_third/pullToRefershLibraryMy/build.gradle
  92. 2 4
      build.gradle
  93. 3 20
      gradle.properties
  94. 2 0
      settings.gradle
  95. 72 39
      version.gradle

+ 78 - 77
WeiChat/build.gradle

@@ -1,10 +1,13 @@
 apply plugin: 'com.android.application'
 apply plugin: 'com.getkeepsafe.dexcount'
+apply plugin: 'me.tatarka.retrolambda'
 
 android {
 
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
+    compileOptions {
+        sourceCompatibility JavaVersion.VERSION_1_8
+        targetCompatibility JavaVersion.VERSION_1_8
+    }
 
     signingConfigs {
         config {
@@ -14,16 +17,22 @@ android {
             keyPassword '13237658359'
         }
     }
+    
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
+   
     defaultConfig {
-        applicationId "com.xzjmyk.pm.activity"
-        minSdkVersion 14
-        targetSdkVersion 24
-        compileOptions {
-            sourceCompatibility JavaVersion.VERSION_1_7
-            targetCompatibility JavaVersion.VERSION_1_7
-        }
+        applicationId project.applicationId
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
         multiDexEnabled true
         signingConfig signingConfigs.config
+
+        // 默认是umeng的渠道
+        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
+        manifestPlaceholders = [UMENG_CHANNEL_VALUE: "umeng"]
     }
 
     useLibrary 'org.apache.http.legacy'
@@ -48,15 +57,73 @@ android {
             signingConfig signingConfigs.config
         }
     }
-    productFlavors {
+    productFlavors {  // Gradle 多渠道打包
+        wandoujia {}
+        _360 {}
+        baidu {}
+        xiaomi {}
+        tencent {}
+        taobao {}
     }
 
+    productFlavors.all {
+        flavor -> flavor.manifestPlaceholders = [UMENG_CHANNEL_VALUE: name]
+    }
+    //给apk添加对应的版本号:这里暂时注释但保留
+//    applicationVariants.all { variant ->
+//        variant.outputs.each { output ->
+//            def outputFile = output.outputFile
+//            if (outputFile != null && outputFile.name.endsWith('.apk')) {
+//                def fileName = outputFile.name.replace(".apk", "-${defaultConfig.versionName}.apk")
+//                output.outputFile = new File(outputFile.parent, fileName)
+//            }
+//        }
+//    }
+}
+
+dependencies {
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    //依赖库
+    testCompile deps.junit
+    compile deps.appcompatV7
+    compile deps.cardviewV7
+    compile deps.design
+    compile deps.multidex
+    compile deps.fastjson
+    compile(deps.stetho) {
+        force = true
+    }
+    compile deps.circleimageview
+    compile deps.jodatime
+    compile deps.systembartint
+    compile deps.photoView
+    compile deps.tagGroup
+    compile deps.analytics
+    compile deps.activityOnCrash
+    compile deps.stickyListHeaders
+    compile deps.stickyGridHeaders
+    compile deps.materialDialogs
 
+    androidTestCompile deps.leakcanaryNp
+    debugCompile deps.leakcanary
+    releaseCompile deps.leakcanaryNp
+    //project
+    compile project(':pullToRefershLibraryMy')
+    compile project(':MPAndroidChart')
+    compile project(':libedittextformlibrary')
+    compile project(':libfloatingactionbutton')
+    compile project(':libbdupdatesdk')
+    compile project(':library-swipemenu_lv')
+    compile project(':library-viewpager-indicator')
+    compile project(':lib-zxing')
+    compile project(':library-refreshlayout')
+    compile 'com.squareup.okhttp3:okhttp:3.8.1'
+    compile project(':android-pdf-viewer')
 }
 
 buildscript {
     repositories {
-        mavenCentral() // or jcenter()
+        mavenCentral()
     }
 
     dependencies {
@@ -76,69 +143,3 @@ dexcount {
     enableForInstantRun = false
 }
 
-dependencies {
-    compile project(':pullToRefershLibraryMy')
-    compile project(':MPAndroidChart')
-    compile project(':libedittextformlibrary')
-    compile project(':libfloatingactionbutton')
-    compile project(':libbdupdatesdk')
-    compile files('libs/android-async-http-1.4.5.jar')
-    compile files('libs/asmack.jar')
-    compile files('libs/BaiduLBS_Android.jar')
-    compile files('libs/cyberplayer-sdk.jar')
-    //    compile files('libs/fastjson-1.1.41.jar')
-    compile files('libs/httpmime-4.2.jar')
-    compile files('libs/nineoldandroids.jar')
-    compile files('libs/org.xbill.dns_2.1.6.jar')
-    compile files('libs/ormlite-android-4.48.jar')
-    compile files('libs/ormlite-core-4.48.jar')
-    compile files('libs/pinyin4j-2.5.0.jar')
-    compile files('libs/universal-image-loader-1.9.0.jar')
-    compile files('libs/volley.jar')
-    compile files('libs/xutils.jar')
-    compile files('libs/flexjson-2.1.jar')
-    compile project(':library-swipemenu_lv')
-    compile project(':library-viewpager-indicator')
-    compile project(':lib-zxing')
-    compile files('libs/SocialSDK_WeiXin_2.jar')
-    compile files('libs/SocialSDK_umengwx.jar')
-    compile files('libs/SocialSDK_QQZone_3.jar')
-    compile files('libs/SocialSDK_umengqq.jar')
-    compile files('libs/umeng_social_apiv6.0.0.jar')
-    compile files('libs/umeng_social_netv6.0.0.jar')
-    compile files('libs/umeng_social_viewv6.0.0.jar')
-    compile files('libs/SocialSDK_umengsina.jar')
-    compile files('libs/SocialSDK_Sina.jar')
-    compile files('libs/weiboSDKCore_3.1.4.jar')
-    compile('com.facebook.stetho:stetho:1.4.1') {
-        force = true
-    }
-    compile project(':library-refreshlayout')
-    compile files('src/main/jniLibs/pushservice-5.3.0.99.jar')
-    compile files('libs/lite-orm-1.7.0.jar')
-    compile files('libs/Msc.jar')
-    compile files('libs/zhy_treeview.jar')
-    compile 'com.alibaba:fastjson:1.2.24'
-    compile 'de.hdodenhof:circleimageview:2.1.0'
-    compile 'joda-time:joda-time:2.9.4'
-    compile 'com.readystatesoftware.systembartint:systembartint:1.0.3'
-    compile 'com.android.support:appcompat-v7:24.2.1'
-    compile 'com.android.support:cardview-v7:24.2.1'
-    compile 'com.android.support:design:24.2.1'
-    compile 'com.commit451:PhotoView:1.2.5'
-    compile 'me.gujun.android.taggroup:library:1.4@aar'
-    compile 'com.umeng.analytics:analytics:latest.integration'
-    compile 'com.android.support:multidex:1.0.1'
-    compile 'cat.ereza:customactivityoncrash:1.5.0'
-    compile 'se.emilsjolander:stickylistheaders:2.7.0'
-    compile 'com.github.TonicArtos:StickyGridHeaders:1.0.1'
-    compile 'com.afollestad.material-dialogs:core:0.9.0.2'
-    testCompile 'junit:junit:4.12'
-    androidTestCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
-    debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5'
-    releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.5'
-    compile files('libs/core.jar')
-    compile 'com.android.support:design:24.2.1'
-    compile 'com.squareup.okhttp3:okhttp:3.8.1'
-    compile project(':android-pdf-viewer')
-}

BIN
WeiChat/libs/asmack-android-8-4.0.7.jar


BIN
WeiChat/libs/asmack.jar


BIN
WeiChat/libs/fastjson-1.1.41.jar


BIN
WeiChat/libs/okhttp-3.4.1.jar


BIN
WeiChat/libs/pushservice-4.5.5.77.jar


+ 0 - 0
WeiChat/src/main/jniLibs/pushservice-5.3.0.99.jar → WeiChat/libs/pushservice-5.3.0.99.jar


Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 320 - 321
WeiChat/src/main/AndroidManifest.xml


+ 8 - 2
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/contanct/ContactsActivity.java

@@ -158,7 +158,7 @@ public class ContactsActivity extends OABaseActivity implements ContactsAdapter.
                             contactsDao.delete();//删除缓存
                             loadUUFriendForNet();//先加载UU好友---》企业架构人员----》本地通讯录
                         } else {
-                            getCaceData(true);//先加载UU好友---》企业架构人员----》本地通讯录
+                            getCaceData(false);//先加载UU好友---》企业架构人员----》本地通讯录
                         }
                     }
                 });
@@ -646,6 +646,7 @@ public class ContactsActivity extends OABaseActivity implements ContactsAdapter.
                         String role = UserRoleUtils.getUserRole();
                         if ("1".equals(role)) {
                             //个人用户不需要加载企业架构
+                            LogUtil.d("Test","個人用戶不需要加載企業架");
                             loadLocalContacts();
                         }
                         boolean isB2b = ApiUtils.getApiModel() instanceof ApiPlatform;
@@ -720,7 +721,12 @@ public class ContactsActivity extends OABaseActivity implements ContactsAdapter.
                                             tmodels.add(model);
                                         }
                                     }
-                                    loadUASFriendsNet();
+                                    if("1".equals(UserRoleUtils.getUserRole())){
+                                        loadLocalContacts();
+                                    }else{
+                                        loadUASFriendsNet();
+                                    }
+                                   
                                 }
                             });
                 } else {

+ 1 - 0
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/crm/VisitReportAddActivity.java

@@ -587,6 +587,7 @@ public class VisitReportAddActivity extends BaseActivity implements View.OnClick
             if (StringUtils.isEmpty(model.getObject()) || !new JsonValidator().validate(model.getObject()))
                 return;
             tv_visit_steps.setText(JSON.parseObject(model.getObject()).getString("CU_NICHESTEP"));
+            tv_linksman_login.setText(StringUtils.isEmpty(JSON.parseObject(model.getObject()).getString("CU_TEL")) ? "" : JSON.parseObject(model.getObject()).getString("CU_TEL"));
 //            String address = model.getAddress();
 //            String name = model.getName();
 //            tv_customer_login.setText(name);

+ 24 - 0
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/datainquiry/activity/ReportStatisticsActivity.java

@@ -3,6 +3,9 @@ package com.xzjmyk.pm.activity.ui.erp.activity.datainquiry.activity;
 import android.os.Bundle;
 import android.os.Handler;
 import android.os.Message;
+import android.view.View;
+import android.view.ViewGroup;
+import android.widget.ListAdapter;
 import android.widget.ListView;
 
 import com.xzjmyk.pm.activity.R;
@@ -102,6 +105,7 @@ public class ReportStatisticsActivity extends BaseActivity {
                                     }
                                 }
                                 mReportStatisticsMenuListAdapter.notifyDataSetChanged();
+                                //setListViewHeightBasedOnChildren(mMenuListView);
                             }
                         } catch (JSONException e) {
                             e.printStackTrace();
@@ -123,4 +127,24 @@ public class ReportStatisticsActivity extends BaseActivity {
             return json.optString(key, "");
         }
     }
+
+
+    public static void setListViewHeightBasedOnChildren(ListView listView) {
+        ListAdapter listAdapter = listView.getAdapter();
+        if (listAdapter == null) {
+            return;
+        }
+        int totalHeight = 0;
+        for (int i = 0; i < listAdapter.getCount(); i++) {
+            View listItem = listAdapter.getView(i, null, listView);
+            listItem.measure(0, 0);
+            totalHeight += listItem.getMeasuredHeight();
+        }
+
+        ViewGroup.LayoutParams params = listView.getLayoutParams();
+
+        params.height = totalHeight
+                + (listView.getDividerHeight() * (listAdapter.getCount() - 1));
+        listView.setLayoutParams(params);
+    }
 }

+ 3 - 0
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/datainquiry/adapter/DataInquiryMenuGridAdapter.java

@@ -72,4 +72,7 @@ public class DataInquiryMenuGridAdapter extends BaseAdapter {
             gridDataInquiryMenuContent = (TextView) view.findViewById(R.id.grid_data_inquiry_menu_content);
         }
     }
+
+  
+
 }

+ 22 - 22
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/message/ProcessMsgActivity.java

@@ -123,7 +123,8 @@ public class ProcessMsgActivity extends BaseActivity implements View.OnClickList
 //                        handleImids(1,array);
                         getEmimids(array);
                         tv_process_un_num.setVisibility(View.VISIBLE);
-                        tv_process_un_num.setText(array.size() + "");
+                        int numSize = ListUtils.getSize(array);
+                        tv_process_un_num.setText(numSize > 99 ? "99+" : (numSize <= 0 ? "" : String.valueOf(numSize)));
                     }
 
                     if (tab_type == 1 && mPosition > 0) {
@@ -599,7 +600,7 @@ public class ProcessMsgActivity extends BaseActivity implements View.OnClickList
                     int tdem_imid = OACheckUtil.getJsonIntager(jsonArray.getJSONObject(position), "EM_IMID");
                     model.name.setText(jp_launchername + "的" + jp_name);
                     if (jp_launchtime != null) {
-                        model.date.setText(DateFormatUtil.getStrDate4Date(new Date(jp_launchtime), "MM-dd HH:mm"));
+                        model.date.setText(DateFormatUtil.getStrDate4Date(new Date(jp_launchtime), "MM-dd HH:mm") + "");
                     } else {
                         model.date.setText("");
                     }
@@ -633,31 +634,30 @@ public class ProcessMsgActivity extends BaseActivity implements View.OnClickList
                     String jn_dealresult = jsonArray.getJSONObject(position).getString("JN_DEALRESULT");
                     int done_emid = OACheckUtil.getJsonIntager(jsonArray.getJSONObject(position), "EM_IMID");
                     model.name.setText(jn_dealmanname + "的" + jp_name);
-                    if (!StringUtils.isEmpty(jn_dealtime)){
-                        Long L = TimeUtils.s_str_2_long(jn_dealtime);
-                        model.date.setText(DateFormatUtil.getStrDate4Date(new Date(L), "MM-dd HH:mm"));
-                    }else {
+                    if (!StringUtils.isEmpty(jn_dealtime)) {
+                        String ttt = DateFormatUtil.getStrDate4Date(new Date(TimeUtils.f_str_2_long(jn_dealtime)), "MM-dd HH:mm");
+                        model.date.setText(ttt + "");
+                    } else {
                         model.date.setText("");
                     }
                     if (!StringUtils.isEmpty(jn_dealresult)) {
-                        if ("不同意".equals(jn_dealresult)) {
-                            model.status.setTextColor(getResources().getColor(R.color.red));
-                            model.status.setText("已拒绝");
-
-                        } else {
-                            if ("变更处理人".equals(jn_dealresult)) {
-                                model.status.setTextColor(getResources().getColor(R.color.done_approval));
-                                if (!StringUtils.isEmpty(jsonArray.getJSONObject(position).getString("JN_OPERATEDDESCRIPTION"))) {
-                                    model.status.setText("已变更处理人(" + jsonArray.getJSONObject(position).getString("JN_OPERATEDDESCRIPTION") + ")");
-                                } else {
-                                    model.status.setText("已变更处理人");
-                                }
+                        model.status.setText(jn_dealresult);
+                        int statusTextId = R.color.done_approval;
+                        if (jn_dealresult.startsWith("不同意") || jn_dealresult.startsWith("结束流程") || jn_dealresult.startsWith("未通过")) {
+                            statusTextId = R.color.red;
+                        } else if (jn_dealresult.startsWith("变更处理人")) {
+                            statusTextId = R.color.done_approval;
+                            if (!StringUtils.isEmpty(jsonArray.getJSONObject(position).getString("JN_OPERATEDDESCRIPTION"))) {
+                                model.status.setText("已变更处理人(" + jsonArray.getJSONObject(position).getString("JN_OPERATEDDESCRIPTION") + ")");
                             } else {
-                                model.status.setTextColor(getResources().getColor(R.color.titleBlue));
-                                model.status.setText("已同意");
+                                model.status.setText("已变更处理人");
                             }
-
+                        } else {
+                            statusTextId=  R.color.titleBlue;
                         }
+                        model.status.setTextColor(getResources().getColor(statusTextId));
+                    } else {
+                        model.status.setText("");
                     }
                     model.JP_NODEID = JP_NODEID;
                     model.imid.setVisibility(View.VISIBLE);
@@ -704,7 +704,7 @@ public class ProcessMsgActivity extends BaseActivity implements View.OnClickList
                         if (!StringUtils.isEmpty(name)) name = name.substring(0, name.length() - 2);
                         model.name.setText(name);
                         if (time != null) {
-                            model.date.setText(DateFormatUtil.getStrDate4Date(new Date(time), "MM-dd HH:mm"));
+                            model.date.setText(DateFormatUtil.getStrDate4Date(new Date(time), "MM-dd HH:mm") + "");
                         } else {
                             model.date.setText("");
                         }

+ 0 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/AddMeetTaskActivity.java

@@ -92,7 +92,6 @@ public class AddMeetTaskActivity extends BaseActivity {
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (data == null) return;
         if (requestCode == 0x11 && resultCode == 0x20) {
             if (!isPower)
                 handler.postDelayed(new Runnable() {

+ 58 - 16
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/ApprovalActivity.java

@@ -2,7 +2,7 @@ package com.xzjmyk.pm.activity.ui.erp.activity.oa;
 
 import android.content.Intent;
 import android.os.Bundle;
-import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.DefaultItemAnimator;
 import android.support.v7.widget.RecyclerView;
 import android.text.Editable;
 import android.view.Gravity;
@@ -48,9 +48,12 @@ import com.xzjmyk.pm.activity.ui.erp.util.oa.OAConfig;
 import com.xzjmyk.pm.activity.ui.erp.util.oa.RecognizerDialogUtil;
 import com.xzjmyk.pm.activity.util.DisplayUtil;
 import com.xzjmyk.pm.activity.util.PreferenceUtils;
+import com.xzjmyk.pm.activity.view.CrashLinearLayoutManager;
 
 import java.util.ArrayList;
+import java.util.LinkedHashSet;
 import java.util.List;
+import java.util.Set;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -70,7 +73,7 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
     @Override
     public boolean onOptionsItemSelected(MenuItem item) {
         if (item.getItemId() == R.id.oa_approval_set && mAdapter != null && !ListUtils.isEmpty(mAdapter.getApprovals())) {
-            mPresenter.trun2SetActivity(this, mAdapter.getApprovals());
+            mPresenter.trun2SetActivity(this);
         } else if (item.getItemId() == R.id.returnOld) {
             Intent intent = new Intent(ct, AppWebViewActivity.class);
             String title = getIntent().getStringExtra("title");
@@ -106,16 +109,28 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
 
     @Override
     protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-        if (data != null && requestCode == 0x20) {
-            SelectEmUser user = data.getParcelableExtra("data");
-            if (user != null && !StringUtils.isEmpty(user.getEmCode())) {
-                mPresenter.updateAssignee(user.getEmCode(), OACheckUtil.getText(opinionET));
+        if (requestCode == 0x20) {
+            if (data==null){
+                mPresenter.updateAssignee(null, OACheckUtil.getText(opinionET));
+            }else{
+                SelectEmUser user = data.getParcelableExtra("data");
+                if (user != null && !StringUtils.isEmpty(user.getEmCode())) {
+                    mPresenter.updateAssignee(user.getEmCode(), OACheckUtil.getText(opinionET));
+                }
             }
-        } else if (data != null && 0x22 == requestCode) {
+
+        } else if (data != null && (0x22 == requestCode || 0x21 == requestCode)) {
             SelectBean d = data.getParcelableExtra("data");
             if (d == null) return;
             String name = StringUtils.isEmpty(d.getName()) ? "" : d.getName();
-            getEmnameByReturn(name);
+            if (0x21 == requestCode) {
+                getEmnameByReturn(name);
+            } else {
+                if (name.equals("回退发起人")) {
+                    name = "RECORDER";
+                }
+                mPresenter.disAgree(OACheckUtil.getText(opinionET), name);
+            }
         } else if (0x25 == requestCode && 0x25 == resultCode) {
             mPresenter.initLoad();
         }
@@ -131,7 +146,7 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
     }
 
     private void initView() {
-        contentRV.setLayoutManager(new LinearLayoutManager(ct));
+        contentRV.setLayoutManager(new CrashLinearLayoutManager(ct));
         findViewById(R.id.commonWordsIV).setOnClickListener(this);//常用语
         findViewById(R.id.nextTV).setOnClickListener(this);
         findViewById(R.id.voiceIV).setOnClickListener(this);
@@ -185,7 +200,17 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
                 mPresenter.loadProcessUpdate(OACheckUtil.getText(opinionET), approvals);
                 break;
             case R.id.disagreeTV://不同意
-                mPresenter.disAgree(OACheckUtil.getText(opinionET));
+                List<String> nodes = mPresenter.getNodesCanReturn();
+                if (StringUtils.isEmpty(OACheckUtil.getText(opinionET))) {
+                    opinionET.setFocusable(true);
+                    showToast(R.string.approval_opinion_error, R.color.load_submit);
+                } else {
+                    if (ListUtils.isEmpty(nodes)) {
+                        mPresenter.disAgree(OACheckUtil.getText(opinionET), null);
+                    } else {
+                        sendToSelect(nodes, 0x22, "选择回退节点");
+                    }
+                }
                 break;
             case R.id.nextTV: //下一条
                 hineOpinion();
@@ -255,8 +280,10 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
 
 
     @Override
-    public void showModels(List<Approval> approvals) {
-        mAdapter = new ApprovalAdapter(this, approvals, mPresenter.isApprovaling());
+    public void showModels(List<Approval> approvals, List<Approval> historyNodes) {
+        mAdapter = new ApprovalAdapter(this, approvals, historyNodes, mPresenter.isApprovaling());
+        contentRV.setHasFixedSize(false);
+        contentRV.setItemAnimator(new DefaultItemAnimator());
         contentRV.setAdapter(mAdapter);
         mAdapter.setOnChangeClickListener(this);
     }
@@ -302,19 +329,34 @@ public class ApprovalActivity extends OABaseActivity implements IApproval, Appro
 
     @Override
     public void sendToSelect(JSONArray data) {
+        List<String> nodes = new ArrayList<>();
+        for (int i = 0; i < data.size(); i++) {
+            nodes.add(data.getString(i));
+        }
+        sendToSelect(nodes, 0x21, "选择审批人");
+    }
+
+    public void sendToSelect(List<String> seletcNodes, int requestCode, String title) {
         ArrayList<SelectBean> beans = new ArrayList<>();
         SelectBean bean = null;
-        for (int i = 0; i < data.size(); i++) {
+        Set<String> set = new LinkedHashSet<String>();
+        set.addAll(seletcNodes);
+        for (String s : set) {
             bean = new SelectBean();
-            bean.setName(data.getString(i));
+            bean.setName(s);
             bean.setClick(false);
             beans.add(bean);
         }
+        if (requestCode == 0x22) {
+            bean = new SelectBean();
+            bean.setName("回退发起人");
+            beans.add(0, bean);
+        }
         Intent intent = new Intent(ct, SelectActivity.class);
         intent.putExtra("type", 2);
         intent.putParcelableArrayListExtra("data", beans);
-        intent.putExtra("title", "选择审批人");
-        startActivityForResult(intent, 0x22);
+        intent.putExtra("title", title);
+        startActivityForResult(intent, requestCode);
     }
 
 

+ 2 - 2
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/activity/oa/ExpenseReimbursementActivity.java

@@ -1298,9 +1298,9 @@ public class ExpenseReimbursementActivity extends BaseActivity implements View.O
                         }
                     }
                 }else {
-//                    for (int i = 0; i < 3; i++) {
+                    for (int i = 0; i < 3; i++) {  //一次刷新不彻底,只能用三次。我也很无奈啊
                     doDetailsHandle();
-//                    }
+                    }
                 }
 
                 closePopupWindow();

+ 89 - 16
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/adapter/oa/ApprovalAdapter.java

@@ -25,14 +25,15 @@ import com.xzjmyk.pm.activity.ui.erp.entity.EditChangeListener;
 import com.xzjmyk.pm.activity.ui.erp.model.oa.Approval;
 import com.xzjmyk.pm.activity.ui.erp.util.ListUtils;
 import com.xzjmyk.pm.activity.ui.erp.util.LogUtil;
-import com.xzjmyk.pm.activity.ui.erp.util.OACheckUtil;
 import com.xzjmyk.pm.activity.ui.erp.util.OpenFilesUtils;
 import com.xzjmyk.pm.activity.ui.erp.util.StringUtils;
+import com.xzjmyk.pm.activity.ui.erp.view.CustomProgressDialog;
 import com.xzjmyk.pm.activity.ui.tool.SingleImagePreviewActivity;
 import com.xzjmyk.pm.activity.util.CalendarUtils;
 import com.xzjmyk.pm.activity.view.wheel.DatePicker;
 
 import java.io.File;
+import java.util.ArrayList;
 import java.util.List;
 
 /**
@@ -42,12 +43,14 @@ import java.util.List;
 public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolder> {
     private OABaseActivity ct;
     private List<Approval> approvals;
+    private List<Approval> historyNodes;
     private boolean isApprovaling;
 
-    public ApprovalAdapter(OABaseActivity ct, List<Approval> approvals, boolean isApprovaling) {
+    public ApprovalAdapter(OABaseActivity ct, List<Approval> approvals, List<Approval> historyNodes, boolean isApprovaling) {
         this.isApprovaling = isApprovaling;
         this.ct = ct;
         this.approvals = approvals;
+        this.historyNodes = historyNodes;
     }
 
     public List<Approval> getApprovals() {
@@ -85,6 +88,8 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
                 return new PointsViewHolder(parent);
             case Approval.NODES:
                 return new NodeViewHolder(parent);
+            case Approval.NODES_TAG:
+                return new NodeTagViewHolder(parent);
             default: return new BaseRVViewHodler(parent);
         }
     }
@@ -102,18 +107,51 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
                 bindPointsView((PointsViewHolder) holder, position);
             } else if (holder instanceof NodeViewHolder) {
                 bindNodeView((NodeViewHolder) holder, position);
+            } else if (holder instanceof NodeTagViewHolder) {
+                bindNodeTagView((NodeTagViewHolder) holder, position);
             }
         } catch (Exception e) {
 
         }
     }
 
+    private void bindNodeTagView(NodeTagViewHolder holder, int position) {
+        View.OnClickListener listener = new View.OnClickListener() {
+            @Override
+            public void onClick(View v) {
+                boolean isNode = v.getId() == R.id.nodeTv;
+                if ((isNode && holder.nodeTag.getVisibility() == View.GONE) || (!isNode && holder.historyTag.getVisibility() == View.GONE)) {
+                    List<Approval> newApprovals = new ArrayList<Approval>();
+                    List<Approval> approvals1 = approvals.subList(0, position + 1);
+                    List<Approval> approvals2 = approvals.subList(position + 1, approvals.size());
+                    newApprovals.addAll(approvals1);
+                    newApprovals.addAll(historyNodes);
+                    historyNodes = approvals2;
+                    if (newApprovals.get(position).getType() == Approval.NODES_TAG) {
+                        newApprovals.get(position).setNeerInput(!isNode);
+                    }
+                    approvals = newApprovals;
+                    notifyItemRangeChanged(position, approvals.size() - 1);
+                }
+            }
+        };
+        holder.historyTV.setOnClickListener(listener);
+        holder.nodeTv.setOnClickListener(listener);
+        if (approvals.get(position).isNeerInput()) {
+            holder.nodeTag.setVisibility(View.GONE);
+            holder.historyTag.setVisibility(View.VISIBLE);
+        } else {
+            holder.nodeTag.setVisibility(View.VISIBLE);
+            holder.historyTag.setVisibility(View.GONE);
+        }
+    }
+
     private void bindNodeView(NodeViewHolder holder, int position) {
         Approval approval = approvals.get(position);
-        if (position > 0 && approvals.get(position - 1).getType() != Approval.NODES) {
-            holder.padding.setVisibility(View.VISIBLE);
-        } else {
+        if (position > 0 && approvals.get(position - 1).getType() == Approval.NODES_TAG || approvals.get(position - 1).getType() == Approval.NODES) {
             holder.padding.setVisibility(View.GONE);
+        } else {
+            holder.padding.setVisibility(View.VISIBLE);
         }
         int textColor = R.color.hintColor;
         int reId = R.drawable.weishenpi;
@@ -122,10 +160,10 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
             if (approval.getIdKey().startsWith("待审批")) {
                 textColor = R.color.approvaling;
                 reId = R.drawable.daishenpi;
-            } else if (approval.getIdKey().startsWith("未通过") || approval.getIdKey().startsWith("结束")) {
+            } else if (approval.getIdKey().startsWith("未通过") || approval.getIdKey().startsWith("结束") || approval.getIdKey().startsWith("不同意")) {
                 textColor = R.color.crimson;
                 reId = R.drawable.node_delete;
-            } else if (approval.getIdKey().startsWith("已审批") || approval.getIdKey().startsWith("变更")) {
+            } else if (approval.getIdKey().startsWith("已审批") || approval.getIdKey().startsWith("变更") || approval.getIdKey().startsWith("同意")) {
                 reId = R.drawable.node_finished3;
             }
         } else {
@@ -136,18 +174,20 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
         holder.statusIV.setImageResource(reId);
         AvatarHelper.getInstance().display(String.valueOf(approval.getId()), holder.handIv, true, false);
         if (reId == R.drawable.daishenpi && isApprovaling) {
-            holder.timeTv.setText(OACheckUtil.getString(R.string.common_changedealman));
-            holder.timeTv.setOnClickListener(new View.OnClickListener() {
+            holder.changeUser.setVisibility(View.VISIBLE);
+            holder.timeTv.setText("");
+            holder.changeUser.setOnClickListener(new View.OnClickListener() {
                 @Override
                 public void onClick(View v) {
                     if (onChangeClickListener != null)
                         onChangeClickListener.click();
                 }
             });
-            holder.timeTv.setTextColor(ct.getResources().getColor(R.color.titleBlue));
+//            holder.timeTv.setTextColor(ct.getResources().getColor(R.color.titleBlue));
         } else {
+            holder.changeUser.setVisibility(View.GONE);
             holder.timeTv.setOnClickListener(null);
-            holder.timeTv.setTextColor(ct.getResources().getColor(R.color.text_normal));
+//            holder.timeTv.setTextColor(ct.getResources().getColor(R.color.text_normal));
             holder.timeTv.setText(approval.getValues());
         }
 
@@ -239,10 +279,12 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
 
     private void gotoReadEnclosure(Approval approval) {
         String url = approval.getIdKey();
+        final CustomProgressDialog progressDialog = CustomProgressDialog.createDialog(ct);
+        progressDialog.setTitile("正在下载");
+        progressDialog.setMessage("正在下载,请勿关闭程序");
+        LogUtil.i("gotoReadEnclosure");
         if (!StringUtils.isEmpty(approval.getCaption())) {
-            if (approval.getCaption().endsWith("jpeg")
-                    || approval.getCaption().endsWith("jpg")
-                    || approval.getCaption().endsWith("png")) {
+            if (isImage(approval.getCaption())) {
                 Intent intent = new Intent(ct, SingleImagePreviewActivity.class);
                 intent.putExtra(AppConstant.EXTRA_IMAGE_URI, url);
                 ct.startActivity(intent);
@@ -250,11 +292,15 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
                 OpenFilesUtils.downLoadFile(url, approval.getCaption(), new OpenFilesUtils.OnFileLoadListener() {
                     @Override
                     public void onLoadIng(int progress, int allProgress) {
-                        //TODO 下载进行中回调
+                        if (progressDialog != null)
+                            progressDialog.show();
+                        LogUtil.i("TODO 下载进行中回调");
                     }
 
                     @Override
                     public void onSuccess(File file) {
+                        if (progressDialog != null)
+                            progressDialog.dismiss();
                         OpenFilesUtils.openCommonFils(ct, file);
                     }
 
@@ -423,7 +469,7 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
     }
 
     private class NodeViewHolder extends RecyclerView.ViewHolder {
-        ImageView handIv, statusIV;
+        ImageView handIv, statusIV, changeUser;
         TextView timeTv, keyTv, valuesTv;
         View padding;
 
@@ -438,7 +484,27 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
             valuesTv = (TextView) itemView.findViewById(R.id.valuesTv);
             handIv = (ImageView) itemView.findViewById(R.id.handIv);
             statusIV = (ImageView) itemView.findViewById(R.id.statusIV);
+            changeUser = (ImageView) itemView.findViewById(R.id.changeUser);
             padding = itemView.findViewById(R.id.padding);
+            changeUser.setVisibility(View.GONE);
+        }
+    }
+
+    private class NodeTagViewHolder extends RecyclerView.ViewHolder {
+        TextView nodeTv, historyTV;
+        View nodeTag, historyTag;
+
+        public NodeTagViewHolder(ViewGroup parent) {
+            this(LayoutInflater.from(ct).inflate(R.layout.item_approval_node_tag, parent, false));
+        }
+
+        public NodeTagViewHolder(View itemView) {
+            super(itemView);
+            nodeTv = (TextView) itemView.findViewById(R.id.nodeTv);
+            historyTV = (TextView) itemView.findViewById(R.id.historyTV);
+            nodeTag = itemView.findViewById(R.id.nodeTag);
+            historyTag = itemView.findViewById(R.id.historyTag);
+            historyTag.setVisibility(View.GONE);
         }
     }
 
@@ -521,4 +587,11 @@ public class ApprovalAdapter extends RecyclerView.Adapter<RecyclerView.ViewHolde
     public interface OnChangeClickListener {
         void click();
     }
+
+
+    private boolean isImage(String name) {
+        return name.toUpperCase().endsWith("jpeg".toUpperCase())
+                || name.toUpperCase().endsWith("jpg".toUpperCase())
+                || name.toUpperCase().endsWith("png".toUpperCase());
+    }
 }

+ 5 - 4
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/model/oa/Approval.java

@@ -24,10 +24,11 @@ public class Approval {
             , MAIN = 12  //主表
             , DETAIL = 13//从表
             , SETUPTASK = 14//历史审批要点
-            ,ENCLOSURE = 16//附件
+            , ENCLOSURE = 16//附件
             , POINTS = 17//要点
-            , NODES = 18//审批节点
-            , TAG = 19;//标题
+            , NODES_TAG = 18//审批节点标记
+            , NODES = 19//审批节点
+            , TAG = 20;//标题
 
     private boolean neerInput = false;//是否需要输入
     private boolean mustInput = false;//是否是必填字段
@@ -255,7 +256,7 @@ public class Approval {
         }
     }
 
-    @IntDef({TITLE, MAIN, DETAIL, ENCLOSURE, POINTS, NODES, TAG,SETUPTASK})
+    @IntDef({TITLE, MAIN, DETAIL, ENCLOSURE, POINTS, NODES, TAG, SETUPTASK, NODES_TAG})
     @Retention(RetentionPolicy.SOURCE)
     public @interface Duration {
     }

+ 1 - 2
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/model/oa/ApprovalRecord.java

@@ -10,6 +10,7 @@ import java.util.Map;
  */
 
 public class ApprovalRecord {
+    public boolean isForknode = false;
     public int id = 0;
     public int nodeId = 0;
     public String title;
@@ -23,8 +24,6 @@ public class ApprovalRecord {
     public String caller = "";
 
 
-
-
     @Override
     public String toString() {
         Map<String, Object> map = new HashMap<>();

+ 158 - 94
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/presenter/ApprovaPresenter.java

@@ -69,22 +69,26 @@ public class ApprovaPresenter implements OnHttpResultListener {
     private String title;
     private String master;
     private List<Approval> approvals;
-    private List<Approval> hineApprovals;
 
-    private boolean submit, loading;
+    private List<Approval> hineApprovals;//隐藏字段
+    private List<Approval> showApprovals;//显示字段
+    private List<Approval> historyNodes;
+
+    private boolean submit, loading, endActivity;
 
     public ApprovaPresenter(IApproval iApproval, Intent intent) {
         this.iApproval = iApproval;
+        endActivity = false;
         if (intent != null) {
             int id = intent.getIntExtra("nodeid", -1);
-            String imid = intent.getStringExtra("imid");
+//            String imid = intent.getStringExtra("imid");
             title = intent.getStringExtra("title");
             master = intent.getStringExtra("master");
             if (StringUtils.isEmpty(master)) master = CommonUtil.getMaster();
             if (id != -1) {
-                initLoad(id, imid);
+                initLoad(id);
             } else {
-                initLoad(0, imid);
+                initLoad(0);
             }
         } else {
             initLoad(0);
@@ -96,38 +100,23 @@ public class ApprovaPresenter implements OnHttpResultListener {
         return title.equals(OACheckUtil.getString(R.string.title_approval));
     }
 
-    public void trun2SetActivity(Activity activity, List<Approval> approvals) {
+    public boolean isApprovaled() {
+        if (StringUtils.isEmpty(title)) return false;
+        return title.equals(OACheckUtil.getString(R.string.task_confimed));
+    }
+
+    public void trun2SetActivity(Activity activity) {
         if (loading) return;
         ArrayList<Data> fields = new ArrayList<>();
         ArrayList<Data> fieldsDis = new ArrayList<>();
-        boolean addDetailed = false;
-        boolean canAddDetail = true;
-        for (Approval approval : approvals) {
-            if (approval.getType() == Approval.MAIN) {
-                Data data = new Data(true, approval);
-                fieldsDis.add(data);
-            } else if (approval.getType() == DETAIL && canAddDetail) {
-                Data data = new Data(false, approval);
-                fieldsDis.add(data);
-                addDetailed = true;
-            } else if (addDetailed) {
-                canAddDetail = false;
-            }
-        }
-        addDetailed = false;
-        canAddDetail = true;
         if (!ListUtils.isEmpty(hineApprovals)) {
             for (Approval approval : hineApprovals) {
-                if (approval.getType() == Approval.MAIN) {
-                    Data data = new Data(true, approval);
-                    fields.add(data);
-                } else if (approval.getType() == DETAIL && canAddDetail) {
-                    Data data = new Data(false, approval);
-                    fields.add(data);
-                    addDetailed = true;
-                } else if (addDetailed) {
-                    canAddDetail = false;
-                }
+                fields.add(new Data(approval.getType() == Approval.MAIN, approval));
+            }
+        }
+        if (!ListUtils.isEmpty(showApprovals)) {
+            for (Approval approval : showApprovals) {
+                fieldsDis.add(new Data(approval.getType() == Approval.MAIN, approval));
             }
         }
         activity.startActivityForResult(new Intent(activity, DataFormFieldActivity.class)
@@ -139,10 +128,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
     }
 
     public void closeDB() {
-//        if (manager != null) {
-//            manager.closeDB();
-//            manager = null;
-//        }
+        endActivity = true;
     }
 
     public String getUrl(String baseUrl, String title) {
@@ -153,6 +139,18 @@ public class ApprovaPresenter implements OnHttpResultListener {
         return baseUrl + record.nodeId + endStatus;
     }
 
+    public List<String> getNodesCanReturn() {
+        List<String> list = new ArrayList<>();
+        if (record.isForknode && !ListUtils.isEmpty(historyNodes)) {
+            for (Approval a : historyNodes) {
+                if (a.getIdKey().startsWith("同意") && a.isNeerInput()) {
+                    list.add(a.getValuesKey());
+                }
+            }
+        }
+        return list;
+    }
+
     public String getMaster() {
         return master == null ? CommonUtil.getMaster() : master;
     }
@@ -161,17 +159,14 @@ public class ApprovaPresenter implements OnHttpResultListener {
         initLoad(record.nodeId);
     }
 
-    private void initLoad(int nodeId) {
-        initLoad(nodeId, "");
-    }
 
-    private void initLoad(int nodeId, String imid) {
+    private void initLoad(int nodeId) {
         record = new ApprovalRecord();
         approvals = new ArrayList<>();
         hineApprovals = new ArrayList<>();
+        showApprovals = new ArrayList<>();
+        historyNodes = null;
         record.nodeId = nodeId;
-        if (imid != null)
-            record.imid = imid;
         iApproval.initStatus();
         submit = false;
         loading = false;
@@ -192,6 +187,10 @@ public class ApprovaPresenter implements OnHttpResultListener {
             iApproval.showToast(R.string.submit_cannot_submit_again, R.color.load_submit);
             return;
         }
+        if (StringUtils.isEmpty(emCode)) {
+            loadNextProcess();
+            return;
+        }
         iApproval.showLoading();
         String url = "common/setAssignee.action";
         Map<String, Object> param = new HashMap<>();
@@ -296,12 +295,26 @@ public class ApprovaPresenter implements OnHttpResultListener {
 
     //结束流程
     private void loadEndProcess() {
-        String url = "common/endProcessInstance.action";
+        //结束流程接口部分
+//        String url = "common/endProcessInstance.action";
+//        Map<String, Object> param = new HashMap<>();
+//        param.put("processInstanceId", record.processInstanceId);
+//        param.put("holdtime", 435);
+//        param.put("nodeId", record.nodeId);
+//        param.put("master", master);
+        if (!canSubmit()) return;
+        iApproval.showLoading();
+        String url = "common/review.action";
         Map<String, Object> param = new HashMap<>();
-        param.put("processInstanceId", record.processInstanceId);
-        param.put("holdtime", 435);
-        param.put("nodeId", record.nodeId);
+        param.put("taskId", record.nodeId);
+        param.put("nodeName", record.nodeName);
+        param.put("nodeLog", "流程异常,结束流程");
         param.put("master", master);
+        param.put("result", false);
+        param.put("backTaskName", "RECORDER");//jn_name
+        param.put("attachs", "");//附件id
+        param.put("_noc", 1);//权限管控
+        param.put("holdtime", 4311);//holdtime
         Request.Bulider bulider = new Request.Bulider()
                 .setUrl(url)
                 .setWhat(LOAD_END_PROCESS)
@@ -328,7 +341,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
     }
 
     /*不同意 submiting*/
-    public void disAgree(String nodeLog) {
+    public void disAgree(String nodeLog, String backTaskName) {
         if (StringUtils.isEmpty(nodeLog)) {
             iApproval.showToast(R.string.approval_opinion_error, R.color.load_submit);
             return;
@@ -343,7 +356,8 @@ public class ApprovaPresenter implements OnHttpResultListener {
         param.put("nodeLog", nodeLog);
         param.put("master", master);
         param.put("result", false);
-        param.put("backTaskName", "RECORDER");
+        if (StringUtils.isEmpty(backTaskName)) backTaskName = "RECORDER";
+        param.put("backTaskName", backTaskName);//jn_name
         param.put("attachs", "");//附件id
         param.put("_noc", 1);//权限管控
         param.put("holdtime", 4311);//holdtime
@@ -502,6 +516,11 @@ public class ApprovaPresenter implements OnHttpResultListener {
 
     @Override
     public void result(int what, boolean isJSON, String message, Bundle bundle) {
+        if (endActivity) {
+            loading = false;
+            submit = false;
+            return;
+        }
         try {
             if (!isJSON) {
                 LogUtil.i("!isJSON");
@@ -518,11 +537,13 @@ public class ApprovaPresenter implements OnHttpResultListener {
 
     @Override
     public void error(int what, String message, Bundle bundle) {
+        if (endActivity) return;
         iApproval.dimssLoading();
         switch (what) {
             case LOAD_AGREE:
                 if (message.contains("程序错误")) {
                     loadEndProcess();
+//                    disAgree("流程异常,结束流程", null);
                 }
             case LOAD_TAKE_OVER:  /*提交部分*/
             case LOAD_PROCESS_UPDATE:
@@ -658,8 +679,8 @@ public class ApprovaPresenter implements OnHttpResultListener {
     //处理当前结点信息
     private void handlerCurrentNode(JSONObject object) throws Exception {
         if (object != null && !loading) {
-            String instanceId = getJson2Text(object, "InstanceId");
-            record.processInstanceId = instanceId;
+            record.processInstanceId = getJson2Text(object, "InstanceId");
+            record.isForknode = OACheckUtil.getJsonIntager(object, "forknode") == 0;
             JSONObject currentnode = OACheckUtil.getJSONObject(object, "currentnode");
             if (currentnode != null) {
                 String recordName = getJson2Text(currentnode, "jp_launcherName");
@@ -696,6 +717,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
             handerTitle(0);
             loadDetailedList();//获取明细表
         } else {
+            LogUtil.i("loading=" + loading);
             loading = false;
         }
     }
@@ -705,10 +727,10 @@ public class ApprovaPresenter implements OnHttpResultListener {
             //计算主表
             JSONArray formdatas = OACheckUtil.getJsonArray(object, "formdata");
             JSONArray formconfigs = OACheckUtil.getJsonArray(object, "formconfigs");
-            if (!ListUtils.isEmpty(formdatas) && !ListUtils.isEmpty(formconfigs)) {
-                final JSONObject formdata = formdatas.getJSONObject(0);
-                if (!ListUtils.isEmpty(formconfigs) && formdata != null) {
-                    final List<Approval> mainApproval = formandGriddata(formdata, formconfigs, record.caller, true);
+            if (!ListUtils.isEmpty(formconfigs)) {
+                final JSONObject formdata = ListUtils.isEmpty(formdatas) ? null : formdatas.getJSONObject(0);
+                if (!ListUtils.isEmpty(formconfigs)) {
+                    final List<Approval> mainApproval = formandGriddata(formdata, formconfigs, record.caller, true, true);
                     setData2ListThread(Approval.MAIN, mainApproval);
                 }
             }
@@ -716,15 +738,21 @@ public class ApprovaPresenter implements OnHttpResultListener {
             JSONArray griddatas = OACheckUtil.getJsonArray(object, "griddata");
             JSONArray gridconfigs = OACheckUtil.getJsonArray(object, "gridconfigs");
             final List<Approval> detailedList = new ArrayList<>();
-            if (!ListUtils.isEmpty(griddatas) && !ListUtils.isEmpty(gridconfigs)) {
-                for (int i = 0; i < griddatas.size(); i++) {
-                    //获取到单个明细表单
-                    final List<Approval> detailedApproval = formandGriddata(griddatas.getJSONObject(i), gridconfigs, record.caller, false);
-                    if (!ListUtils.isEmpty(detailedApproval)) {
-                        Approval approval = new Approval(Approval.TAG);
-                        approval.setCaption(getString(R.string.serial_number) + (i + 1));
-                        detailedApproval.add(0, approval);
-                        detailedList.addAll(detailedApproval);
+            if (!ListUtils.isEmpty(gridconfigs)) {
+                if (ListUtils.isEmpty(griddatas)) {
+                    formandGriddata(null, gridconfigs, record.caller, false, true);
+                } else {
+                    for (int i = 0; i < griddatas.size(); i++) {
+                        //获取到单个明细表单
+                        final List<Approval> detailedApproval = formandGriddata(griddatas.getJSONObject(i),
+                                gridconfigs, record.caller,
+                                false, i == 0);
+                        if (!ListUtils.isEmpty(detailedApproval)) {
+                            Approval approval = new Approval(Approval.TAG);
+                            approval.setCaption(getString(R.string.serial_number) + (i + 1));
+                            detailedApproval.add(0, approval);
+                            detailedList.addAll(detailedApproval);
+                        }
                     }
                 }
             }
@@ -745,7 +773,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
                     if (!ListUtils.isEmpty(otherGriddata) && !ListUtils.isEmpty(otherGridconfigs)) {
                         for (int j = 0; j < otherGriddata.size(); j++) {
                             //获取到单个明细表单
-                            final List<Approval> detailedApproval = formandGriddata(otherGriddata.getJSONObject(j), otherGridconfigs, caller, false);
+                            final List<Approval> detailedApproval = formandGriddata(otherGriddata.getJSONObject(j), otherGridconfigs, caller, false, false);
                             if (!ListUtils.isEmpty(detailedApproval)) {
                                 Approval approval = new Approval(Approval.TAG);
                                 approval.setCaption(name + " " + getString(R.string.serial_number) + (j + 1));
@@ -772,8 +800,12 @@ public class ApprovaPresenter implements OnHttpResultListener {
         }
     }
 
-
-    private List<Approval> formandGriddata(final JSONObject data, final JSONArray configs, String caller, boolean isMain) throws Exception {
+    //TODO 1.隐藏字段明细表重复 2.不该显示字段被显示
+    private List<Approval> formandGriddata(final JSONObject data,
+                                           final JSONArray configs,
+                                           String caller,
+                                           boolean isMain,
+                                           boolean addHint) throws Exception {
         List<Approval> approvals = new ArrayList<>();
         String idTag = "";
         int id = 0;
@@ -810,13 +842,22 @@ public class ApprovaPresenter implements OnHttpResultListener {
             if (approval.isDftypeEQ("H")
                     || isdefault != -1
                     || appwidth == 0
-                    || (!isMain && OACheckUtil.getJsonIntager(config, "DG_WIDTH") == 0)
-                    || OACheckUtil.isEmpty(valueKey)
-                    || OACheckUtil.isEmpty(caption)
-                    || (merged.length() > 0 && merged.toString().contains(valueKey))) {
-                if (isdefault == 0) {
+                    || (!isMain && OACheckUtil.getJsonIntager(config, "DG_WIDTH") == 0)) {
+                continue;
+            }
+            boolean showAble = data != null && data.containsKey(valueKey);
+            if (!OACheckUtil.isEmpty(caption)) {
+                if (showAble) {
+                    approval.setValues(OACheckUtil.getJson2Text(data, valueKey)); //获取第一个字段的值
+                    if (addHint) {
+                        showApprovals.add(approval);
+                    }
+                } else if (addHint) {
                     hineApprovals.add(approval);
                 }
+            }
+
+            if (OACheckUtil.isEmpty(valueKey) || OACheckUtil.isEmpty(caption) || (merged.length() > 0 && merged.toString().contains("," + valueKey + ","))) {
                 continue;
             }
             //添加下拉数据
@@ -829,7 +870,6 @@ public class ApprovaPresenter implements OnHttpResultListener {
                         approval.getDatas().add(new Approval.Data(display, value));
                 }
             }
-            approval.setValues(OACheckUtil.getJson2Text(data, valueKey)); ;//获取第一个字段的值
             boolean mergeAble = appwidth == 1 || (approval.isDftypeEQ("MT"));
             approval.data2Values();
             approval.setMustInput(true);
@@ -848,7 +888,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
             }
             if (!isApprovaling())
                 approval.setNeerInput(false);
-            if (!approval.isNeerInput() && StringUtils.isEmpty(approval.getValues())) {
+            if ((!approval.isNeerInput() && StringUtils.isEmpty(approval.getValues())) || !showAble || approval.getValues().equals("null") || !showAble || approval.getValues().equals("(null)")) {
                 continue;//如果不是要输入的对象,同时显示值为空,需要隐藏去
             }
             if (mergeAble) {
@@ -856,7 +896,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
                 if (!StringUtils.isEmpty(valueTagKey)) {
                     String valueTag = OACheckUtil.getJson2Text(data, valueTagKey);
                     if (!StringUtils.isEmpty(valueTag)) {
-                        merged.append(valueTagKey + ",");
+                        merged.append("," + valueTagKey + ",");
                         approval.addValues("/" + valueTag);
                     }
                 }
@@ -864,7 +904,10 @@ public class ApprovaPresenter implements OnHttpResultListener {
             approval.setCaller(caller);
             approvals.add(approval);
         }
-        for (Approval approval : approvals) {
+        for (
+                Approval approval : approvals)
+
+        {
             approval.setId(id);
             approval.setIdKey(idTag);
         }
@@ -904,14 +947,17 @@ public class ApprovaPresenter implements OnHttpResultListener {
         return itemSetuptasks;
     }
 
+    //    //1.forknode==0 (非并行节点)    2.jn_dealResult == '同意'   3.jn_attach == 'T'
     private Approval getNodeApproval(JSONObject object) {
         String nodeName = OACheckUtil.getJson2Text(object, "jn_name");//当前结点名称
         String emCode = OACheckUtil.getJson2Text(object, "jn_dealManId");//节点处理人编号
         String manName = OACheckUtil.getJson2Text(object, "jn_dealManName");//处理人名字
         String dealTime = OACheckUtil.getJson2Text(object, "jn_dealTime");//审批时间
         String result = OACheckUtil.getJson2Text(object, "jn_dealResult");//审批结果
+        String attach = OACheckUtil.getJson2Text(object, "jn_attach");//选择类型
         String description = OACheckUtil.getJson2Text(object, "jn_nodeDescription");//审批意见
         Approval approval = new Approval(Approval.NODES);
+        approval.setNeerInput("T".equals(attach));
         approval.setCaption(manName);
         approval.setDfType(emCode);
         if (!StringUtils.isEmpty(dealTime)) {
@@ -919,19 +965,17 @@ public class ApprovaPresenter implements OnHttpResultListener {
         }
         StringBuilder resultBuilder = new StringBuilder();
         if (!StringUtils.isEmpty(result)) {
-            if (result.equals("同意")) {
-                resultBuilder.append("已审批");
-            } else if (result.equals("不同意")) {
-                resultBuilder.append("未通过");
-            } else {
-                resultBuilder.append(result);
-            }
+            resultBuilder.append(result);
         }
         if (!StringUtils.isEmpty(description)) {
             resultBuilder.append("(" + description + ")");
         }
         approval.setIdKey(resultBuilder.toString());
         approval.setValuesKey(nodeName);
+        if (!StringUtils.isEmpty(emCode)) {
+            int imId = getImByCode(emCode);
+            approval.setId(imId);
+        }
         return approval;
     }
 
@@ -951,15 +995,16 @@ public class ApprovaPresenter implements OnHttpResultListener {
         ThreadUtil.getInstance().addTask(new Runnable() {
             @Override
             public void run() {
+                boolean showNode = true;
                 JSONArray nodes = OACheckUtil.getJsonArray(object, "nodes");
                 JSONArray processs = OACheckUtil.getJsonArray(object, "processs");
                 JSONArray datas = OACheckUtil.getJsonArray(object, "data");
                 List<Approval> approvals = getNodDatas(datas);
-                List<Approval> historyNodes = null;
                 if (bundle != null && !StringUtils.isEmpty(bundle.getString("historyNode"))) {
                     historyNodes = handlerHistorySetuptask(JSON.parseObject(bundle.getString("historyNode")));
                 }
-                if (ListUtils.isEmpty(approvals) && !ListUtils.isEmpty(historyNodes)) {
+                if ((isApprovaled() || ListUtils.isEmpty(approvals)) && !ListUtils.isEmpty(historyNodes)) {
+                    showNode = false;
                     approvals = historyNodes;
                 }
                 if (!ListUtils.isEmpty(processs)) {
@@ -968,25 +1013,42 @@ public class ApprovaPresenter implements OnHttpResultListener {
                 if (!ListUtils.isEmpty(nodes)) {
                     mergeNode(nodes, approvals, true);
                 }
-                //判断当前
                 boolean hanNotApproval = false;
                 for (Approval a : approvals) {
                     if (!a.getIdKey().startsWith("已审批")) {
                         hanNotApproval = true;
+                        if (a.getIdKey().startsWith("待审批"))
+                            a.setValues("");
+                    }
+                    String emcode = null;
+                    if (a.getDfType().contains(",")) {
+                        String[] emcodes = a.getDfType().split(",");
+                        if (!StringUtils.isEmpty(emcodes[0])) {
+                            emcode = emcodes[0];
+                        }
+                    } else {
+                        emcode = a.getDfType();
                     }
-                    String[] emcode = a.getDfType().split(",");
-                    if (!StringUtils.isEmpty(emcode[0])) {
-                        int imId = getImByCode(emcode[0]);
+                    if (!StringUtils.isEmpty(emcode)) {
+                        int imId = getImByCode(emcode);
                         a.setId(imId);
                     }
                 }
                 int reId = -1;
                 if ("未通过".equals(record.status) || "已结束".equals(record.status)) {
                     reId = R.drawable.unapproved;
-                } else if (!hanNotApproval) {
+                } else if (!hanNotApproval && !isApprovaling()) {//没有未审批的数据
+                    showNode = false;
+                    if (!ListUtils.isEmpty(historyNodes)) {
+                        approvals = historyNodes;
+                    }
                     reId = R.drawable.approved;
                 }
                 handerTitle(reId);
+                if (!ListUtils.isEmpty(approvals) && !ListUtils.isEmpty(historyNodes) && showNode) {
+                    Approval nodeTag = new Approval(Approval.NODES_TAG);
+                    approvals.add(0, nodeTag);
+                }
                 setData2ListThread(Approval.NODES, approvals);
                 loading = false;
             }
@@ -1032,10 +1094,12 @@ public class ApprovaPresenter implements OnHttpResultListener {
                         enclosureList.add(enclosure);
                     }
                 }
-                Approval tag = new Approval(Approval.TAG);
-                tag.setCaption("附件");
-                enclosureList.add(0, tag);
-                setData2ListThread(Approval.ENCLOSURE, enclosureList);
+                if (!ListUtils.isEmpty(enclosureList)) {
+                    Approval tag = new Approval(Approval.TAG);
+                    tag.setCaption("附件");
+                    enclosureList.add(0, tag);
+                    setData2ListThread(Approval.ENCLOSURE, enclosureList);
+                }
             }
         });
     }
@@ -1382,7 +1446,7 @@ public class ApprovaPresenter implements OnHttpResultListener {
                 if (type == Approval.TITLE) {
                     iApproval.showOpinion();
                 }
-                iApproval.showModels(merges);
+                iApproval.showModels(merges, historyNodes);
 
             }
         });

+ 1 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/presenter/imp/IApproval.java

@@ -14,7 +14,7 @@ public interface IApproval extends HttpImp {
 
     void nodeDealMan(String nodeDealMan);
 
-    void showModels(List<Approval> approvals);
+    void showModels(List<Approval> approvals,List<Approval> historyNodes);
 
     void initStatus();
 

+ 1 - 1
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/erp/util/OpenFilesUtils.java

@@ -39,7 +39,7 @@ public class OpenFilesUtils {
     //定义用于检查要打开的文件的后缀是否在遍历后缀数组中,调用下面的方法之前必须先用这个方法判断
     public static boolean checkEndsWithInStringArray(String checkItsEnd, String[] fileEndings) {
         for (String aEnd : fileEndings) {
-            if (checkItsEnd.endsWith(aEnd))
+            if (checkItsEnd.toUpperCase().endsWith(aEnd.toUpperCase()))
                 return true;
         }
         return false;

+ 5 - 3
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/me/MeFragment.java

@@ -35,6 +35,7 @@ import com.xzjmyk.pm.activity.ui.MainActivity;
 import com.xzjmyk.pm.activity.ui.base.EasyFragment;
 import com.xzjmyk.pm.activity.ui.circle.BusinessCircleActivity;
 import com.xzjmyk.pm.activity.ui.erp.activity.BaseInfoActivity;
+import com.xzjmyk.pm.activity.ui.erp.activity.message.PersonalRegActivity;
 import com.xzjmyk.pm.activity.ui.erp.activity.oa.OAMainActivity;
 import com.xzjmyk.pm.activity.ui.erp.model.Master;
 import com.xzjmyk.pm.activity.ui.erp.net.ViewUtil;
@@ -342,7 +343,7 @@ public class MeFragment extends EasyFragment implements View.OnClickListener {
         } else {
 //            test_rl.setVisibility(View.VISIBLE);
             my_qr_code_rl.setVisibility(View.GONE);
-            picture_selector_rl.setVisibility(View.VISIBLE);
+            picture_selector_rl.setVisibility(View.GONE);
         }
 
         my_qr_code_rl.setOnClickListener(new View.OnClickListener() {
@@ -363,8 +364,9 @@ public class MeFragment extends EasyFragment implements View.OnClickListener {
             @Override
             public void onClick(View v) {
 //                startActivity(new Intent(ct, PictureSelectorDemo.class));
-//                startActivity(new Intent(ct, PersonalRegActivity.class));
-                startActivity(new Intent(ct,TemperatureActivity.class));
+                startActivity(new Intent(ct, PersonalRegActivity.class));
+//                startActivity(new Intent(ct,TemperatureActivity.class));
+//                startActivity(new Intent(ct,ToastDemoActivity.class));
             }
         });
 

+ 12 - 11
WeiChat/src/main/java/com/xzjmyk/pm/activity/ui/platform/task/TaskAddErpActivity.java

@@ -50,7 +50,7 @@ import java.util.Map;
  * Created by FANGlh on 2017/3/30.
  * function:erp添加任务界面同步于b2b任务添加界面
  */
-public class TaskAddErpActivity extends BaseActivity implements View.OnClickListener,RecognizerDialogListener {
+public class TaskAddErpActivity extends BaseActivity implements View.OnClickListener, RecognizerDialogListener {
     private static final int TASK_ADD_ERP = 0x330;
     @ViewInject(R.id.et_title)
     private EditText et_title;
@@ -119,7 +119,7 @@ public class TaskAddErpActivity extends BaseActivity implements View.OnClickList
         voice_search_iv.setOnClickListener(new View.OnClickListener() {
             @Override
             public void onClick(View v) {
-                RecognizerDialogUtil.showRecognizerDialog(ct,TaskAddErpActivity.this);
+                RecognizerDialogUtil.showRecognizerDialog(ct, TaskAddErpActivity.this);
             }
         });
     }
@@ -131,12 +131,12 @@ public class TaskAddErpActivity extends BaseActivity implements View.OnClickList
 //                CommonUtil.showDateDialog(mContext, v);
 //                showDateDialog(this, et_startime);
 
-                startActivityForResult(new Intent(mContext,SelectCalendarActivity.class)
+                startActivityForResult(new Intent(mContext, SelectCalendarActivity.class)
                                 .putExtra("startDate", et_startime.getText().toString())
                                 .putExtra("endDate", et_endtime.getText().toString())
-                                .putExtra("hasMenu",false)
+                                .putExtra("hasMenu", false)
                                 .putExtra("caller", "Workovertime")
-                        ,0x30);
+                        , 0x30);
                 break;
             case R.id.iv_find:
                 Intent intent = new Intent(ct, SelectCollisionActivity.class);
@@ -151,12 +151,12 @@ public class TaskAddErpActivity extends BaseActivity implements View.OnClickList
             case R.id.et_endtime:
 //                showDateDialog(this, et_endtime);
 
-                startActivityForResult(new Intent(mContext,SelectCalendarActivity.class)
+                startActivityForResult(new Intent(mContext, SelectCalendarActivity.class)
                                 .putExtra("startDate", et_startime.getText().toString())
                                 .putExtra("endDate", et_endtime.getText().toString())
-                                .putExtra("hasMenu",false)
+                                .putExtra("hasMenu", false)
                                 .putExtra("caller", "Workovertime")
-                        ,0x30);
+                        , 0x30);
                 break;
             default:
                 break;
@@ -218,9 +218,9 @@ public class TaskAddErpActivity extends BaseActivity implements View.OnClickList
                 break;
         }
 
-        if (requestCode == 0x30 && resultCode == 0x11){
-            String startDate=data.getStringExtra("startDate");
-            String endDate=data.getStringExtra("endDate");
+        if (requestCode == 0x30 && resultCode == 0x11) {
+            String startDate = data.getStringExtra("startDate");
+            String endDate = data.getStringExtra("endDate");
 //            startDate=startDate+":00";
 //            endDate=endDate+":00";
             et_startime.setText(startDate);
@@ -340,6 +340,7 @@ public class TaskAddErpActivity extends BaseActivity implements View.OnClickList
                         Log.i("task_erp_result", task_erp_result + "");
                         if (JSON.parseObject(task_erp_result).containsKey("success") && JSON.parseObject(task_erp_result).getBoolean("success")) {
                             Toast.makeText(mContext, getString(R.string.task_send_success), Toast.LENGTH_LONG).show();
+                            setResult(0x20, null);
                             finish();
                         }
                     }

+ 25 - 0
WeiChat/src/main/java/com/xzjmyk/pm/activity/view/CrashLinearLayoutManager.java

@@ -0,0 +1,25 @@
+package com.xzjmyk.pm.activity.view;
+
+import android.content.Context;
+import android.support.v7.widget.LinearLayoutManager;
+import android.support.v7.widget.RecyclerView;
+
+/**
+ * Created by Bitliker on 2017/8/17.
+ */
+
+public class CrashLinearLayoutManager extends LinearLayoutManager {
+    public CrashLinearLayoutManager(Context context) {
+        super(context);
+    }
+
+    @Override
+    public void onLayoutChildren(RecyclerView.Recycler recycler, RecyclerView.State state) {
+        try {
+            super.onLayoutChildren(recycler, state);
+        } catch (IndexOutOfBoundsException e) {
+            e.printStackTrace();
+        }
+    }
+
+}

+ 12 - 11
WeiChat/src/main/java/com/xzjmyk/pm/activity/xmpp/XReconnectionManager.java

@@ -15,10 +15,8 @@ import com.xzjmyk.pm.activity.util.DeviceInfoUtil;
 import com.xzjmyk.pm.activity.volley.Result;
 
 import org.jivesoftware.smack.AbstractConnectionListener;
-import org.jivesoftware.smack.ConnectionListener;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException.StreamErrorException;
-import org.jivesoftware.smack.XMPPTCPConnection;
 import org.jivesoftware.smack.packet.StreamError;
 import org.jivesoftware.smack.util.StringUtils;
 
@@ -134,6 +132,7 @@ public class XReconnectionManager extends AbstractConnectionListener {
 							doReconnecting = false;
 							LogUtil.d("Token","1:表示检查成功Token过期");
 							//TODO 关闭自动登录  可能出现账号异常情况
+							//mConnection.login();
 //							conflict();
 						} else if (checkTokenStatus == 2) {// 2、表示检查成功,Token没有改变,可以继续下面的重新登陆
 							LogUtil.d("Token","2:表示检查成功,Token没有改变,可以继续下面的重新登陆");
@@ -192,7 +191,6 @@ public class XReconnectionManager extends AbstractConnectionListener {
 	private int syncCheckToken() {// 同步网络请求Token
 		if (CoreService.DEBUG) {
 			Log.d(CoreService.TAG, "开始重新登陆前的 Token 状态检查");
-			Log.d("wang", "开始重新登陆前的 Token 状态检查");
 			String requestUrl = MyApplication.getInstance().getConfig().USER_LOGIN_AUTO;
 			if (requestUrl == null) {
 				return 1;
@@ -232,10 +230,11 @@ public class XReconnectionManager extends AbstractConnectionListener {
 
 				StringBuilder sb = new StringBuilder();
 				sb.append("access_token=" + access_token + "&");
-				String user = ((XMPPTCPConnection) mConnection).getDirectUser();
+				//String user = ((XMPPTCPConnection) mConnection).getDirectUser();
+				LogUtil.d("wang",JSON.toJSONString(mConnection));
+				String user =mConnection.getUser();
 				Log.d("wang", "user..." + user);
 				if (user == null) {
-					Log.d("wang", "user == null");
 					return 1;
 				}
 				sb.append("userId=" + StringUtils.parseName(user) + "&");
@@ -321,17 +320,19 @@ public class XReconnectionManager extends AbstractConnectionListener {
 
 	private void notifyReconnectionFailed(Exception exception) {
 		if (isReconnectionAllowed()) {
-			for (ConnectionListener listener : mConnection.getConnectionListeners()) {
-				listener.reconnectionFailed(exception);
-			}
+			LogUtil.d("xmppLogs","notifyReconnectionFailed");
+//			for (ConnectionListener listener : mConnection.getConnectionListeners()) {
+//				listener.reconnectionFailed(exception);
+//			}
 		}
 	}
 
 	private void notifyAttemptToReconnectIn(int seconds) {
 		if (isReconnectionAllowed()) {
-			for (ConnectionListener listener : mConnection.getConnectionListeners()) {
-				listener.reconnectingIn(seconds);
-			}
+			LogUtil.d("xmppLogs","notifyAttemptToReconnectIn");
+//			for (ConnectionListener listener : mConnection.getConnectionListeners()) {
+//				listener.reconnectingIn(seconds);
+//			}
 		}
 	}
 

+ 25 - 7
WeiChat/src/main/java/com/xzjmyk/pm/activity/xmpp/XmppConnectionManager.java

@@ -11,6 +11,7 @@ import android.util.Log;
 
 import com.xzjmyk.pm.activity.MyApplication;
 import com.xzjmyk.pm.activity.ui.erp.util.CommonUtil;
+import com.xzjmyk.pm.activity.ui.erp.util.LogUtil;
 
 import org.apache.harmony.javax.security.sasl.SaslException;
 import org.jivesoftware.smack.AbstractConnectionListener;
@@ -19,7 +20,7 @@ import org.jivesoftware.smack.SmackException;
 import org.jivesoftware.smack.SmackException.NotConnectedException;
 import org.jivesoftware.smack.XMPPConnection;
 import org.jivesoftware.smack.XMPPException;
-import org.jivesoftware.smack.XMPPTCPConnection;
+import org.jivesoftware.smack.tcp.XMPPTCPConnection;
 import org.jivesoftware.smack.packet.Presence;
 import org.jivesoftware.smack.util.StringUtils;
 import org.jivesoftware.smackx.ping.PingManager;
@@ -118,7 +119,7 @@ public class XmppConnectionManager {
 			}
 			final boolean isConnected = isGprsOrWifiConnected();
 			if (mIsNetWorkActive != isConnected) {// 和之前的状态不同
-				Log.d("roamer", "网络状态改变了");
+				Log.d("roamer", "网络状态改变了doLogining:"+doLogining);
 				mIsNetWorkActive = isConnected;
 				// 网络状态改变了
 				if (!mIsNetWorkActive) {// 由有网变为没网
@@ -126,6 +127,8 @@ public class XmppConnectionManager {
 						mLoginThread.interrupt();
 					}
 				} else {
+					LogUtil.d("Xmpp","isLoginAllowed():"+isLoginAllowed());
+					doLogining=true;
 					if (isLoginAllowed()) {
 						login(mLoginUserId, mLoginPassword);
 					}
@@ -197,6 +200,12 @@ public class XmppConnectionManager {
 	private boolean doLogining = false;
 
 	private boolean isLoginAllowed() {
+		LogUtil.d("Xmpp","---------isLoginAllowed()------------");
+		LogUtil.d("Xmpp","doLogining:"+doLogining);
+		LogUtil.d("Xmpp","mIsNetWorkActive:"+mIsNetWorkActive);
+		LogUtil.d("Xmpp","!mConnection.isConnected():"+!mConnection.isConnected());
+		LogUtil.d("Xmpp","!mConnection.isAuthenticated():"+!mConnection.isAuthenticated());
+		LogUtil.d("Xmpp","---------isLoginAllowed()------------");
 		return doLogining && mIsNetWorkActive && (!mConnection.isConnected() || !mConnection.isAuthenticated());
 	}
 
@@ -219,11 +228,19 @@ public class XmppConnectionManager {
 			presenceOffline();
 		}
 		if (mConnection.isConnected()) {
-			mConnection.disconnect();
+			disconnect();
 		}
 
 	}
 
+	private void disconnect()  {
+		try {
+			mConnection.disconnect();
+		} catch (NotConnectedException e) {
+			e.printStackTrace();
+		}
+	}
+
 	public synchronized void login(final String userId, final String password) {
 		Log.d("roamer", "login start");
 		if (mConnection.isAuthenticated()) {// 如果已经登陆
@@ -231,7 +248,7 @@ public class XmppConnectionManager {
 			if (StringUtils.parseName(mConnection.getUser()).equals(userId)) {// 如果登陆的用户和需要在登陆的是同一个用户,赋予可能改变的用户名和密码,返回
 				return;
 			} else {
-				mConnection.disconnect();
+				disconnect();
 			}
 		}
 
@@ -278,7 +295,7 @@ public class XmppConnectionManager {
 		}
 		mReconnectionManager.release();
 		if (mConnection != null && mConnection.isConnected()) {
-			mConnection.disconnect();
+			disconnect();
 		}
 		presenceOffline();
 	}
@@ -326,7 +343,8 @@ public class XmppConnectionManager {
 				Log.d("roamer", "login try");
 				try {
 					if (!mConnection.isConnected()) {
-						((XMPPTCPConnection) mConnection).connectWithoutLogin();
+						//((XMPPTCPConnection) mConnection).connectWithoutLogin();
+						 mConnection.connect();
 					}
 					if (mConnection.isConnected()) {
 						PingManager.getInstanceFor(mConnection).setPingInterval(60);
@@ -347,7 +365,7 @@ public class XmppConnectionManager {
 
 				if (mConnection.isAuthenticated()) {
 					if (!StringUtils.parseName(mConnection.getUser()).equals(loginUserId)) {
-						mConnection.disconnect();
+						disconnect();
 					} else {
 						doLogining = false;
 						mAbstractConnectionListener.authenticated(mConnection);

+ 1 - 1
WeiChat/src/main/java/com/xzjmyk/pm/newpedo/service/StepService.java

@@ -107,7 +107,7 @@ public class StepService extends Service implements SensorEventListener {
          */
         nfIntent = new Intent(this, StepSplashActivity.class);
         builder.setContentIntent(PendingIntent.getActivity(this, 0, nfIntent, 0)) // 设置PendingIntent
-               // .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.uuu)) // 设置下拉列表中的图标(大图标)
+                .setLargeIcon(BitmapFactory.decodeResource(this.getResources(), R.drawable.uuu)) // 设置下拉列表中的图标(大图标)
                 .setContentTitle(MyApplication.getInstance().getString(R.string.uu_step_Running_in_the_background)) // 设置下拉列表里的标题
                 .setSmallIcon(R.drawable.uuu) // 设置状态栏内的小图标
                 .setContentText(MyApplication.getInstance().getString(R.string.comeon_more_sport)); // 设置上下文内容

BIN
WeiChat/src/main/res/drawable-hdpi/edit_template.png


BIN
WeiChat/src/main/res/drawable-xhdpi/edit_template.png


BIN
WeiChat/src/main/res/drawable-xxhdpi/edit_template.png


+ 2 - 2
WeiChat/src/main/res/layout/expense_details_menu.xml

@@ -10,10 +10,10 @@
         android:padding="10dp"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
-        android:text="若未获取到明细,请前往通讯录下拉获取您的部门信息"
+        android:text="@string/crm_nodatas"
         android:drawableLeft="@drawable/expense_tishi_detail"
         android:background="@color/bg_main"
-        android:visibility="visible"
+        android:visibility="gone"
         />
     <com.xzjmyk.pm.activity.ui.erp.view.CustomerScrollView
         android:layout_width="match_parent"

+ 1 - 3
WeiChat/src/main/res/layout/grid_item_simpletext.xml

@@ -9,14 +9,12 @@
         android:layout_height="wrap_content"
         android:layout_centerInParent="true"
         android:gravity="center"
-        android:singleLine="true"
-        android:ellipsize="end"
-        android:background="@drawable/shape_button_fields"
         android:textSize="13sp"
         android:minWidth="90dp"
         android:paddingBottom="8dp"
         android:paddingLeft="15dp"
         android:paddingRight="15dp"
         android:paddingTop="8dp"
+        android:background="@drawable/shape_button_fields"
         android:text="字段名字:你好" />
 </RelativeLayout>

+ 8 - 0
WeiChat/src/main/res/layout/item_approval_node.xml

@@ -29,6 +29,14 @@
             android:layout_marginRight="10dp"
             android:layout_toRightOf="@id/statusIV"/>
 
+
+        <ImageView
+            android:id="@+id/changeUser"
+            android:layout_width="22dp"
+            android:layout_height="22dp"
+            android:layout_alignParentRight="true"
+            android:visibility="gone"/>
+
         <TextView
             android:id="@+id/timeTv"
             style="@style/commonTextStyle"

+ 66 - 0
WeiChat/src/main/res/layout/item_approval_node_tag.xml

@@ -0,0 +1,66 @@
+<?xml version="1.0" encoding="utf-8"?>
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+                android:layout_width="match_parent"
+                android:layout_height="50dp">
+
+    <View
+        android:id="@+id/padding"
+        android:layout_width="match_parent"
+        android:layout_height="@dimen/paddingApp"
+        android:background="@color/item_line"/>
+
+    <View
+        android:id="@+id/line"
+        android:layout_width="2px"
+        android:layout_height="match_parent"
+        android:layout_below="@id/padding"
+        android:layout_centerHorizontal="true"
+        android:layout_margin="5dp"
+        android:layout_marginBottom="4px"
+        android:background="@color/item_line"/>
+
+
+    <TextView
+        android:id="@+id/nodeTv"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@id/padding"
+        android:layout_marginBottom="4px"
+        android:layout_toLeftOf="@id/line"
+        android:gravity="center"
+        android:text="审批节点"
+        android:textSize="@dimen/text_main"/>
+
+
+    <TextView
+        android:id="@+id/historyTV"
+        android:layout_width="match_parent"
+        android:layout_height="match_parent"
+        android:layout_below="@id/padding"
+        android:layout_marginBottom="4px"
+        android:layout_toRightOf="@id/line"
+        android:gravity="center"
+        android:text="审批历史"
+        android:textCursorDrawable="@color/yellow_home"
+        android:textSize="@dimen/text_main"/>
+
+    <View
+        android:id="@+id/nodeTag"
+        android:layout_width="match_parent"
+        android:layout_height="4px"
+        android:layout_alignParentBottom="true"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"
+        android:layout_toLeftOf="@id/line"
+        android:background="@color/darkorange"/>
+
+    <View
+        android:id="@+id/historyTag"
+        android:layout_width="match_parent"
+        android:layout_height="4px"
+        android:layout_alignParentBottom="true"
+        android:layout_marginLeft="10dp"
+        android:layout_marginRight="10dp"
+        android:layout_toRightOf="@id/line"
+        android:background="@color/darkorange"/>
+</RelativeLayout>

+ 4 - 0
WeiChat/src/main/res/layout/item_approval_tag.xml

@@ -21,7 +21,11 @@
         style="@style/approvalItemStyle"
         android:layout_width="match_parent"
         android:layout_height="wrap_content"
+        android:ellipsize="middle"
+        android:lines="1"
+        android:paddingBottom="8dp"
         android:paddingLeft="10dp"
+        android:paddingTop="8dp"
         android:text="tagTv"
         android:textColor="@color/titleBlue"/>
 </LinearLayout>

+ 8 - 10
WeiChat/src/main/res/layout/item_list_data_inquiry_menu.xml

@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="utf-8"?>
 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
-              android:layout_width="match_parent"
-              android:layout_height="wrap_content"
-              android:orientation="vertical"
-              android:padding="6dp">
+    android:layout_width="match_parent"
+    android:layout_height="wrap_content"
+    android:orientation="vertical"
+    android:padding="6dp">
 
     <LinearLayout
         android:layout_width="match_parent"
@@ -15,20 +15,18 @@
             android:id="@+id/data_inquiry_modul_view"
             android:layout_width="10dp"
             android:layout_height="20dp"
-            android:layout_marginLeft="10dp"/>
+            android:layout_marginLeft="10dp" />
 
         <TextView
             android:id="@+id/data_inquiry_modul_title_tv"
             android:layout_width="match_parent"
             android:layout_height="wrap_content"
-            android:padding="10dp"
-            />
+            android:padding="10dp" />
     </LinearLayout>
 
     <LinearLayout
         android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:padding="5dp">
+        android:layout_height="wrap_content">
 
         <com.xzjmyk.pm.activity.view.MyGridView
             android:id="@+id/data_inquiry_modul_gv"
@@ -36,7 +34,7 @@
             android:layout_height="wrap_content"
             android:gravity="center"
             android:numColumns="3"
-            android:scrollbars="none"/>
+            android:scrollbars="none" />
     </LinearLayout>
 
 </LinearLayout>

+ 150 - 0
WeiChat/src/main/res/layout/toast_demo.xml

@@ -0,0 +1,150 @@
+<?xml version="1.0" encoding="utf-8"?>
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:orientation="horizontal"
+    android:background="@color/bg_main">
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginLeft="10dp">
+
+        <Button
+            android:id="@+id/btn_a1"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="base"
+            />
+        <Button
+            android:id="@+id/btn_a2"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Top"/>
+        <Button
+            android:id="@+id/btn_a3"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Bottom"/>
+        <Button
+            android:id="@+id/btn_a4"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+        <Button
+            android:id="@+id/btn_a5"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginLeft="10dp">
+
+        <Button
+            android:id="@+id/btn_b1"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="base"
+            />
+        <Button
+            android:id="@+id/btn_b2"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Top"/>
+        <Button
+            android:id="@+id/btn_b3"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Bottom"
+            />
+        <Button
+            android:id="@+id/btn_b4"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+        <Button
+            android:id="@+id/btn_b5"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+    </LinearLayout>
+
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginLeft="10dp">
+
+        <Button
+            android:id="@+id/btn_c1"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="base"
+            />
+        <Button
+            android:id="@+id/btn_c2"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Top"/>
+        <Button
+            android:id="@+id/btn_c3"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Bottom"/>
+        <Button
+            android:id="@+id/btn_c4"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+    </LinearLayout>
+    <LinearLayout
+        android:layout_width="wrap_content"
+        android:layout_height="wrap_content"
+        android:orientation="vertical"
+        android:layout_marginLeft="10dp">
+
+        <Button
+            android:id="@+id/btn_d1"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="base"
+            />
+        <Button
+            android:id="@+id/btn_d2"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Top"/>
+        <Button
+            android:id="@+id/btn_d3"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Bottom"
+            />
+        <Button
+            android:id="@+id/btn_d4"
+            android:layout_width="80dp"
+            android:layout_height="wrap_content"
+            android:layout_marginTop="10dp"
+            android:text="Center"/>
+    </LinearLayout>
+</LinearLayout>

+ 1 - 0
WeiChat/src/main/res/menu/menu_aproval_set.xml

@@ -4,6 +4,7 @@
     <item
         android:id="@+id/oa_approval_set"
         android:title="编辑模板"
+        android:icon="@drawable/edit_template"
         app:showAsAction="always" />
 
 

+ 1 - 0
WeiChat/src/main/res/values/values.xml

@@ -32,6 +32,7 @@
 
         <item>.bmp</item>
 
+
     </array>
 
 

+ 8 - 17
app_core/common/build.gradle

@@ -2,18 +2,13 @@ apply plugin: 'com.android.library'
 
 
 android {
-    compileSdkVersion 25
-    buildToolsVersion "25.0.0"
-
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -25,10 +20,6 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
-        exclude group: 'com.android.support', module: 'support-annotations'
-    })
-
-    compile 'com.android.support:appcompat-v7:25.3.1'
-    testCompile 'junit:junit:4.12'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 0 - 25
app_core/common/proguard-rules.pro

@@ -1,25 +0,0 @@
-# Add project specific ProGuard rules here.
-# By default, the flags in this file are appended to flags specified
-# in C:\Android\sdk/tools/proguard/proguard-android.txt
-# You can edit the include path and order by changing the proguardFiles
-# directive in build.gradle.
-#
-# For more details, see
-#   http://developer.android.com/guide/developing/tools/proguard.html
-
-# Add any project specific keep options here:
-
-# If your project uses WebView with JS, uncomment the following
-# and specify the fully qualified class name to the JavaScript interface
-# class:
-#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
-#   public *;
-#}
-
-# Uncomment this to preserve the line number information for
-# debugging stack traces.
-#-keepattributes SourceFile,LineNumberTable
-
-# If you keep the line number information, uncomment this to
-# hide the original source file name.
-#-renamesourcefileattribute SourceFile

+ 0 - 26
app_core/common/src/androidTest/java/base/android/com/commom/ExampleInstrumentedTest.java

@@ -1,26 +0,0 @@
-package base.android.com.commom;
-
-import android.content.Context;
-import android.support.test.InstrumentationRegistry;
-import android.support.test.runner.AndroidJUnit4;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-import static org.junit.Assert.*;
-
-/**
- * Instrumentation test, which will execute on an Android device.
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-@RunWith(AndroidJUnit4.class)
-public class ExampleInstrumentedTest {
-    @Test
-    public void useAppContext() throws Exception {
-        // Context of the app under test.
-        Context appContext = InstrumentationRegistry.getTargetContext();
-
-        assertEquals("base.android.com.commom.test", appContext.getPackageName());
-    }
-}

+ 1 - 1
app_core/common/src/main/AndroidManifest.xml

@@ -1,2 +1,2 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="base.android.com.commom" />
+    package="base.android.com.commom" />

+ 0 - 3
app_core/common/src/main/res/values/strings.xml

@@ -1,3 +0,0 @@
-<resources>
-    <string name="app_name">commom</string>
-</resources>

+ 0 - 17
app_core/common/src/test/java/base/android/com/commom/ExampleUnitTest.java

@@ -1,17 +0,0 @@
-package base.android.com.commom;
-
-import org.junit.Test;
-
-import static org.junit.Assert.*;
-
-/**
- * Example local unit test, which will execute on the development machine (host).
- *
- * @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
- */
-public class ExampleUnitTest {
-    @Test
-    public void addition_isCorrect() throws Exception {
-        assertEquals(4, 2 + 2);
-    }
-}

+ 11 - 17
app_core/imageload/build.gradle

@@ -1,19 +1,13 @@
 apply plugin: 'com.android.library'
 
-
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -25,10 +19,10 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
-        exclude group: 'com.android.support', module: 'support-annotations'
-    })
+    testCompile deps.junit
+    compile deps.appcompatV7
+
 
-    compile 'com.android.support:appcompat-v7:24.2.1'
-    testCompile 'junit:junit:4.12'
+    compile deps.glide
+    
 }

+ 9 - 1
app_core/imageload/src/main/AndroidManifest.xml

@@ -1,2 +1,10 @@
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="base.android.com.imageload" />
+    package="base.android.com.imageload" >
+
+    <application android:allowBackup="true" android:label="@string/app_name"
+        android:supportsRtl="true">
+
+    </application>
+
+
+</manifest>

+ 37 - 0
app_core/imageload/src/main/java/com/library/imageloader/BaseImageLoaderStrategy.java

@@ -0,0 +1,37 @@
+package com.library.imageloader;
+
+import android.content.Context;
+import android.widget.ImageView;
+
+import com.library.imageloader.listener.ImageSaveListener;
+import com.library.imageloader.listener.ProgressLoadListener;
+import com.library.imageloader.listener.SourceReadyListener;
+
+
+/**
+ * Created by Arison on 2017/5/22.
+ */
+public interface BaseImageLoaderStrategy {
+
+    void loadImage(String url, ImageView imageView);
+    void loadImageWithAppCxt(String url, ImageView imageView); //这里的context指定为ApplicationContext
+    void loadImage(String url, int placeholder, ImageView imageView);
+    void loadImage(Context context, String url, int placeholder, ImageView imageView);
+
+    void loadCircleImage(String url, int placeholder, ImageView imageView);
+    void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor);
+    void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor, int heightPx, int widthPx);
+
+    void loadGifImage(String url, int placeholder, ImageView imageView);
+
+    void loadImageWithProgress(String url, ImageView imageView, ProgressLoadListener listener);
+    void loadImageWithPrepareCall(String url, ImageView imageView, int placeholder, SourceReadyListener listener);
+    void loadGifWithPrepareCall(String url, ImageView imageView, SourceReadyListener listener);
+
+    void clearImageDiskCache(final Context context);//清除硬盘缓存
+    void clearImageMemoryCache(Context context);   //清除内存缓存
+    void trimMemory(Context context, int level);    //根据不同的内存状态,来响应不同的内存释放策略
+    String getCacheSize(Context context); //获取缓存大小
+
+    void saveImage(Context context, String url, String savePath, String saveFileName, ImageSaveListener listener);//保存图像
+}

+ 137 - 0
app_core/imageload/src/main/java/com/library/imageloader/ImageLoaderUtil.java

@@ -0,0 +1,137 @@
+
+package com.library.imageloader;
+
+import android.content.Context;
+import android.widget.ImageView;
+
+import com.library.imageloader.iml.GlideImageLoaderStrategy;
+import com.library.imageloader.listener.ImageSaveListener;
+import com.library.imageloader.listener.ProgressLoadListener;
+import com.library.imageloader.listener.SourceReadyListener;
+
+
+public class ImageLoaderUtil{
+
+
+    private static ImageLoaderUtil mInstance;
+    private BaseImageLoaderStrategy mStrategy;
+
+    public ImageLoaderUtil() {
+        mStrategy = new GlideImageLoaderStrategy();
+    }
+
+    //单例模式,节省资源
+    public static ImageLoaderUtil getInstance() {
+        if (mInstance == null) {
+            synchronized (ImageLoaderUtil.class) {
+                if (mInstance == null) {
+                    mInstance = new ImageLoaderUtil();
+                    return mInstance;
+                }
+            }
+        }
+        return mInstance;
+    }
+
+
+    public void loadImage(String url, int placeholder, ImageView imageView) {
+        mStrategy.loadImage(imageView.getContext(), url, placeholder, imageView);
+    }
+
+    public void loadGifImage(String url, int placeholder, ImageView imageView) {
+        mStrategy.loadGifImage(url, placeholder, imageView);
+    }
+
+    public void loadCircleImage(String url, int placeholder, ImageView imageView) {
+        mStrategy.loadCircleImage(url,placeholder,imageView);
+    }
+
+    public void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor) {
+        mStrategy.loadCircleBorderImage(url, placeholder, imageView, borderWidth, borderColor);
+    }
+
+    public void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor, int heightPX,int widthPX) {
+        mStrategy.loadCircleBorderImage(url, placeholder, imageView, borderWidth, borderColor, heightPX,widthPX);
+    }
+
+    public void loadImage(String url, ImageView imageView) {
+        mStrategy.loadImage(url, imageView);
+    }
+
+    public void loadImageWithAppCxt(String url, ImageView imageView) {
+        mStrategy.loadImageWithAppCxt(url,imageView);
+    }
+
+    public void loadImageWithProgress(String url, ImageView imageView, ProgressLoadListener listener) {
+        mStrategy.loadImageWithProgress(url,imageView,listener);
+    }
+
+    public void loadGifWithPrepareCall(String url, ImageView imageView, SourceReadyListener listener) {
+        mStrategy.loadGifWithPrepareCall(url,imageView,listener);
+    }
+
+    public void loadImageWithPrepareCall(String url, ImageView imageView,int placeholder, SourceReadyListener listener) {
+        mStrategy.loadImageWithPrepareCall(url, imageView, placeholder, listener);
+    }
+
+    /**
+     * 策略模式的注入操作
+     *
+     * @param strategy
+     */
+    public void setLoadImgStrategy(BaseImageLoaderStrategy strategy) {
+        mStrategy = strategy;
+    }
+
+    /**
+     * 需要展示图片加载进度的请参考 GalleryAdapter
+     * 样例如下所示
+     */
+
+    /**
+     * 清除图片磁盘缓存
+     */
+    public void clearImageDiskCache(final Context context) {
+        mStrategy.clearImageDiskCache(context);
+    }
+
+    /**
+     * 清除图片内存缓存
+     */
+    public void clearImageMemoryCache(Context context) {
+        mStrategy.clearImageMemoryCache(context);
+    }
+
+    /**
+     * 根据不同的内存状态,来响应不同的内存释放策略
+     *
+     * @param context
+     * @param level
+     */
+    public void trimMemory(Context context, int level) {
+        mStrategy.trimMemory(context, level);
+    }
+
+    /**
+     * 清除图片所有缓存
+     */
+    public void clearImageAllCache(Context context) {
+        clearImageDiskCache(context.getApplicationContext());
+        clearImageMemoryCache(context.getApplicationContext());
+    }
+
+    /**
+     * 获取缓存大小
+     *
+     * @return CacheSize
+     */
+    public String getCacheSize(Context context) {
+        return mStrategy.getCacheSize(context);
+    }
+
+    public void saveImage(Context context, String url, String savePath, String saveFileName, ImageSaveListener listener) {
+        mStrategy.saveImage(context, url, savePath, saveFileName, listener);
+    }
+
+
+}

+ 300 - 0
app_core/imageload/src/main/java/com/library/imageloader/iml/GlideImageLoaderStrategy.java

@@ -0,0 +1,300 @@
+package com.library.imageloader.iml;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Looper;
+import android.text.TextUtils;
+import android.widget.ImageView;
+
+import com.bumptech.glide.Glide;
+import com.bumptech.glide.load.engine.DiskCacheStrategy;
+import com.bumptech.glide.load.resource.drawable.GlideDrawable;
+import com.bumptech.glide.load.resource.gif.GifDrawable;
+import com.bumptech.glide.request.RequestListener;
+import com.bumptech.glide.request.target.Target;
+import com.library.imageloader.BaseImageLoaderStrategy;
+import com.library.imageloader.listener.ImageSaveListener;
+import com.library.imageloader.listener.ProgressLoadListener;
+import com.library.imageloader.listener.SourceReadyListener;
+import com.library.imageloader.transformation.GlideCircleTransform;
+import com.library.imageloader.utils.FileUtils;
+import com.library.imageloader.utils.ImageUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.concurrent.ExecutionException;
+/**
+ * Created by Arison on 2017/5/22.
+ * 用GlideImageLoader加载图片
+ */
+public class GlideImageLoaderStrategy implements BaseImageLoaderStrategy {
+    @Override
+    public void loadImage(String url, ImageView imageView) {
+        Glide.with(imageView.getContext()).load(url)
+                .placeholder(imageView.getDrawable())
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .into(imageView);
+    }
+
+    @Override
+    public void loadImageWithAppCxt(String url, ImageView imageView) {
+        Glide.with(imageView.getContext().getApplicationContext()).load(url)
+                .placeholder(imageView.getDrawable())
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .into(imageView);
+    }
+
+    @Override
+    public void loadImage(String url, int placeholder, ImageView imageView) {
+        loadNormal(imageView.getContext(), url, placeholder, imageView);
+    }
+
+    @Override
+    public void loadImage(Context context, String url, int placeholder, ImageView imageView) {
+        loadNormal(context, url, placeholder, imageView);
+    }
+
+    @Override
+    public void loadCircleImage(String url, int placeholder, ImageView imageView) {
+        Glide.with(imageView.getContext())
+                .load(url)
+                .placeholder(placeholder).dontAnimate()
+                .transform(new GlideCircleTransform(imageView.getContext()))
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .into(imageView);
+    }
+
+    @Override
+    public void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor) {
+        Glide.with(imageView.getContext())
+                .load(url)
+                .placeholder(placeholder)
+                .dontAnimate()
+                .transform(new GlideCircleTransform(imageView.getContext(), borderWidth, borderColor))
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .into(imageView);
+    }
+
+    @Override
+    public void loadCircleBorderImage(String url, int placeholder, ImageView imageView, float borderWidth, int borderColor, int heightPx, int widthPx) {
+        Glide.with(imageView.getContext())
+                .load(url)
+                .placeholder(placeholder)
+                .dontAnimate()
+                .transform(new GlideCircleTransform(imageView.getContext(), borderWidth, borderColor, heightPx, widthPx))
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .into(imageView);
+    }
+
+    @Override
+    public void loadGifImage(String url, int placeholder, ImageView imageView) {
+        loadGif(imageView.getContext(), url, placeholder, imageView);
+    }
+
+    /**
+      * @desc:图片加载进度 暂未实现
+      * @author:Arison on 2017/5/23
+      */
+    @Override
+    public void loadImageWithProgress(String url, ImageView imageView, ProgressLoadListener listener) {
+
+    }
+
+    @Override
+    public void loadImageWithPrepareCall(String url, ImageView imageView, int placeholder, final SourceReadyListener listener) {
+        Glide.with(imageView.getContext()).load(url)
+                .skipMemoryCache(true)
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .placeholder(placeholder)
+                .listener(new RequestListener<String, GlideDrawable>() {
+                    @Override
+                    public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
+                        listener.onResourceReady(resource.getIntrinsicWidth(), resource.getIntrinsicHeight());
+                        return false;
+                    }
+                }).into(imageView);
+    }
+
+    @Override
+    public void loadGifWithPrepareCall(String url, ImageView imageView, final SourceReadyListener listener) {
+        Glide.with(imageView.getContext()).load(url).asGif()
+                .skipMemoryCache(true)
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE).
+                listener(new RequestListener<String, GifDrawable>() {
+                    @Override
+                    public boolean onException(Exception e, String model, Target<GifDrawable> target, boolean isFirstResource) {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean onResourceReady(GifDrawable resource, String model, Target<GifDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
+                        listener.onResourceReady(resource.getIntrinsicWidth(), resource.getIntrinsicHeight());
+                        return false;
+                    }
+                }).into(imageView);
+    }
+
+    @Override
+    public void clearImageDiskCache(final Context context) {
+        try {
+            if (Looper.myLooper() == Looper.getMainLooper()) {
+                new Thread(new Runnable() {
+                    @Override
+                    public void run() {
+                        Glide.get(context.getApplicationContext()).clearDiskCache();
+                    }
+                }).start();
+            } else {
+                Glide.get(context.getApplicationContext()).clearDiskCache();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void clearImageMemoryCache(Context context) {
+        try {
+            if (Looper.myLooper() == Looper.getMainLooper()) {
+                //只能在主线程,即UI线程执行
+                Glide.get(context.getApplicationContext()).clearMemory();
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+
+    @Override
+    public void trimMemory(Context context, int level) {
+        Glide.get(context).trimMemory(level);
+    }
+
+    /**
+     * @desc:获取缓存文件的大小
+     * @author:Arison on 2017/5/23
+     */
+    @Override
+    public String getCacheSize(Context context) {
+        try {
+            return FileUtils.getFormatSize(FileUtils.getFolderSize(Glide.getPhotoCacheDir(context.getApplicationContext())));
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return null;
+    }
+
+    @Override
+    public void saveImage(Context context, String url, String savePath, String saveFileName, ImageSaveListener listener) {
+        if (!FileUtils.isSDCardExsit() || TextUtils.isEmpty(url)) {
+            listener.onSaveFail();
+            return;
+        }
+        InputStream fromStream=null;
+        OutputStream toStream=null;
+        try {
+            File cacheFile=Glide.with(context).load(url).downloadOnly(Target.SIZE_ORIGINAL,Target.SIZE_ORIGINAL).get();
+            if (cacheFile == null || !cacheFile.exists()) {
+                listener.onSaveFail();
+                return;
+            }
+
+            File dir = new File(savePath);
+            if (!dir.exists()) {
+                dir.mkdir();
+            }
+
+            File file = new File(dir, saveFileName + ImageUtils.getPicType(cacheFile.getAbsolutePath()));
+            fromStream = new FileInputStream(cacheFile);
+            toStream = new FileOutputStream(file);
+            byte length[] = new byte[1024];
+            int count;
+            while ((count = fromStream.read(length)) > 0) {
+                toStream.write(length, 0, count);
+            }
+            //用广播通知相册进行更新相册
+            Intent intent = new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE);
+            Uri uri = Uri.fromFile(file);
+            intent.setData(uri);
+            context.sendBroadcast(intent);
+            listener.onSaveSuccess();
+
+        } catch (InterruptedException e) {
+            e.printStackTrace();
+            listener.onSaveFail();
+        } catch (ExecutionException e) {
+            e.printStackTrace();
+            listener.onSaveFail();
+        } catch (Exception e){
+            e.printStackTrace();
+            listener.onSaveFail();
+        }finally {
+            if (fromStream != null) {
+                try {
+                    fromStream.close();
+                    toStream.close();
+                } catch (IOException e) {
+                    e.printStackTrace();
+                    fromStream = null;
+                    toStream = null;
+                }
+            }
+        }
+
+    }
+
+
+    /**
+     * load image with Glide
+     */
+    private void loadNormal(final Context ctx, final String url, int placeholder, ImageView imageView) {
+        Glide.with(ctx)
+                .load(url)
+                .placeholder(placeholder)
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .listener(new RequestListener<String, GlideDrawable>() {
+                    @Override
+                    public boolean onException(Exception e, String model, Target<GlideDrawable> target, boolean isFirstResource) {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean onResourceReady(GlideDrawable resource, String model, Target<GlideDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
+                        return false;
+                    }
+                })
+                .into(imageView);
+    }
+
+
+    /**
+     * load image with Glide
+     */
+    private void loadGif(final Context ctx, String url, int placeholder, ImageView imageView) {
+        Glide.with(ctx).load(url)
+                .asGif()
+                .placeholder(placeholder)
+                .skipMemoryCache(true)//禁止内存缓存:
+                .diskCacheStrategy(DiskCacheStrategy.SOURCE)
+                .listener(new RequestListener<String, GifDrawable>() {
+                    @Override
+                    public boolean onException(Exception e, String model, Target<GifDrawable> target, boolean isFirstResource) {
+                        return false;
+                    }
+
+                    @Override
+                    public boolean onResourceReady(GifDrawable resource, String model, Target<GifDrawable> target, boolean isFromMemoryCache, boolean isFirstResource) {
+                        return false;
+                    }
+                }).into(imageView);
+    }
+}

+ 11 - 0
app_core/imageload/src/main/java/com/library/imageloader/listener/ImageSaveListener.java

@@ -0,0 +1,11 @@
+package com.library.imageloader.listener;
+
+/**
+ * Created by Arison on 2017/5/22.
+ * 图片保存监听器
+ */
+public interface ImageSaveListener {
+    void onSaveSuccess();
+
+    void onSaveFail();
+}

+ 14 - 0
app_core/imageload/src/main/java/com/library/imageloader/listener/ProgressLoadListener.java

@@ -0,0 +1,14 @@
+package com.library.imageloader.listener;
+
+/**
+ * Created by Arison on 2017/5/22.
+ * 图片加载进度
+ */
+public interface ProgressLoadListener {
+
+    void update(int bytesRead, int contentLength);
+
+    void onException();
+
+    void onResourceReady();
+}

+ 10 - 0
app_core/imageload/src/main/java/com/library/imageloader/listener/SourceReadyListener.java

@@ -0,0 +1,10 @@
+package com.library.imageloader.listener;
+
+/**
+ * 图片加载前
+ * 通知准备就绪
+ */
+public interface SourceReadyListener {
+
+    void onResourceReady(int width, int height);
+}

+ 164 - 0
app_core/imageload/src/main/java/com/library/imageloader/transformation/GlideCircleTransform.java

@@ -0,0 +1,164 @@
+package com.library.imageloader.transformation;
+
+import android.content.Context;
+import android.content.res.Resources;
+import android.graphics.Bitmap;
+import android.graphics.BitmapShader;
+import android.graphics.Canvas;
+import android.graphics.Paint;
+import android.graphics.PorterDuff;
+import android.graphics.PorterDuffXfermode;
+import android.graphics.Rect;
+import android.graphics.RectF;
+
+import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
+import com.bumptech.glide.load.resource.bitmap.BitmapTransformation;
+import com.library.imageloader.utils.ScreenUtils;
+
+/**
+ * @desc:自定义BitmapTransformation来实现圆形图片加载
+ * @author:Arison on 2017/5/23
+ */
+public class GlideCircleTransform extends BitmapTransformation {
+
+    private Paint mBorderPaint;
+    private float mBorderWidth;
+
+    private int height = 0;
+    private int width = 0;
+    private int borderColor = 0;
+
+    public GlideCircleTransform(Context context) {
+        super(context);
+    }
+
+    public GlideCircleTransform(Context context, float borderWidth, int borderColor) {
+        super(context);
+        mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
+        mBorderWidth = ScreenUtils.dip2px( borderWidth);
+        mBorderPaint = new Paint();
+        mBorderPaint.setDither(true);
+        mBorderPaint.setAntiAlias(true);
+        mBorderPaint.setColor(borderColor);
+        mBorderPaint.setStyle(Paint.Style.STROKE);
+        mBorderPaint.setStrokeWidth(mBorderWidth);
+    }
+
+    public GlideCircleTransform(Context context, float borderWidth, int borderColor, int heightPX, int widthPx) {
+        super(context);
+        mBorderWidth = Resources.getSystem().getDisplayMetrics().density * borderWidth;
+        mBorderWidth = ScreenUtils.dip2px(borderWidth);
+        mBorderPaint = new Paint();
+        mBorderPaint.setDither(true);
+        mBorderPaint.setAntiAlias(true);
+        mBorderPaint.setColor(borderColor);
+        mBorderPaint.setStyle(Paint.Style.STROKE);
+        mBorderPaint.setStrokeWidth(mBorderWidth);
+        width = widthPx;
+        height = heightPX;
+        this.borderColor = borderColor;
+    }
+
+
+    protected Bitmap transform(BitmapPool pool, Bitmap toTransform, int outWidth, int outHeight) {
+        if (width > 0) {
+            return circleCrop(pool, toTransform, outWidth, outHeight);
+        } else {
+            return circleCrop(pool, toTransform);
+        }
+    }
+
+    private Bitmap circleCrop(BitmapPool pool, Bitmap source) {
+        if (source == null) return null;
+
+        int size = (int) (Math.min(source.getWidth(), source.getHeight()) - (mBorderWidth / 2));
+        int x = (source.getWidth() - size) / 2;
+        int y = (source.getHeight() - size) / 2;
+        // TODO this could be acquired from the pool too
+        Bitmap squared = Bitmap.createBitmap(source, x, y, size, size);
+        Bitmap result = pool.get(size, size, Bitmap.Config.ARGB_8888);
+        if (result == null) {
+            result = Bitmap.createBitmap(size, size, Bitmap.Config.ARGB_8888);
+        }
+        Canvas canvas = new Canvas(result);
+        Paint paint = new Paint();
+        paint.setShader(new BitmapShader(squared, BitmapShader.TileMode.CLAMP, BitmapShader.TileMode.CLAMP));
+        paint.setAntiAlias(true);
+        float r = size / 2f;
+        canvas.drawCircle(r, r, r, paint);
+        if (mBorderPaint != null) {
+            float borderRadius = r - mBorderWidth / 2;
+            canvas.drawCircle(r, r, borderRadius, mBorderPaint);
+        }
+        return result;
+    }
+
+    private Bitmap circleCrop(BitmapPool pool, Bitmap source, int outWidth, int outHeight) {
+        if (source == null) return null;
+        Bitmap result = pool.get(width, width, Bitmap.Config.ARGB_8888);
+        Bitmap output = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(output);
+        Paint paint = new Paint();
+        paint.setColor(borderColor);
+        paint.setAntiAlias(true);
+        Rect rect = new Rect(0, 0, width, width);
+        RectF rectF = new RectF(rect);
+        canvas.drawRoundRect(rectF, width, width, paint);
+        output = makeRoundCorner(output, width, borderColor);
+        result = makeRoundCorner(source, (int) (width - 2 * mBorderWidth), 0);
+        result = getAvatarInRoundBg(output, result);
+        return result;
+    }
+
+    //把头像保存成圆形图片
+    public Bitmap makeRoundCorner(Bitmap bitmap, int px, int borderColor) {
+        Bitmap output = Bitmap.createBitmap(px, px, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(output);
+        int color = 0xffffffff;
+        if (borderColor != 0) {
+            color = borderColor;
+        }
+        Paint paint = new Paint();
+        Rect rect = new Rect(0, 0, px, px);
+        RectF rectF = new RectF(rect);
+        paint.setAntiAlias(true);
+        canvas.drawARGB(0, 0, 0, 0);
+        paint.setColor(color);
+        canvas.drawRoundRect(rectF, px, px, paint);
+        paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN));
+
+//        if(bitmap.getWidth()/2-67>0 && bitmap.getHeight()/2-67>0) {
+        bitmap = Bitmap.createScaledBitmap(bitmap, px, px, true);
+//        }
+
+        canvas.drawBitmap(bitmap, rect, rect, paint);
+        return output;
+    }
+
+    //加上圆形背景环
+    private Bitmap getAvatarInRoundBg(Bitmap bg, Bitmap avatar) {
+        // 生成画布图像
+        Bitmap resultBitmap = Bitmap.createBitmap(width,
+                width, Bitmap.Config.ARGB_8888);
+        Canvas canvas = new Canvas(resultBitmap);// 使用空白图片生成canvas
+
+        // 将bmp1绘制在画布上
+        bg = Bitmap.createScaledBitmap(bg, width, width, true);
+        Rect srcRect = new Rect(0, 0, width, width);// 截取bmp1中的矩形区域
+        Rect dstRect = new Rect(0, 0, width, width);// bmp1在目标画布中的位置
+        canvas.drawBitmap(bg, srcRect, dstRect, null);
+
+        avatar = Bitmap.createScaledBitmap(avatar, (int) (width - 2 * mBorderWidth), (int) (width - 2 * mBorderWidth), true);
+        // 将bmp2绘制在画布上
+        srcRect = new Rect(0, 0, (int) (width - 2 * mBorderWidth), (int) (width - 2 * mBorderWidth));// 截取bmp1中的矩形区域
+        dstRect = new Rect((int) mBorderWidth, (int) mBorderWidth, (int) (width - mBorderWidth), (int) (width - mBorderWidth));// bmp2在目标画布中的位置
+        canvas.drawBitmap(avatar, srcRect, dstRect, null);
+        // 将bmp1,bmp2合并显示
+        return resultBitmap;
+    }
+
+    @Override
+    public String getId() {
+        return getClass().getName();
+    }
+}

+ 90 - 0
app_core/imageload/src/main/java/com/library/imageloader/utils/FileUtils.java

@@ -0,0 +1,90 @@
+package com.library.imageloader.utils;
+
+import android.os.Environment;
+
+import java.io.File;
+import java.math.BigDecimal;
+
+/**
+ * 文件操作
+ * 
+ * Created by Arison on 2017/5/17.
+ */
+public class FileUtils {
+
+    /**
+     * 获取SD卡的根目录
+     *
+     * @return
+     */
+    public static String getSDRoot() {
+        return Environment.getExternalStorageDirectory().getAbsolutePath();
+    }
+
+    public static boolean isSDCardExsit() {
+        String state = Environment.getExternalStorageState();
+        if (Environment.MEDIA_MOUNTED.equals(state)) {
+            return true;
+        }
+        return false;
+    }
+
+    /**
+     * 获取指定文件夹内所有文件大小的和
+     *
+     * @param file file
+     * @return size
+     * @throws Exception
+     */
+    public static long getFolderSize(File file) throws Exception {
+        long size = 0;
+        try {
+            File[] fileList = file.listFiles();
+            for (File aFileList : fileList) {
+                if (aFileList.isDirectory()) {
+                    size = size + getFolderSize(aFileList);
+                } else {
+                    size = size + aFileList.length();
+                }
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        return size;
+    }
+
+    /**
+     * 格式化单位
+     *
+     * @param size size
+     * @return size
+     */
+    public static String getFormatSize(double size) {
+        
+        double kiloByte = size / 1024;
+        if (kiloByte < 1) {
+            return size + "Byte";
+        }
+
+        double megaByte = kiloByte / 1024;
+        if (megaByte < 1) {
+            BigDecimal result1 = new BigDecimal(Double.toString(kiloByte));
+            return result1.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "KB";
+        }
+
+        double gigaByte = megaByte / 1024;
+        if (gigaByte < 1) {
+            BigDecimal result2 = new BigDecimal(Double.toString(megaByte));
+            return result2.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "MB";
+        }
+
+        double teraBytes = gigaByte / 1024;
+        if (teraBytes < 1) {
+            BigDecimal result3 = new BigDecimal(Double.toString(gigaByte));
+            return result3.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "GB";
+        }
+        BigDecimal result4 = new BigDecimal(teraBytes);
+
+        return result4.setScale(2, BigDecimal.ROUND_HALF_UP).toPlainString() + "TB";
+    }
+}

+ 32 - 0
app_core/imageload/src/main/java/com/library/imageloader/utils/ImageUtils.java

@@ -0,0 +1,32 @@
+package com.library.imageloader.utils;
+
+import android.graphics.BitmapFactory;
+import android.text.TextUtils;
+
+/**
+ * 图像处理工具类
+ * 
+ * Created by Arison on 2017/5/23.
+ */
+public class ImageUtils {
+
+    
+    
+    public static String getPicType(String pathName) {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inJustDecodeBounds = true;
+        BitmapFactory.decodeFile(pathName, options);
+        String type = options.outMimeType;
+        if (!TextUtils.isEmpty(type)) {
+            try {
+                type = type.substring(6, type.length());
+                if ("gif".equals(type)) {
+                    return ".gif";
+                }
+            } catch (IndexOutOfBoundsException e) {
+                e.printStackTrace();
+            }
+        }
+        return ".jpg";
+    }
+}

+ 96 - 0
app_core/imageload/src/main/java/com/library/imageloader/utils/ScreenUtils.java

@@ -0,0 +1,96 @@
+package com.library.imageloader.utils;
+
+import android.app.Activity;
+import android.content.Context;
+import android.content.res.TypedArray;
+import android.util.DisplayMetrics;
+
+import java.lang.reflect.Field;
+
+/**
+ * 屏幕相关工具类
+ * 
+ * Created by Arison on 2017/5/23.
+ */
+public class ScreenUtils {
+
+    public static int dip2px( float dpValue) {
+        final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
+        return (int) (dpValue * scale + 0.5f);
+    }
+
+
+    public static int px2dip( float pxValue) {
+        final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public static int px2sp( float pxValue) {
+        final float scale = Utils.getContext().getResources().getDisplayMetrics().density;
+        return (int) (pxValue / scale + 0.5f);
+    }
+
+    public static int sp2px(float spValue) {
+        final float scale =Utils.getContext().getResources().getDisplayMetrics().density;
+        return (int) (spValue * scale + 0.5f);
+    }
+
+    public static int getScreenWidth(Context context) {
+        DisplayMetrics localDisplayMetrics = new DisplayMetrics();
+        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);
+        return localDisplayMetrics.widthPixels;
+    }
+
+    public static int getScreenHeight(Context context) {
+        DisplayMetrics localDisplayMetrics = new DisplayMetrics();
+        ((Activity) context).getWindowManager().getDefaultDisplay().getMetrics(localDisplayMetrics);
+        return localDisplayMetrics.heightPixels - getStatusBarHeight(context);
+    }
+
+
+    /**
+     * @deprecated  use {@link #getScreenHeight(Context)} instead
+     * get screen size height in pixels
+     *
+     * @param context
+     * @return the pixels of the screen height
+     */
+    public static int getHeight(Activity context) {
+        DisplayMetrics dm = new DisplayMetrics();
+        context.getWindowManager().getDefaultDisplay().getMetrics(dm);
+        return dm.heightPixels;
+    }
+
+    public static int getStatusBarHeight(Context context){
+        Class<?> c = null;
+        Object obj = null;
+        Field field = null;
+        int x = 0, statusBarHeight = 0;
+        try {
+            c = Class.forName("com.android.internal.R$dimen");
+            obj = c.newInstance();
+            field = c.getField("status_bar_height");
+            x = Integer.parseInt(field.get(obj).toString());
+            statusBarHeight = context.getResources().getDimensionPixelSize(x);
+        } catch (Exception e1) {
+            e1.printStackTrace();
+        }
+        return statusBarHeight;
+    }
+
+
+    /**
+     * get toolbar height
+     *
+     * @param context
+     * @return
+     */
+    public static int getToolbarHeight(Context context) {
+        final TypedArray styledAttributes = context.getTheme().obtainStyledAttributes(
+                new int[]{android.R.attr.actionBarSize});
+        int toolbarHeight = (int) styledAttributes.getDimension(0, 0);
+        styledAttributes.recycle();
+
+        return toolbarHeight;
+    }
+}

+ 36 - 0
app_core/imageload/src/main/java/com/library/imageloader/utils/Utils.java

@@ -0,0 +1,36 @@
+package com.library.imageloader.utils;
+
+import android.annotation.SuppressLint;
+import android.content.Context;
+
+/**
+ * 需要注意Context对象为空的情况
+ * Created by Arison on 2017/5/24.
+ */
+public class Utils {
+    @SuppressLint("StaticFieldLeak")
+    private static Context context;
+
+    private Utils() {
+        throw new UnsupportedOperationException("u can't instantiate me...");
+    }
+
+    /**
+     * 初始化工具类
+     *
+     * @param context 上下文
+     */
+    public static void init(Context context) {
+        Utils.context = context.getApplicationContext();
+    }
+
+    /**
+     * 获取ApplicationContext
+     *
+     * @return ApplicationContext
+     */
+    public static Context getContext() {
+        if (context != null) return context;
+        throw new NullPointerException("u should init first");
+    }
+}

+ 5 - 5
app_core/message/build.gradle

@@ -2,15 +2,15 @@ apply plugin: 'com.android.library'
 
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
 
 
     defaultConfig {
         minSdkVersion 16
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
 
     }
     buildTypes {

+ 18 - 11
app_core/network/build.gradle

@@ -2,18 +2,13 @@ apply plugin: 'com.android.library'
 
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -28,7 +23,19 @@ dependencies {
     androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
         exclude group: 'com.android.support', module: 'support-annotations'
     })
+    compile fileTree(dir: 'libs', include: ['*.jar'])
+    testCompile deps.junit
+    compile deps.appcompatV7
 
     compile 'com.android.support:appcompat-v7:24.2.1'
     testCompile 'junit:junit:4.12'
+    compile deps.rxjava
+    compile deps.rxandroid
+    compile deps.okhttp
+    compile deps.retrofit
+    compile deps.converterGson
+    compile deps.adapterRxjava
+    compile deps.fastjson
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 185 - 0
app_core/network/src/main/java/network/app/base/BaseActivity.java

@@ -0,0 +1,185 @@
+package network.app.base;
+
+import android.os.Build;
+import android.os.Bundle;
+import android.support.v7.app.AppCompatActivity;
+import android.view.View;
+import android.view.Window;
+import android.view.WindowManager;
+
+/**
+ * 一般标准的activity基类封装
+ * 1:沉浸栏设置问题
+ * 2:
+ * Created by Arison on 2017/5/3.
+ */
+public abstract class BaseActivity extends AppCompatActivity implements View.OnClickListener{
+   
+    /*设置是否沉浸栏*/
+    private boolean isSetStatusBar = false;
+    /*设置是否全屏显示*/
+    private boolean isFullScreen = false;
+    /*设置是否禁止旋转屏幕*/
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        if (isSetStatusBar){
+            setStatusBar();
+        }
+        if (isFullScreen){
+            setAllowFullScreen(isFullScreen);
+        }
+        setContentView(getLayoutId());
+        initView();
+        setListener();
+        initData();
+    }
+
+    /**
+     * [沉浸状态栏]
+     */
+    private void setStatusBar() {
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.KITKAT) {
+            // 透明状态栏
+            getWindow().addFlags(
+                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_STATUS);
+            // 透明导航栏
+            getWindow().addFlags(
+                    WindowManager.LayoutParams.FLAG_TRANSLUCENT_NAVIGATION);
+        }
+    }
+
+    /**
+     * [是否允许全屏]
+     *
+     * @param allowFullScreen
+     */
+    protected void setAllowFullScreen(boolean allowFullScreen) {
+        if (allowFullScreen) {
+            requestWindowFeature(Window.FEATURE_NO_TITLE);
+            getWindow().setFlags(
+                    WindowManager.LayoutParams.FLAG_FULLSCREEN,
+                    WindowManager.LayoutParams.FLAG_FULLSCREEN
+            );
+        }
+    }
+
+    /**
+     * 获取状态栏高度
+     * @return
+     */
+/*    protected int getStatusBarHeight() {
+        int result = 0;
+        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
+        if (resourceId > 0) {
+            result = getResources().getDimensionPixelSize(resourceId);
+        }
+        return result;
+    }*/
+
+    /**
+     * 设置ContentView
+     * @return R.layout.xxx
+     */
+    protected abstract int getLayoutId();
+
+    /**
+     * 初始化View
+     */
+    protected abstract void initView();
+
+    /**
+     * add Listener
+     */
+    protected abstract void setListener();
+
+    /**
+     * 初始化数据
+     */
+    protected abstract void initData();
+    
+    
+    @Override
+    public void onClick(View view) {
+        
+    }
+
+
+    @Override
+    protected void onResume() {
+        super.onResume();
+    }
+
+    @Override
+    protected void onPause() {
+        super.onPause();
+    
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+    }
+
+    // findViewById
+ /*   public <T extends View> T $findViewById(int resId) {
+        return (T) findViewById(resId);
+    }*/
+
+    // Toast
+   /* protected void toast(CharSequence msg) {
+        Toast.makeText(this, msg, Toast.LENGTH_SHORT).show();
+    }*/
+
+    // Toast
+   /* protected void toast(int resId) {
+        Toast.makeText(this, resId, Toast.LENGTH_SHORT).show();
+    }*/
+
+    
+    // Log
+//    protected void $Log(String msg) {
+//        if (isDebug) {
+//            Log.d(this.getClass().getName(), msg);
+//        }
+//    }
+
+
+    // startActivity
+ /*   protected void startActivity(Class<?> cls) {
+        startActivity(cls, null);
+    }*/
+
+    // startActivity
+   /* protected void startActivity(Class<?> cls, Bundle bundle) {
+        Intent intent = new Intent(this, cls);
+        if (bundle != null) {
+            intent.putExtras(bundle);
+        }
+        startActivity(intent);
+    }*/
+
+    // startActivityForResult
+  /*  protected void startActivityForResult(Class<?> cls, int requestCode) {
+        startActivityForResult(cls, null, requestCode);
+    }*/
+
+    // startActivityForResult
+   /* protected void startActivityForResult(Class<?> cls, Bundle bundle, int requestCode) {
+        Intent intent = new Intent(this, cls);
+        if (bundle != null) {
+            intent.putExtras(bundle);
+        }
+        startActivityForResult(intent, requestCode);
+    }*/
+
+    // getIntent
+   /* protected Bundle getIntentExtra() {
+        Intent intent = getIntent();
+        Bundle bundle = null;
+        if (null != intent)
+            bundle = intent.getExtras();
+        return bundle;
+    }*/
+}

+ 57 - 0
app_core/network/src/main/java/network/app/base/BaseApplication.java

@@ -0,0 +1,57 @@
+package network.app.base;
+
+import android.app.Application;
+
+/**
+ * Created by Arison on 2017/5/15.
+ */
+public abstract class BaseApplication extends Application {
+    private static Application mApplication=null;
+    @Override
+    public void onCreate() {
+        super.onCreate();
+      
+        mApplication=this;
+        init();
+        //初始化网络库
+        initHttpClient();
+        //初始化图片库
+        initImageClient();
+        //初始化DBHelper
+        initDBHelper();
+        //初始化消息提醒库
+        initNotifyHelper();
+        //初始化日志打印
+        initLogHelper();
+      
+    }
+
+    public void initLogHelper() {
+//        Logger.init().
+//                logLevel(LogLevel.FULL)
+//                .methodCount(1);
+    }
+
+
+    public abstract void init();
+
+    public void initHttpClient() {
+
+    }
+
+    public void initImageClient() {
+
+    }
+
+    public void initDBHelper() {
+
+    }
+
+    public void initNotifyHelper() {
+
+    }
+
+    public static Application getInstance(){
+        return  mApplication;
+    }
+}

+ 52 - 0
app_core/network/src/main/java/network/app/http/HttpBase.java

@@ -0,0 +1,52 @@
+package network.app.http;
+
+
+import rx.Subscriber;
+
+public abstract class HttpBase {
+
+    public HttpClient mbuilder;
+
+    /**
+     * 设置全局builder
+     * 初始化全局参数
+     *
+     * @param client
+     */
+    public void setBuilder(HttpClient client) {
+        this.mbuilder = client;
+    }
+
+    /**
+     * 初始化具体的网络请求客户端
+     * 初始化全局参数
+     * 比如Okhttp,Retrofit,Volley,HttpClient,HttpUrlConnection
+     */
+    public abstract void initClient();
+
+
+    /**
+     * @param builder
+     * @param s       rxjava
+     */
+    public void send(HttpClient builder, Subscriber<Object> s) {
+        if (builder.getMethod() == Method.GET) {
+            get(builder, s);
+        }
+        if (builder.getMethod() == Method.POST) {
+            post(builder, s);
+        }
+    }
+
+    /**
+     * @desc:上传功能 支持多文件上传
+     * @author:Arison on 2017/5/17
+     */
+    public void uploads(HttpClient builder, Subscriber<Object> s) {
+    }
+
+    public abstract void get(HttpClient builder, Subscriber<Object> s);
+
+    public abstract void post(HttpClient builder, Subscriber<Object> s);
+
+}

+ 338 - 0
app_core/network/src/main/java/network/app/http/HttpClient.java

@@ -0,0 +1,338 @@
+package network.app.http;
+
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+import network.app.http.impl.RetrofitImpl;
+
+
+/**
+ * @author Arison
+ * @desc:使用构建者设计模式封装
+ */
+public class HttpClient {
+
+    private String baseUrl;
+    private Map<String, Object> params = new HashMap<>();// 请求参数
+    private Map<String, Object> headers = new HashMap<>();//请求头
+
+    private long retryTimeout = 5;
+    private long connectTimeout;
+    private long readTimeout;
+    private long writeTimeout;
+
+    private int method;// 方法
+    private boolean isSyn;// 是否是同步
+    private int cacheType;// 缓存类型
+    private long cacheTime;//缓存时间
+    private File cacheFile;//缓存文件路径
+    private long cacheFileSize;//缓存文件大小
+    private int maxRetryCount;// 最大重试次数
+    private boolean isDebug;// 是否开启打印日志
+    private Builder mBuilder;
+
+    private HttpBase httpBase;
+    
+
+    public HttpClient(Builder builder) {
+        super();
+        setBuilder(builder);
+    }
+
+    private void setBuilder(Builder builder) {
+        this.baseUrl = builder.baseUrl;
+        this.params = builder.params;
+        this.headers = builder.headers;
+        this.retryTimeout = builder.retryTimeout;
+        this.connectTimeout = builder.connectTimeout;
+        this.readTimeout = builder.readTimeout;
+        this.writeTimeout = builder.writeTimeout;
+        this.method = builder.method;
+        this.isSyn = builder.isSyn;
+        this.cacheType = builder.cacheType;
+        this.cacheTime = builder.cacheTime;
+        this.cacheFile = builder.cacheFile;
+        this.cacheFileSize = builder.cacheFileSize;
+        this.maxRetryCount = builder.maxRetryCount;
+        this.isDebug = builder.isDebug;
+        this.httpBase = builder.httpBase;
+    }
+
+
+    private static HttpClient instance;
+    
+    public static HttpClient getInstance(){
+        if (instance == null) {
+            synchronized (HttpClient.class) {
+                if (instance == null) {
+                     instance=newInstance(new Builder());
+                }
+            }
+        }
+        return instance;
+    }
+
+    public static HttpClient getInstance(Builder builder) {
+        if (instance == null) {
+            synchronized (HttpClient.class) {
+                if (instance == null) {
+                    instance = newInstance(builder);
+                }
+            }
+        }
+        instance.setBuilder(builder);
+        return instance;
+    }
+
+    public static HttpClient newInstance(Builder builder) {
+        instance = new HttpClient(builder);
+        return instance;
+    }
+
+
+    public Builder newBuilder() {
+        return new Builder(this);
+    }
+
+
+    public static class Builder {
+
+        private String baseUrl;
+        private Map<String, Object> params = new HashMap<>();// 请求参数
+        private Map<String, Object> headers = new HashMap<>();//
+        private long connectTimeout;
+        private long readTimeout;
+        private long writeTimeout;
+        private int method;// 方法
+        private boolean isSyn;// 是否是同步
+        private int cacheType;// 缓存类型
+        private long cacheTime;//缓存时间
+        private File cacheFile;//缓存文件路径
+        private long cacheFileSize;//缓存文件大小
+        private int maxRetryCount;// 最大重试次数
+        private long retryTimeout = 5;//重试间隔时间
+        private boolean isDebug;// 是否开启打印日志
+        private HttpBase httpBase;//具体的网络请求类
+
+        //默认的参数
+        public Builder() {   
+            this.method = Method.GET;
+        }
+
+        public Builder(String url) {
+            this.baseUrl = url;
+        }
+
+        public Builder(HttpClient httpClient) {
+            this.baseUrl = httpClient.getBaseUrl();
+            this.params = httpClient.getParams();
+            this.headers = httpClient.getHeaders();
+            this.method = httpClient.getMethod();
+            this.connectTimeout = httpClient.getConnectTimeout();
+            this.readTimeout = httpClient.getReadTimeout();
+            this.retryTimeout = httpClient.getRetryTimeout();
+            this.writeTimeout = httpClient.getWriteTimeout();
+            this.isSyn = httpClient.isSyn();
+            this.isDebug = httpClient.isDebug();
+            this.cacheType = httpClient.getCacheType();
+            this.cacheTime = httpClient.getCacheTime();
+            this.cacheFileSize = httpClient.getCacheFileSize();
+            this.cacheFile = httpClient.getCacheFile();
+            this.maxRetryCount = httpClient.getMaxRetryCount();
+            this.httpBase = httpClient.Api();
+
+        }
+
+        public Builder url(String url) {
+            this.baseUrl = url;
+            return this;
+        }
+
+        public Builder add(String key, Object value) {
+            this.params.put(key, value);
+            return this;
+        }
+
+        public Builder header(String key, Object value) {
+            this.headers.put(key, value);
+            return this;
+        }
+
+        public Builder retryTimeout(long time) {
+            this.retryTimeout = time;
+            return this;
+        }
+
+        public Builder connectTimeout(long time) {
+            this.connectTimeout = time;
+            return this;
+        }
+
+        public Builder readTimeout(long time) {
+            this.readTimeout = time;
+            return this;
+        }
+
+        public Builder writeTimeout(long time) {
+            this.writeTimeout = time;
+            return this;
+        }
+
+        public Builder cacheType(int cacheType) {
+            this.cacheType = cacheType;
+            return this;
+        }
+
+        public Builder cacheTime(long cacheTime) {
+            this.cacheTime = cacheTime;
+            return this;
+        }
+
+        public Builder cacheFile(File cacheFile) {
+            this.cacheFile = cacheFile;
+            return this;
+        }
+
+        public Builder cacheFileSize(long cacheFileSize) {
+            this.cacheFileSize = cacheFileSize;
+            return this;
+        }
+
+        public Builder maxRetryCount(int maxRetryCount) {
+            this.maxRetryCount = maxRetryCount;
+            return this;
+        }
+
+        public Builder isDebug(boolean isDebug) {
+            this.isDebug = isDebug;
+            return this;
+        }
+
+        public Builder method(int method) {
+            this.method = method;
+            return this;
+        }
+
+        public Builder syn(boolean isSyn) {
+            this.isSyn = isSyn;
+            return this;
+        }
+
+        public Builder httpBase(HttpBase hb) {
+            this.httpBase = hb;
+            return this;
+        }
+
+        public HttpClient build() {
+            HttpClient client = newInstance(this);
+            return client;
+        }
+
+        public HttpClient build(boolean isSingle) {
+            if (isSingle) {
+                return getInstance(this);
+            } else {
+                return newInstance(this);
+            }
+        }
+    }
+
+
+    public String getBaseUrl() {
+        return baseUrl;
+    }
+
+    public Map<String, Object> getParams() {
+        return params;
+    }
+
+    public Map<String, Object> getHeaders() {
+        return headers;
+    }
+
+    public int getMethod() {
+        return method;
+    }
+
+    public boolean isSyn() {
+        return isSyn;
+    }
+
+    public int getCacheType() {
+        return cacheType;
+    }
+
+    public int getMaxRetryCount() {
+        return maxRetryCount;
+    }
+
+    public boolean isDebug() {
+        return isDebug;
+    }
+
+
+    public HttpBase Api() {
+        if (httpBase!=null) {
+            httpBase.setBuilder(this);
+            httpBase.initClient();
+        }else{
+            httpBase= RetrofitImpl.getInstance();
+        }
+        return httpBase;
+    }
+
+    public Builder getmBuilder() {
+        return mBuilder;
+    }
+
+    public void setmBuilder(Builder mBuilder) {
+        setBuilder(mBuilder);
+        this.mBuilder = mBuilder;
+    }
+
+
+    public long getRetryTimeout() {
+        return retryTimeout;
+    }
+
+    public long getConnectTimeout() {
+        return connectTimeout;
+    }
+
+    public long getReadTimeout() {
+        return readTimeout;
+    }
+
+    public long getWriteTimeout() {
+        return writeTimeout;
+    }
+
+
+    public long getCacheTime() {
+        return cacheTime;
+    }
+
+    public void setCacheTime(long cacheTime) {
+        this.cacheTime = cacheTime;
+    }
+
+
+    public File getCacheFile() {
+        return cacheFile;
+    }
+
+    public void setCacheFile(File cacheFile) {
+        this.cacheFile = cacheFile;
+    }
+
+    public long getCacheFileSize() {
+        return cacheFileSize;
+    }
+
+    public void setCacheFileSize(long cacheFileSize) {
+        this.cacheFileSize = cacheFileSize;
+    }
+  
+}

+ 9 - 0
app_core/network/src/main/java/network/app/http/Method.java

@@ -0,0 +1,9 @@
+package network.app.http;
+
+/**
+ * Created by Arison on 2017/5/12.
+ */
+public class Method {
+    public final static int GET = 0;
+    public final static int POST = 1;
+}

+ 11 - 0
app_core/network/src/main/java/network/app/http/cache/CacheType.java

@@ -0,0 +1,11 @@
+package network.app.http.cache;
+
+/**
+ * Created by Arison on 2017/5/12.
+ */
+public class CacheType {
+    public final static int ONLY_NETWORK = 0;//读取网络
+    public final static int ONLY_CACHED = 1;//读取缓存
+    public final static int CACHED_ELSE_NETWORK = 2;//先缓存后网络
+    public final static int NETWORK_ELSE_CACHED = 3;//先网络后缓存
+}

+ 170 - 0
app_core/network/src/main/java/network/app/http/impl/RetrofitImpl.java

@@ -0,0 +1,170 @@
+package network.app.http.impl;
+
+
+import com.google.gson.Gson;
+
+import java.io.File;
+import java.security.SecureRandom;
+import java.util.concurrent.TimeUnit;
+
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.SSLSocketFactory;
+import javax.net.ssl.TrustManager;
+
+import network.app.http.HttpBase;
+import network.app.http.HttpClient;
+import network.app.http.interceptor.CacheInterceptor;
+import network.app.http.interceptor.LogInterceptor;
+import network.app.http.retrofit.StringConverterFactory;
+import network.app.http.rx.RxJavaUtils;
+import network.app.http.service.ParamService;
+import network.app.http.ssl.TrustAllCerts;
+import network.app.http.ssl.TrustAllHostnameVerifier;
+import okhttp3.Cache;
+import okhttp3.MultipartBody;
+import okhttp3.OkHttpClient;
+import okhttp3.OkHttpClient.Builder;
+import okhttp3.RequestBody;
+import retrofit2.Retrofit;
+import retrofit2.adapter.rxjava.RxJavaCallAdapterFactory;
+import retrofit2.converter.gson.GsonConverterFactory;
+import rx.Observable;
+import rx.Subscriber;
+import rx.android.schedulers.AndroidSchedulers;
+import rx.functions.Func1;
+
+/**
+ * Retrofit封装Okhttp的方式进行网络操作
+ * 
+ * @author Arison
+ *
+ */
+public class RetrofitImpl extends HttpBase {
+
+	public Retrofit retrofit;
+	public ParamService paramService;
+	private static RetrofitImpl instance;
+	
+
+	public static RetrofitImpl getInstance() {
+		if (instance == null) {
+			synchronized (RetrofitImpl.class) {
+				if (instance == null) {
+					instance = new RetrofitImpl();
+				}
+			}
+		}
+
+		return instance;
+	}
+
+	@Override
+	public void initClient() {
+	  
+		Builder okBuilder = new Builder()
+				.connectTimeout(mbuilder.getConnectTimeout(), TimeUnit.SECONDS)
+				.readTimeout(mbuilder.getReadTimeout(), TimeUnit.SECONDS)
+				.writeTimeout(mbuilder.getWriteTimeout(), TimeUnit.SECONDS)
+				.sslSocketFactory(createSSLSocketFactory(), new TrustAllCerts())// 信任所有证书
+				.hostnameVerifier(new TrustAllHostnameVerifier());
+
+		LogInterceptor logInterceptor = new LogInterceptor();
+		logInterceptor.setBuilder(mbuilder);
+		okBuilder.addInterceptor(logInterceptor);	
+		okBuilder.cache(new Cache(mbuilder.getCacheFile(), mbuilder.getCacheFileSize()));
+		okBuilder.addInterceptor(new CacheInterceptor(String.valueOf(mbuilder.getCacheTime()),mbuilder.getCacheType()));
+
+
+		OkHttpClient client = okBuilder.build();
+		retrofit = new Retrofit.Builder().client(client)
+				.baseUrl(mbuilder.getBaseUrl())
+				.addConverterFactory(StringConverterFactory.create())
+				.addConverterFactory(GsonConverterFactory.create(new Gson()))
+				.addCallAdapterFactory(RxJavaCallAdapterFactory.create())
+				.build();
+
+		paramService = initApi(ParamService.class);
+	}
+
+	public <T> T initApi(Class<T> service) {
+		return retrofit.create(service);
+	}
+
+	@Override
+	public void get(HttpClient builder, Subscriber<Object> s) {
+		Observable<Object> o = paramService.getParam(builder.getBaseUrl(), builder.getParams(), builder.getHeaders());
+		toSubscribe(o, s);
+		
+	}
+
+	@Override
+	public void post(HttpClient builder, Subscriber<Object> s) {
+		Observable<Object> o = paramService.postParam(builder.getBaseUrl(), builder.getParams(), builder.getHeaders());
+		toSubscribe(o, s);
+	}
+	
+	@Override
+	public void uploads(HttpClient mBuilder,Subscriber<Object> s){
+		MultipartBody.Builder builder = new MultipartBody.Builder();
+		builder.setType(MultipartBody.FORM);
+		//追加参数
+		for (String key : mBuilder.getParams().keySet()) {
+			Object object = mBuilder.getParams().get(key);
+			if (!(object instanceof File)) {
+				builder.addFormDataPart(key, object.toString());
+			} else {
+				File file = (File) object;
+				//其中参数“file”和服务器接收的参数 一一对应,保证多文件上传唯一key不变
+				builder.addFormDataPart("file", file.getName(), RequestBody.create(null, file));
+			}
+		}
+		//创建RequestBody
+		RequestBody body = builder.build();
+		Observable<Object> o=paramService.uploads(mBuilder.getBaseUrl(), body);
+		toSubscribe(o, s);
+	}
+
+	private <T> void toSubscribe(Observable<T> o, Subscriber<T> s) {
+		o.retryWhen(new Func1<Observable<? extends Throwable>, Observable<?>>() {
+
+			@Override
+			public Observable<?> call(Observable<? extends Throwable> t) {
+           
+				return t.flatMap(new Func1<Throwable, Observable<?>>() {
+					private int count = 0;
+                     
+					@Override
+					public Observable<?> call(Throwable t) {
+						if (++count <= mbuilder.getMaxRetryCount()) {
+//							Logger.d("请求重试"+count+":"+t.getMessage());
+							Observable<?> ob=	Observable.timer(mbuilder.getRetryTimeout(), TimeUnit.MILLISECONDS);
+							return ob;
+						}
+		
+						return Observable.error(t);
+					}
+				});
+			}
+		}).map(new Func1<T, T>() {
+
+			@Override
+			public T call(T t) {
+				return (T) t;
+			}
+		}).subscribeOn(RxJavaUtils.getScheduler("newThread"))
+				.observeOn(AndroidSchedulers.mainThread())
+				.subscribe(s);
+	}
+
+
+	public SSLSocketFactory createSSLSocketFactory() {
+		SSLSocketFactory ssfFactory = null;
+		try {
+			SSLContext sc = SSLContext.getInstance("TLS");
+			sc.init(null,  new TrustManager[] { new TrustAllCerts() }, new SecureRandom());
+			ssfFactory = sc.getSocketFactory();
+		} catch (Exception e) {
+		}
+		return ssfFactory;
+	}
+}

+ 55 - 0
app_core/network/src/main/java/network/app/http/interceptor/CacheInterceptor.java

@@ -0,0 +1,55 @@
+package network.app.http.interceptor;
+
+
+import java.io.IOException;
+
+import network.app.http.cache.CacheType;
+import okhttp3.CacheControl;
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+/**
+ * 缓存拦截器
+ * @author Arison
+ * 
+ */
+public class CacheInterceptor implements Interceptor {
+	
+	private String cacheTime;//缓存时间
+	private int cacheType;//缓存时间
+	
+	public CacheInterceptor(String cacheTime,int cacheType) {
+		super();
+		this.cacheTime = cacheTime;
+		this.cacheType=cacheType;
+	}
+
+	@Override
+	public Response intercept(Chain chain) throws IOException {
+		  Request request = chain.request();
+		  
+		  switch(cacheType) {
+		  	case CacheType.ONLY_NETWORK:
+		  		 request = request.newBuilder()
+               .cacheControl(CacheControl.FORCE_NETWORK)//只访问網絡
+               .build();
+			break;
+			case CacheType.ONLY_CACHED:
+				 request = request.newBuilder()
+               .cacheControl(CacheControl.FORCE_CACHE)//只访问缓存
+               .build();
+			break;
+			default:
+			break;
+		}
+	      Response response = chain.proceed(request);
+	      Response response1 = response.newBuilder()
+	                .removeHeader("Pragma")
+	                .removeHeader("Cache-Control")
+	                .header("Cache-Control", "max-age=" + cacheTime)
+	                .build();
+	        return response1;
+	}
+
+}

+ 99 - 0
app_core/network/src/main/java/network/app/http/interceptor/LogInterceptor.java

@@ -0,0 +1,99 @@
+package network.app.http.interceptor;
+
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+import network.app.http.HttpClient;
+import okhttp3.FormBody;
+import okhttp3.HttpUrl;
+import okhttp3.Interceptor;
+import okhttp3.Request;
+import okhttp3.Response;
+
+public class LogInterceptor implements Interceptor {
+	
+	private HttpClient builder;
+
+	public LogInterceptor() {
+	  super();
+	}
+	
+	public LogInterceptor(HttpClient builder) {
+		this.builder = builder;
+	}
+
+	@Override
+	public Response intercept(Chain chain) throws IOException {
+		  Request request = chain.request();
+		  Map<String, Object> headers;
+		  Map<String, Object> params;
+		  Map<String,Object> postParam=new HashMap<>();
+		  //添加公共Header,公共参数
+		  if (builder!=null) {
+			  headers=builder.getHeaders();
+			  params=builder.getParams();
+			if(!headers.isEmpty()){
+			  for (Map.Entry<String,Object> entry : headers.entrySet()) {
+				  request=request.newBuilder()
+						  .addHeader(entry.getKey(), String.valueOf(entry.getValue()))
+						  .build();
+				  }
+			}
+			if (!params.isEmpty()) {
+				  //get请求    添加公共参数
+				  if(request.method().equals("GET")){
+					  for (Map.Entry<String, Object> entry : params.entrySet()) {
+						  HttpUrl httpUrl=request.url().newBuilder()
+								  .addQueryParameter(entry.getKey(), String.valueOf(entry.getValue()))
+								  .build();
+						  postParam.put(entry.getKey(),  String.valueOf(entry.getValue()));
+						  request=request.newBuilder().url(httpUrl).build();
+						
+					} 
+				  }
+				  if(request.method().equals("POST")){
+					  if (request.body() instanceof FormBody) {
+						  FormBody.Builder bodyBuilder = new FormBody.Builder();
+						  FormBody formBody = (FormBody) request.body();
+						  for (int i = 0; i < formBody.size(); i++) {
+								postParam.put(formBody.encodedName(i), formBody.encodedValue(i));
+				                bodyBuilder.addEncoded(formBody.encodedName(i), formBody.encodedValue(i));
+				            }
+						  for (Map.Entry<String, Object> entry :params.entrySet()) {
+							  postParam.put(entry.getKey(), String.valueOf(entry.getValue()));
+							  formBody = bodyBuilder
+					                    .addEncoded(entry.getKey(), String.valueOf(entry.getValue()))
+					                    .build();
+						  }
+						  request = request.newBuilder().post(formBody).build();
+					  }
+				  }
+			}
+		  }
+		
+		  Response response = chain.proceed(request);
+		  okhttp3.MediaType mediaType = response.body().contentType();
+          String content = response.body().string();
+		
+         if (builder.isDebug()) {
+			/* Logger.init("PRETTYLOGGER")
+					 .hideThreadInfo()
+					 .methodCount(0);
+			 Logger.i("url:" + JSON.toJSONString(response.request().url().toString()));
+			 Logger.i("headers:"+ JSON.toJSONString(response.request().headers().toMultimap()));
+			 Logger.i("params:" + JSON.toJSONString(postParam));
+			 Logger.init("PRETTYLOGGER")
+					 .methodCount(1);*/
+		}
+    
+		return response.newBuilder()
+                .body(okhttp3.ResponseBody.create(mediaType, content))
+                .build();
+	}
+
+	public void setBuilder(HttpClient builder) {
+		this.builder = builder;
+	}
+	
+}

+ 31 - 0
app_core/network/src/main/java/network/app/http/retrofit/StringConverterFactory.java

@@ -0,0 +1,31 @@
+package network.app.http.retrofit;
+
+import java.lang.annotation.Annotation;
+import java.lang.reflect.Type;
+
+import okhttp3.RequestBody;
+import okhttp3.ResponseBody;
+import retrofit2.Converter;
+import retrofit2.Retrofit;
+
+public class StringConverterFactory extends Converter.Factory{
+	
+	  public static StringConverterFactory create() {
+	        return new StringConverterFactory();
+	    }
+
+	    private StringConverterFactory() {
+
+	    }
+	 @Override
+	    public Converter<ResponseBody, ?> responseBodyConverter(Type type, Annotation[] annotations,
+	                                                            Retrofit retrofit) {
+	        return new StringResponseBodyConverter();
+	    }
+
+	    @Override
+	    public Converter<?, RequestBody> requestBodyConverter(Type type,
+	                                                          Annotation[] parameterAnnotations, Annotation[] methodAnnotations, Retrofit retrofit) {
+	        return new StringRequestBodyConverter();
+	    }
+}

+ 27 - 0
app_core/network/src/main/java/network/app/http/retrofit/StringRequestBodyConverter.java

@@ -0,0 +1,27 @@
+package network.app.http.retrofit;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.Writer;
+import java.nio.charset.Charset;
+
+import okhttp3.MediaType;
+import okhttp3.RequestBody;
+import okio.Buffer;
+import retrofit2.Converter;
+
+public class StringRequestBodyConverter  implements Converter<String, RequestBody> {
+    private static final MediaType MEDIA_TYPE = MediaType.parse("application/json; charset=UTF-8");
+    private static final Charset UTF_8 = Charset.forName("UTF-8");
+
+    StringRequestBodyConverter() {
+    }
+
+    @Override public RequestBody convert(String value) throws IOException {
+        @SuppressWarnings("resource")
+		Buffer buffer = new Buffer();
+        Writer writer = new OutputStreamWriter(buffer.outputStream(), UTF_8);
+        writer.write(value);
+        writer.close();
+        return RequestBody.create(MEDIA_TYPE, buffer.readByteString());
+    }
+}

+ 19 - 0
app_core/network/src/main/java/network/app/http/retrofit/StringResponseBodyConverter.java

@@ -0,0 +1,19 @@
+package network.app.http.retrofit;
+
+import java.io.IOException;
+
+import okhttp3.ResponseBody;
+import retrofit2.Converter;
+
+public class StringResponseBodyConverter implements Converter<ResponseBody, String> {
+
+	@Override
+	public String convert(ResponseBody value) throws IOException {
+		  try {
+	            return value.string();
+	        } finally {
+	            value.close();
+	        }
+	}
+
+}

+ 10 - 0
app_core/network/src/main/java/network/app/http/rx/Result1Listener.java

@@ -0,0 +1,10 @@
+package network.app.http.rx;
+
+/**
+ * @author Arison
+ * 回调接口
+ * @param <T>
+ */
+public interface Result1Listener<T> extends ResultListener<T>{
+	void onResponse(T t);
+}

+ 11 - 0
app_core/network/src/main/java/network/app/http/rx/Result2Listener.java

@@ -0,0 +1,11 @@
+package network.app.http.rx;
+
+/**
+ * @author Arison
+ * 回调接口
+ * @param <T>
+ */
+public interface Result2Listener<T> extends ResultListener<T>{
+	 void onResponse(T t);
+	 void onFailure(Object t);
+}

+ 8 - 0
app_core/network/src/main/java/network/app/http/rx/ResultListener.java

@@ -0,0 +1,8 @@
+package network.app.http.rx;
+
+/**
+ * Created by Arison on 2017/5/16.
+ */
+public interface ResultListener<T> {
+    void onResponse(T t);
+}

+ 86 - 0
app_core/network/src/main/java/network/app/http/rx/ResultSubscriber.java

@@ -0,0 +1,86 @@
+package network.app.http.rx;
+
+
+import java.io.IOException;
+import java.net.ConnectException;
+import java.net.SocketTimeoutException;
+
+import retrofit2.adapter.rxjava.HttpException;
+import rx.Subscriber;
+
+/**
+ * @author Arison
+ * 网络订阅者
+ * @param <T>
+ */
+public class ResultSubscriber<T> extends Subscriber<T> {
+
+	private ResultListener<T> resultListener;
+	private Result2Listener<T> result2Listener;
+	
+	public ResultSubscriber(ResultListener<T> listener) {
+		if (listener!=null){
+			if (listener instanceof  Result2Listener){
+				this.result2Listener= (Result2Listener<T>) listener;
+			}
+			this.resultListener=listener;
+		}
+	}
+	
+	@Override
+	public void onStart() {
+		super.onStart();
+		//Logger.d("网络请求开始 onStart()");
+	}
+	
+	
+	@Override
+	public void onCompleted() {
+		//Logger.d("网络请求结束 onCompleted()");
+	}
+
+	@Override
+	public void onError(Throwable e) {
+		if (result2Listener!=null) {
+			if (e instanceof SocketTimeoutException) {
+//				Logger.e("SocketTimeoutException");
+				result2Listener.onFailure(e);
+			} else if (e instanceof ConnectException) {
+//				Logger.e("ConnectException");
+				result2Listener.onFailure(e);
+			} else if(e instanceof HttpException){
+				HttpException he = (HttpException) e;
+				try {
+					result2Listener.onFailure(he.response().errorBody().string());
+				} catch (IOException e1) {
+					e1.printStackTrace();
+				}
+			}else{
+				resultListener.onResponse((T)e);
+			}
+		}else{
+			if (e instanceof HttpException){
+				try {
+					resultListener.onResponse((T) ((HttpException) e).response().errorBody().string());
+				} catch (IOException e1) {
+					e1.printStackTrace();
+				}
+			}else if (e instanceof SocketTimeoutException){
+				resultListener.onResponse((T) e);
+			}else if(e instanceof ConnectException){
+				resultListener.onResponse((T)e);
+			}else {
+				resultListener.onResponse((T)e);
+			}
+			
+		}
+	}
+
+	@Override
+	public void onNext(T t) {
+		if (resultListener!=null){
+			resultListener.onResponse(t);
+		}
+	}
+
+}

+ 23 - 0
app_core/network/src/main/java/network/app/http/rx/RxJavaUtils.java

@@ -0,0 +1,23 @@
+package network.app.http.rx;
+
+import java.util.concurrent.Executors;
+import java.util.concurrent.ThreadFactory;
+
+import rx.Scheduler;
+import rx.schedulers.Schedulers;
+
+/**
+ * Created by Arison on 2017/5/15.
+ */
+public class RxJavaUtils {
+
+    public static Scheduler getScheduler(final String name) {
+       return Schedulers.from(Executors.newCachedThreadPool(new ThreadFactory() {
+            @Override
+            public Thread newThread(Runnable runnable) {
+                return new Thread(runnable,name);
+            }
+        }));
+       // return Schedulers.from(Executors.newCachedThreadPool(r -> new Thread(r,name)));
+    }
+}

+ 45 - 0
app_core/network/src/main/java/network/app/http/service/ParamService.java

@@ -0,0 +1,45 @@
+package network.app.http.service;
+
+import java.util.Map;
+
+import okhttp3.RequestBody;
+import retrofit2.http.Body;
+import retrofit2.http.FieldMap;
+import retrofit2.http.FormUrlEncoded;
+import retrofit2.http.GET;
+import retrofit2.http.HeaderMap;
+import retrofit2.http.POST;
+import retrofit2.http.QueryMap;
+import retrofit2.http.Url;
+import rx.Observable;
+
+/**
+ * @desc:主要用于网络请求
+ * @name:ParamService
+ * @method:Rxjava+Retrofit
+ * @author Arison
+ */
+public interface ParamService {
+   
+	@GET()
+	Observable<Object> getParam(@Url String url);
+	@GET()
+	Observable<Object> getParam(@Url String url, @QueryMap Map<String, Object> param);
+	@GET()
+	Observable<Object> getParam(@Url String url, @QueryMap Map<String, Object> param, @HeaderMap Map<String, Object> header);
+	@FormUrlEncoded
+	@POST()
+	Observable<Object> postParam(@Url String url);
+	@FormUrlEncoded
+	@POST()
+	Observable<Object> postParam(@Url String url, @FieldMap Map<String, Object> param);
+	@FormUrlEncoded
+	@POST()
+	Observable<Object> postParam(@Url String url, @FieldMap Map<String, Object> param, @HeaderMap Map<String, Object> header);
+
+
+	@POST()
+	Observable<Object> uploads(
+            @Url String url,
+            @Body RequestBody body);
+}

+ 26 - 0
app_core/network/src/main/java/network/app/http/ssl/TrustAllCerts.java

@@ -0,0 +1,26 @@
+package network.app.http.ssl;
+
+import java.security.cert.CertificateException;
+import java.security.cert.X509Certificate;
+
+import javax.net.ssl.X509TrustManager;
+
+/**
+ * Created by Arison on 2017/5/15.
+ */
+public class TrustAllCerts implements X509TrustManager {
+    @Override
+    public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+        
+    }
+
+    @Override
+    public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
+
+    }
+
+    @Override
+    public X509Certificate[] getAcceptedIssuers() {
+        return new X509Certificate[0];
+    }
+}

+ 14 - 0
app_core/network/src/main/java/network/app/http/ssl/TrustAllHostnameVerifier.java

@@ -0,0 +1,14 @@
+package network.app.http.ssl;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.SSLSession;
+
+/**
+ * Created by Arison on 2017/5/15.
+ */
+public class TrustAllHostnameVerifier implements HostnameVerifier {
+    @Override
+    public boolean verify(String s, SSLSession sslSession) {
+        return true;
+    }
+}

+ 8 - 8
app_third/MPAndroidChart/build.gradle

@@ -1,14 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -20,5 +19,6 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 8 - 16
app_third/lib-zxing/build.gradle

@@ -1,17 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
-
-        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
-
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -23,12 +19,8 @@ android {
 
 dependencies {
     compile fileTree(include: ['*.jar'], dir: 'libs')
-    androidTestCompile('com.android.support.test.espresso:espresso-core:2.2.2', {
-        exclude group: 'com.android.support', module: 'support-annotations'
-    })
-    compile files('libs/zxing.jar')
-    compile 'com.android.support:appcompat-v7:24.2.1'
-    testCompile 'junit:junit:4.12'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }
 
 ext {

+ 8 - 9
app_third/libbdupdatesdk/build.gradle

@@ -1,14 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -20,6 +19,6 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    testCompile 'junit:junit:4.12'
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 8 - 9
app_third/libedittextformlibrary/build.gradle

@@ -1,14 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -20,6 +19,6 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    testCompile 'junit:junit:4.12'
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 8 - 8
app_third/libfloatingactionbutton/build.gradle

@@ -1,14 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -20,5 +19,6 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 8 - 12
app_third/library-refreshlayout/build.gradle

@@ -1,23 +1,19 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion '25.0.0'
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 8
-        versionName "1.2.3"
-    }
-    compileOptions {
-        sourceCompatibility JavaVersion.VERSION_1_7
-        targetCompatibility JavaVersion.VERSION_1_7
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
 }
 
 dependencies {
     compile fileTree(include: ['*.jar'], dir: 'libs')
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }
 

+ 8 - 8
app_third/library-swipemenu_lv/build.gradle

@@ -1,15 +1,14 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
     resourcePrefix "swipemenulistview"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -21,6 +20,7 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }
 

+ 8 - 6
app_third/library-viewpager-indicator/build.gradle

@@ -1,12 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
 
     buildTypes {
@@ -18,5 +19,6 @@ android {
 }
 
 dependencies {
-    compile 'com.android.support:appcompat-v7:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 10 - 9
app_third/materialdialogs/build.gradle

@@ -1,14 +1,13 @@
 apply plugin: 'com.android.library'
 
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
-
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
-        versionCode 1
-        versionName "1.0"
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
     buildTypes {
         release {
@@ -20,6 +19,8 @@ android {
 
 dependencies {
     compile fileTree(dir: 'libs', include: ['*.jar'])
-    compile 'com.android.support:appcompat-v7:24.2.1'
-    compile 'com.android.support:design:24.2.1'
+    testCompile deps.junit
+    compile deps.appcompatV7
+    compile deps.design
+
 }

+ 8 - 5
app_third/pullToRefershLibraryMy/build.gradle

@@ -1,10 +1,12 @@
 apply plugin: 'com.android.library'
 android {
-    compileSdkVersion 24
-    buildToolsVersion "25.0.0"
+    compileSdkVersion rootProject.ext.android.compileSdkVersion
+    buildToolsVersion rootProject.ext.android.buildToolsVersion
     defaultConfig {
-        minSdkVersion 9
-        targetSdkVersion 24
+        minSdkVersion rootProject.ext.android.minSdkVersion
+        targetSdkVersion rootProject.ext.android.targetSdkVersion
+        versionCode rootProject.ext.android.versionCode
+        versionName rootProject.ext.android.versionName
     }
 
     buildTypes {
@@ -16,5 +18,6 @@ android {
 }
 
 dependencies {
-    compile project(':MPAndroidChart')
+    testCompile deps.junit
+    compile deps.appcompatV7
 }

+ 2 - 4
build.gradle

@@ -1,5 +1,5 @@
 // Top-level build file where you can add configuration options common to all sub-projects/modules.
-
+apply from: "version.gradle"
 buildscript {
     repositories {
         jcenter()
@@ -10,12 +10,10 @@ buildscript {
         classpath 'com.android.tools.build:gradle:2.3.2'
         classpath 'com.github.dcendents:android-maven-gradle-plugin:1.4.1'
         classpath 'com.jfrog.bintray.gradle:gradle-bintray-plugin:1.0'
+        classpath 'me.tatarka:gradle-retrolambda:3.2.2'
     }
 }
 
-
-
-
 allprojects {
     repositories {
         jcenter()

+ 3 - 20
gradle.properties

@@ -1,23 +1,6 @@
-# Project-wide Gradle settings.
-
-# IDE (e.g. Android Studio) users:
-# Gradle settings configured through the IDE *will override*
-# any settings specified in this file.
-
-# For more details on how to configure your build environment visit
-# http://www.gradle.org/docs/current/userguide/build_environment.html
-
-# Specifies the JVM arguments used for the daemon process.
-# The setting is particularly useful for tweaking memory settings.
-# Default value: -Xmx10248m -XX:MaxPermSize=256m
-# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
-
-# When configured, Gradle will run in incubating parallel mode.
-# This option should only be used with decoupled projects. More details, visit
-# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
-# org.gradle.parallel=true
-
 android.useDeprecatedNdk=true
 org.gradle.daemon=true
 org.gradle.parallel=true
-org.gradle.jvmargs=-Xmx5120m
+org.gradle.jvmargs=-Xmx5120m
+
+applicationId=com.xzjmyk.pm.activity

+ 2 - 0
settings.gradle

@@ -6,6 +6,8 @@ include ':network'
 include ':imageload'
 include ':common'
 include ':message'
+
+
 //第三库模块
 include ':lib-zxing'
 include ':libbdupdatesdk'

+ 72 - 39
version.gradle

@@ -1,5 +1,7 @@
 /*
 Shared gradle properties
+    android:versionCode="111"
+    android:versionName="5.8.9"
 */
 
 ext {
@@ -9,51 +11,82 @@ ext {
             minSdkVersion    : 14,
             targetSdkVersion : 24,
             javaVersion      : JavaVersion.VERSION_1_8,
-            versionCode      : 1,
-            versionName      : '1.0',
+            versionCode      : 111,
+            versionName      : '5.8.9',
     ]
 
     depsVersion = [
-            junitVersion      : '4.12',
-            supportVersion    : '25.1.1',
-            butterknifeVersion: '8.2.1',
-            fastjsonVersion   : '1.2.24',
-            logVersion        : '1.15',
-            rxJavaVersion     : '1.1.8',
-            rxAndroidVersion  : '1.2.1',
-            okhttpVersion     : '3.4.1',
-            retrofitVersion   : '2.1.0',
-            glideVersion      : '3.8.0',
-            supertoastsVersion: '2.0',
-            alerterVersion    : '1.0.6',
+            junitVersion            : '4.12',
+            supportVersion          : '24.2.1',
+            multidex                : '1.0.1',
+            butterknifeVersion      : '8.2.1',
+            fastjsonVersion         : '1.2.24',
+            logVersion              : '1.15',
+            rxJavaVersion           : '1.1.8',
+            rxAndroidVersion        : '1.2.1',
+            okhttpVersion           : '3.4.1',
+            retrofitVersion         : '2.1.0',
+            stethoVersion           : '1.4.1',
+            glideVersion            : '3.8.0',
+            supertoastsVersion      : '2.0',
+            alerterVersion          : '1.0.6',
+            circleimageviewVersion  : '2.1.0',
+            systembartintVersion    : '1.0.3',
+            photoViewVersion        : '1.2.5',
+            leakcanaryVersion       : '1.5',
+            materialDialogsVersion  : '0.9.0.2',
+            stickyGridHeadersVersion: '1.0.1',
+            stickyListHeadersVersion: '2.7.0',
+            activityOnCrashVersion  : '1.5.0',
+            analyticsVersion        : 'latest.integration',
+            tagGroupVersion         : '1.4@aar',
+            jodatimeVersion         : '2.9.4'
     ]
 
     deps = [
-            junit             : 'junit:junit:' + depsVersion.junitVersion,
-            appcompatV7       : 'com.android.support:appcompat-v7:' + depsVersion.supportVersion,
-            supportV4         : 'com.android.support:support-v4:' + depsVersion.supportVersion,
-            supportAnnotations: 'com.android.support:support-annotations:' + depsVersion.supportVersion,
-            design            : 'com.android.support:design:' + depsVersion.supportVersion,
-            gridlayoutV7      : 'com.android.support:gridlayout-v7:' + depsVersion.supportVersion,
-            recyclerviewV7    : 'com.android.support:recyclerview-v7:' + depsVersion.supportVersion,
-            cardviewV7        : 'com.android.support:cardview-v7:' + depsVersion.supportVersion,
-           
-            logger            : 'com.orhanobut:logger:'+depsVersion.logVersion,
-            fastjson          : 'com.alibaba:fastjson:'+depsVersion.fastjsonVersion,
-            
-            butterknife       : 'com.jakewharton:butterknife:' + depsVersion.butterknifeVersion,
-            butterknifeCompiler   : 'com.jakewharton:butterknife-compiler:' + depsVersion.butterknifeVersion,
-            rxjava            : 'io.reactivex:rxjava:' + depsVersion.rxJavaVersion,
-            rxandroid         : 'io.reactivex:rxandroid:' + depsVersion.rxAndroidVersion,
-            okhttp            : 'com.squareup.okhttp3:okhttp:' + depsVersion.okhttpVersion,
-            retrofit          : 'com.squareup.retrofit2:retrofit:' + depsVersion.retrofitVersion,
-            converterGson     : 'com.squareup.retrofit2:converter-gson:' + depsVersion.retrofitVersion,
-            adapterRxjava     : 'com.squareup.retrofit2:adapter-rxjava:' + depsVersion.retrofitVersion,
-
-            glide             : 'com.github.bumptech.glide:glide:' + depsVersion.glideVersion,
-            
-            supertoasts       :'com.github.johnpersano:supertoasts:'+depsVersion.supertoastsVersion,
-            alerter            :'com.tapadoo.android:alerter:'+depsVersion.alerterVersion
+            junit              : 'junit:junit:' + depsVersion.junitVersion,
+            appcompatV7        : 'com.android.support:appcompat-v7:' + depsVersion.supportVersion,
+            supportV4          : 'com.android.support:support-v4:' + depsVersion.supportVersion,
+            supportAnnotations : 'com.android.support:support-annotations:' + depsVersion.supportVersion,
+            design             : 'com.android.support:design:' + depsVersion.supportVersion,
+            gridlayoutV7       : 'com.android.support:gridlayout-v7:' + depsVersion.supportVersion,
+            recyclerviewV7     : 'com.android.support:recyclerview-v7:' + depsVersion.supportVersion,
+            cardviewV7         : 'com.android.support:cardview-v7:' + depsVersion.supportVersion,
+            multidex           : 'com.android.support:multidex:' + depsVersion.multidex,
+
+            logger             : 'com.orhanobut:logger:' + depsVersion.logVersion,
+            fastjson           : 'com.alibaba:fastjson:' + depsVersion.fastjsonVersion,
+            stetho             : 'com.facebook.stetho:stetho:' + depsVersion.stethoVersion,
+
+            butterknife        : 'com.jakewharton:butterknife:' + depsVersion.butterknifeVersion,
+            butterknifeCompiler: 'com.jakewharton:butterknife-compiler:' + depsVersion.butterknifeVersion,
+            rxjava             : 'io.reactivex:rxjava:' + depsVersion.rxJavaVersion,
+            rxandroid          : 'io.reactivex:rxandroid:' + depsVersion.rxAndroidVersion,
+            okhttp             : 'com.squareup.okhttp3:okhttp:' + depsVersion.okhttpVersion,
+            retrofit           : 'com.squareup.retrofit2:retrofit:' + depsVersion.retrofitVersion,
+            converterGson      : 'com.squareup.retrofit2:converter-gson:' + depsVersion.retrofitVersion,
+            adapterRxjava      : 'com.squareup.retrofit2:adapter-rxjava:' + depsVersion.retrofitVersion,
+
+            glide              : 'com.github.bumptech.glide:glide:' + depsVersion.glideVersion,
+
+            supertoasts        : 'com.github.johnpersano:supertoasts:' + depsVersion.supertoastsVersion,
+            alerter            : 'com.tapadoo.android:alerter:' + depsVersion.alerterVersion,
+
+            circleimageview    : 'de.hdodenhof:circleimageview:' + depsVersion.circleimageviewVersion,
+            systembartint      : 'com.readystatesoftware.systembartint:systembartint:' + depsVersion.systembartintVersion,
+            photoView          : 'com.commit451:PhotoView:' + depsVersion.photoViewVersion,
+
+            tagGroup           : 'me.gujun.android.taggroup:library:' + depsVersion.tagGroupVersion,
+            analytics          : 'com.umeng.analytics:analytics:' + depsVersion.analyticsVersion,
+            activityOnCrash    : 'cat.ereza:customactivityoncrash:' + depsVersion.activityOnCrashVersion,
+            stickyListHeaders  : 'se.emilsjolander:stickylistheaders:' + depsVersion.stickyListHeadersVersion,
+            stickyGridHeaders  : 'com.github.TonicArtos:StickyGridHeaders:' + depsVersion.stickyGridHeadersVersion,
+            materialDialogs    : 'com.afollestad.material-dialogs:core:' + depsVersion.materialDialogsVersion,
+            leakcanary         : 'com.squareup.leakcanary:leakcanary-android:' + depsVersion.leakcanaryVersion,
+            leakcanaryNp       : 'com.squareup.leakcanary:leakcanary-android-no-op:' + depsVersion.leakcanaryVersion,
+            jodatime           : 'joda-time:joda-time:' + depsVersion.jodatimeVersion
+
+
     ]
 }
   

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác