Browse Source

提交完整代码

mq 3 years ago
commit
73a8afcacd
100 changed files with 5516 additions and 0 deletions
  1. 14 0
      .gitignore
  2. 1 0
      app/.gitignore
  3. 73 0
      app/build.gradle
  4. 0 0
      app/libs/armeabi/libtbs.so
  5. BIN
      app/libs/tbs_sdk_thirdapp_v4.3.0.1148_43697_sharewithdownloadwithfile_withoutGame_obfs_20190805_175505.jar
  6. 21 0
      app/proguard-rules.pro
  7. BIN
      app/release/OA4App_release_1_201911121540.apk
  8. 1 0
      app/release/output.json
  9. 64 0
      app/src/main/AndroidManifest.xml
  10. 127 0
      app/src/main/java/com/mq/oaapp/App.java
  11. 23 0
      app/src/main/java/com/mq/oaapp/UrlPath.java
  12. 311 0
      app/src/main/java/com/mq/oaapp/base/BaseActivity.java
  13. 12 0
      app/src/main/java/com/mq/oaapp/base/BaseOnTouchListener.java
  14. 586 0
      app/src/main/java/com/mq/oaapp/ui/BrowserActivity.java
  15. 146 0
      app/src/main/java/com/mq/oaapp/ui/LoginActivity.java
  16. 23 0
      app/src/main/java/com/mq/oaapp/ui/MainActivity.java
  17. 163 0
      app/src/main/java/com/mq/oaapp/ui/WebActivity.java
  18. 20 0
      app/src/main/java/com/mq/oaapp/utils/MyConstant.java
  19. 6 0
      app/src/main/java/com/mq/oaapp/utils/WebViewJavaScriptFunction.java
  20. 92 0
      app/src/main/java/com/mq/oaapp/utils/X5WebView.java
  21. BIN
      app/src/main/res/drawable-hdpi/ic_exit_to_app_grey_700_24dp.png
  22. BIN
      app/src/main/res/drawable-hdpi/ic_home_grey_700_24dp.png
  23. BIN
      app/src/main/res/drawable-hdpi/ic_keyboard_arrow_left_black_36dp.png
  24. BIN
      app/src/main/res/drawable-hdpi/ic_keyboard_arrow_left_grey_700_24dp.png
  25. BIN
      app/src/main/res/drawable-hdpi/ic_keyboard_arrow_right_grey_700_24dp.png
  26. BIN
      app/src/main/res/drawable-mdpi/ic_exit_to_app_grey_700_24dp.png
  27. BIN
      app/src/main/res/drawable-mdpi/ic_home_grey_700_24dp.png
  28. BIN
      app/src/main/res/drawable-mdpi/ic_keyboard_arrow_left_black_36dp.png
  29. BIN
      app/src/main/res/drawable-mdpi/ic_keyboard_arrow_left_grey_700_24dp.png
  30. BIN
      app/src/main/res/drawable-mdpi/ic_keyboard_arrow_right_grey_700_24dp.png
  31. BIN
      app/src/main/res/drawable-xhdpi/ic_exit_to_app_grey_700_24dp.png
  32. BIN
      app/src/main/res/drawable-xhdpi/ic_home_grey_700_24dp.png
  33. BIN
      app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_left_black_36dp.png
  34. BIN
      app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_left_grey_700_24dp.png
  35. BIN
      app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_right_grey_700_24dp.png
  36. BIN
      app/src/main/res/drawable-xhdpi/ic_login_path.png
  37. BIN
      app/src/main/res/drawable-xhdpi/ic_login_pwd.png
  38. BIN
      app/src/main/res/drawable-xhdpi/ic_login_title.png
  39. BIN
      app/src/main/res/drawable-xhdpi/ic_login_top.png
  40. BIN
      app/src/main/res/drawable-xhdpi/ic_login_user.png
  41. BIN
      app/src/main/res/drawable-xxhdpi/ic_exit_to_app_grey_700_24dp.png
  42. BIN
      app/src/main/res/drawable-xxhdpi/ic_home_grey_700_24dp.png
  43. BIN
      app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_left_black_36dp.png
  44. BIN
      app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_left_grey_700_24dp.png
  45. BIN
      app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_right_grey_700_24dp.png
  46. BIN
      app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_grey_700_24dp.png
  47. BIN
      app/src/main/res/drawable-xxxhdpi/ic_home_grey_700_24dp.png
  48. BIN
      app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_left_black_36dp.png
  49. BIN
      app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_left_grey_700_24dp.png
  50. BIN
      app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_right_grey_700_24dp.png
  51. 24 0
      app/src/main/res/drawable/btn_blue_bg.xml
  52. 29 0
      app/src/main/res/drawable/color_progressbar.xml
  53. BIN
      app/src/main/res/drawable/ic_open_bg.png
  54. 9 0
      app/src/main/res/drawable/open_bg.xml
  55. 167 0
      app/src/main/res/layout/activity_browser.xml
  56. 167 0
      app/src/main/res/layout/activity_login.xml
  57. 13 0
      app/src/main/res/layout/activity_main.xml
  58. 117 0
      app/src/main/res/layout/activity_web.xml
  59. 19 0
      app/src/main/res/layout/filechooser_layout.xml
  60. 21 0
      app/src/main/res/layout/progress_layout.xml
  61. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  62. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  63. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  64. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  65. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  66. 11 0
      app/src/main/res/values/colors.xml
  67. 3 0
      app/src/main/res/values/strings.xml
  68. 26 0
      app/src/main/res/values/styles.xml
  69. 4 0
      app/src/main/res/xml/network_security_config.xml
  70. 33 0
      build.gradle
  71. 15 0
      gradle.properties
  72. BIN
      gradle/wrapper/gradle-wrapper.jar
  73. 6 0
      gradle/wrapper/gradle-wrapper.properties
  74. 172 0
      gradlew
  75. 84 0
      gradlew.bat
  76. 1 0
      mylibrary/.gitignore
  77. 29 0
      mylibrary/build.gradle
  78. 21 0
      mylibrary/proguard-rules.pro
  79. 2 0
      mylibrary/src/main/AndroidManifest.xml
  80. 140 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ActivityTool.java
  81. 48 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/AssetsTool.java
  82. 70 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/Base64Tool.java
  83. 137 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/CodeUtils.java
  84. 45 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/DPTool.java
  85. 535 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/DateTool.java
  86. 122 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ETTool.java
  87. 182 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/FileUtil.java
  88. 275 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/HappySQL.java
  89. 89 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/LogTool.java
  90. 114 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/PermissionTool.java
  91. 196 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/SPTool.java
  92. 79 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ScreenTool.java
  93. 242 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/StringTool.java
  94. 267 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ToastTool.java
  95. 154 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ValidatorTool.java
  96. 123 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/VersionTool.java
  97. 39 0
      mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ViewTool.java
  98. 3 0
      mylibrary/src/main/res/values/strings.xml
  99. BIN
      oaapp.jks
  100. 0 0
      settings.gradle

+ 14 - 0
.gitignore

@@ -0,0 +1,14 @@
1
+*.iml
2
+.gradle
3
+/local.properties
4
+/.idea/caches
5
+/.idea/libraries
6
+/.idea/modules.xml
7
+/.idea/workspace.xml
8
+/.idea/navEditor.xml
9
+/.idea/assetWizardSettings.xml
10
+.DS_Store
11
+/build
12
+/captures
13
+/.idea
14
+.externalNativeBuild

+ 1 - 0
app/.gitignore

@@ -0,0 +1 @@
1
+/build

+ 73 - 0
app/build.gradle

@@ -0,0 +1,73 @@
1
+apply plugin: 'com.android.application'
2
+apply plugin: 'com.jakewharton.butterknife'
3
+
4
+android {
5
+    signingConfigs {
6
+        release {
7
+            storeFile file('..\\oaapp.jks')
8
+            storePassword '111111'
9
+            keyAlias = 'oaapp'
10
+            keyPassword '111111'
11
+        }
12
+    }
13
+    compileSdkVersion 28
14
+    defaultConfig {
15
+        applicationId "com.mq.oaapp"
16
+        minSdkVersion 15
17
+        targetSdkVersion 28
18
+        versionCode 1
19
+        versionName "1.0.0"
20
+
21
+        ndk {
22
+            //设置支持的SO库架构
23
+            abiFilters 'armeabi' //, 'x86', 'armeabi-v7a', 'x86_64', 'arm64-v8a'
24
+        }
25
+    }
26
+    buildTypes {
27
+        release {
28
+            minifyEnabled false
29
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
30
+            signingConfig signingConfigs.release
31
+            zipAlignEnabled = true
32
+        }
33
+        debug {
34
+            signingConfig signingConfigs.release
35
+        }
36
+    }
37
+    // Butterknife requires Java 8.
38
+    compileOptions {
39
+        sourceCompatibility 1.8
40
+        targetCompatibility 1.8
41
+    }
42
+
43
+    sourceSets {
44
+        main {
45
+            jniLibs.srcDirs = ['libs']
46
+        }
47
+    }
48
+
49
+    //配置自定义打包名称
50
+    android.applicationVariants.all { variant ->
51
+        variant.outputs.all { output ->
52
+            def outputFile = output.outputFile
53
+            if (outputFile != null && outputFile.name.endsWith('release.apk')) {
54
+                def fileName = "OA4App_release_" +
55
+                        "${defaultConfig.versionCode}_${new Date().format("yyyyMMddHHmm")}.apk"
56
+                outputFileName = fileName
57
+            }
58
+        }
59
+    }
60
+}
61
+
62
+dependencies {
63
+    implementation fileTree(include: ['*.jar'], dir: 'libs')
64
+    implementation 'com.android.support:appcompat-v7:28.0.0'
65
+    implementation 'com.android.support:design:28.0.0'
66
+    implementation 'com.lzy.net:okgo:3.0.4'
67
+    implementation 'com.google.code.gson:gson:2.8.5'
68
+    implementation 'com.jaeger.statusbarutil:library:1.5.1'
69
+    implementation 'com.jakewharton:butterknife:9.0.0-rc2'
70
+    annotationProcessor 'com.jakewharton:butterknife-compiler:9.0.0-rc2'
71
+    implementation project(path: ':mylibrary')
72
+    implementation files('libs/tbs_sdk_thirdapp_v4.3.0.1148_43697_sharewithdownloadwithfile_withoutGame_obfs_20190805_175505.jar')
73
+}

+ 0 - 0
app/libs/armeabi/libtbs.so


BIN
app/libs/tbs_sdk_thirdapp_v4.3.0.1148_43697_sharewithdownloadwithfile_withoutGame_obfs_20190805_175505.jar


+ 21 - 0
app/proguard-rules.pro

@@ -0,0 +1,21 @@
1
+# Add project specific ProGuard rules here.
2
+# You can control the set of applied configuration files using the
3
+# proguardFiles setting in build.gradle.
4
+#
5
+# For more details, see
6
+#   http://developer.android.com/guide/developing/tools/proguard.html
7
+
8
+# If your project uses WebView with JS, uncomment the following
9
+# and specify the fully qualified class name to the JavaScript interface
10
+# class:
11
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12
+#   public *;
13
+#}
14
+
15
+# Uncomment this to preserve the line number information for
16
+# debugging stack traces.
17
+#-keepattributes SourceFile,LineNumberTable
18
+
19
+# If you keep the line number information, uncomment this to
20
+# hide the original source file name.
21
+#-renamesourcefileattribute SourceFile

BIN
app/release/OA4App_release_1_201911121540.apk


+ 1 - 0
app/release/output.json

@@ -0,0 +1 @@
1
+[{"outputType":{"type":"APK"},"apkData":{"type":"MAIN","splits":[],"versionCode":1,"versionName":"1.0.0","enabled":true,"outputFile":"OA4App_release_1_201911121540.apk","fullName":"release","baseName":"release"},"path":"OA4App_release_1_201911121540.apk","properties":{}}]

+ 64 - 0
app/src/main/AndroidManifest.xml

@@ -0,0 +1,64 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:tools="http://schemas.android.com/tools"
4
+    package="com.mq.oaapp">
5
+
6
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
7
+    <uses-permission android:name="android.permission.INTERNET" />
8
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
9
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
10
+    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
11
+    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
12
+    <uses-permission android:name="android.permission.READ_SETTINGS" />
13
+    <uses-permission android:name="android.permission.WRITE_SETTINGS" />
14
+    <uses-permission android:name="android.permission.INTERNET" />
15
+    <uses-permission android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS" />
16
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
17
+
18
+    <!-- 硬件加速对X5视频播放非常重要,建议开启 -->
19
+    <uses-permission android:name="android.permission.GET_TASKS" />
20
+
21
+    <application
22
+        android:name=".App"
23
+        android:allowBackup="true"
24
+        android:icon="@mipmap/ic_launcher"
25
+        android:label="@string/app_name"
26
+        android:networkSecurityConfig="@xml/network_security_config"
27
+        android:supportsRtl="true"
28
+        android:theme="@style/MyAppTheme"
29
+        tools:ignore="GoogleAppIndexingWarning">
30
+        <meta-data
31
+            android:name="android.max_aspect"
32
+            android:value="2.1" />
33
+
34
+        <uses-library
35
+            android:name="org.apache.http.legacy"
36
+            android:required="false" />
37
+
38
+        <activity
39
+            android:name=".ui.BrowserActivity"
40
+            android:configChanges="orientation|screenSize|keyboardHidden" />
41
+        <activity
42
+            android:name=".ui.WebActivity"
43
+            android:configChanges="orientation|keyboardHidden"
44
+            android:launchMode="singleTop"
45
+            android:windowSoftInputMode="stateHidden|adjustPan" />
46
+        <activity
47
+            android:name=".ui.LoginActivity"
48
+            android:launchMode="singleTop"
49
+            android:screenOrientation="portrait"
50
+            android:windowSoftInputMode="stateHidden|adjustPan" />
51
+        <activity
52
+            android:name=".ui.MainActivity"
53
+            android:screenOrientation="portrait"
54
+            android:theme="@style/OpenTheme">
55
+            <intent-filter>
56
+                <action android:name="android.intent.action.MAIN" />
57
+
58
+                <category android:name="android.intent.category.LAUNCHER" />
59
+            </intent-filter>
60
+        </activity>
61
+
62
+    </application>
63
+
64
+</manifest>

+ 127 - 0
app/src/main/java/com/mq/oaapp/App.java

@@ -0,0 +1,127 @@
1
+package com.mq.oaapp;
2
+
3
+import android.app.Application;
4
+import android.content.Context;
5
+
6
+import com.lzy.okgo.OkGo;
7
+import com.lzy.okgo.cache.CacheEntity;
8
+import com.lzy.okgo.cache.CacheMode;
9
+import com.lzy.okgo.cookie.CookieJarImpl;
10
+import com.lzy.okgo.cookie.store.SPCookieStore;
11
+import com.lzy.okgo.https.HttpsUtils;
12
+import com.lzy.okgo.interceptor.HttpLoggingInterceptor;
13
+import com.lzy.okgo.model.HttpHeaders;
14
+import com.lzy.okgo.model.HttpParams;
15
+import com.tencent.smtt.sdk.QbSdk;
16
+import com.xyxsbj.mylibrary.tool.LogTool;
17
+import com.xyxsbj.mylibrary.tool.SPTool;
18
+import com.xyxsbj.mylibrary.tool.ToastTool;
19
+
20
+import java.util.concurrent.TimeUnit;
21
+import java.util.logging.Level;
22
+
23
+import okhttp3.OkHttpClient;
24
+
25
+/**
26
+ * 创建人 mQ
27
+ * 创建时间 2019/9/24 0024 19:55
28
+ * 文件名称 App
29
+ * 说明:
30
+ **/
31
+public class App extends Application {
32
+
33
+    private static Context applicationContext;
34
+
35
+    @Override
36
+    public void onCreate() {
37
+        super.onCreate();
38
+        applicationContext = this;
39
+        SPTool.init(this, "oa4app");
40
+        ToastTool.init(this);
41
+        initX5WebView();
42
+        initOkGo();
43
+//        Bugly.init(getApplicationContext(), "823351b056", true);
44
+    }
45
+
46
+    public static Context getAppContext() {
47
+        return applicationContext;
48
+    }
49
+
50
+    private void initOkGo() {
51
+        OkGo.getInstance().init(this);
52
+        OkHttpClient.Builder builder = new OkHttpClient.Builder();
53
+        HttpLoggingInterceptor loggingInterceptor = new HttpLoggingInterceptor("OkGo");
54
+        //log打印级别,决定了log显示的详细程度
55
+        loggingInterceptor.setPrintLevel(HttpLoggingInterceptor.Level.BODY);
56
+        //log颜色级别,决定了log在控制台显示的颜色
57
+        loggingInterceptor.setColorLevel(Level.INFO);
58
+        builder.addInterceptor(loggingInterceptor);
59
+
60
+        //非必要情况,不建议使用,第三方的开源库,使用通知显示当前请求的log,不过在做文件下载的时候,这个库好像有问题,对文件判断不准确
61
+        //builder.addInterceptor(new ChuckInterceptor(this));
62
+        //全局的读取超时时间
63
+        builder.readTimeout(30 * 1000, TimeUnit.MILLISECONDS);
64
+        //全局的写入超时时间
65
+        builder.writeTimeout(30 * 1000, TimeUnit.MILLISECONDS);
66
+        //全局的连接超时时间
67
+        builder.connectTimeout(30 * 1000, TimeUnit.MILLISECONDS);
68
+
69
+        //使用sp保持cookie,如果cookie不过期,则一直有效
70
+        builder.cookieJar(new CookieJarImpl(new SPCookieStore(this)));
71
+        //使用数据库保持cookie,如果cookie不过期,则一直有效
72
+//        builder.cookieJar(new CookieJarImpl(new DBCookieStore(this)));
73
+        //使用内存保持cookie,app退出后,cookie消失
74
+//        builder.cookieJar(new CookieJarImpl(new MemoryCookieStore()));
75
+
76
+        //方法一:信任所有证书,不安全有风险
77
+        HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
78
+//        方法二:自定义信任规则,校验服务端证书
79
+//        HttpsUtils.SSLParams sslParams2 = HttpsUtils.getSslSocketFactory(new SafeTrustManager());
80
+//        方法三:使用预埋证书,校验服务端证书(自签名证书)
81
+//        HttpsUtils.SSLParams sslParams3 = HttpsUtils.getSslSocketFactory(getAssets().open("srca.cer"));
82
+//        方法四:使用bks证书和密码管理客户端证书(双向认证),使用预埋证书,校验服务端证书(自签名证书)
83
+//        HttpsUtils.SSLParams sslParams4 = HttpsUtils.getSslSocketFactory(getAssets().open("xxx.bks"), "123456", getAssets().open("yyy.cer"));
84
+        builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);
85
+//        配置https的域名匹配规则,详细看demo的初始化介绍,不需要就不要加入,使用不当会导致https握手失败
86
+//        builder.hostnameVerifier(new SafeHostnameVerifier());
87
+
88
+        //---------这里给出的是示例代码,告诉你可以这么传,实际使用的时候,根据需要传,不需要就不传-------------//
89
+        HttpHeaders headers = new HttpHeaders();
90
+//        headers.put("commonHeaderKey1", "commonHeaderValue1");    //header不支持中文,不允许有特殊字符
91
+//        headers.put("commonHeaderKey2", "commonHeaderValue2");
92
+        HttpParams params = new HttpParams();
93
+//        params.put("commonParamsKey1", "commonParamsValue1");     //param支持中文,直接传,不要自己编码
94
+//        params.put("commonParamsKey2", "这里支持中文参数");
95
+        //-------------------------------------------------------------------------------------//
96
+
97
+        OkGo.getInstance().init(this)                       //必须调用初始化
98
+                .setOkHttpClient(builder.build())               //建议设置OkHttpClient,不设置将使用默认的
99
+                .setCacheMode(CacheMode.NO_CACHE)               //全局统一缓存模式,默认不使用缓存,可以不传
100
+                .setCacheTime(CacheEntity.CACHE_NEVER_EXPIRE)   //全局统一缓存时间,默认永不过期,可以不传
101
+                .setRetryCount(3)                               //全局统一超时重连次数,默认为三次,那么最差的情况会请求4次(一次原始请求,三次重连请求),不需要可以设置为0
102
+                .addCommonHeaders(headers)                      //全局公共头
103
+                .addCommonParams(params);                       //全局公共参数
104
+    }
105
+
106
+    private void initX5WebView() {
107
+        //搜集本地tbs内核信息并上报服务器,服务器返回结果决定使用哪个内核。
108
+
109
+        QbSdk.PreInitCallback cb = new QbSdk.PreInitCallback() {
110
+
111
+            @Override
112
+            public void onViewInitFinished(boolean arg0) {
113
+                // TODO Auto-generated method stub
114
+                //x5內核初始化完成的回调,为true表示x5内核加载成功,否则表示x5内核加载失败,会自动切换到系统内核。
115
+                LogTool.d(" onViewInitFinished is x5内核加载:" + arg0);
116
+            }
117
+
118
+            @Override
119
+            public void onCoreInitFinished() {
120
+                // TODO Auto-generated method stub
121
+            }
122
+        };
123
+        //x5内核初始化接口
124
+        QbSdk.initX5Environment(getApplicationContext(),  cb);
125
+    }
126
+
127
+}

+ 23 - 0
app/src/main/java/com/mq/oaapp/UrlPath.java

@@ -0,0 +1,23 @@
1
+package com.mq.oaapp;
2
+
3
+/**
4
+ * 创建人 mQ
5
+ * 创建时间 2019/10/14 0014 18:03
6
+ * 文件名称 UrlPath
7
+ * 说明:
8
+ **/
9
+public class UrlPath {
10
+
11
+    /**
12
+     * 登录
13
+     */
14
+    public static final String LOGIN = "http://192.168.123.132:15000/login/userLogin";
15
+//    public static final String LOGIN = "http://172.16.3.40:8088/login/userLogin";
16
+
17
+    /**
18
+     * 首页
19
+     */
20
+        public static final String HOME = "http://192.168.80.183:8088/wxapi/wxclientmenu/71431b577bd64a838ed8747e813323d6";
21
+//    public static final String HOME = "http://172.16.3.40:8088/wxapi/wxclientmenu/22c9c0b39d454c239f9d9e0a00aa0078";
22
+
23
+}

+ 311 - 0
app/src/main/java/com/mq/oaapp/base/BaseActivity.java

@@ -0,0 +1,311 @@
1
+package com.mq.oaapp.base;
2
+
3
+import android.app.Activity;
4
+import android.content.Context;
5
+import android.content.pm.ActivityInfo;
6
+import android.content.res.Configuration;
7
+import android.content.res.Resources;
8
+import android.os.Bundle;
9
+import android.support.v7.app.AppCompatActivity;
10
+import android.util.Log;
11
+import android.view.MotionEvent;
12
+import android.view.View;
13
+import android.view.ViewGroup;
14
+import android.view.Window;
15
+import android.view.WindowManager;
16
+import android.view.inputmethod.InputMethodManager;
17
+import android.widget.EditText;
18
+
19
+import com.google.gson.Gson;
20
+import com.jaeger.library.StatusBarUtil;
21
+import com.mq.oaapp.R;
22
+import com.xyxsbj.mylibrary.tool.ActivityTool;
23
+import com.xyxsbj.mylibrary.tool.LogTool;
24
+
25
+import java.util.ArrayList;
26
+
27
+import butterknife.ButterKnife;
28
+
29
+/**
30
+ * 创建人 mQ
31
+ * 创建时间 2018/12/10 0010 17:06
32
+ * 文件名称 BaseActivity
33
+ * 说明:
34
+ **/
35
+public abstract class BaseActivity extends AppCompatActivity {
36
+
37
+    private int mScreenOrientation = 0;//0 不限制, 1 横向, 2 纵向
38
+
39
+    private ArrayList<BaseOnTouchListener> onTouchListeners = new ArrayList<>();
40
+
41
+    private boolean active;
42
+    private Gson mGson;
43
+    private View mProgressBar;
44
+    private boolean mIsLight = false;
45
+
46
+    protected abstract int getLayoutRes();
47
+
48
+    protected abstract void init();
49
+
50
+    protected abstract void workTask();
51
+
52
+    @Override
53
+    protected void onCreate(Bundle savedInstanceState) {
54
+        super.onCreate(savedInstanceState);
55
+        setContentView(getLayoutRes());
56
+        getWindow().getDecorView().setOnSystemUiVisibilityChangeListener(new View.OnSystemUiVisibilityChangeListener() {
57
+            @Override
58
+            public void onSystemUiVisibilityChange(int visibility) {
59
+                showLightOrDark();
60
+            }
61
+        });
62
+        ButterKnife.bind(this);
63
+        active = true;
64
+        init();
65
+        workTask();
66
+    }
67
+//    android:fitsSystemWindows="true"
68
+
69
+    @Override
70
+    public void setContentView(int layoutResID) {
71
+        super.setContentView(layoutResID);
72
+        //设置沉浸式标题栏颜色
73
+        StatusBarUtil.setTranslucent(this, 0);
74
+        setFitsSystemWindows(this, false);
75
+    }
76
+
77
+    /**
78
+     * 设置界面主题的明暗
79
+     */
80
+    public void setActivityLightOrDark(boolean isLight) {
81
+        mIsLight = isLight;
82
+        showLightOrDark();
83
+    }
84
+    private void showLightOrDark() {
85
+        if (mIsLight)
86
+            ActivityTool.hideNavigationAndLight(getContext(), getWindow());
87
+        else
88
+            ActivityTool.hideNavigationAndDark(getContext(), getWindow());
89
+
90
+    }
91
+
92
+    @Override
93
+    protected void onResume() {
94
+        setScreenOrientation();
95
+        super.onResume();
96
+        //隐藏底部虚拟按键
97
+//        ActivityTool.hideNavigationAndLight(getContext(), getWindow());
98
+//        LogTool.d("基类onResume");
99
+    }
100
+
101
+    @Override
102
+    protected void onDestroy() {
103
+        super.onDestroy();
104
+        active = false;
105
+
106
+    }
107
+
108
+    public boolean isActive() {
109
+        return active;
110
+    }
111
+
112
+    /*点击屏幕非文本框的区域,关闭键盘*/
113
+    @Override
114
+    public boolean dispatchTouchEvent(MotionEvent ev) {
115
+        for (BaseOnTouchListener l : onTouchListeners) {
116
+            if (l != null)
117
+                l.onTouch(ev);
118
+        }
119
+        if (ev.getAction() == MotionEvent.ACTION_DOWN) {
120
+            View v = getCurrentFocus();
121
+            if (isShouldHideInput(v, ev)) {
122
+
123
+                InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
124
+                if (imm != null) {
125
+                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
126
+                }
127
+            }
128
+            return super.dispatchTouchEvent(ev);
129
+        }
130
+        // 必不可少,否则所有的组件都不会有TouchEvent了
131
+        if (getWindow().superDispatchTouchEvent(ev)) {
132
+            return true;
133
+        }
134
+        return onTouchEvent(ev);
135
+    }
136
+
137
+    /*** 注册触摸事件 ***/
138
+    public void registOnTouchListener(BaseOnTouchListener listener) {
139
+        onTouchListeners.add(listener);
140
+    }
141
+
142
+    /*** 解除触摸事件 ***/
143
+    public void unregistOnTouchListener(BaseOnTouchListener listener) {
144
+        onTouchListeners.remove(listener);
145
+    }
146
+
147
+    public boolean isShouldHideInput(View v, MotionEvent event) {
148
+        if (v != null && (v instanceof EditText)) {
149
+            int[] leftTop = {0, 0};
150
+            //获取输入框当前的location位置
151
+            v.getLocationInWindow(leftTop);
152
+            int left = leftTop[0];
153
+            int top = leftTop[1];
154
+            int bottom = top + v.getHeight();
155
+            int right = left + v.getWidth();
156
+            return !(event.getRawX() > left && event.getRawX() < right
157
+                    && event.getRawY() > top && event.getRawY() < bottom);
158
+        }
159
+        return false;
160
+    }
161
+
162
+    /**
163
+     * 设置窗口为全屏
164
+     */
165
+    protected void setWindowIsFullscreen() {
166
+        //隐藏标题
167
+        requestWindowFeature(Window.FEATURE_NO_TITLE);
168
+        //设置全屏
169
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
170
+                WindowManager.LayoutParams.FLAG_FULLSCREEN);
171
+    }
172
+
173
+    /**
174
+     * 是否将屏幕限制为横向, 不调用此方法则不限制横纵切换
175
+     *
176
+     * @param isLandscape true 限制为横向  false 限制为纵向
177
+     */
178
+    protected void setScreenLandscape(boolean isLandscape) {
179
+        if (isLandscape) {
180
+            mScreenOrientation = 1;
181
+        } else {
182
+            mScreenOrientation = 2;
183
+        }
184
+    }
185
+
186
+
187
+    /**
188
+     * 设置屏幕方向
189
+     */
190
+    private void setScreenOrientation() {
191
+        if (mScreenOrientation == 1) {
192
+            //屏幕切换为横向
193
+            if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE) {
194
+                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
195
+            }
196
+        } else if (mScreenOrientation == 2) {
197
+            //屏幕切换为纵向
198
+            if (getRequestedOrientation() != ActivityInfo.SCREEN_ORIENTATION_PORTRAIT) {
199
+                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
200
+            }
201
+        }
202
+    }
203
+
204
+    /**
205
+     * 给整个页面做顶部间距
206
+     */
207
+    public void setStatusHeightForContent() {
208
+        setStatusHeight(findViewById(android.R.id.content));
209
+    }
210
+
211
+    /**
212
+     * 获取状态栏高度 给View添加顶部间距
213
+     */
214
+    protected void setStatusHeight(View statusView) {
215
+//        StatusBarUtil.setTranslucent(this, 0);
216
+        //获取状态栏高度
217
+        int height = -1;
218
+        //获取status_bar_height资源的ID
219
+        int resourceId = getResources().getIdentifier("status_bar_height", "dimen", "android");
220
+        if (resourceId > 0) {
221
+            //根据资源ID获取响应的尺寸值
222
+            height = getResources().getDimensionPixelSize(resourceId);
223
+        }
224
+        LogTool.i("状态栏高度setStatusHeight: " + height);
225
+        //将高度赋值给View
226
+        statusView.setPadding(0, height, 0, 0);
227
+    }
228
+
229
+    private int getNavigationBarHeight() {
230
+        Resources resources = getResources();
231
+        int resourceId = resources.getIdentifier("navigation_bar_height", "dimen", "android");
232
+        int height = resources.getDimensionPixelSize(resourceId);
233
+        Log.v("dbw", "Navi height:" + height);
234
+        return height;
235
+    }
236
+
237
+    /**
238
+     * 设置页面最外层布局 FitsSystemWindows 属性 *
239
+     *
240
+     * @param activity
241
+     * @param value
242
+     */
243
+    public void setFitsSystemWindows(Activity activity, boolean value) {
244
+        ViewGroup contentFrameLayout = activity.findViewById(android.R.id.content);
245
+        View parentView = contentFrameLayout.getChildAt(0);
246
+        if (parentView != null) {
247
+            parentView.setFitsSystemWindows(value);
248
+        }
249
+    }
250
+
251
+
252
+    /**
253
+     * 根据手机或平板设定横屏或竖屏
254
+     */
255
+    protected void setScreenOrientationForPhoneAndPad() {
256
+        if (!isTabletDevice()) {
257
+            //手机,竖屏
258
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);
259
+//            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_PORTRAIT);
260
+        } else {
261
+            //平板,横屏
262
+            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
263
+//            setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_SENSOR_LANDSCAPE);
264
+        }
265
+    }
266
+
267
+    /**
268
+     * 判断是否平板设备
269
+     *
270
+     * @return true:平板,false:手机
271
+     */
272
+    protected boolean isTabletDevice() {
273
+        return (getResources().getConfiguration().screenLayout
274
+                & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE;
275
+    }
276
+
277
+    public Context getContext() {
278
+        return this;
279
+    }
280
+
281
+
282
+    public Gson getGson() {
283
+        if (mGson == null)
284
+            mGson = new Gson();
285
+        return mGson;
286
+    }
287
+
288
+    /**
289
+     * 弹出等待对话框
290
+     */
291
+    public void showLoading(boolean isTouch) {
292
+        mProgressBar = findViewById(R.id.progressBar);
293
+        if (mProgressBar == null)
294
+            return;
295
+        mProgressBar.setVisibility(View.VISIBLE);
296
+        if (!isTouch) {
297
+            getWindow().setFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE, WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
298
+        }
299
+    }
300
+
301
+    /**
302
+     * 隐藏等待对话框
303
+     */
304
+    public void dismissLoading() {
305
+        if (mProgressBar == null)
306
+            return;
307
+        mProgressBar.setVisibility(View.GONE);
308
+        getWindow().clearFlags(WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE);
309
+    }
310
+
311
+}

+ 12 - 0
app/src/main/java/com/mq/oaapp/base/BaseOnTouchListener.java

@@ -0,0 +1,12 @@
1
+package com.mq.oaapp.base;
2
+
3
+import android.view.MotionEvent;
4
+
5
+/**
6
+ * Created by mq on 2017/10/20 0020.
7
+ * 触摸事件接口
8
+ */
9
+
10
+public interface BaseOnTouchListener {
11
+    boolean onTouch(MotionEvent ev);
12
+}

+ 586 - 0
app/src/main/java/com/mq/oaapp/ui/BrowserActivity.java

@@ -0,0 +1,586 @@
1
+package com.mq.oaapp.ui;
2
+
3
+import android.annotation.SuppressLint;
4
+import android.app.Activity;
5
+import android.app.AlertDialog;
6
+import android.content.Context;
7
+import android.content.DialogInterface;
8
+import android.content.Intent;
9
+import android.graphics.PixelFormat;
10
+import android.net.Uri;
11
+import android.os.Build;
12
+import android.os.Bundle;
13
+import android.os.Handler;
14
+import android.os.Message;
15
+import android.os.Process;
16
+import android.text.Editable;
17
+import android.text.TextWatcher;
18
+import android.view.KeyEvent;
19
+import android.view.View;
20
+import android.view.View.OnClickListener;
21
+import android.view.View.OnFocusChangeListener;
22
+import android.view.ViewGroup;
23
+import android.view.WindowManager;
24
+import android.view.inputmethod.InputMethodManager;
25
+import android.widget.Button;
26
+import android.widget.EditText;
27
+import android.widget.FrameLayout;
28
+import android.widget.ImageButton;
29
+import android.widget.LinearLayout;
30
+import android.widget.ProgressBar;
31
+import android.widget.Toast;
32
+
33
+import com.mq.oaapp.R;
34
+import com.mq.oaapp.utils.MyConstant;
35
+import com.mq.oaapp.utils.X5WebView;
36
+import com.tencent.smtt.export.external.interfaces.IX5WebChromeClient.CustomViewCallback;
37
+import com.tencent.smtt.export.external.interfaces.JsResult;
38
+import com.tencent.smtt.sdk.CookieManager;
39
+import com.tencent.smtt.sdk.CookieSyncManager;
40
+import com.tencent.smtt.sdk.DownloadListener;
41
+import com.tencent.smtt.sdk.ValueCallback;
42
+import com.tencent.smtt.sdk.WebChromeClient;
43
+import com.tencent.smtt.sdk.WebSettings;
44
+import com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm;
45
+import com.tencent.smtt.sdk.WebView;
46
+import com.tencent.smtt.sdk.WebViewClient;
47
+import com.tencent.smtt.utils.TbsLog;
48
+import com.xyxsbj.mylibrary.tool.LogTool;
49
+import com.xyxsbj.mylibrary.tool.SPTool;
50
+import com.xyxsbj.mylibrary.tool.ToastTool;
51
+
52
+import java.net.MalformedURLException;
53
+import java.net.URL;
54
+
55
+import butterknife.BindView;
56
+import butterknife.ButterKnife;
57
+import butterknife.OnClick;
58
+
59
+public class BrowserActivity extends Activity {
60
+    @BindView(R.id.navigation1)
61
+    LinearLayout mNavigation1;
62
+    /**
63
+     * 作为一个浏览器的示例展示出来,采用android+web的模式
64
+     */
65
+    private X5WebView mWebView;
66
+    private ViewGroup mViewParent;
67
+    private ImageButton mBack;
68
+    private ImageButton mForward;
69
+    private ImageButton mHome;
70
+    private ImageButton mMore;
71
+    private Button mGo;
72
+    private EditText mUrl;
73
+
74
+    private static String mHomeUrl = "http://www.baidu.com";
75
+    private static final String TAG = "SdkDemo";
76
+    private static final int MAX_LENGTH = 14;
77
+    private boolean mNeedTestPage = false;
78
+
79
+    private final int disable = 120;
80
+    private final int enable = 255;
81
+
82
+    private ProgressBar mPageLoadingProgressBar = null;
83
+
84
+    private ValueCallback<Uri> uploadFile;
85
+
86
+
87
+    @Override
88
+    protected void onCreate(Bundle savedInstanceState) {
89
+        super.onCreate(savedInstanceState);
90
+        getWindow().setFormat(PixelFormat.TRANSLUCENT);
91
+
92
+        Intent intent = getIntent();
93
+        if (intent != null) {
94
+            mHomeUrl = intent.getStringExtra("path");
95
+            LogTool.i("首页地址:" + mHomeUrl);
96
+        }
97
+        //
98
+        try {
99
+            if (Integer.parseInt(Build.VERSION.SDK) >= 11) {
100
+                getWindow()
101
+                        .setFlags(
102
+                                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED,
103
+                                WindowManager.LayoutParams.FLAG_HARDWARE_ACCELERATED);
104
+            }
105
+        } catch (Exception e) {
106
+        }
107
+
108
+        /*
109
+         * getWindow().addFlags(
110
+         * android.view.WindowManager.LayoutParams.FLAG_FULLSCREEN);
111
+         */
112
+        setContentView(R.layout.activity_browser);
113
+        ButterKnife.bind(this);
114
+        mViewParent = (ViewGroup) findViewById(R.id.webView1);
115
+
116
+        initBtnListenser();
117
+
118
+        mTestHandler.sendEmptyMessageDelayed(MSG_INIT_UI, 10);
119
+
120
+    }
121
+
122
+    private void changGoForwardButton(WebView view) {
123
+        if (view.canGoBack())
124
+            mBack.setAlpha(enable);
125
+        else
126
+            mBack.setAlpha(disable);
127
+        if (view.canGoForward())
128
+            mForward.setAlpha(enable);
129
+        else
130
+            mForward.setAlpha(disable);
131
+        if (view.getUrl() != null && view.getUrl().equalsIgnoreCase(mHomeUrl)) {
132
+            mHome.setAlpha(disable);
133
+            mHome.setEnabled(false);
134
+        } else {
135
+            mHome.setAlpha(enable);
136
+            mHome.setEnabled(true);
137
+        }
138
+    }
139
+
140
+    private void initProgressBar() {
141
+        mPageLoadingProgressBar = (ProgressBar) findViewById(R.id.progressBar1);// new
142
+        // ProgressBar(getApplicationContext(),
143
+        // null,
144
+        // android.R.attr.progressBarStyleHorizontal);
145
+        mPageLoadingProgressBar.setMax(100);
146
+        mPageLoadingProgressBar.setProgressDrawable(this.getResources()
147
+                .getDrawable(R.drawable.color_progressbar));
148
+    }
149
+
150
+    private void init() {
151
+        mNavigation1.setVisibility(View.GONE);
152
+
153
+        mWebView = new X5WebView(this, null);
154
+
155
+        mViewParent.addView(mWebView, new FrameLayout.LayoutParams(
156
+                FrameLayout.LayoutParams.FILL_PARENT,
157
+                FrameLayout.LayoutParams.FILL_PARENT));
158
+
159
+        initProgressBar();
160
+
161
+        mWebView.setWebViewClient(new WebViewClient() {
162
+            @Override
163
+            public boolean shouldOverrideUrlLoading(WebView view, String url) {
164
+                return false;
165
+            }
166
+
167
+            @Override
168
+            public void onPageFinished(WebView view, String url) {
169
+                super.onPageFinished(view, url);
170
+                // mTestHandler.sendEmptyMessage(MSG_OPEN_TEST_URL);
171
+                mTestHandler.sendEmptyMessageDelayed(MSG_OPEN_TEST_URL, 5000);// 5s?
172
+                if (Integer.parseInt(Build.VERSION.SDK) >= 16)
173
+                    changGoForwardButton(view);
174
+                /* mWebView.showLog("test Log"); */
175
+            }
176
+        });
177
+
178
+        mWebView.setWebChromeClient(new WebChromeClient() {
179
+
180
+            @Override
181
+            public boolean onJsConfirm(WebView arg0, String arg1, String arg2,
182
+                                       JsResult arg3) {
183
+                return super.onJsConfirm(arg0, arg1, arg2, arg3);
184
+            }
185
+
186
+            View myVideoView;
187
+            View myNormalView;
188
+            CustomViewCallback callback;
189
+
190
+            // /////////////////////////////////////////////////////////
191
+            //
192
+
193
+            /**
194
+             * 全屏播放配置
195
+             */
196
+            @Override
197
+            public void onShowCustomView(View view,
198
+                                         CustomViewCallback customViewCallback) {
199
+                FrameLayout normalView = (FrameLayout) findViewById(R.id.web_filechooser);
200
+                ViewGroup viewGroup = (ViewGroup) normalView.getParent();
201
+                viewGroup.removeView(normalView);
202
+                viewGroup.addView(view);
203
+                myVideoView = view;
204
+                myNormalView = normalView;
205
+                callback = customViewCallback;
206
+            }
207
+
208
+            @Override
209
+            public void onHideCustomView() {
210
+                if (callback != null) {
211
+                    callback.onCustomViewHidden();
212
+                    callback = null;
213
+                }
214
+                if (myVideoView != null) {
215
+                    ViewGroup viewGroup = (ViewGroup) myVideoView.getParent();
216
+                    viewGroup.removeView(myVideoView);
217
+                    viewGroup.addView(myNormalView);
218
+                }
219
+            }
220
+
221
+            @Override
222
+            public boolean onJsAlert(WebView arg0, String arg1, String arg2,
223
+                                     JsResult arg3) {
224
+                /**
225
+                 * 这里写入你自定义的window alert
226
+                 */
227
+                return super.onJsAlert(null, arg1, arg2, arg3);
228
+            }
229
+
230
+            @Override
231
+            public void onProgressChanged(WebView webView, int i) {
232
+                super.onProgressChanged(webView, i);
233
+                if (i == 100) {
234
+                    mPageLoadingProgressBar.setVisibility(View.GONE);//加载完网页进度条消失
235
+                } else {
236
+                    mPageLoadingProgressBar.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
237
+                    mPageLoadingProgressBar.setProgress(i);//设置进度值
238
+                }
239
+            }
240
+        });
241
+
242
+        mWebView.setDownloadListener(new DownloadListener() {
243
+
244
+            @Override
245
+            public void onDownloadStart(String arg0, String arg1, String arg2,
246
+                                        String arg3, long arg4) {
247
+                TbsLog.d(TAG, "url: " + arg0);
248
+                new AlertDialog.Builder(BrowserActivity.this)
249
+                        .setTitle("allow to download?")
250
+                        .setPositiveButton("yes",
251
+                                new DialogInterface.OnClickListener() {
252
+                                    @Override
253
+                                    public void onClick(DialogInterface dialog,
254
+                                                        int which) {
255
+                                        ToastTool.showLong("fake message: i'll download...");
256
+                                    }
257
+                                })
258
+                        .setNegativeButton("no",
259
+                                new DialogInterface.OnClickListener() {
260
+
261
+                                    @Override
262
+                                    public void onClick(DialogInterface dialog,
263
+                                                        int which) {
264
+                                        // TODO Auto-generated method stub
265
+                                        ToastTool.showLong("fake message: refuse download...");
266
+                                    }
267
+                                })
268
+                        .setOnCancelListener(
269
+                                new DialogInterface.OnCancelListener() {
270
+
271
+                                    @Override
272
+                                    public void onCancel(DialogInterface dialog) {
273
+                                        // TODO Auto-generated method stub
274
+                                        ToastTool.showLong("fake message: refuse download...");
275
+                                    }
276
+                                }).show();
277
+            }
278
+        });
279
+
280
+        WebSettings webSetting = mWebView.getSettings();
281
+        webSetting.setAllowFileAccess(true);
282
+        webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
283
+        webSetting.setSupportZoom(true);
284
+        webSetting.setBuiltInZoomControls(true);
285
+        webSetting.setUseWideViewPort(true);
286
+        webSetting.setSupportMultipleWindows(false);
287
+        // webSetting.setLoadWithOverviewMode(true);
288
+        webSetting.setAppCacheEnabled(true);
289
+        // webSetting.setDatabaseEnabled(true);
290
+        webSetting.setDomStorageEnabled(true);
291
+        webSetting.setJavaScriptEnabled(true);
292
+        webSetting.setGeolocationEnabled(true);
293
+        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
294
+        webSetting.setAppCachePath(this.getDir("appcache", 0).getPath());
295
+        webSetting.setDatabasePath(this.getDir("databases", 0).getPath());
296
+        webSetting.setGeolocationDatabasePath(this.getDir("geolocation", 0)
297
+                .getPath());
298
+        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
299
+        webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
300
+        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
301
+        // webSetting.setPreFectch(true);
302
+        long time = System.currentTimeMillis();
303
+        mWebView.loadUrl(mHomeUrl);
304
+        TbsLog.d("time-cost", "cost time: "
305
+                + (System.currentTimeMillis() - time));
306
+        CookieSyncManager.createInstance(this);
307
+        CookieSyncManager.getInstance().sync();
308
+    }
309
+
310
+    private void initBtnListenser() {
311
+        mBack = (ImageButton) findViewById(R.id.btnBack1);
312
+        mForward = (ImageButton) findViewById(R.id.btnForward1);
313
+        mHome = (ImageButton) findViewById(R.id.btnHome1);
314
+        mGo = (Button) findViewById(R.id.btnGo1);
315
+        mUrl = (EditText) findViewById(R.id.editUrl1);
316
+        mMore = (ImageButton) findViewById(R.id.btnMore);
317
+        if (Integer.parseInt(Build.VERSION.SDK) >= 16) {
318
+            mBack.setAlpha(disable);
319
+            mForward.setAlpha(disable);
320
+            mHome.setAlpha(disable);
321
+        }
322
+        mHome.setEnabled(false);
323
+
324
+        mBack.setOnClickListener(new OnClickListener() {
325
+
326
+            @Override
327
+            public void onClick(View v) {
328
+                if (mWebView != null && mWebView.canGoBack())
329
+                    mWebView.goBack();
330
+            }
331
+        });
332
+
333
+        mForward.setOnClickListener(new OnClickListener() {
334
+
335
+            @Override
336
+            public void onClick(View v) {
337
+                if (mWebView != null && mWebView.canGoForward())
338
+                    mWebView.goForward();
339
+            }
340
+        });
341
+
342
+        mGo.setOnClickListener(new OnClickListener() {
343
+
344
+            @Override
345
+            public void onClick(View v) {
346
+                String url = mUrl.getText().toString();
347
+                mWebView.loadUrl(url);
348
+                mWebView.requestFocus();
349
+            }
350
+        });
351
+
352
+        mMore.setOnClickListener(new OnClickListener() {
353
+
354
+            @Override
355
+            public void onClick(View v) {
356
+                Toast.makeText(BrowserActivity.this, "not completed",
357
+                        Toast.LENGTH_LONG).show();
358
+            }
359
+        });
360
+
361
+        mUrl.setOnFocusChangeListener(new OnFocusChangeListener() {
362
+
363
+            @Override
364
+            public void onFocusChange(View v, boolean hasFocus) {
365
+                if (hasFocus) {
366
+                    mGo.setVisibility(View.VISIBLE);
367
+                    if (null == mWebView.getUrl())
368
+                        return;
369
+                    if (mWebView.getUrl().equalsIgnoreCase(mHomeUrl)) {
370
+                        mUrl.setText("");
371
+                        mGo.setText("首页");
372
+                        mGo.setTextColor(0X6F0F0F0F);
373
+                    } else {
374
+                        mUrl.setText(mWebView.getUrl());
375
+                        mGo.setText("进入");
376
+                        mGo.setTextColor(0X6F0000CD);
377
+                    }
378
+                } else {
379
+                    mGo.setVisibility(View.GONE);
380
+                    String title = mWebView.getTitle();
381
+                    if (title != null && title.length() > MAX_LENGTH)
382
+                        mUrl.setText(title.subSequence(0, MAX_LENGTH) + "...");
383
+                    else
384
+                        mUrl.setText(title);
385
+                    InputMethodManager imm = (InputMethodManager) getSystemService(Context.INPUT_METHOD_SERVICE);
386
+                    imm.hideSoftInputFromWindow(v.getWindowToken(), 0);
387
+                }
388
+            }
389
+
390
+        });
391
+
392
+        mUrl.addTextChangedListener(new TextWatcher() {
393
+
394
+            @Override
395
+            public void afterTextChanged(Editable s) {
396
+                // TODO Auto-generated method stub
397
+
398
+                String url = null;
399
+                if (mUrl.getText() != null) {
400
+                    url = mUrl.getText().toString();
401
+                }
402
+
403
+                if (url == null
404
+                        || mUrl.getText().toString().equalsIgnoreCase("")) {
405
+                    mGo.setText("请输入网址");
406
+                    mGo.setTextColor(0X6F0F0F0F);
407
+                } else {
408
+                    mGo.setText("进入");
409
+                    mGo.setTextColor(0X6F0000CD);
410
+                }
411
+            }
412
+
413
+            @Override
414
+            public void beforeTextChanged(CharSequence arg0, int arg1,
415
+                                          int arg2, int arg3) {
416
+                // TODO Auto-generated method stub
417
+
418
+            }
419
+
420
+            @Override
421
+            public void onTextChanged(CharSequence arg0, int arg1, int arg2,
422
+                                      int arg3) {
423
+                // TODO Auto-generated method stub
424
+
425
+            }
426
+        });
427
+
428
+        mHome.setOnClickListener(new OnClickListener() {
429
+
430
+            @Override
431
+            public void onClick(View v) {
432
+                if (mWebView != null)
433
+                    mWebView.loadUrl(mHomeUrl);
434
+            }
435
+        });
436
+    }
437
+
438
+    boolean[] m_selected = new boolean[]{true, true, true, true, false,
439
+            false, true};
440
+
441
+    @Override
442
+    public boolean onKeyDown(int keyCode, KeyEvent event) {
443
+
444
+        if (keyCode == KeyEvent.KEYCODE_BACK) {
445
+            if (mWebView != null && mWebView.canGoBack()) {
446
+                mWebView.goBack();
447
+                if (Integer.parseInt(Build.VERSION.SDK) >= 16)
448
+                    changGoForwardButton(mWebView);
449
+                return true;
450
+            } else
451
+                return super.onKeyDown(keyCode, event);
452
+        }
453
+        return super.onKeyDown(keyCode, event);
454
+    }
455
+
456
+    @Override
457
+    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
458
+        TbsLog.d(TAG, "onActivityResult, requestCode:" + requestCode
459
+                + ",resultCode:" + resultCode);
460
+
461
+        if (resultCode == RESULT_OK) {
462
+            switch (requestCode) {
463
+                case 0:
464
+                    if (null != uploadFile) {
465
+                        Uri result = data == null || resultCode != RESULT_OK ? null
466
+                                : data.getData();
467
+                        uploadFile.onReceiveValue(result);
468
+                        uploadFile = null;
469
+                    }
470
+                    break;
471
+                default:
472
+                    break;
473
+            }
474
+        } else if (resultCode == RESULT_CANCELED) {
475
+            if (null != uploadFile) {
476
+                uploadFile.onReceiveValue(null);
477
+                uploadFile = null;
478
+            }
479
+
480
+        }
481
+
482
+    }
483
+
484
+    @Override
485
+    protected void onNewIntent(Intent intent) {
486
+        if (intent == null || mWebView == null || intent.getData() == null)
487
+            return;
488
+        mWebView.loadUrl(intent.getStringExtra("path"));
489
+    }
490
+
491
+    @Override
492
+    protected void onDestroy() {
493
+        if (mTestHandler != null)
494
+            mTestHandler.removeCallbacksAndMessages(null);
495
+        if (mWebView != null)
496
+            mWebView.destroy();
497
+        super.onDestroy();
498
+    }
499
+
500
+    public static final int MSG_OPEN_TEST_URL = 0;
501
+    public static final int MSG_INIT_UI = 1;
502
+    private final int mUrlStartNum = 0;
503
+    private int mCurrentUrl = mUrlStartNum;
504
+
505
+    @SuppressLint("HandlerLeak")
506
+    private Handler mTestHandler = new Handler() {
507
+        @Override
508
+        public void handleMessage(Message msg) {
509
+            switch (msg.what) {
510
+                case MSG_OPEN_TEST_URL:
511
+                    if (!mNeedTestPage) {
512
+                        return;
513
+                    }
514
+
515
+                    String testUrl = "http://www.baidu.com";
516
+                    if (mWebView != null) {
517
+                        mWebView.loadUrl(testUrl);
518
+                    }
519
+
520
+                    mCurrentUrl++;
521
+                    break;
522
+                case MSG_INIT_UI:
523
+                    init();
524
+                    break;
525
+            }
526
+            super.handleMessage(msg);
527
+        }
528
+    };
529
+
530
+    @OnClick({R.id.bar_back, R.id.bar_path, R.id.btnExit1})
531
+    public void onViewClicked(View view) {
532
+        switch (view.getId()) {
533
+            case R.id.bar_back:
534
+                //退出软件
535
+                finish();
536
+                break;
537
+            case R.id.bar_path:
538
+                if (mNavigation1.getVisibility() == View.VISIBLE) {
539
+                    mNavigation1.setVisibility(View.GONE);
540
+                } else {
541
+                    mNavigation1.setVisibility(View.VISIBLE);
542
+                }
543
+                break;
544
+            case R.id.btnExit1:
545
+                //退出登录
546
+                //设置非自动登录, 并跳转回首页
547
+                new AlertDialog.Builder(BrowserActivity.this)
548
+                        .setMessage("是否要退出并切换用户?")
549
+                        .setNegativeButton("取消", null)
550
+                        .setPositiveButton("确认", new DialogInterface.OnClickListener() {
551
+                            @Override
552
+                            public void onClick(DialogInterface dialog, int which) {
553
+                                loginOut();//退出登录
554
+                            }
555
+                        }).create().show();
556
+                break;
557
+        }
558
+    }
559
+
560
+    //退出登录
561
+    private void loginOut() {
562
+        clearWebCache();//清除Web缓存
563
+        //关闭自动登录
564
+        SPTool.save(MyConstant.AUTO_LOGIN, "1");
565
+        //清除用户信息
566
+        SPTool.save(MyConstant.USER_CODE, "");
567
+        //进入登录页
568
+        startActivity(new Intent(BrowserActivity.this, LoginActivity.class));
569
+        finish();
570
+    }
571
+
572
+    //清除Web缓存
573
+    private void clearWebCache() {
574
+        CookieSyncManager.createInstance(BrowserActivity.this.getApplicationContext());
575
+        CookieManager cookieManager = CookieManager.getInstance();
576
+        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
577
+            cookieManager.removeSessionCookies(null);
578
+            cookieManager.removeAllCookie();
579
+            cookieManager.flush();
580
+        } else {
581
+            cookieManager.removeSessionCookies(null);
582
+            cookieManager.removeAllCookie();
583
+            CookieSyncManager.getInstance().sync();
584
+        }
585
+    }
586
+}

+ 146 - 0
app/src/main/java/com/mq/oaapp/ui/LoginActivity.java

@@ -0,0 +1,146 @@
1
+package com.mq.oaapp.ui;
2
+
3
+import android.content.Intent;
4
+import android.net.Uri;
5
+import android.widget.EditText;
6
+
7
+import com.lzy.okgo.OkGo;
8
+import com.lzy.okgo.callback.StringCallback;
9
+import com.lzy.okgo.model.Response;
10
+import com.mq.oaapp.R;
11
+import com.mq.oaapp.UrlPath;
12
+import com.mq.oaapp.base.BaseActivity;
13
+import com.mq.oaapp.utils.MyConstant;
14
+import com.xyxsbj.mylibrary.tool.ETTool;
15
+import com.xyxsbj.mylibrary.tool.LogTool;
16
+import com.xyxsbj.mylibrary.tool.SPTool;
17
+import com.xyxsbj.mylibrary.tool.StringTool;
18
+import com.xyxsbj.mylibrary.tool.ToastTool;
19
+
20
+import org.json.JSONException;
21
+import org.json.JSONObject;
22
+
23
+import java.util.HashMap;
24
+import java.util.Map;
25
+
26
+import butterknife.BindView;
27
+import butterknife.OnClick;
28
+
29
+/**
30
+ * 创建人 mQ
31
+ * 创建时间 2019/9/24 0024 18:02
32
+ * 文件名称 LoginActivity
33
+ * 说明:
34
+ **/
35
+public class LoginActivity extends BaseActivity {
36
+    @BindView(R.id.et_path)
37
+    EditText mEtPath;
38
+    @BindView(R.id.et_user)
39
+    EditText mEtUser;
40
+    @BindView(R.id.et_pwd)
41
+    EditText mEtPwd;
42
+
43
+    @Override
44
+    protected int getLayoutRes() {
45
+        setActivityLightOrDark(false);
46
+        return R.layout.activity_login;
47
+    }
48
+
49
+    @Override
50
+    protected void init() {
51
+
52
+        //检测是否自动登录
53
+        String autoLogin = (String) SPTool.get(MyConstant.AUTO_LOGIN, "");
54
+        String userCode = (String) SPTool.get(MyConstant.USER_CODE, "");
55
+        if (autoLogin.equals("0") && !userCode.equals("")) {
56
+            //开启自动登录,且用户不为空,则进入主页
57
+            startHome(userCode);
58
+        }
59
+    }
60
+
61
+    @Override
62
+    protected void workTask() {
63
+        mEtUser.setText((String) SPTool.get(MyConstant.USER_NAME, ""));
64
+//        mEtPwd.setText("123456");
65
+    }
66
+
67
+    @OnClick(R.id.btn_login)
68
+    public void onViewClicked() {
69
+        //点击登录
70
+        String user = ETTool.getData(mEtUser);
71
+        String pwd = ETTool.getData(mEtPwd);
72
+        if (StringTool.isEmpty(user)) {
73
+            ToastTool.showLong("请输入账号");
74
+            return;
75
+        }
76
+        if (StringTool.isEmpty(pwd)) {
77
+            ToastTool.showLong("请输入密码");
78
+            return;
79
+        }
80
+        //存储账号
81
+        SPTool.save(MyConstant.USER_NAME, user);
82
+        //发起登录请求
83
+        login(user, pwd);
84
+    }
85
+
86
+    //后台登录
87
+    private void login(String name, String pwd) {
88
+        Map<String, String> map = new HashMap<>();
89
+        map.put("userAccount", name);
90
+        map.put("userPasswd", pwd);
91
+        String data = getGson().toJson(map);
92
+        LogTool.d("请求参数:" + data);
93
+
94
+        showLoading(false);
95
+        OkGo.<String>post(UrlPath.LOGIN)
96
+                .upJson(data)
97
+                .execute(getCallback());
98
+    }
99
+    //后台登录结果
100
+    public StringCallback getCallback() {
101
+        return new StringCallback() {
102
+            @Override
103
+            public void onSuccess(Response<String> response) {
104
+                ToastTool.showLong("登录成功");
105
+                dismissLoading();
106
+                try {
107
+                    JSONObject jsonObject = new JSONObject(response.body());
108
+                    JSONObject data = jsonObject.optJSONObject("data");
109
+                    if (data == null) {
110
+                        ToastTool.showLong("未获取到登录信息");
111
+                        return;
112
+                    }
113
+                    startHome(data.optString("code"));
114
+                } catch (JSONException e) {
115
+                    e.printStackTrace();
116
+                }
117
+            }
118
+
119
+            @Override
120
+            public void onError(Response<String> response) {
121
+                super.onError(response);
122
+                dismissLoading();
123
+                ToastTool.showLong("登录失败");
124
+            }
125
+        };
126
+    }
127
+
128
+    /**
129
+     * 进入用户首页
130
+     */
131
+    private void startHome(String code) {
132
+        SPTool.save(MyConstant.AUTO_LOGIN, "0");//自动登录
133
+        SPTool.save(MyConstant.USER_CODE, code);//存储用户代码
134
+        LogTool.i("进入首页Code:"+code);
135
+//        Uri uri = Uri.parse(UrlPath.HOME + "?code=" + code);
136
+//        Intent intent = new Intent(getContext(), BrowserActivity.class);
137
+//        intent.setData(uri);
138
+//        startActivity(intent);
139
+//        finish();
140
+        Intent intent = new Intent(getContext(), BrowserActivity.class);
141
+        intent.putExtra("path",UrlPath.HOME + "?code=" + code);
142
+        startActivity(intent);
143
+        finish();
144
+    }
145
+
146
+}

+ 23 - 0
app/src/main/java/com/mq/oaapp/ui/MainActivity.java

@@ -0,0 +1,23 @@
1
+package com.mq.oaapp.ui;
2
+
3
+import android.support.v7.app.AppCompatActivity;
4
+import android.os.Bundle;
5
+
6
+import com.xyxsbj.mylibrary.tool.ActivityTool;
7
+
8
+/**
9
+ * 创建人 mQ
10
+ * 创建时间 2019/9/24 0024 18:01
11
+ * 文件名称 MainActivity
12
+ * 说明:  开机页
13
+ **/
14
+public class MainActivity extends AppCompatActivity {
15
+
16
+    @Override
17
+    protected void onCreate(Bundle savedInstanceState) {
18
+        super.onCreate(savedInstanceState);
19
+//        setContentView(R.layout.activity_main);
20
+        ActivityTool.startActivity(this, LoginActivity.class);
21
+        finish();
22
+    }
23
+}

+ 163 - 0
app/src/main/java/com/mq/oaapp/ui/WebActivity.java

@@ -0,0 +1,163 @@
1
+package com.mq.oaapp.ui;
2
+
3
+import android.view.View;
4
+import android.webkit.CookieSyncManager;
5
+import android.widget.ImageButton;
6
+import android.widget.ImageView;
7
+import android.widget.LinearLayout;
8
+import android.widget.ProgressBar;
9
+
10
+import com.mq.oaapp.R;
11
+import com.mq.oaapp.base.BaseActivity;
12
+import com.mq.oaapp.utils.X5WebView;
13
+import com.tencent.smtt.sdk.WebChromeClient;
14
+import com.tencent.smtt.sdk.WebViewClient;
15
+import com.xyxsbj.mylibrary.tool.LogTool;
16
+
17
+import butterknife.BindView;
18
+import butterknife.OnClick;
19
+
20
+
21
+/**
22
+ * 创建人 mQ
23
+ * 创建时间 2019/7/4 0004 17:44
24
+ * 文件名称 WebActivity
25
+ * 说明: web页面
26
+ **/
27
+public class WebActivity extends BaseActivity {
28
+
29
+
30
+    @BindView(R.id.bar_back)
31
+    ImageView mBarBack;
32
+    @BindView(R.id.progressBar)
33
+    ProgressBar mProgressBar;
34
+    @BindView(R.id.webView)
35
+    X5WebView mWebView;
36
+    @BindView(R.id.btnBack)
37
+    ImageButton mBtnBack;
38
+    @BindView(R.id.btnForward)
39
+    ImageButton mBtnForward;
40
+    @BindView(R.id.btnHome)
41
+    ImageButton mBtnHome;
42
+    @BindView(R.id.bottom_layout)
43
+    LinearLayout mBottomLayout;
44
+
45
+    private final int disable = 120;
46
+    private final int enable = 255;
47
+
48
+    private String mHomeUrl = "http://www.baidu.com";
49
+
50
+    @Override
51
+    protected int getLayoutRes() {
52
+        return R.layout.activity_web;
53
+    }
54
+
55
+    @Override
56
+    protected void init() {
57
+        setStatusHeightForContent();
58
+        mProgressBar.setMax(100);
59
+        initWebView();
60
+    }
61
+
62
+    @Override
63
+    protected void workTask() {
64
+        mWebView.loadUrl(mHomeUrl);
65
+//        mWebView.loadData(mHomeUrl, "text/html", "UTF-8");
66
+        mBtnHome.setEnabled(false);
67
+        mBtnHome.setAlpha(disable);
68
+    }
69
+
70
+
71
+    private void initWebView() {
72
+
73
+        mWebView.setWebViewClient(new WebViewClient() {
74
+            @Override
75
+            public boolean shouldOverrideUrlLoading(com.tencent.smtt.sdk.WebView webView, String s) {
76
+                return super.shouldOverrideUrlLoading(webView, s);
77
+            }
78
+
79
+            @Override
80
+            public void onPageFinished(com.tencent.smtt.sdk.WebView webView, String s) {
81
+                super.onPageFinished(webView, s);
82
+                changGoForwardButton(webView);
83
+            }
84
+        });
85
+        mWebView.setWebChromeClient(new WebChromeClient() {
86
+            @Override
87
+            public void onProgressChanged(com.tencent.smtt.sdk.WebView webView, int i) {
88
+                super.onProgressChanged(webView, i);
89
+                if (i == 100) {
90
+                    mProgressBar.setVisibility(View.GONE);//加载完网页进度条消失
91
+                } else {
92
+                    mProgressBar.setVisibility(View.VISIBLE);//开始加载网页时显示进度条
93
+                    mProgressBar.setProgress(i);//设置进度值
94
+                }
95
+            }
96
+        });
97
+
98
+        com.tencent.smtt.sdk.WebSettings webSetting = mWebView.getSettings();
99
+        webSetting.setAllowFileAccess(true);
100
+        webSetting.setLayoutAlgorithm(com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm.NARROW_COLUMNS);
101
+        webSetting.setSupportZoom(true);
102
+        webSetting.setBuiltInZoomControls(true);
103
+        webSetting.setUseWideViewPort(true);
104
+        webSetting.setSupportMultipleWindows(false);
105
+        // webSetting.setLoadWithOverviewMode(true);
106
+        webSetting.setAppCacheEnabled(true);
107
+        // webSetting.setDatabaseEnabled(true);
108
+        webSetting.setDomStorageEnabled(true);
109
+        webSetting.setJavaScriptEnabled(true);
110
+        webSetting.setGeolocationEnabled(true);
111
+        webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
112
+        webSetting.setAppCachePath(getDir("appcache", 0).getPath());
113
+        webSetting.setDatabasePath(getDir("databases", 0).getPath());
114
+        webSetting.setGeolocationDatabasePath(getDir("geolocation", 0)
115
+                .getPath());
116
+        // webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
117
+        webSetting.setPluginState(com.tencent.smtt.sdk.WebSettings.PluginState.ON_DEMAND);
118
+        // webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
119
+        // webSetting.setPreFectch(true);
120
+
121
+        CookieSyncManager.createInstance(getContext());
122
+        CookieSyncManager.getInstance().sync();
123
+    }
124
+
125
+    private void changGoForwardButton(com.tencent.smtt.sdk.WebView view) {
126
+        if (view.canGoBack())
127
+            mBtnBack.setAlpha(enable);
128
+        else
129
+            mBtnBack.setAlpha(disable);
130
+        if (view.canGoForward())
131
+            mBtnForward.setAlpha(enable);
132
+        else
133
+            mBtnForward.setAlpha(disable);
134
+        LogTool.i("changGoForwardButton加载地址: " + view.getUrl());
135
+        if (view.getUrl() != null && view.getUrl().equalsIgnoreCase(mHomeUrl)) {
136
+            mBtnHome.setAlpha(disable);
137
+            mBtnHome.setEnabled(false);
138
+        } else {
139
+            mBtnHome.setAlpha(enable);
140
+            mBtnHome.setEnabled(true);
141
+        }
142
+    }
143
+
144
+    @OnClick({R.id.bar_back, R.id.btnBack, R.id.btnForward, R.id.btnHome})
145
+    public void onViewClicked(View view) {
146
+        switch (view.getId()) {
147
+            case R.id.bar_back:
148
+                onBackPressed();
149
+                break;
150
+            case R.id.btnBack:
151
+                if (mWebView != null && mWebView.canGoBack())
152
+                    mWebView.goBack();
153
+                break;
154
+            case R.id.btnForward:
155
+                if (mWebView != null && mWebView.canGoForward())
156
+                    mWebView.goForward();
157
+                break;
158
+            case R.id.btnHome:
159
+                workTask();
160
+                break;
161
+        }
162
+    }
163
+}

+ 20 - 0
app/src/main/java/com/mq/oaapp/utils/MyConstant.java

@@ -0,0 +1,20 @@
1
+package com.mq.oaapp.utils;
2
+
3
+/**
4
+ * 创建人 mQ
5
+ * 创建时间 2019/10/15 0015 16:15
6
+ * 文件名称 MyConstant
7
+ * 说明:  常量类
8
+ **/
9
+public class MyConstant {
10
+
11
+    //自动登录 0自动登录
12
+    public static final String AUTO_LOGIN = "auto_login";
13
+    //用户账号
14
+    public static final String USER_NAME = "user_name";
15
+    //用户密码
16
+    public static final String USER_PWD = "user_pwd";
17
+    //用户代码
18
+    public static final String USER_CODE = "user_code";
19
+
20
+}

+ 6 - 0
app/src/main/java/com/mq/oaapp/utils/WebViewJavaScriptFunction.java

@@ -0,0 +1,6 @@
1
+package com.mq.oaapp.utils;
2
+
3
+public interface WebViewJavaScriptFunction {
4
+
5
+	void onJsFunctionCalled(String tag);
6
+}

+ 92 - 0
app/src/main/java/com/mq/oaapp/utils/X5WebView.java

@@ -0,0 +1,92 @@
1
+package com.mq.oaapp.utils;
2
+
3
+import android.annotation.SuppressLint;
4
+import android.content.Context;
5
+import android.graphics.Canvas;
6
+import android.util.AttributeSet;
7
+import android.view.View;
8
+import android.widget.TextView;
9
+
10
+import com.tencent.smtt.sdk.WebSettings;
11
+import com.tencent.smtt.sdk.WebSettings.LayoutAlgorithm;
12
+import com.tencent.smtt.sdk.WebView;
13
+import com.tencent.smtt.sdk.WebViewClient;
14
+
15
+public class X5WebView extends WebView {
16
+	TextView title;
17
+	private WebViewClient client = new WebViewClient() {
18
+		/**
19
+		 * 防止加载网页时调起系统浏览器
20
+		 */
21
+		public boolean shouldOverrideUrlLoading(WebView view, String url) {
22
+			view.loadUrl(url);
23
+			return true;
24
+		}
25
+	};
26
+
27
+	@SuppressLint("SetJavaScriptEnabled")
28
+	public X5WebView(Context arg0, AttributeSet arg1) {
29
+		super(arg0, arg1);
30
+		this.setWebViewClient(client);
31
+		// this.setWebChromeClient(chromeClient);
32
+		// WebStorage webStorage = WebStorage.getInstance();
33
+		initWebViewSettings();
34
+		this.getView().setClickable(true);
35
+	}
36
+
37
+	private void initWebViewSettings() {
38
+		WebSettings webSetting = this.getSettings();
39
+		webSetting.setJavaScriptEnabled(true);
40
+		webSetting.setJavaScriptCanOpenWindowsAutomatically(true);
41
+		webSetting.setAllowFileAccess(true);
42
+		webSetting.setLayoutAlgorithm(LayoutAlgorithm.NARROW_COLUMNS);
43
+		webSetting.setSupportZoom(true);
44
+		webSetting.setBuiltInZoomControls(true);
45
+		webSetting.setUseWideViewPort(true);
46
+		webSetting.setSupportMultipleWindows(true);
47
+		// webSetting.setLoadWithOverviewMode(true);
48
+		webSetting.setAppCacheEnabled(true);
49
+		// webSetting.setDatabaseEnabled(true);
50
+		webSetting.setDomStorageEnabled(true);
51
+		webSetting.setGeolocationEnabled(true);
52
+		webSetting.setAppCacheMaxSize(Long.MAX_VALUE);
53
+		// webSetting.setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);
54
+		webSetting.setPluginState(WebSettings.PluginState.ON_DEMAND);
55
+		// webSetting.setRenderPriority(WebSettings.RenderPriority.HIGH);
56
+		webSetting.setCacheMode(WebSettings.LOAD_NO_CACHE);
57
+
58
+		// this.getSettingsExtension().setPageCacheCapacity(IX5WebSettings.DEFAULT_CACHE_CAPACITY);//extension
59
+		// settings 的设计
60
+	}
61
+
62
+	@Override
63
+	protected boolean drawChild(Canvas canvas, View child, long drawingTime) {
64
+		boolean ret = super.drawChild(canvas, child, drawingTime);
65
+//		canvas.save();
66
+//		Paint paint = new Paint();
67
+//		paint.setColor(0x7fff0000);
68
+//		paint.setTextSize(24.f);
69
+//		paint.setAntiAlias(true);
70
+//		if (getX5WebViewExtension() != null) {
71
+//			canvas.drawText(this.getContext().getPackageName() + "-pid:"
72
+//					+ android.os.Process.myPid(), 10, 50, paint);
73
+//			canvas.drawText(
74
+//					"X5  Core:" + QbSdk.getTbsVersion(this.getContext()), 10,
75
+//					100, paint);
76
+//		} else {
77
+//			canvas.drawText(this.getContext().getPackageName() + "-pid:"
78
+//					+ android.os.Process.myPid(), 10, 50, paint);
79
+//			canvas.drawText("Sys Core", 10, 100, paint);
80
+//		}
81
+//		canvas.drawText(Build.MANUFACTURER, 10, 150, paint);
82
+//		canvas.drawText(Build.MODEL, 10, 200, paint);
83
+//		canvas.restore();
84
+		return ret;
85
+	}
86
+
87
+	public X5WebView(Context arg0) {
88
+		super(arg0);
89
+		setBackgroundColor(85621);
90
+	}
91
+
92
+}

BIN
app/src/main/res/drawable-hdpi/ic_exit_to_app_grey_700_24dp.png


BIN
app/src/main/res/drawable-hdpi/ic_home_grey_700_24dp.png


BIN
app/src/main/res/drawable-hdpi/ic_keyboard_arrow_left_black_36dp.png


BIN
app/src/main/res/drawable-hdpi/ic_keyboard_arrow_left_grey_700_24dp.png


BIN
app/src/main/res/drawable-hdpi/ic_keyboard_arrow_right_grey_700_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_exit_to_app_grey_700_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_home_grey_700_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_keyboard_arrow_left_black_36dp.png


BIN
app/src/main/res/drawable-mdpi/ic_keyboard_arrow_left_grey_700_24dp.png


BIN
app/src/main/res/drawable-mdpi/ic_keyboard_arrow_right_grey_700_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_exit_to_app_grey_700_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_home_grey_700_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_left_black_36dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_left_grey_700_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_keyboard_arrow_right_grey_700_24dp.png


BIN
app/src/main/res/drawable-xhdpi/ic_login_path.png


BIN
app/src/main/res/drawable-xhdpi/ic_login_pwd.png


BIN
app/src/main/res/drawable-xhdpi/ic_login_title.png


BIN
app/src/main/res/drawable-xhdpi/ic_login_top.png


BIN
app/src/main/res/drawable-xhdpi/ic_login_user.png


BIN
app/src/main/res/drawable-xxhdpi/ic_exit_to_app_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_home_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_left_black_36dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_left_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxhdpi/ic_keyboard_arrow_right_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_exit_to_app_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_home_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_left_black_36dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_left_grey_700_24dp.png


BIN
app/src/main/res/drawable-xxxhdpi/ic_keyboard_arrow_right_grey_700_24dp.png


+ 24 - 0
app/src/main/res/drawable/btn_blue_bg.xml

@@ -0,0 +1,24 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+    <item android:state_pressed="false">
5
+        <shape>
6
+            <corners android:radius="8dp" />
7
+            <solid android:color="@color/colorPrimary" />
8
+        </shape>
9
+    </item>
10
+
11
+    <item android:state_pressed="true">
12
+        <shape>
13
+            <corners android:radius="8dp" />
14
+            <solid android:color="@color/colorPrimaryLight" />
15
+        </shape>
16
+    </item>
17
+
18
+    <item>
19
+        <shape>
20
+            <corners android:radius="8dp" />
21
+            <solid android:color="@color/colorPrimary" />
22
+        </shape>
23
+    </item>
24
+</selector>

+ 29 - 0
app/src/main/res/drawable/color_progressbar.xml

@@ -0,0 +1,29 @@
1
+<?xml version="1.0" encoding="UTF-8"?>
2
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3
+
4
+    <!-- 设置背景色(白色) -->
5
+    <item android:id="@android:id/background">
6
+        <shape>
7
+            <corners android:radius="3dip" />
8
+            <gradient
9
+                android:angle="270"
10
+                android:centerColor="#ffedeff2"
11
+                android:centerY="0.75"
12
+                android:endColor="#ffedeff2"
13
+                android:startColor="#ffedeff2" />
14
+        </shape>
15
+    </item>
16
+
17
+    <!-- 设置进度条颜色(蓝色) -->
18
+    <item android:id="@android:id/progress">
19
+        <clip>
20
+            <shape>
21
+                <corners android:radius="3dip" />
22
+                <gradient
23
+                    android:endColor="@color/colorPrimary"
24
+                    android:startColor="@color/colorPrimaryLight" />
25
+            </shape>
26
+        </clip>
27
+    </item>
28
+
29
+</layer-list>

BIN
app/src/main/res/drawable/ic_open_bg.png


+ 9 - 0
app/src/main/res/drawable/open_bg.xml

@@ -0,0 +1,9 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<layer-list xmlns:android="http://schemas.android.com/apk/res/android"
3
+    android:opacity="opaque">
4
+    <item>
5
+        <bitmap
6
+            android:gravity="fill"
7
+            android:src="@drawable/ic_open_bg" />
8
+    </item>
9
+</layer-list>

+ 167 - 0
app/src/main/res/layout/activity_browser.xml

@@ -0,0 +1,167 @@
1
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2
+    xmlns:tools="http://schemas.android.com/tools"
3
+    android:layout_width="fill_parent"
4
+    android:layout_height="fill_parent"
5
+    android:orientation="vertical">
6
+
7
+    <RelativeLayout
8
+        android:layout_width="match_parent"
9
+        android:layout_height="48dp"
10
+        android:visibility="gone"
11
+        android:background="@color/colorWhite">
12
+
13
+        <TextView
14
+            android:layout_width="wrap_content"
15
+            android:layout_height="wrap_content"
16
+            android:layout_centerInParent="true"
17
+            android:text="OA"
18
+            android:textColor="@android:color/black"
19
+            android:textSize="18sp" />
20
+
21
+        <ImageView
22
+            android:id="@+id/bar_back"
23
+            android:layout_width="wrap_content"
24
+            android:layout_height="match_parent"
25
+            android:foreground="?android:selectableItemBackground"
26
+            android:scaleType="center"
27
+            android:src="@drawable/ic_keyboard_arrow_left_black_36dp" />
28
+
29
+        <View
30
+            android:layout_width="match_parent"
31
+            android:layout_height="1px"
32
+            android:layout_alignParentBottom="true"
33
+            android:background="@color/colorLine" />
34
+
35
+        <TextView
36
+            android:id="@+id/bar_path"
37
+            android:layout_width="wrap_content"
38
+            android:layout_height="wrap_content"
39
+            android:layout_alignParentRight="true"
40
+            android:layout_centerVertical="true"
41
+            android:layout_marginRight="8dp"
42
+            android:text="网址"
43
+            android:textColor="@android:color/black"
44
+            android:textSize="18sp" />
45
+
46
+    </RelativeLayout>
47
+
48
+    <LinearLayout
49
+        android:id="@+id/navigation1"
50
+        android:layout_width="fill_parent"
51
+        android:layout_height="wrap_content"
52
+        android:background="#ECF0F2"
53
+        android:focusable="true"
54
+        android:visibility="gone"
55
+        android:focusableInTouchMode="true"
56
+        android:orientation="horizontal">
57
+
58
+        <EditText
59
+            android:id="@+id/editUrl1"
60
+            android:layout_width="fill_parent"
61
+            android:layout_height="wrap_content"
62
+            android:layout_marginLeft="10dp"
63
+            android:layout_marginTop="3dp"
64
+            android:layout_marginRight="10dp"
65
+            android:layout_weight="1"
66
+            android:ems="10"
67
+            android:hint="请输入网址..."
68
+            android:singleLine="true"
69
+            android:textSize="35px"></EditText>
70
+
71
+        <Button
72
+            android:id="@+id/btnGo1"
73
+            android:layout_width="wrap_content"
74
+            android:layout_height="wrap_content"
75
+            android:layout_marginLeft="1dp"
76
+            android:layout_marginTop="3dp"
77
+            android:layout_marginRight="10dp"
78
+            android:background="#ECF0F2"
79
+            android:linksClickable="false"
80
+            android:text="GO"
81
+            android:textSize="35px"
82
+            android:visibility="gone" />
83
+
84
+    </LinearLayout>
85
+
86
+    <ProgressBar
87
+        android:id="@+id/progressBar1"
88
+        style="?android:attr/progressBarStyleHorizontal"
89
+        android:layout_width="match_parent"
90
+        android:layout_height="4dp" />
91
+
92
+    <RelativeLayout
93
+        android:layout_width="match_parent"
94
+        android:layout_height="match_parent"
95
+        android:layout_weight="1"
96
+        android:orientation="vertical">
97
+
98
+        <FrameLayout
99
+            android:id="@+id/webView1"
100
+            android:layout_width="match_parent"
101
+            android:layout_height="match_parent"></FrameLayout>
102
+
103
+        <!--<TextView-->
104
+            <!--android:id="@+id/logView1"-->
105
+            <!--android:layout_width="match_parent"-->
106
+            <!--android:layout_height="match_parent"-->
107
+            <!--android:singleLine="false"-->
108
+            <!--android:visibility="gone"></TextView>-->
109
+
110
+
111
+    </RelativeLayout>
112
+
113
+    <LinearLayout
114
+        android:id="@+id/toolbar1"
115
+        android:layout_width="match_parent"
116
+        android:layout_height="wrap_content"
117
+        android:background="#ECF0F2"
118
+        android:orientation="horizontal">
119
+
120
+        <ImageButton
121
+            android:id="@+id/btnBack1"
122
+            android:layout_width="match_parent"
123
+            android:layout_height="wrap_content"
124
+            android:layout_weight="1"
125
+            android:background="#ECF0F2"
126
+            android:padding="10dp"
127
+            android:src="@drawable/ic_keyboard_arrow_left_grey_700_24dp" />
128
+
129
+        <ImageButton
130
+            android:id="@+id/btnForward1"
131
+            android:layout_width="match_parent"
132
+            android:layout_height="wrap_content"
133
+            android:layout_weight="1"
134
+            android:background="#ECF0F2"
135
+            android:padding="10dp"
136
+            android:src="@drawable/ic_keyboard_arrow_right_grey_700_24dp" />
137
+
138
+        <ImageButton
139
+            android:id="@+id/btnMore"
140
+            android:layout_width="fill_parent"
141
+            android:layout_height="wrap_content"
142
+            android:layout_weight="1"
143
+            android:background="#ECF0F2"
144
+            android:padding="10dp"
145
+            android:src="@drawable/ic_home_grey_700_24dp"
146
+            android:visibility="gone" />
147
+
148
+        <ImageButton
149
+            android:id="@+id/btnHome1"
150
+            android:layout_width="match_parent"
151
+            android:layout_height="wrap_content"
152
+            android:layout_weight="1"
153
+            android:background="#ECF0F2"
154
+            android:padding="10dp"
155
+            android:src="@drawable/ic_home_grey_700_24dp" />
156
+
157
+        <ImageButton
158
+            android:id="@+id/btnExit1"
159
+            android:layout_width="match_parent"
160
+            android:layout_height="wrap_content"
161
+            android:layout_weight="1"
162
+            android:background="#ECF0F2"
163
+            android:padding="10dp"
164
+            android:src="@drawable/ic_exit_to_app_grey_700_24dp" />
165
+    </LinearLayout>
166
+
167
+</LinearLayout>

+ 167 - 0
app/src/main/res/layout/activity_login.xml

@@ -0,0 +1,167 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:app="http://schemas.android.com/apk/res-auto"
4
+    xmlns:tools="http://schemas.android.com/tools"
5
+    android:layout_width="match_parent"
6
+    android:layout_height="match_parent"
7
+    tools:context=".ui.LoginActivity">
8
+
9
+    <LinearLayout
10
+        android:layout_width="match_parent"
11
+        android:layout_height="match_parent"
12
+        android:orientation="vertical">
13
+
14
+        <ImageView
15
+            android:layout_width="match_parent"
16
+            android:layout_height="wrap_content"
17
+            android:adjustViewBounds="true"
18
+            android:src="@drawable/ic_login_top" />
19
+
20
+        <View
21
+            android:layout_width="match_parent"
22
+            android:layout_height="0dp"
23
+            android:layout_weight="1" />
24
+
25
+        <ImageView
26
+            android:layout_width="wrap_content"
27
+            android:layout_height="wrap_content"
28
+            android:layout_centerHorizontal="true"
29
+            android:layout_marginLeft="48dp"
30
+            android:layout_marginRight="48dp"
31
+            android:src="@drawable/ic_login_title" />
32
+
33
+        <View
34
+            android:layout_width="match_parent"
35
+            android:layout_height="0dp"
36
+            android:layout_weight="1" />
37
+
38
+
39
+        <android.support.design.card.MaterialCardView
40
+            style="@style/login_edit_bg"
41
+            android:layout_marginLeft="16dp"
42
+            android:layout_marginRight="16dp"
43
+            android:visibility="gone">
44
+
45
+            <LinearLayout
46
+                android:layout_width="match_parent"
47
+                android:layout_height="match_parent"
48
+                android:gravity="center_vertical">
49
+
50
+                <ImageView
51
+                    android:layout_width="wrap_content"
52
+                    android:layout_height="wrap_content"
53
+                    android:layout_marginLeft="8dp"
54
+                    android:src="@drawable/ic_login_path" />
55
+
56
+                <EditText
57
+                    android:id="@+id/et_path"
58
+                    android:layout_width="match_parent"
59
+                    android:layout_height="match_parent"
60
+                    android:background="@android:color/transparent"
61
+                    android:hint="请输入网址"
62
+                    android:padding="8dp"
63
+                    android:singleLine="true" />
64
+            </LinearLayout>
65
+        </android.support.design.card.MaterialCardView>
66
+
67
+
68
+        <android.support.design.card.MaterialCardView
69
+            style="@style/login_edit_bg"
70
+            android:layout_marginLeft="16dp"
71
+            android:layout_marginTop="8dp"
72
+            android:layout_marginRight="16dp">
73
+
74
+            <LinearLayout
75
+                android:layout_width="match_parent"
76
+                android:layout_height="match_parent"
77
+                android:gravity="center_vertical">
78
+
79
+                <ImageView
80
+                    android:layout_width="wrap_content"
81
+                    android:layout_height="wrap_content"
82
+                    android:layout_marginLeft="8dp"
83
+                    android:src="@drawable/ic_login_user" />
84
+
85
+                <EditText
86
+                    android:id="@+id/et_user"
87
+                    android:layout_width="match_parent"
88
+                    android:layout_height="match_parent"
89
+                    android:background="@android:color/transparent"
90
+                    android:hint="请输入账号"
91
+                    android:padding="8dp"
92
+                    android:singleLine="true" />
93
+            </LinearLayout>
94
+        </android.support.design.card.MaterialCardView>
95
+
96
+
97
+        <android.support.design.card.MaterialCardView
98
+            style="@style/login_edit_bg"
99
+            android:layout_marginLeft="16dp"
100
+            android:layout_marginTop="8dp"
101
+            android:layout_marginRight="16dp">
102
+
103
+            <LinearLayout
104
+                android:layout_width="match_parent"
105
+                android:layout_height="match_parent"
106
+                android:gravity="center_vertical">
107
+
108
+                <ImageView
109
+                    android:layout_width="wrap_content"
110
+                    android:layout_height="wrap_content"
111
+                    android:layout_marginLeft="8dp"
112
+                    android:src="@drawable/ic_login_pwd" />
113
+
114
+                <EditText
115
+                    android:id="@+id/et_pwd"
116
+                    android:layout_width="match_parent"
117
+                    android:layout_height="match_parent"
118
+                    android:background="@android:color/transparent"
119
+                    android:hint="请输入密码"
120
+                    android:inputType="textPassword"
121
+                    android:padding="8dp"
122
+                    android:singleLine="true" />
123
+            </LinearLayout>
124
+        </android.support.design.card.MaterialCardView>
125
+
126
+        <CheckBox
127
+            android:id="@+id/cb_auto_login"
128
+            android:layout_width="wrap_content"
129
+            android:layout_height="wrap_content"
130
+            android:layout_marginLeft="16dp"
131
+            android:text="自动登录"
132
+            android:visibility="gone"/>
133
+
134
+        <Button
135
+            android:id="@+id/btn_login"
136
+            android:layout_width="match_parent"
137
+            android:layout_height="wrap_content"
138
+            android:layout_marginLeft="16dp"
139
+            android:layout_marginTop="16dp"
140
+            android:layout_marginRight="16dp"
141
+            android:layout_marginBottom="8dp"
142
+            android:background="@drawable/btn_blue_bg"
143
+            android:text="登录"
144
+            android:textColor="@color/colorWhite"
145
+            android:textSize="18sp" />
146
+
147
+        <View
148
+            android:layout_width="match_parent"
149
+            android:layout_height="0dp"
150
+            android:layout_weight="1.5" />
151
+
152
+        <TextView
153
+            android:layout_width="wrap_content"
154
+            android:layout_height="wrap_content"
155
+            android:layout_gravity="center_horizontal"
156
+            android:text="云南省粮食和物资储备局"
157
+            android:textSize="16sp" />
158
+
159
+        <View
160
+            android:layout_width="match_parent"
161
+            android:layout_height="0dp"
162
+            android:layout_weight="1" />
163
+    </LinearLayout>
164
+
165
+    <include layout="@layout/progress_layout" />
166
+
167
+</RelativeLayout>

+ 13 - 0
app/src/main/res/layout/activity_main.xml

@@ -0,0 +1,13 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:app="http://schemas.android.com/apk/res-auto"
4
+    xmlns:tools="http://schemas.android.com/tools"
5
+    android:layout_width="match_parent"
6
+    android:layout_height="match_parent"
7
+    android:gravity="center"
8
+    android:orientation="vertical"
9
+    tools:context=".ui.MainActivity">
10
+
11
+    <include layout="@layout/progress_layout" />
12
+
13
+</LinearLayout>

+ 117 - 0
app/src/main/res/layout/activity_web.xml

@@ -0,0 +1,117 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:app="http://schemas.android.com/apk/res-auto"
4
+    xmlns:tools="http://schemas.android.com/tools"
5
+    android:layout_width="match_parent"
6
+    android:layout_height="match_parent"
7
+    android:background="@color/colorBackground"
8
+    android:orientation="vertical">
9
+
10
+    <RelativeLayout
11
+        android:layout_width="match_parent"
12
+        android:layout_height="48dp"
13
+        android:background="@color/colorWhite">
14
+
15
+        <TextView
16
+            android:layout_width="wrap_content"
17
+            android:layout_height="wrap_content"
18
+            android:layout_centerInParent="true"
19
+            android:text="OA"
20
+            android:textColor="@android:color/black"
21
+            android:textSize="18sp" />
22
+
23
+        <ImageView
24
+            android:id="@+id/bar_back"
25
+            android:layout_width="wrap_content"
26
+            android:layout_height="match_parent"
27
+            android:foreground="?android:selectableItemBackground"
28
+            android:scaleType="center"
29
+            android:src="@drawable/ic_keyboard_arrow_left_black_36dp" />
30
+
31
+        <View
32
+            android:layout_width="match_parent"
33
+            android:layout_height="1px"
34
+            android:layout_alignParentBottom="true"
35
+            android:background="@color/colorLine" />
36
+
37
+        <TextView
38
+            android:id="@+id/bar_path"
39
+            android:layout_width="wrap_content"
40
+            android:layout_height="wrap_content"
41
+            android:layout_alignParentRight="true"
42
+            android:layout_centerVertical="true"
43
+            android:layout_marginRight="8dp"
44
+            android:text="网址"
45
+            android:visibility="gone"
46
+            android:textColor="@android:color/black"
47
+            android:textSize="18sp" />
48
+        <TextView
49
+            android:id="@+id/bar_out"
50
+            android:layout_width="wrap_content"
51
+            android:layout_height="wrap_content"
52
+            android:layout_alignParentRight="true"
53
+            android:layout_centerVertical="true"
54
+            android:layout_marginRight="8dp"
55
+            android:text="退出"
56
+            android:textColor="@android:color/black"
57
+            android:textSize="18sp" />
58
+    </RelativeLayout>
59
+
60
+    <ProgressBar
61
+        android:id="@+id/progressBar"
62
+        style="?android:progressBarStyleHorizontal"
63
+        android:layout_width="match_parent"
64
+        android:layout_height="3dp" />
65
+
66
+    <com.mq.oaapp.utils.X5WebView
67
+        android:id="@+id/webView"
68
+        android:layout_width="match_parent"
69
+        android:layout_height="0dp"
70
+        android:layout_weight="1"
71
+        android:background="@android:color/white" />
72
+
73
+    <View
74
+        android:layout_width="match_parent"
75
+        android:layout_height="1dp"
76
+        android:background="@color/colorLine" />
77
+
78
+    <LinearLayout
79
+        android:id="@+id/bottom_layout"
80
+        android:layout_width="match_parent"
81
+        android:layout_height="wrap_content"
82
+        android:background="@color/colorBackground"
83
+        android:orientation="horizontal">
84
+
85
+        <ImageButton
86
+            android:id="@+id/btnBack"
87
+            android:layout_width="match_parent"
88
+            android:layout_height="wrap_content"
89
+            android:layout_weight="1"
90
+            android:background="@android:color/transparent"
91
+            android:foreground="?android:selectableItemBackground"
92
+            android:padding="10dp"
93
+            android:src="@drawable/ic_keyboard_arrow_left_grey_700_24dp" />
94
+
95
+        <ImageButton
96
+            android:id="@+id/btnForward"
97
+            android:layout_width="match_parent"
98
+            android:layout_height="wrap_content"
99
+            android:layout_weight="1"
100
+            android:background="@android:color/transparent"
101
+            android:foreground="?android:selectableItemBackground"
102
+            android:padding="10dp"
103
+            android:src="@drawable/ic_keyboard_arrow_right_grey_700_24dp" />
104
+
105
+        <ImageButton
106
+            android:id="@+id/btnHome"
107
+            android:layout_width="match_parent"
108
+            android:layout_height="wrap_content"
109
+            android:layout_weight="1"
110
+            android:background="@android:color/transparent"
111
+            android:foreground="?android:selectableItemBackground"
112
+            android:padding="10dp"
113
+            android:src="@drawable/ic_home_grey_700_24dp" />
114
+
115
+    </LinearLayout>
116
+
117
+</LinearLayout>

+ 19 - 0
app/src/main/res/layout/filechooser_layout.xml

@@ -0,0 +1,19 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
3
+    android:layout_width="match_parent"
4
+    android:layout_height="match_parent" >
5
+    <FrameLayout android:layout_height="match_parent"
6
+        android:layout_width="match_parent"
7
+        android:id="@+id/frame_web_video"></FrameLayout>
8
+    
9
+
10
+    <com.example.test_webview_demo.utils.X5WebView 
11
+        android:layout_width="fill_parent"
12
+        android:layout_height="match_parent"
13
+        android:id="@+id/web_filechooser">
14
+        
15
+        
16
+    </com.example.test_webview_demo.utils.X5WebView>
17
+    
18
+
19
+</RelativeLayout>

+ 21 - 0
app/src/main/res/layout/progress_layout.xml

@@ -0,0 +1,21 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<android.support.design.card.MaterialCardView xmlns:android="http://schemas.android.com/apk/res/android"
3
+    xmlns:app="http://schemas.android.com/apk/res-auto"
4
+    android:id="@+id/progressBar"
5
+    android:layout_width="wrap_content"
6
+    android:layout_height="wrap_content"
7
+    android:layout_gravity="center_horizontal"
8
+    android:layout_marginTop="72dp"
9
+    app:cardCornerRadius="48dp"
10
+    app:cardElevation="8dp"
11
+    android:layout_centerInParent="true"
12
+    app:strokeColor="@color/colorLine"
13
+    android:visibility="gone"
14
+    app:strokeWidth="1dp">
15
+
16
+    <ProgressBar
17
+        android:layout_width="wrap_content"
18
+        android:layout_height="wrap_content"
19
+        android:background="@color/colorWhite" />
20
+
21
+</android.support.design.card.MaterialCardView>

BIN
app/src/main/res/mipmap-hdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-mdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxhdpi/ic_launcher.png


BIN
app/src/main/res/mipmap-xxxhdpi/ic_launcher.png


+ 11 - 0
app/src/main/res/values/colors.xml

@@ -0,0 +1,11 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<resources>
3
+    <color name="colorPrimary">#0379FC</color>
4
+    <color name="colorPrimaryDark">#0379FC</color>
5
+    <color name="colorAccent">#0379FC</color>
6
+    <color name="colorBackground">#FDFDFE</color>
7
+    <color name="colorPrimaryLight">#3E9AFF</color>
8
+
9
+    <color name="colorLine">#DEDEDE</color>
10
+    <color name="colorWhite">#FFFFFF</color>
11
+</resources>

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

@@ -0,0 +1,3 @@
1
+<resources>
2
+    <string name="app_name">云粮政务移动办公系统</string>
3
+</resources>

+ 26 - 0
app/src/main/res/values/styles.xml

@@ -0,0 +1,26 @@
1
+<resources>
2
+
3
+    <style name="MyAppTheme" parent="Theme.AppCompat.Light.NoActionBar">
4
+        <item name="colorPrimary">@color/colorPrimary</item>
5
+        <item name="colorPrimaryDark">@color/colorPrimaryDark</item>
6
+        <item name="colorAccent">@color/colorAccent</item>
7
+        <item name="android:colorBackground">@color/colorBackground</item>
8
+    </style>
9
+
10
+    <style name="OpenTheme" parent="MyAppTheme">
11
+        <item name="windowNoTitle">true</item>
12
+        <item name="android:windowContentOverlay">@null</item>
13
+        <item name="android:windowBackground">@drawable/open_bg</item>
14
+        <item name="android:windowFullscreen">true</item>
15
+        <!--<item name="android:fontFamily">@font/siyuanheitinormal</item>-->
16
+    </style>
17
+
18
+    <style name="login_edit_bg">
19
+        <item name="android:layout_width">match_parent</item>
20
+        <item name="android:layout_height">48dp</item>
21
+        <item name="cardCornerRadius">8dp</item>
22
+        <item name="cardElevation">2dp</item>
23
+        <item name="strokeColor">@color/colorLine</item>
24
+        <item name="strokeWidth">1dp</item>
25
+    </style>
26
+</resources>

+ 4 - 0
app/src/main/res/xml/network_security_config.xml

@@ -0,0 +1,4 @@
1
+<?xml version="1.0" encoding="utf-8"?>
2
+<network-security-config>
3
+    <base-config cleartextTrafficPermitted="true" />
4
+</network-security-config>

+ 33 - 0
build.gradle

@@ -0,0 +1,33 @@
1
+// Top-level build file where you can add configuration options common to all sub-projects/modules.
2
+
3
+buildscript {
4
+    repositories {
5
+        google()
6
+        jcenter()
7
+        
8
+    }
9
+    dependencies {
10
+        classpath 'com.android.tools.build:gradle:3.4.2'
11
+        classpath 'com.jakewharton:butterknife-gradle-plugin:9.0.0-rc2'
12
+
13
+        // NOTE: Do not place your application dependencies here; they belong
14
+        // in the individual module build.gradle files
15
+    }
16
+}
17
+
18
+allprojects {
19
+    repositories {
20
+        // 添加下面的内容
21
+        flatDir {
22
+            dirs 'libs'
23
+        }
24
+        google()
25
+        jcenter()
26
+        maven { url "https://jitpack.io" }
27
+        maven { url 'https://maven.google.com' }
28
+    }
29
+}
30
+
31
+task clean(type: Delete) {
32
+    delete rootProject.buildDir
33
+}

+ 15 - 0
gradle.properties

@@ -0,0 +1,15 @@
1
+# Project-wide Gradle settings.
2
+# IDE (e.g. Android Studio) users:
3
+# Gradle settings configured through the IDE *will override*
4
+# any settings specified in this file.
5
+# For more details on how to configure your build environment visit
6
+# http://www.gradle.org/docs/current/userguide/build_environment.html
7
+# Specifies the JVM arguments used for the daemon process.
8
+# The setting is particularly useful for tweaking memory settings.
9
+org.gradle.jvmargs=-Xmx1536m
10
+# When configured, Gradle will run in incubating parallel mode.
11
+# This option should only be used with decoupled projects. More details, visit
12
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
13
+# org.gradle.parallel=true
14
+
15
+

BIN
gradle/wrapper/gradle-wrapper.jar


+ 6 - 0
gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,6 @@
1
+#Tue Sep 24 16:46:12 CST 2019
2
+distributionBase=GRADLE_USER_HOME
3
+distributionPath=wrapper/dists
4
+zipStoreBase=GRADLE_USER_HOME
5
+zipStorePath=wrapper/dists
6
+distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-all.zip

+ 172 - 0
gradlew

@@ -0,0 +1,172 @@
1
+#!/usr/bin/env sh
2
+
3
+##############################################################################
4
+##
5
+##  Gradle start up script for UN*X
6
+##
7
+##############################################################################
8
+
9
+# Attempt to set APP_HOME
10
+# Resolve links: $0 may be a link
11
+PRG="$0"
12
+# Need this for relative symlinks.
13
+while [ -h "$PRG" ] ; do
14
+    ls=`ls -ld "$PRG"`
15
+    link=`expr "$ls" : '.*-> \(.*\)$'`
16
+    if expr "$link" : '/.*' > /dev/null; then
17
+        PRG="$link"
18
+    else
19
+        PRG=`dirname "$PRG"`"/$link"
20
+    fi
21
+done
22
+SAVED="`pwd`"
23
+cd "`dirname \"$PRG\"`/" >/dev/null
24
+APP_HOME="`pwd -P`"
25
+cd "$SAVED" >/dev/null
26
+
27
+APP_NAME="Gradle"
28
+APP_BASE_NAME=`basename "$0"`
29
+
30
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31
+DEFAULT_JVM_OPTS=""
32
+
33
+# Use the maximum available, or set MAX_FD != -1 to use that value.
34
+MAX_FD="maximum"
35
+
36
+warn () {
37
+    echo "$*"
38
+}
39
+
40
+die () {
41
+    echo
42
+    echo "$*"
43
+    echo
44
+    exit 1
45
+}
46
+
47
+# OS specific support (must be 'true' or 'false').
48
+cygwin=false
49
+msys=false
50
+darwin=false
51
+nonstop=false
52
+case "`uname`" in
53
+  CYGWIN* )
54
+    cygwin=true
55
+    ;;
56
+  Darwin* )
57
+    darwin=true
58
+    ;;
59
+  MINGW* )
60
+    msys=true
61
+    ;;
62
+  NONSTOP* )
63
+    nonstop=true
64
+    ;;
65
+esac
66
+
67
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68
+
69
+# Determine the Java command to use to start the JVM.
70
+if [ -n "$JAVA_HOME" ] ; then
71
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72
+        # IBM's JDK on AIX uses strange locations for the executables
73
+        JAVACMD="$JAVA_HOME/jre/sh/java"
74
+    else
75
+        JAVACMD="$JAVA_HOME/bin/java"
76
+    fi
77
+    if [ ! -x "$JAVACMD" ] ; then
78
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79
+
80
+Please set the JAVA_HOME variable in your environment to match the
81
+location of your Java installation."
82
+    fi
83
+else
84
+    JAVACMD="java"
85
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86
+
87
+Please set the JAVA_HOME variable in your environment to match the
88
+location of your Java installation."
89
+fi
90
+
91
+# Increase the maximum file descriptors if we can.
92
+if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93
+    MAX_FD_LIMIT=`ulimit -H -n`
94
+    if [ $? -eq 0 ] ; then
95
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96
+            MAX_FD="$MAX_FD_LIMIT"
97
+        fi
98
+        ulimit -n $MAX_FD
99
+        if [ $? -ne 0 ] ; then
100
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
101
+        fi
102
+    else
103
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104
+    fi
105
+fi
106
+
107
+# For Darwin, add options to specify how the application appears in the dock
108
+if $darwin; then
109
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110
+fi
111
+
112
+# For Cygwin, switch paths to Windows format before running java
113
+if $cygwin ; then
114
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116
+    JAVACMD=`cygpath --unix "$JAVACMD"`
117
+
118
+    # We build the pattern for arguments to be converted via cygpath
119
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120
+    SEP=""
121
+    for dir in $ROOTDIRSRAW ; do
122
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
123
+        SEP="|"
124
+    done
125
+    OURCYGPATTERN="(^($ROOTDIRS))"
126
+    # Add a user-defined pattern to the cygpath arguments
127
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129
+    fi
130
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
131
+    i=0
132
+    for arg in "$@" ; do
133
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
135
+
136
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
137
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138
+        else
139
+            eval `echo args$i`="\"$arg\""
140
+        fi
141
+        i=$((i+1))
142
+    done
143
+    case $i in
144
+        (0) set -- ;;
145
+        (1) set -- "$args0" ;;
146
+        (2) set -- "$args0" "$args1" ;;
147
+        (3) set -- "$args0" "$args1" "$args2" ;;
148
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154
+    esac
155
+fi
156
+
157
+# Escape application args
158
+save () {
159
+    for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160
+    echo " "
161
+}
162
+APP_ARGS=$(save "$@")
163
+
164
+# Collect all arguments for the java command, following the shell quoting and substitution rules
165
+eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166
+
167
+# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168
+if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169
+  cd "$(dirname "$0")"
170
+fi
171
+
172
+exec "$JAVACMD" "$@"

+ 84 - 0
gradlew.bat

@@ -0,0 +1,84 @@
1
+@if "%DEBUG%" == "" @echo off
2
+@rem ##########################################################################
3
+@rem
4
+@rem  Gradle startup script for Windows
5
+@rem
6
+@rem ##########################################################################
7
+
8
+@rem Set local scope for the variables with windows NT shell
9
+if "%OS%"=="Windows_NT" setlocal
10
+
11
+set DIRNAME=%~dp0
12
+if "%DIRNAME%" == "" set DIRNAME=.
13
+set APP_BASE_NAME=%~n0
14
+set APP_HOME=%DIRNAME%
15
+
16
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17
+set DEFAULT_JVM_OPTS=
18
+
19
+@rem Find java.exe
20
+if defined JAVA_HOME goto findJavaFromJavaHome
21
+
22
+set JAVA_EXE=java.exe
23
+%JAVA_EXE% -version >NUL 2>&1
24
+if "%ERRORLEVEL%" == "0" goto init
25
+
26
+echo.
27
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28
+echo.
29
+echo Please set the JAVA_HOME variable in your environment to match the
30
+echo location of your Java installation.
31
+
32
+goto fail
33
+
34
+:findJavaFromJavaHome
35
+set JAVA_HOME=%JAVA_HOME:"=%
36
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37
+
38
+if exist "%JAVA_EXE%" goto init
39
+
40
+echo.
41
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42
+echo.
43
+echo Please set the JAVA_HOME variable in your environment to match the
44
+echo location of your Java installation.
45
+
46
+goto fail
47
+
48
+:init
49
+@rem Get command-line arguments, handling Windows variants
50
+
51
+if not "%OS%" == "Windows_NT" goto win9xME_args
52
+
53
+:win9xME_args
54
+@rem Slurp the command line arguments.
55
+set CMD_LINE_ARGS=
56
+set _SKIP=2
57
+
58
+:win9xME_args_slurp
59
+if "x%~1" == "x" goto execute
60
+
61
+set CMD_LINE_ARGS=%*
62
+
63
+:execute
64
+@rem Setup the command line
65
+
66
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67
+
68
+@rem Execute Gradle
69
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70
+
71
+:end
72
+@rem End local scope for the variables with windows NT shell
73
+if "%ERRORLEVEL%"=="0" goto mainEnd
74
+
75
+:fail
76
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77
+rem the _cmd.exe /c_ return code!
78
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79
+exit /b 1
80
+
81
+:mainEnd
82
+if "%OS%"=="Windows_NT" endlocal
83
+
84
+:omega

+ 1 - 0
mylibrary/.gitignore

@@ -0,0 +1 @@
1
+/build

+ 29 - 0
mylibrary/build.gradle

@@ -0,0 +1,29 @@
1
+apply plugin: 'com.android.library'
2
+
3
+android {
4
+    compileSdkVersion 28
5
+
6
+
7
+    defaultConfig {
8
+        minSdkVersion 15
9
+        targetSdkVersion 28
10
+        versionCode 1
11
+        versionName "1.0"
12
+
13
+
14
+    }
15
+
16
+    buildTypes {
17
+        release {
18
+            minifyEnabled false
19
+            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
20
+        }
21
+    }
22
+
23
+}
24
+
25
+dependencies {
26
+    implementation fileTree(dir: 'libs', include: ['*.jar'])
27
+
28
+    implementation 'com.android.support:appcompat-v7:28.0.0'
29
+}

+ 21 - 0
mylibrary/proguard-rules.pro

@@ -0,0 +1,21 @@
1
+# Add project specific ProGuard rules here.
2
+# You can control the set of applied configuration files using the
3
+# proguardFiles setting in build.gradle.
4
+#
5
+# For more details, see
6
+#   http://developer.android.com/guide/developing/tools/proguard.html
7
+
8
+# If your project uses WebView with JS, uncomment the following
9
+# and specify the fully qualified class name to the JavaScript interface
10
+# class:
11
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12
+#   public *;
13
+#}
14
+
15
+# Uncomment this to preserve the line number information for
16
+# debugging stack traces.
17
+#-keepattributes SourceFile,LineNumberTable
18
+
19
+# If you keep the line number information, uncomment this to
20
+# hide the original source file name.
21
+#-renamesourcefileattribute SourceFile

+ 2 - 0
mylibrary/src/main/AndroidManifest.xml

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

+ 140 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ActivityTool.java

@@ -0,0 +1,140 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.content.Context;
4
+import android.content.Intent;
5
+import android.content.res.Resources;
6
+import android.os.Build;
7
+import android.os.Bundle;
8
+import android.support.v4.app.Fragment;
9
+import android.support.v4.app.FragmentManager;
10
+import android.view.View;
11
+import android.view.Window;
12
+
13
+import java.lang.reflect.Method;
14
+
15
+/**
16
+ * 创建人 mQ
17
+ * 创建时间 2019/5/20 0020 10:35
18
+ * 文件名称 ActivityTool
19
+ * 说明: activity工具类
20
+ **/
21
+public class ActivityTool {
22
+
23
+    public static void startActivity(Context context, Class<?> cls) {
24
+        startActivity(context, cls, null);
25
+    }
26
+
27
+    public static void startActivity(Context context, Class<?> cls, Bundle bundle) {
28
+        Intent intent = new Intent(context, cls);
29
+        if (bundle != null)
30
+            intent.putExtras(bundle);
31
+        context.startActivity(intent);
32
+    }
33
+
34
+    /**
35
+     * 添加Fragment
36
+     */
37
+    public static void addFragment(FragmentManager manager, int layout, Fragment fragment) {
38
+        manager.beginTransaction()
39
+                .add(layout, fragment)
40
+                .commit();
41
+    }
42
+
43
+    /**
44
+     * 隐藏底部虚拟按键 并设置为亮色主题(状态栏字体深色)
45
+     */
46
+    public static void hideNavigationAndLight(Context context, Window window) {
47
+        if (Build.VERSION.SDK_INT < 19 || !checkDeviceHasNavigationBar(context)) {
48
+            //一定要判断是否存在按键,否则在没有按键的手机调用会影响别的功能。如之前没有考虑到,导致图传全屏变成小屏显示。
49
+        } else {
50
+            int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
51
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
52
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
53
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide Navigation
54
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
55
+                    | View.SYSTEM_UI_FLAG_LIGHT_STATUS_BAR;
56
+
57
+            // 设置属性
58
+            window.getDecorView().setSystemUiVisibility(flag);
59
+        }
60
+    }
61
+
62
+    /**
63
+     * 隐藏底部虚拟按键 并设置为暗色主题(状态栏字体白色)
64
+     */
65
+    public static void hideNavigationAndDark(Context context, Window window) {
66
+        if (Build.VERSION.SDK_INT < 19 || !checkDeviceHasNavigationBar(context)) {
67
+            //一定要判断是否存在按键,否则在没有按键的手机调用会影响别的功能。如之前没有考虑到,导致图传全屏变成小屏显示。
68
+        } else {
69
+            int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
70
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
71
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
72
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide Navigation
73
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
74
+
75
+            // 设置属性
76
+            window.getDecorView().setSystemUiVisibility(flag);
77
+        }
78
+    }
79
+
80
+
81
+    /**
82
+     * 隐藏顶部状态栏
83
+     */
84
+    public static void hideStatusBar(Context context, Window window) {
85
+        if (Build.VERSION.SDK_INT < 19 || !checkDeviceHasNavigationBar(context)) {
86
+            //一定要判断是否存在按键,否则在没有按键的手机调用会影响别的功能。如之前没有考虑到,导致图传全屏变成小屏显示。
87
+        } else {
88
+            int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
89
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
90
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
91
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
92
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
93
+            // 设置属性
94
+            window.getDecorView().setSystemUiVisibility(flag);
95
+        }
96
+    }
97
+
98
+    /**
99
+     * 隐藏底部虚拟按键和顶部状态栏
100
+     */
101
+    public static void hideNavigationAndStatusBar(Context context, Window window) {
102
+        if (Build.VERSION.SDK_INT < 19 || !checkDeviceHasNavigationBar(context)) {
103
+            //一定要判断是否存在按键,否则在没有按键的手机调用会影响别的功能。如之前没有考虑到,导致图传全屏变成小屏显示。
104
+        } else {
105
+            int flag = View.SYSTEM_UI_FLAG_LAYOUT_STABLE
106
+                    | View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
107
+                    | View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
108
+                    | View.SYSTEM_UI_FLAG_HIDE_NAVIGATION // hide Navigation
109
+                    | View.SYSTEM_UI_FLAG_FULLSCREEN // hide status bar
110
+                    | View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY;
111
+            // 设置属性
112
+            window.getDecorView().setSystemUiVisibility(flag);
113
+        }
114
+    }
115
+
116
+    /**
117
+     * 判断是否存在虚拟按键
118
+     */
119
+    private static boolean checkDeviceHasNavigationBar(Context context) {
120
+        boolean hasNavigationBar = false;
121
+        Resources rs = context.getResources();
122
+        int id = rs.getIdentifier("config_showNavigationBar", "bool", "android");
123
+        if (id > 0) {
124
+            hasNavigationBar = rs.getBoolean(id);
125
+        }
126
+        try {
127
+            Class<?> systemPropertiesClass = Class.forName("android.os.SystemProperties");
128
+            Method m = systemPropertiesClass.getMethod("get", String.class);
129
+            String navBarOverride = (String) m.invoke(systemPropertiesClass, "qemu.hw.mainkeys");
130
+            if ("1".equals(navBarOverride)) {
131
+                hasNavigationBar = false;
132
+            } else if ("0".equals(navBarOverride)) {
133
+                hasNavigationBar = true;
134
+            }
135
+        } catch (Exception e) {
136
+
137
+        }
138
+        return hasNavigationBar;
139
+    }
140
+}

+ 48 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/AssetsTool.java

@@ -0,0 +1,48 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.content.Context;
4
+
5
+import java.io.BufferedReader;
6
+import java.io.IOException;
7
+import java.io.InputStream;
8
+import java.io.InputStreamReader;
9
+
10
+/**
11
+ * 创建人 mQ
12
+ * 创建时间 2019/5/20 0020 10:35
13
+ * 文件名称 AssetsTool
14
+ * 说明:
15
+ **/
16
+public class AssetsTool {
17
+
18
+    public static String getFromAssets(Context context, String fileName) {
19
+        try {
20
+            InputStreamReader ir = new InputStreamReader(context.getAssets().open(fileName));
21
+            BufferedReader br = new BufferedReader(ir);
22
+            String line = "";
23
+            StringBuilder result = new StringBuilder();
24
+            while ((line = br.readLine()) != null) {
25
+                result.append(line);
26
+            }
27
+            LogTool.i("getFromAssets: 读取assets: " + result.toString());
28
+            return result.toString();
29
+        } catch (IOException e) {
30
+            e.printStackTrace();
31
+        }
32
+        return null;
33
+    }
34
+
35
+    public static byte[] getFromAssetsToByte(Context context, String fileName) {
36
+        try {
37
+            InputStream is = context.getAssets().open(fileName);
38
+            int lenght = is.available();
39
+            byte[] result = new byte[lenght];
40
+            is.read(result);
41
+            return result;
42
+        } catch (IOException e) {
43
+            e.printStackTrace();
44
+        }
45
+        return null;
46
+    }
47
+
48
+}

+ 70 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/Base64Tool.java

@@ -0,0 +1,70 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+/**
4
+ * 创建人 mQ
5
+ * 创建时间 2019/5/20 0020 10:35
6
+ * 文件名称 Base64Tool
7
+ * 说明: Base64 工具类
8
+ **/
9
+public class Base64Tool {
10
+
11
+    private static final char last2byte = (char) Integer.parseInt("00000011", 2);
12
+    private static final char last4byte = (char) Integer.parseInt("00001111", 2);
13
+    private static final char last6byte = (char) Integer.parseInt("00111111", 2);
14
+    private static final char lead6byte = (char) Integer.parseInt("11111100", 2);
15
+    private static final char lead4byte = (char) Integer.parseInt("11110000", 2);
16
+    private static final char lead2byte = (char) Integer.parseInt("11000000", 2);
17
+    private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};
18
+
19
+    public Base64Tool() {
20
+    }
21
+
22
+    public static String encode(byte[] from) {
23
+        StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);
24
+        int num = 0;
25
+        char currentByte = 0;
26
+
27
+        int i;
28
+        for (i = 0; i < from.length; ++i) {
29
+            for (num %= 8; num < 8; num += 6) {
30
+                switch (num) {
31
+                    case 0:
32
+                        currentByte = (char) (from[i] & lead6byte);
33
+                        currentByte = (char) (currentByte >>> 2);
34
+                    case 1:
35
+                    case 3:
36
+                    case 5:
37
+                    default:
38
+                        break;
39
+                    case 2:
40
+                        currentByte = (char) (from[i] & last6byte);
41
+                        break;
42
+                    case 4:
43
+                        currentByte = (char) (from[i] & last4byte);
44
+                        currentByte = (char) (currentByte << 2);
45
+                        if (i + 1 < from.length) {
46
+                            currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);
47
+                        }
48
+                        break;
49
+                    case 6:
50
+                        currentByte = (char) (from[i] & last2byte);
51
+                        currentByte = (char) (currentByte << 4);
52
+                        if (i + 1 < from.length) {
53
+                            currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);
54
+                        }
55
+                }
56
+
57
+                to.append(encodeTable[currentByte]);
58
+            }
59
+        }
60
+
61
+        if (to.length() % 4 != 0) {
62
+            for (i = 4 - to.length() % 4; i > 0; --i) {
63
+                to.append("=");
64
+            }
65
+        }
66
+
67
+        return to.toString();
68
+    }
69
+
70
+}

+ 137 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/CodeUtils.java

@@ -0,0 +1,137 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.graphics.Bitmap;
4
+import android.graphics.Canvas;
5
+import android.graphics.Color;
6
+import android.graphics.Paint;
7
+
8
+import java.util.Random;
9
+
10
+/**
11
+ * 创建人 mQ
12
+ * 创建时间 2019/8/13 0013 18:13
13
+ * 文件名称 CodeUtils
14
+ * 说明: 用于图片验证码的工具类
15
+ **/
16
+public class CodeUtils {
17
+
18
+    private static final char[] CHARS = {
19
+            '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
20
+            'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
21
+            'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
22
+            'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
23
+            'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z'
24
+    };
25
+
26
+    private static CodeUtils mCodeUtils;
27
+    private int mPaddingLeft, mPaddingTop;
28
+    private StringBuilder mBuilder = new StringBuilder();
29
+    private Random mRandom = new Random();
30
+
31
+    //Default Settings
32
+    private static final int DEFAULT_CODE_LENGTH = 4;//验证码的长度  这里是6位
33
+    private static final int DEFAULT_FONT_SIZE = 60;//字体大小
34
+    private static final int DEFAULT_LINE_NUMBER = 3;//多少条干扰线
35
+    private static final int BASE_PADDING_LEFT = 20; //左边距
36
+    private static final int RANGE_PADDING_LEFT = 30;//左边距范围值
37
+    private static final int BASE_PADDING_TOP = 70;//上边距
38
+    private static final int RANGE_PADDING_TOP = 15;//上边距范围值
39
+    private static final int DEFAULT_WIDTH = 300;//默认宽度.图片的总宽
40
+    private static final int DEFAULT_HEIGHT = 100;//默认高度.图片的总高
41
+    private static final int DEFAULT_COLOR = 0xDF;//默认背景颜色值
42
+
43
+    private String code;
44
+
45
+    public static CodeUtils getInstance() {
46
+        if(mCodeUtils == null) {
47
+            mCodeUtils = new CodeUtils();
48
+        }
49
+        return mCodeUtils;
50
+    }
51
+
52
+    //生成验证码图片
53
+    public Bitmap createBitmap() {
54
+        mPaddingLeft = 0; //每次生成验证码图片时初始化
55
+        mPaddingTop = 0;
56
+
57
+        Bitmap bitmap = Bitmap.createBitmap(DEFAULT_WIDTH, DEFAULT_HEIGHT, Bitmap.Config.ARGB_8888);
58
+        Canvas canvas = new Canvas(bitmap);
59
+        code = createCode();
60
+        canvas.drawColor(Color.rgb(DEFAULT_COLOR, DEFAULT_COLOR, DEFAULT_COLOR));
61
+        Paint paint = new Paint();
62
+        paint.setTextSize(DEFAULT_FONT_SIZE);
63
+
64
+        for (int i = 0; i < code.length(); i++) {
65
+            randomTextStyle(paint);
66
+            randomPadding();
67
+            canvas.drawText(code.charAt(i) + "" , mPaddingLeft, mPaddingTop, paint);
68
+        }
69
+        //干扰线
70
+        for (int i = 0; i < DEFAULT_LINE_NUMBER; i++) {
71
+            drawLine(canvas, paint);
72
+        }
73
+        canvas.save();//保存
74
+        canvas.restore();
75
+        return bitmap;
76
+    }
77
+    /**
78
+     * 得到图片中的验证码字符串
79
+     * @return
80
+     */
81
+    public String getCode() {
82
+        return code;
83
+    }
84
+
85
+    //生成验证码
86
+    public String createCode() {
87
+        mBuilder.delete(0, mBuilder.length()); //使用之前首先清空内容
88
+        for (int i = 0; i < DEFAULT_CODE_LENGTH; i++) {
89
+            mBuilder.append(CHARS[mRandom.nextInt(CHARS.length)]);
90
+        }
91
+        return mBuilder.toString();
92
+    }
93
+
94
+    //生成干扰线
95
+    private void drawLine(Canvas canvas, Paint paint) {
96
+        int color = randomColor();
97
+        int startX = mRandom.nextInt(DEFAULT_WIDTH);
98
+        int startY = mRandom.nextInt(DEFAULT_HEIGHT);
99
+        int stopX = mRandom.nextInt(DEFAULT_WIDTH);
100
+        int stopY = mRandom.nextInt(DEFAULT_HEIGHT);
101
+        paint.setStrokeWidth(1);
102
+        paint.setColor(color);
103
+        canvas.drawLine(startX, startY, stopX, stopY, paint);
104
+    }
105
+
106
+    //随机颜色
107
+    private int randomColor() {
108
+        mBuilder.delete(0, mBuilder.length()); //使用之前首先清空内容
109
+        String haxString;
110
+        for (int i = 0; i < 3; i++) {
111
+            haxString = Integer.toHexString(mRandom.nextInt(0xFF));
112
+            if (haxString.length() == 1) {
113
+                haxString = "0" + haxString;
114
+            }
115
+            mBuilder.append(haxString);
116
+        }
117
+        return Color.parseColor("#" + mBuilder.toString());
118
+    }
119
+
120
+    //随机文本样式
121
+    private void randomTextStyle(Paint paint) {
122
+        int color = randomColor();
123
+        paint.setColor(color);
124
+        paint.setFakeBoldText(mRandom.nextBoolean());  //true为粗体,false为非粗体
125
+        float skewX = mRandom.nextInt(11) / 10;
126
+        skewX = mRandom.nextBoolean() ? skewX : -skewX;
127
+        paint.setTextSkewX(skewX); //float类型参数,负数表示右斜,整数左斜
128
+//        paint.setUnderlineText(true); //true为下划线,false为非下划线
129
+//        paint.setStrikeThruText(true); //true为删除线,false为非删除线
130
+    }
131
+
132
+    //随机间距
133
+    private void randomPadding() {
134
+        mPaddingLeft += BASE_PADDING_LEFT + mRandom.nextInt(RANGE_PADDING_LEFT);
135
+        mPaddingTop = BASE_PADDING_TOP + mRandom.nextInt(RANGE_PADDING_TOP);
136
+    }
137
+}

+ 45 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/DPTool.java

@@ -0,0 +1,45 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.content.Context;
4
+
5
+
6
+/**
7
+ * 创建人 mQ
8
+ * 创建时间 2019/5/20 0020 10:34
9
+ * 文件名称 DPTool
10
+ * 说明: 像素工具类
11
+ **/
12
+public class DPTool {
13
+
14
+    /**
15
+     * 将dip或dp值转换为px值,保证尺寸大小不变
16
+     */
17
+    public static int dp2px(Context context, float dp) {
18
+        final float scale = context.getResources().getDisplayMetrics().density;
19
+        return (int) (dp * scale + 0.5f);
20
+    }
21
+
22
+    /**
23
+     * 将px值转换为dip或dp值,保证尺寸大小不变
24
+     */
25
+    public static int px2dp(Context context, float px) {
26
+        final float scale = context.getResources().getDisplayMetrics().density;
27
+        return (int) (px / scale + 0.5f);
28
+    }
29
+
30
+    /**
31
+     * 将px值转换为sp值,保证文字大小不变
32
+     */
33
+    public static int px2sp(Context context, float pxValue) {
34
+        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
35
+        return (int) (pxValue / fontScale + 0.5f);
36
+    }
37
+
38
+    /**
39
+     * 将sp值转换为px值,保证文字大小不变
40
+     */
41
+    public static int sp2px(Context context, float spValue) {
42
+        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;
43
+        return (int) (spValue * fontScale + 0.5f);
44
+    }
45
+}

+ 535 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/DateTool.java

@@ -0,0 +1,535 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.support.annotation.StringDef;
4
+
5
+import java.lang.annotation.Retention;
6
+import java.lang.annotation.RetentionPolicy;
7
+import java.text.ParseException;
8
+import java.text.SimpleDateFormat;
9
+import java.util.Arrays;
10
+import java.util.Calendar;
11
+import java.util.Date;
12
+import java.util.TimeZone;
13
+
14
+/**
15
+ * 创建人 mQ
16
+ * 创建时间 2019/5/20 0020 10:35
17
+ * 文件名称 DateTool
18
+ * 说明: 日期时间工具类
19
+ **/
20
+public class DateTool {
21
+
22
+    public static final String FULL_DATE = "yyyy-MM-dd HH:mm:ss";//年-月-日 时:分:秒
23
+    public static final String YTDTD_DATE = "yyyy-MM-dd HH:mm";//年-月-日 时:分
24
+    public static final String YTD_DATE = "yyyy-MM-dd";//年-月-日
25
+    public static final String YT_DATE = "yyyy-MM";//年-月
26
+    public static final String Y_DATE = "yyyy";//年
27
+    public static final String MD_DATE = "MM-dd";//月-日
28
+    public static final String TDS_DATE = "HH:mm:ss";//时:分:秒
29
+    public static final String TD_DATE = "HH:mm";//时:分
30
+    public static final String T_DATE = "HH";//时
31
+    public static final String FULL_TEXT_DATE = "yyyy年MM月dd日 HH时mm分ss秒";//年-月-日 时:分:秒
32
+    public static final String YTD_TEXT_DATE = "yyyy年MM月dd日";//年-月-日
33
+    public static final String NYR_DATE = "yyyyMMdd";//年月日
34
+    public static final String GLNZSJ_DATE = "yyyy-MM-dd'T'HH:mm:ss.SSSZ";//格林尼治时间
35
+
36
+
37
+    @Retention(RetentionPolicy.SOURCE)
38
+    @StringDef({FULL_DATE, YTD_DATE, YT_DATE, Y_DATE, TDS_DATE, TD_DATE, MD_DATE, YTDTD_DATE,
39
+            FULL_TEXT_DATE, YTD_TEXT_DATE, NYR_DATE, GLNZSJ_DATE, T_DATE})
40
+    @interface DateType {
41
+    }
42
+
43
+    /**
44
+     * 将字符串转为完整日期类型
45
+     *
46
+     * @param date
47
+     * @return
48
+     */
49
+    public static Date toFullDate(String date) {
50
+        SimpleDateFormat format = new SimpleDateFormat(FULL_DATE);
51
+        try {
52
+            return format.parse(date);
53
+        } catch (ParseException e) {
54
+            e.printStackTrace();
55
+        }
56
+        return null;
57
+    }
58
+
59
+    /**
60
+     * 格式化日期
61
+     *
62
+     * @param date
63
+     * @param type 格式
64
+     * @return
65
+     */
66
+    public static String formatDate(String date, @DateType String type) {
67
+        if (StringTool.isEmpty(date)) {
68
+            return null;
69
+        }
70
+        SimpleDateFormat format = new SimpleDateFormat(type);
71
+        try {
72
+            Date parse = format.parse(date);
73
+            return format.format(parse);
74
+        } catch (ParseException e) {
75
+            e.printStackTrace();
76
+        }
77
+        return null;
78
+    }
79
+
80
+    /**
81
+     * 格式化日期 已知旧格式 转换新格式
82
+     *
83
+     * @param date
84
+     * @param oldType
85
+     * @param newType
86
+     * @return
87
+     */
88
+    public static String formatDate(String date, @DateType String oldType, @DateType String newType) {
89
+        SimpleDateFormat format = new SimpleDateFormat(oldType);
90
+        try {
91
+            Date parse = format.parse(date);
92
+            SimpleDateFormat dateFormat = new SimpleDateFormat(newType);
93
+            return dateFormat.format(parse);
94
+        } catch (ParseException e) {
95
+            e.printStackTrace();
96
+        }
97
+        return null;
98
+    }
99
+
100
+    /**
101
+     * 格式化日期
102
+     *
103
+     * @param date
104
+     * @param type 格式
105
+     * @return
106
+     */
107
+    public static String formatDate(Date date, @DateType String type) {
108
+        SimpleDateFormat format = new SimpleDateFormat(type);
109
+        return format.format(date);
110
+    }
111
+
112
+
113
+    /**
114
+     * 时间戳转日期
115
+     *
116
+     * @param date
117
+     * @param dateType 格式
118
+     * @return
119
+     */
120
+    public static String formatDate(long date, @DateType String dateType) {
121
+        if (date == 0) {
122
+            return "";
123
+        }
124
+        SimpleDateFormat format = new SimpleDateFormat(dateType);
125
+        return format.format(new Date(date * 1000));
126
+    }
127
+
128
+
129
+    /**
130
+     * 根据时间转换时间戳
131
+     *
132
+     * @param dateStr
133
+     * @param dateType
134
+     * @return
135
+     */
136
+    public static long getStamp(String dateStr, @DateType String dateType) {
137
+        if (StringTool.isEmpty(dateStr)) {
138
+            return 0;
139
+        }
140
+        SimpleDateFormat format = new SimpleDateFormat(dateType);
141
+        try {
142
+            return format.parse(dateStr).getTime() / 1000;
143
+        } catch (ParseException e) {
144
+            e.printStackTrace();
145
+            LogTool.i("时间转换失败,格式错误.时间 :" + dateStr + ",类型:" + dateType);
146
+        }
147
+        return 0;
148
+    }
149
+
150
+    /**
151
+     * 制定日期 添加/减少 时间
152
+     *
153
+     * @param time     日期
154
+     * @param num      添加或减少的数
155
+     * @param dateType 返回日期格式
156
+     * @param field    增减规则常量 Calebdar.DAY
157
+     * @return
158
+     */
159
+    public static String addDays(String time, int num, @DateType String dateType, int field) {
160
+        Calendar calendar = Calendar.getInstance();
161
+        calendar.setTime(new Date(time));
162
+        calendar.add(field, num);
163
+        SimpleDateFormat format = new SimpleDateFormat(dateType);
164
+        return format.format(calendar.getTime());
165
+    }
166
+
167
+    /**
168
+     * 制定日期 添加/减少 时间
169
+     *
170
+     * @param date     日期
171
+     * @param num      添加或减少的数
172
+     * @param dateType 返回日期格式
173
+     * @param field    增减规则常量 Calebdar.DAY
174
+     * @return
175
+     */
176
+    public static String addDays(Date date, int num, @DateType String dateType, int field) {
177
+        Calendar calendar = Calendar.getInstance();
178
+        calendar.setTime(date);
179
+        calendar.add(field, num);
180
+        SimpleDateFormat format = new SimpleDateFormat(dateType);
181
+        return format.format(calendar.getTime());
182
+    }
183
+
184
+
185
+    /**
186
+     * 根据生日时间戳 获取年龄
187
+     *
188
+     * @param birthday
189
+     * @return
190
+     */
191
+    public static String getAge(long birthday) {
192
+        SimpleDateFormat format = new SimpleDateFormat("yyyy");
193
+        String b = format.format(new Date(birthday));
194
+        String b2 = format.format(Calendar.getInstance().getTime());
195
+        try {
196
+            int age = Integer.valueOf(b2) - Integer.valueOf(b);
197
+            if (age == 0)
198
+                return "1";
199
+            else
200
+                return String.valueOf(age);
201
+        } catch (Exception e) {
202
+        }
203
+        return null;
204
+    }
205
+
206
+    /**
207
+     * 以友好的方式显示时间
208
+     *
209
+     * @param sdate
210
+     * @param dateType 格式
211
+     * @return
212
+     */
213
+    public static String friendlyDate(String sdate, @DateType String dateType) {
214
+        Date time = null;
215
+        if (isInEasternEightZones())
216
+            time = toFullDate(sdate);
217
+        else
218
+            time = transformTime(toFullDate(sdate),
219
+                    TimeZone.getTimeZone("GMT+08"), TimeZone.getDefault());
220
+
221
+        if (time == null) {
222
+            return "";
223
+        }
224
+        String ftime = "";
225
+        Calendar cal = Calendar.getInstance();
226
+
227
+        // 判断是否在今天
228
+        SimpleDateFormat dayFormat = new SimpleDateFormat(YTD_DATE);
229
+        String curDate = dayFormat.format(cal.getTime());
230
+        String paramDate = dayFormat.format(time);
231
+        if (curDate.equals(paramDate)) {
232
+            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
233
+            if (hour == 0)
234
+                ftime = Math.max(
235
+                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
236
+                        + "分钟前";
237
+            else
238
+                ftime = hour + "小时前";
239
+            return ftime;
240
+        }
241
+
242
+        long lt = time.getTime() / 86400000;
243
+        long ct = cal.getTimeInMillis() / 86400000;
244
+        int days = (int) (ct - lt);
245
+        if (days == 0) {
246
+            int hour = (int) ((cal.getTimeInMillis() - time.getTime()) / 3600000);
247
+            if (hour == 0)
248
+                ftime = Math.max(
249
+                        (cal.getTimeInMillis() - time.getTime()) / 60000, 1)
250
+                        + "分钟前";
251
+            else
252
+                ftime = hour + "小时前";
253
+        } else if (days == 1) {
254
+            ftime = "昨天";
255
+        } else if (days == 2) {
256
+            ftime = "前天 ";
257
+        } else if (days > 2 && days < 31) {
258
+            ftime = days + "天前";
259
+        } else if (days >= 31 && days <= 2 * 31) {
260
+            ftime = "一个月前";
261
+        } else if (days > 2 * 31 && days <= 3 * 31) {
262
+            ftime = "2个月前";
263
+        } else if (days > 3 * 31 && days <= 4 * 31) {
264
+            ftime = "3个月前";
265
+        } else {
266
+            ftime = new SimpleDateFormat(dateType).format(time);
267
+        }
268
+        return ftime;
269
+    }
270
+
271
+    /**
272
+     * 判断用户的设备时区是否为东八区(中国) 2014年7月31日
273
+     *
274
+     * @return
275
+     */
276
+    public static boolean isInEasternEightZones() {
277
+        boolean defaultVaule = true;
278
+        defaultVaule = TimeZone.getDefault() == TimeZone.getTimeZone("GMT+08");
279
+        return defaultVaule;
280
+    }
281
+
282
+    /**
283
+     * 根据不同时区,转换时间 2014年7月31日
284
+     *
285
+     * @return
286
+     */
287
+    public static Date transformTime(Date date, TimeZone oldZone, TimeZone newZone) {
288
+        Date finalDate = null;
289
+        if (date != null) {
290
+            int timeOffset = oldZone.getOffset(date.getTime())
291
+                    - newZone.getOffset(date.getTime());
292
+            finalDate = new Date(date.getTime() - timeOffset);
293
+        }
294
+        return finalDate;
295
+    }
296
+
297
+    /**
298
+     * 获取系统当前时间戳
299
+     *
300
+     * @return
301
+     */
302
+    public static long getCurrenTimeStamp() {
303
+        return System.currentTimeMillis() / 1000;
304
+    }
305
+
306
+    /**
307
+     * 与系统时间计算时间差
308
+     * 一分钟内显示"刚刚"
309
+     * 一小时内显示"xx分钟前"
310
+     * 一天内显示"xx小时前"
311
+     * 七天内显示"xx天前"
312
+     * 超过七天按照格式显示日期
313
+     *
314
+     * @param time
315
+     * @param dateType
316
+     * @return
317
+     */
318
+    public static String getTimeDifference(String time, @DateType String dateType) {
319
+        if (!StringTool.isEmpty(time)) {
320
+            long l = (long) Integer.parseInt(time);//传入的时间
321
+            long timeStamp = getCurrenTimeStamp();//系统时间
322
+            timeStamp = timeStamp - l;
323
+            long timeResult = timeStamp / 60 / 60;
324
+            if (timeResult > 0 && timeResult < 24) {
325
+                return timeResult + "小时前";
326
+            } else if (timeResult > 24) {
327
+                if (timeResult / 24 < 7)
328
+                    return formatDate(l, dateType);
329
+                else
330
+                    return timeResult / 24 + "天前";
331
+            } else if (timeResult < 24) {
332
+                if (timeStamp / 60 > 0) {
333
+                    return timeStamp / 60 + "分钟前";
334
+                } else {
335
+                    return "刚刚";
336
+                }
337
+            }
338
+        }
339
+        return null;
340
+    }
341
+
342
+    /**
343
+     * 获取当前日期是星期几
344
+     *
345
+     * @param time
346
+     * @return 当前日期是星期几
347
+     */
348
+    public static int getWeekOfDate(String time) {
349
+        return getWeekOfTime(new Date(time));
350
+    }
351
+
352
+    /**
353
+     * 获取当前日期是星期几
354
+     *
355
+     * @param time
356
+     * @return 当前日期是星期几
357
+     */
358
+    public static int getWeekOfDate(long time) {
359
+        return getWeekOfTime(new Date(time));
360
+    }
361
+
362
+    //获取当前日期是星期几
363
+    public static int getWeekOfTime(Date date) {
364
+        Calendar cal = Calendar.getInstance();
365
+        cal.setTime(date);
366
+        int w = cal.get(Calendar.DAY_OF_WEEK) - 1;
367
+        if (w < 0)
368
+            w = 0;
369
+        return w;
370
+    }
371
+
372
+
373
+    /**
374
+     * 获取日期为每年第几周
375
+     *
376
+     * @param date
377
+     * @return
378
+     */
379
+    public static int getWeekOfYear(long date) {
380
+        return getWeekOfYear(new Date(date));
381
+    }
382
+
383
+    /**
384
+     * 获取日期为每年第几周
385
+     *
386
+     * @param date
387
+     * @return
388
+     */
389
+    public static int getWeekOfYear(String date) {
390
+        return getWeekOfYear(new Date(date));
391
+    }
392
+
393
+    /**
394
+     * 获取日期为每年第几周
395
+     *
396
+     * @param date
397
+     * @return
398
+     */
399
+    public static int getWeekOfYear(Date date) {
400
+        Calendar c = Calendar.getInstance();
401
+        c.setFirstDayOfWeek(Calendar.MONDAY);
402
+        c.setTime(date);
403
+        int week = c.get(Calendar.WEEK_OF_YEAR) - 1;
404
+        week = week == 0 ? 52 : week;
405
+        return week > 0 ? week : 1;
406
+    }
407
+
408
+    public static String friendly_time2(String sdate) {
409
+        String res = "";
410
+        if (StringTool.isEmpty(sdate))
411
+            return "";
412
+
413
+        String[] weekDays = {"星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六"};
414
+        //获取当前时间 月 日
415
+        String currentData = formatDate(getCurrenTimeStamp(), MD_DATE);
416
+        int currentDay = StringTool.toInt(currentData.substring(3));
417
+        int currentMoth = StringTool.toInt(currentData.substring(0, 2));
418
+
419
+        int sMoth = StringTool.toInt(sdate.substring(5, 7));
420
+        int sDay = StringTool.toInt(sdate.substring(8, 10));
421
+        int sYear = StringTool.toInt(sdate.substring(0, 4));
422
+        Date dt = new Date(sYear, sMoth - 1, sDay - 1);
423
+
424
+        if (sDay == currentDay && sMoth == currentMoth) {
425
+            res = "今天 / " + weekDays[getWeekOfDate(getCurrenTimeStamp())];
426
+        } else if (sDay == currentDay + 1 && sMoth == currentMoth) {
427
+            res = "昨天 / " + weekDays[(getWeekOfDate(getCurrenTimeStamp()) + 6) % 7];
428
+        } else {
429
+            if (sMoth < 10) {
430
+                res = "0";
431
+            }
432
+            res += sMoth + "/";
433
+            if (sDay < 10) {
434
+                res += "0";
435
+            }
436
+            res += sDay + " / " + weekDays[getWeekOfDate(dt.getTime())];
437
+        }
438
+
439
+        return res;
440
+    }
441
+
442
+
443
+    /**
444
+     * 获取日期当天的开始时间
445
+     */
446
+    public static long getDayStartTime(long date) {
447
+        return getDayStartTime(new Date(date));
448
+    }
449
+
450
+    /**
451
+     * 获取日期当天的开始时间
452
+     */
453
+    public static long getDayStartTime(Date date) {
454
+        Calendar cal = Calendar.getInstance();
455
+        cal.setTime(date);
456
+        //当天的开始时间
457
+        cal.set(Calendar.HOUR, 0);
458
+        cal.set(Calendar.MINUTE, 0);
459
+        cal.set(Calendar.SECOND, 0);
460
+        return cal.getTimeInMillis() / 1000;
461
+    }
462
+
463
+    /**
464
+     * 获取日期当天结束时间
465
+     */
466
+    public static long getDayEndTime(long date) {
467
+        return getDayEndTime(new Date(date));
468
+    }
469
+
470
+    /**
471
+     * 获取日期当天结束时间
472
+     */
473
+    public static long getDayEndTime(Date date) {
474
+        Calendar cal = Calendar.getInstance();
475
+        cal.setTime(date);
476
+        //当天的结束时间
477
+        cal.set(Calendar.HOUR, 23);
478
+        cal.set(Calendar.MINUTE, 59);
479
+        cal.set(Calendar.SECOND, 59);
480
+        return cal.getTimeInMillis() / 1000;
481
+    }
482
+
483
+    /**
484
+     * 拆分开始时间和结束时间 以数组形式返回
485
+     *
486
+     * @param date 数据格式 年-月-日 时:分:秒~年-月-日 时:分:秒
487
+     * @return 数组长度为4 起始日期、起始时间、结束日期、结束时间
488
+     */
489
+    public static String[] getStartEndDate(String date) {
490
+        String[] result = new String[]{"", "", "", ""};//起始日期、起始时间、结束日期、结束时间
491
+
492
+        if (StringTool.isEmpty(date))
493
+            return result;
494
+
495
+        //数据格式 年-月-日 时:分:秒~年-月-日 时:分:秒
496
+        String[] split = date.split("~");
497
+        if (split == null)
498
+            return result;
499
+
500
+        LogTool.i("日期拆分: 1----" + Arrays.toString(split));
501
+        //拆分起始日期
502
+        String start = split[0]; //年-月-日 时:分:秒
503
+        if (!StringTool.isEmpty(start)) {
504
+            LogTool.i("日期拆分: 2----" + start);
505
+
506
+            String[] start1 = start.split(" ");
507
+            if (start1 != null && start1.length > 0) {
508
+                LogTool.i("日期拆分: 3----" + Arrays.toString(start1));
509
+
510
+                result[0] = start1[0];//年-月-日
511
+                if (start1.length > 1)
512
+                    result[1] = start1[1];//时:分:秒
513
+            }
514
+        }
515
+        //拆分结束日期
516
+        String end = split[1];  //年-月-日 时:分:秒
517
+        if (!StringTool.isEmpty(end)) {
518
+            LogTool.i("日期拆分: 4----" + end);
519
+
520
+            String[] end1 = end.split(" ");
521
+            if (end1 != null && end1.length > 0) {
522
+                LogTool.i("日期拆分: 5----" + Arrays.toString(end1));
523
+
524
+                result[2] = end1[0];//年-月-日
525
+                if (end1.length > 1)
526
+                    result[3] = end1[1];//时:分:秒
527
+            }
528
+
529
+        }
530
+        return result;
531
+    }
532
+
533
+
534
+
535
+}

+ 122 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ETTool.java

@@ -0,0 +1,122 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.annotation.SuppressLint;
4
+import android.graphics.drawable.Drawable;
5
+import android.util.SparseArray;
6
+import android.view.MotionEvent;
7
+import android.view.View;
8
+import android.widget.EditText;
9
+import android.widget.TextView;
10
+
11
+/**
12
+ * 创建人 mQ
13
+ * 创建时间 2019/5/20 0020 10:34
14
+ * 文件名称 ETTool
15
+ * 说明: EditText工具类
16
+ **/
17
+public class ETTool {
18
+
19
+
20
+    private static SparseArray<OnRightListener> listenerMap;
21
+
22
+    public interface OnRightListener {
23
+        void onRight(EditText et, MotionEvent event);
24
+    }
25
+
26
+    /**
27
+     * 给EditText添加右侧图片点击事件
28
+     *
29
+     * @param et
30
+     * @param rightListener
31
+     */
32
+    @SuppressLint("ClickableViewAccessibility")
33
+    public static void addOnRightClickListiner(EditText et, OnRightListener rightListener) {
34
+
35
+        if (null != et && null != rightListener) {
36
+
37
+            //将id和接口添加到集合中便于后面使用
38
+            if (null == listenerMap)
39
+                listenerMap = new SparseArray<>();
40
+            listenerMap.put(et.getId(), rightListener);
41
+
42
+            //根据触摸位置判断是否点击在右侧图片上
43
+            et.setOnTouchListener(new View.OnTouchListener() {
44
+                @Override
45
+                public boolean onTouch(View v, MotionEvent event) {
46
+                    EditText et = (EditText) v;
47
+                    // et.getCompoundDrawables()得到一个长度为4的数组,分别表示左右上下四张图片
48
+                    Drawable drawable = et.getCompoundDrawables()[2];
49
+                    //如果右边没有图片,不再处理
50
+                    if (drawable == null)
51
+                        return false;
52
+                    //如果不是按下事件,不再处理
53
+                    if (event.getAction() != MotionEvent.ACTION_UP)
54
+                        return false;
55
+                    //点击了右侧
56
+                    if (event.getX() > et.getWidth() - et.getPaddingRight()
57
+                            - drawable.getIntrinsicWidth()) {
58
+                        //从集合中取出对应的接口 并调用回调方法
59
+                        OnRightListener listener = listenerMap.get(et.getId());
60
+                        if (null != listener)
61
+                            listener.onRight(et, event);
62
+                    }
63
+                    return false;
64
+                }
65
+            });
66
+        }
67
+    }
68
+
69
+    /**
70
+     * 获取控件中的文字
71
+     * 仅支持TextView的子类
72
+     *
73
+     * @param view
74
+     * @return
75
+     */
76
+    public static String getData(View view) {
77
+        if (view != null) {
78
+            if (view instanceof EditText) {
79
+                return ((EditText) view).getText().toString().trim();
80
+            } else if (view instanceof TextView) {
81
+                return ((TextView) view).getText().toString().trim();
82
+            }
83
+        }
84
+        return "";
85
+    }
86
+
87
+    /**
88
+     * 给文字控件赋值
89
+     * 仅支持TextView的子类
90
+     *
91
+     * @param view
92
+     * @param data
93
+     */
94
+    public static void setData(View view, String data) {
95
+        if (view != null) {
96
+            if (view instanceof EditText) {
97
+                EditText et = (EditText) view;
98
+                et.setText(data);
99
+            } else if (view instanceof TextView) {
100
+                TextView et = (TextView) view;
101
+                et.setText(data);
102
+            }
103
+        }
104
+    }
105
+
106
+    //编辑框 是否 可点击、可获取焦点
107
+    public static void setFocus(EditText et, boolean isFocusable) {
108
+        if (et != null)
109
+            if (isFocusable) {
110
+                et.setCursorVisible(true);
111
+                et.setTextIsSelectable(true);
112
+                et.setFocusableInTouchMode(true);
113
+                et.setFocusable(true);
114
+                et.requestFocus();
115
+            } else {
116
+                et.setCursorVisible(false);//不显示光标
117
+                et.setTextIsSelectable(false);//不可编辑状态下文字不可选
118
+                et.setFocusable(false);
119
+                et.setFocusableInTouchMode(false);
120
+            }
121
+    }
122
+}

+ 182 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/FileUtil.java

@@ -0,0 +1,182 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.content.Context;
4
+import android.os.Environment;
5
+
6
+import java.io.BufferedInputStream;
7
+import java.io.ByteArrayOutputStream;
8
+import java.io.File;
9
+import java.io.FileInputStream;
10
+import java.io.FileNotFoundException;
11
+import java.io.IOException;
12
+
13
+/**
14
+ * 创建人 mQ
15
+ * 创建时间 2019/5/20 0020 10:34
16
+ * 文件名称 FileUtil
17
+ * 说明:  文件读写工具类
18
+ **/
19
+public class FileUtil {
20
+
21
+    /**
22
+     * 读取文件内容,作为字符串返回
23
+     */
24
+    public static String readFileAsString(String filePath) throws IOException {
25
+        File file = new File(filePath);
26
+        if (!file.exists()) {
27
+            throw new FileNotFoundException(filePath);
28
+        }
29
+
30
+        if (file.length() > 1024 * 1024 * 1024) {
31
+            throw new IOException("File is too large");
32
+        }
33
+
34
+        StringBuilder sb = new StringBuilder((int) (file.length()));
35
+        // 创建字节输入流
36
+        FileInputStream fis = new FileInputStream(filePath);
37
+        // 创建一个长度为10240的Buffer
38
+        byte[] bbuf = new byte[10240];
39
+        // 用于保存实际读取的字节数
40
+        int hasRead = 0;
41
+        while ((hasRead = fis.read(bbuf)) > 0) {
42
+            sb.append(new String(bbuf, 0, hasRead));
43
+        }
44
+        fis.close();
45
+        return sb.toString();
46
+    }
47
+
48
+    /**
49
+     * 根据文件路径读取byte[] 数组
50
+     */
51
+    public static byte[] readFileByBytes(String filePath) throws IOException {
52
+        File file = new File(filePath);
53
+        if (!file.exists()) {
54
+            throw new FileNotFoundException(filePath);
55
+        } else {
56
+            ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());
57
+            BufferedInputStream in = null;
58
+
59
+            try {
60
+                in = new BufferedInputStream(new FileInputStream(file));
61
+                short bufSize = 1024;
62
+                byte[] buffer = new byte[bufSize];
63
+                int len1;
64
+                while (-1 != (len1 = in.read(buffer, 0, bufSize))) {
65
+                    bos.write(buffer, 0, len1);
66
+                }
67
+
68
+                byte[] var7 = bos.toByteArray();
69
+                return var7;
70
+            } finally {
71
+                try {
72
+                    if (in != null) {
73
+                        in.close();
74
+                    }
75
+                } catch (IOException var14) {
76
+                    var14.printStackTrace();
77
+                }
78
+
79
+                bos.close();
80
+            }
81
+        }
82
+    }
83
+
84
+    /**
85
+     * 删除文件,可以是文件或文件夹
86
+     *
87
+     * @param delFile 要删除的文件夹或文件名
88
+     * @return 删除成功返回true,否则返回false
89
+     */
90
+    public static boolean delete(String delFile) {
91
+        File file = new File(delFile);
92
+        if (!file.exists()) {
93
+            return false;
94
+        } else {
95
+            if (file.isFile())
96
+                return deleteSingleFile(delFile);
97
+            else
98
+                return deleteDirectory(delFile);
99
+        }
100
+    }
101
+
102
+    /**
103
+     * 删除单个文件
104
+     *
105
+     * @param filePath$Name 要删除的文件的文件名
106
+     * @return 单个文件删除成功返回true,否则返回false
107
+     */
108
+    public static boolean deleteSingleFile(String filePath$Name) {
109
+        File file = new File(filePath$Name);
110
+        // 如果文件路径所对应的文件存在,并且是一个文件,则直接删除
111
+        if (file.exists() && file.isFile()) {
112
+            if (file.delete()) {
113
+                LogTool.i("deleteSingleFile删除单个文件: " + filePath$Name + " 成功!");
114
+                return true;
115
+            } else {
116
+                return false;
117
+            }
118
+        } else {
119
+            return false;
120
+        }
121
+    }
122
+
123
+    /**
124
+     * 删除目录及目录下的文件
125
+     *
126
+     * @param filePath 要删除的目录的文件路径
127
+     * @return 目录删除成功返回true,否则返回false
128
+     */
129
+    public static boolean deleteDirectory(String filePath) {
130
+        // 如果dir不以文件分隔符结尾,自动添加文件分隔符
131
+        if (!filePath.endsWith(File.separator))
132
+            filePath = filePath + File.separator;
133
+        File dirFile = new File(filePath);
134
+        // 如果dir对应的文件不存在,或者不是一个目录,则退出
135
+        if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
136
+            LogTool.i("deleteSingleFile删除目录失败: " + filePath + " 不存在!");
137
+            return false;
138
+        }
139
+        boolean flag = true;
140
+        // 删除文件夹中的所有文件包括子目录
141
+        File[] files = dirFile.listFiles();
142
+        for (File file : files) {
143
+            // 删除子文件
144
+            if (file.isFile()) {
145
+                flag = deleteSingleFile(file.getAbsolutePath());
146
+                if (!flag)
147
+                    break;
148
+            }
149
+            // 删除子目录
150
+            else if (file.isDirectory()) {
151
+                flag = deleteDirectory(file
152
+                        .getAbsolutePath());
153
+                if (!flag)
154
+                    break;
155
+            }
156
+        }
157
+        if (!flag) {
158
+            LogTool.i("deleteSingleFile删除目录失败: " + filePath);
159
+            return false;
160
+        }
161
+        // 删除当前目录
162
+        if (dirFile.delete()) {
163
+            LogTool.i("deleteSingleFile删除目录: " + filePath + "成功!");
164
+            return true;
165
+        } else {
166
+            return false;
167
+        }
168
+    }
169
+
170
+    /**
171
+     * 创建文件,以时间来命名就不会产生命名冲突
172
+     */
173
+    public static File createFileForDate(Context context, String name) {
174
+        String filePath = Environment.getExternalStorageDirectory() + "/sjlsxxgl/" + name + "_" + System.currentTimeMillis() + ".jpg";
175
+        File outputFile = new File(filePath);
176
+        if (!outputFile.getParentFile().exists()) {
177
+            outputFile.getParentFile().mkdir();
178
+        }
179
+        return outputFile;
180
+    }
181
+
182
+}

+ 275 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/HappySQL.java

@@ -0,0 +1,275 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.database.Cursor;
4
+import android.database.sqlite.SQLiteDatabase;
5
+
6
+import org.xml.sax.helpers.LocatorImpl;
7
+
8
+import java.lang.reflect.Constructor;
9
+import java.lang.reflect.Field;
10
+import java.util.HashMap;
11
+import java.util.LinkedList;
12
+import java.util.List;
13
+import java.util.Map;
14
+
15
+/**
16
+ * 创建人 mQ
17
+ * 创建时间 2019/5/20 0020 10:33
18
+ * 文件名称 HappySQL
19
+ * 说明: sql查询结果转实体,转集合
20
+ **/
21
+public class HappySQL {
22
+
23
+    /**
24
+     * 通过SQL语句获得对应的VO。注意:Cursor的字段名或者别名一定要和VO的成员名一样
25
+     *
26
+     * @param db
27
+     * @param sql
28
+     * @param clazz
29
+     * @return
30
+     */
31
+    @SuppressWarnings("rawtypes")
32
+    public static Object sql2VO(SQLiteDatabase db, String sql, Class clazz) {
33
+        Cursor c = db.rawQuery(sql, null);
34
+        return cursor2VO(c, clazz);
35
+    }
36
+
37
+    /**
38
+     * 通过SQL语句获得对应的VO。注意:Cursor的字段名或者别名一定要和VO的成员名一样
39
+     *
40
+     * @param db
41
+     * @param sql
42
+     * @param selectionArgs
43
+     * @param clazz
44
+     * @return
45
+     */
46
+    @SuppressWarnings("rawtypes")
47
+    public static Object sql2VO(SQLiteDatabase db, String sql,
48
+                                String[] selectionArgs, Class clazz) {
49
+        Cursor c = db.rawQuery(sql, selectionArgs);
50
+        return cursor2VO(c, clazz);
51
+    }
52
+
53
+    /**
54
+     * 通过SQL语句获得对应的VO的List。注意:Cursor的字段名或者别名一定要和VO的成员名一样
55
+     *
56
+     * @param db
57
+     * @param sql
58
+     * @param clazz
59
+     * @return
60
+     */
61
+    @SuppressWarnings("rawtypes")
62
+    public static List sql2VOList(SQLiteDatabase db, String sql, Class clazz) {
63
+        Cursor c = db.rawQuery(sql, null);
64
+        return cursor2VOList(c, clazz);
65
+    }
66
+
67
+    /**
68
+     * 通过SQL语句获得对应的VO的List。注意:Cursor的字段名或者别名一定要和VO的成员名一样
69
+     *
70
+     * @param db
71
+     * @param sql
72
+     * @param selectionArgs
73
+     * @param clazz
74
+     * @return
75
+     */
76
+    @SuppressWarnings("rawtypes")
77
+    public static List sql2VOList(SQLiteDatabase db, String sql,
78
+                                  String[] selectionArgs, Class clazz) {
79
+        Cursor c = db.rawQuery(sql, selectionArgs);
80
+        return cursor2VOList(c, clazz);
81
+    }
82
+
83
+    /**
84
+     * 通过Cursor转换成对应的VO。注意:Cursor里的字段名(可用别名)必须要和VO的属性名一致
85
+     *
86
+     * @param c
87
+     * @param clazz
88
+     * @return
89
+     */
90
+    @SuppressWarnings({"rawtypes", "unused"})
91
+    public static Object cursor2VO(Cursor c, Class clazz) {
92
+        if (c == null) {
93
+            return null;
94
+        }
95
+        Object obj;
96
+        int i = 1;
97
+        try {
98
+            c.moveToNext();
99
+            obj = setValuesToClass(c, clazz);
100
+
101
+            return obj;
102
+        } catch (Exception e) {
103
+            System.out.println(e);
104
+            System.out.println("ERROR @:cursor2VO");
105
+            return null;
106
+        } finally {
107
+            c.close();
108
+        }
109
+    }
110
+
111
+    /**
112
+     * 通过Cursor转换成对应的VO集合。注意:Cursor里的字段名(可用别名)必须要和VO的属性名一致
113
+     *
114
+     * @param c
115
+     * @param clazz
116
+     * @return
117
+     */
118
+    @SuppressWarnings({"rawtypes", "unchecked"})
119
+    public static List cursor2VOList(Cursor c, Class clazz) {
120
+        if (c == null) {
121
+            return null;
122
+        }
123
+        List list = new LinkedList();
124
+        Object obj;
125
+        try {
126
+            while (c.moveToNext()) {
127
+                obj = setValuesToClass(c, clazz);
128
+                list.add(obj);
129
+            }
130
+            return list;
131
+        } catch (Exception e) {
132
+            e.printStackTrace();
133
+            System.out.println("ERROR @:cursor2VOList");
134
+            return null;
135
+        } finally {
136
+            c.close();
137
+        }
138
+    }
139
+
140
+    /**
141
+     * 把值设置进类属性里
142
+     *
143
+     * @param c
144
+     * @throws Exception
145
+     */
146
+    @SuppressWarnings("rawtypes")
147
+    private static Object setValues2Fields(Cursor c, Class clazz)
148
+            throws Exception {
149
+        String[] columnNames = c.getColumnNames();// 字段数组
150
+        Object obj = clazz.newInstance();
151
+        Field[] fields = clazz.getFields();
152
+
153
+        for (Field _field : fields) {
154
+            Class<? extends Object> typeClass = _field.getType();// 属性类型
155
+            for (int j = 0; j < columnNames.length; j++) {
156
+                String columnName = columnNames[j];
157
+                typeClass = getBasicClass(typeClass);
158
+                boolean isBasicType = isBasicType(typeClass);
159
+
160
+                if (isBasicType) {
161
+                    if (columnName.equalsIgnoreCase(_field.getName())) {// 是基本类型
162
+                        String _str = c.getString(c.getColumnIndex(columnName));
163
+                        if (_str == null) {
164
+                            break;
165
+                        }
166
+                        _str = _str == null ? "" : _str;
167
+                        Constructor<? extends Object> cons = typeClass
168
+                                .getConstructor(String.class);
169
+                        Object attribute = cons.newInstance(_str);
170
+                        _field.setAccessible(true);
171
+                        _field.set(obj, attribute);
172
+                        break;
173
+                    }
174
+                } else {
175
+                    Object obj2 = setValues2Fields(c, typeClass);// 递归
176
+                    _field.set(obj, obj2);
177
+                    break;
178
+                }
179
+
180
+            }
181
+        }
182
+        return obj;
183
+    }
184
+
185
+    private static Object setValuesToClass(Cursor c, Class clazz) throws Exception {
186
+        String[] columnNames = c.getColumnNames();//字段数组
187
+        Object obj = clazz.newInstance();
188
+        Field[] fields = clazz.getFields();
189
+
190
+        for (Field _field : fields) {
191
+            Class<?> type = _field.getType();
192
+            for (int i = 0; i < columnNames.length; i++) {
193
+                String columnName = columnNames[i];
194
+                if (columnName.equalsIgnoreCase(_field.getName())) {
195
+
196
+                    if (type == byte[].class) {
197
+                        byte[] blob = c.getBlob(c.getColumnIndex(columnName));
198
+                        _field.set(obj, blob);
199
+                    } else if (type == String.class) {
200
+                        String string = c.getString(c.getColumnIndex(columnName));
201
+                        _field.set(obj, string);
202
+                    } else if (type == Integer.class) {
203
+                        int anInt = c.getInt(c.getColumnIndex(columnName));
204
+                        _field.set(obj, anInt);
205
+                    } else if (type == Double.class) {
206
+                        double aDouble = c.getDouble(c.getColumnIndex(columnName));
207
+                        _field.set(obj, aDouble);
208
+                    } else if (type == Float.class) {
209
+                        float aFloat = c.getFloat(c.getColumnIndex(columnName));
210
+                        _field.set(obj, aFloat);
211
+                    } else if (type == Long.class) {
212
+                        long aLong = c.getLong(c.getColumnIndex(columnName));
213
+                        _field.set(obj, aLong);
214
+                    } else if (type == Short.class) {
215
+                        short aShort = c.getShort(c.getColumnIndex(columnName));
216
+                        _field.set(obj, aShort);
217
+                    }
218
+                }
219
+            }
220
+        }
221
+        return obj;
222
+    }
223
+
224
+
225
+    /**
226
+     * 判断是不是基本类型
227
+     *
228
+     * @param typeClass
229
+     * @return
230
+     */
231
+    @SuppressWarnings("rawtypes")
232
+    private static boolean isBasicType(Class typeClass) {
233
+        if (typeClass.equals(Integer.class) || typeClass.equals(Long.class)
234
+                || typeClass.equals(Float.class)
235
+                || typeClass.equals(Double.class)
236
+                || typeClass.equals(Boolean.class)
237
+                || typeClass.equals(Byte.class)
238
+                || typeClass.equals(Short.class)
239
+                || typeClass.equals(String.class)) {
240
+
241
+            return true;
242
+
243
+        } else {
244
+            return false;
245
+        }
246
+    }
247
+
248
+    /**
249
+     * 获得包装类
250
+     *
251
+     * @param typeClass
252
+     * @return
253
+     */
254
+    @SuppressWarnings("all")
255
+    public static Class<? extends Object> getBasicClass(Class typeClass) {
256
+        Class _class = basicMap.get(typeClass);
257
+        if (_class == null)
258
+            _class = typeClass;
259
+        return _class;
260
+    }
261
+
262
+    @SuppressWarnings("rawtypes")
263
+    private static Map<Class, Class> basicMap = new HashMap<Class, Class>();
264
+
265
+    static {
266
+        basicMap.put(int.class, Integer.class);
267
+        basicMap.put(long.class, Long.class);
268
+        basicMap.put(float.class, Float.class);
269
+        basicMap.put(double.class, Double.class);
270
+        basicMap.put(boolean.class, Boolean.class);
271
+        basicMap.put(byte.class, Byte.class);
272
+        basicMap.put(short.class, Short.class);
273
+    }
274
+
275
+}

+ 89 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/LogTool.java

@@ -0,0 +1,89 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.util.Log;
4
+
5
+/**
6
+ * 创建人 mQ
7
+ * 创建时间 2019/5/20 0020 10:32
8
+ * 文件名称 LogTool
9
+ * 说明: 日志打印工具类
10
+ **/
11
+public class LogTool {
12
+    private static final String TAG = "LogTool";
13
+    //类名
14
+    private static String className;
15
+    //方法名
16
+    private static String methodName;
17
+    //行数
18
+    private static int lineNumber;
19
+    private static boolean isDebug = true;
20
+
21
+    public static void isDebug(boolean debug) {
22
+        isDebug = debug;
23
+    }
24
+
25
+    private LogTool() {
26
+        /* Protect from instantiations */
27
+    }
28
+
29
+
30
+    private static String createLog(String log) {
31
+        return methodName + "(" + className + ":" + lineNumber + ") = " + log;
32
+    }
33
+
34
+    private static void getMethodNames(StackTraceElement[] sElements) {
35
+        className = sElements[1].getFileName();
36
+        methodName = sElements[1].getMethodName();
37
+        lineNumber = sElements[1].getLineNumber();
38
+    }
39
+
40
+    public static void e(String message) {
41
+        if (!isDebug) {
42
+            return;
43
+        }
44
+        // Throwable instance must be created before any methods
45
+        getMethodNames(new Throwable().getStackTrace());
46
+        Log.e(className, createLog(message));
47
+    }
48
+
49
+
50
+    public static void i(String message) {
51
+        if (!isDebug) {
52
+            return;
53
+        }
54
+        getMethodNames(new Throwable().getStackTrace());
55
+        Log.i(className, createLog(message));
56
+    }
57
+
58
+    public static void d(String message) {
59
+        if (!isDebug) {
60
+            return;
61
+        }
62
+        getMethodNames(new Throwable().getStackTrace());
63
+        Log.d(className, createLog(message));
64
+    }
65
+
66
+    public static void v(String message) {
67
+        if (!isDebug) {
68
+            return;
69
+        }
70
+        getMethodNames(new Throwable().getStackTrace());
71
+        Log.v(className, createLog(message));
72
+    }
73
+
74
+    public static void w(String message) {
75
+        if (!isDebug) {
76
+            return;
77
+        }
78
+        getMethodNames(new Throwable().getStackTrace());
79
+        Log.w(className, createLog(message));
80
+    }
81
+
82
+    public static void wtf(String message) {
83
+        if (!isDebug) {
84
+            return;
85
+        }
86
+        getMethodNames(new Throwable().getStackTrace());
87
+        Log.wtf(className, createLog(message));
88
+    }
89
+}

+ 114 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/PermissionTool.java

@@ -0,0 +1,114 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.app.Activity;
4
+import android.content.pm.PackageManager;
5
+import android.support.annotation.NonNull;
6
+import android.support.v4.app.ActivityCompat;
7
+import android.support.v4.content.ContextCompat;
8
+
9
+import java.util.ArrayList;
10
+import java.util.List;
11
+
12
+/**
13
+ * 创建人 mQ
14
+ * 创建时间 2019/5/20 0020 10:32
15
+ * 文件名称 PermissionTool
16
+ * 说明: 权限申请工具类
17
+ **/
18
+public class PermissionTool {
19
+
20
+    private String[] mPermissions;
21
+
22
+    private static final int mRequestPermissionCode = 1001;
23
+
24
+//    private Activity mActivity;
25
+
26
+    private PermissionTool() {
27
+    }
28
+
29
+    private static class SingleHelper {
30
+        private static final PermissionTool INSTANCE = new PermissionTool();
31
+    }
32
+
33
+    public static PermissionTool get() {
34
+        return SingleHelper.INSTANCE;
35
+    }
36
+
37
+    public PermissionTool init(String[] permissions) {
38
+        mPermissions = permissions;
39
+        return this;
40
+    }
41
+
42
+    /**
43
+     * 权限是否全部授权
44
+     */
45
+    public boolean checkPermissionAll(Activity mActivity) {
46
+        for (String p : mPermissions) {
47
+            if (!(ContextCompat.checkSelfPermission(mActivity, p) == PackageManager.PERMISSION_GRANTED)) {
48
+                return false;
49
+            }
50
+        }
51
+        return true;
52
+    }
53
+
54
+    /**
55
+     * 申请权限
56
+     */
57
+    public PermissionTool requestPermission(Activity mActivity) {
58
+        //申请权限
59
+        ActivityCompat.requestPermissions(mActivity, mPermissions, mRequestPermissionCode);
60
+        return this;
61
+    }
62
+
63
+    /**
64
+     * 是否可以显示申请UI
65
+     */
66
+    public boolean getIsRequestUI(Activity mActivity, String[] permissions) {
67
+        //是否可以显示UI
68
+        boolean isRequestUI = false;
69
+        for (String permission : permissions) {
70
+            LogTool.i("requestPermission: " + ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permission));
71
+            if (ActivityCompat.shouldShowRequestPermissionRationale(mActivity, permission)) {
72
+                isRequestUI = true;
73
+            }
74
+        }
75
+        return isRequestUI;
76
+    }
77
+
78
+    /**
79
+     * 处理权限申请结果
80
+     */
81
+    public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
82
+                                           @NonNull int[] grantResults, PermissionCallBack callBack) {
83
+        if (requestCode == mRequestPermissionCode) {
84
+            if (grantResults.length > 0) {
85
+                List<String> mDeniedPermissions = new ArrayList<>();
86
+                for (int i = 0; i < grantResults.length; i++) {
87
+                    if (grantResults[i] != PackageManager.PERMISSION_GRANTED) {
88
+                        mDeniedPermissions.add(permissions[i]);
89
+                        LogTool.i("权限被拒绝: " + permissions[i]);
90
+                    }
91
+                }
92
+                if (mDeniedPermissions.size() == 0) {
93
+                    LogTool.i("权限全部通过");
94
+                    if (callBack != null)
95
+                        callBack.onGrantedPermissionAll();
96
+                } else {
97
+                    //权限申请被拒绝
98
+                    if (callBack != null)
99
+                        callBack.onDeniedPermission(mDeniedPermissions.toArray(new String[mDeniedPermissions.size()]));
100
+                }
101
+            }
102
+        }
103
+    }
104
+
105
+    public interface PermissionCallBack {
106
+        void onGrantedPermissionAll();
107
+
108
+        void onDeniedPermission(String[] deniedPermissions);
109
+
110
+    }
111
+
112
+
113
+
114
+}

+ 196 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/SPTool.java

@@ -0,0 +1,196 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.app.Application;
4
+import android.content.Context;
5
+import android.content.SharedPreferences;
6
+import android.text.TextUtils;
7
+import android.util.Base64;
8
+
9
+import java.io.ByteArrayInputStream;
10
+import java.io.ByteArrayOutputStream;
11
+import java.io.IOException;
12
+import java.io.ObjectInputStream;
13
+import java.io.ObjectOutputStream;
14
+import java.util.Map;
15
+
16
+/**
17
+ * 创建人 mQ
18
+ * 创建时间 2019/5/20 0020 10:32
19
+ * 文件名称 SPTool
20
+ * 说明: SharedPreferences工具类
21
+ *   用来存储轻量数据
22
+ **/
23
+public class SPTool {
24
+
25
+    private static Application context;
26
+    /**
27
+     * 保存在手机里面的文件名
28
+     */
29
+    private static String FILE_NAME;
30
+
31
+    //初始化方式
32
+    public static void init(Application application, String fileName) {
33
+        context = application;
34
+        FILE_NAME = fileName;
35
+    }
36
+
37
+    /**
38
+     * 保存数据
39
+     * 我们需要拿到保存数据的具体类型,然后根据类型调用不同的保存方法
40
+     *
41
+     * @param key
42
+     * @param object
43
+     */
44
+    public static void save(String key, Object object) {
45
+        saveByFileName(FILE_NAME, key, object);
46
+    }
47
+
48
+    public static void saveByFileName(String fileName, String key, Object object) {
49
+        String type = object.getClass().getSimpleName();
50
+        SharedPreferences sp = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
51
+        SharedPreferences.Editor editor = sp.edit();
52
+
53
+        if ("String".equals(type)) {
54
+            editor.putString(key, (String) object);
55
+        } else if ("Integer".equals(type)) {
56
+            editor.putInt(key, (Integer) object);
57
+        } else if ("Boolean".equals(type)) {
58
+            editor.putBoolean(key, (Boolean) object);
59
+        } else if ("Float".equals(type)) {
60
+            editor.putFloat(key, (Float) object);
61
+        } else if ("Long".equals(type)) {
62
+            editor.putLong(key, (Long) object);
63
+        }
64
+
65
+        editor.commit();
66
+    }
67
+
68
+
69
+    /**
70
+     * 查看已存的数据
71
+     * 我们根据默认值得到保存的数据的具体类型,然后调用相对于的方法获取值
72
+     *
73
+     * @param key
74
+     * @param defaultObject
75
+     * @return
76
+     */
77
+    public static Object get(String key, Object defaultObject) {
78
+        return getByFileName(FILE_NAME, key, defaultObject);
79
+    }
80
+
81
+    public static Object getByFileName(String fileName, String key, Object defaultObject) {
82
+        String type = defaultObject.getClass().getSimpleName();
83
+        SharedPreferences sp = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
84
+
85
+        if ("String".equals(type)) {
86
+            return sp.getString(key, (String) defaultObject);
87
+        } else if ("Integer".equals(type)) {
88
+            return sp.getInt(key, (Integer) defaultObject);
89
+        } else if ("Boolean".equals(type)) {
90
+            return sp.getBoolean(key, (Boolean) defaultObject);
91
+        } else if ("Float".equals(type)) {
92
+            return sp.getFloat(key, (Float) defaultObject);
93
+        } else if ("Long".equals(type)) {
94
+            return sp.getLong(key, (Long) defaultObject);
95
+        }
96
+
97
+        return null;
98
+    }
99
+
100
+    public static Map<String, String> getAllByFileName(String fileName) {
101
+        SharedPreferences sp = context.getSharedPreferences(fileName, Context.MODE_PRIVATE);
102
+        return (Map<String, String>) sp.getAll();
103
+    }
104
+
105
+    /**
106
+     * 移除指定数据
107
+     */
108
+    public static void remove(String key) {
109
+        removeByFileName(FILE_NAME, key);
110
+    }
111
+
112
+    /**
113
+     * 移除指定数据
114
+     */
115
+    public static void removeByFileName(String fileName, String key) {
116
+        SharedPreferences sp = context.getSharedPreferences(fileName,
117
+                Context.MODE_PRIVATE);
118
+        SharedPreferences.Editor editor = sp.edit();
119
+        editor.remove(key);
120
+        editor.commit();
121
+    }
122
+
123
+    /**
124
+     * 移除所有数据
125
+     */
126
+    public static void removeAll() {
127
+        removeAllByFileName(FILE_NAME);
128
+    }
129
+
130
+    /**
131
+     * 移除所有数据
132
+     */
133
+    public static void removeAllByFileName(String fileName) {
134
+        SharedPreferences sp = context.getSharedPreferences(fileName,
135
+                Context.MODE_PRIVATE);
136
+        SharedPreferences.Editor editor = sp.edit();
137
+        editor.clear().commit();
138
+    }
139
+
140
+    /**
141
+     * 将对象进行base64编码后保存到SharePref中
142
+     *
143
+     * @param context
144
+     * @param key
145
+     * @param object
146
+     */
147
+    public static void saveObj(Context context, String key, Object object) {
148
+        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
149
+
150
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
151
+        ObjectOutputStream oos = null;
152
+        try {
153
+            oos = new ObjectOutputStream(baos);
154
+            oos.writeObject(object);
155
+            // 将对象的转为base64码
156
+            String objBase64 = new String(Base64.encode(baos.toByteArray(),
157
+                    Base64.DEFAULT));
158
+
159
+            sp.edit().putString(key, objBase64).commit();
160
+            oos.close();
161
+        } catch (IOException e) {
162
+            e.printStackTrace();
163
+        }
164
+    }
165
+
166
+    /**
167
+     * 将SharePref中经过base64编码的对象读取出来
168
+     *
169
+     * @param context
170
+     * @param key
171
+     * @param
172
+     * @return
173
+     */
174
+    public static Object getObj(Context context, String key) {
175
+        SharedPreferences sp = context.getSharedPreferences(FILE_NAME, Context.MODE_PRIVATE);
176
+        String objBase64 = sp.getString(key, null);
177
+        if (TextUtils.isEmpty(objBase64)) {
178
+            return null;
179
+        }
180
+
181
+        // 对Base64格式的字符串进行解码
182
+        byte[] base64Bytes = Base64.decode(objBase64.getBytes(), Base64.DEFAULT);
183
+        ByteArrayInputStream bais = new ByteArrayInputStream(base64Bytes);
184
+
185
+        ObjectInputStream ois;
186
+        Object obj = null;
187
+        try {
188
+            ois = new ObjectInputStream(bais);
189
+            obj = (Object) ois.readObject();
190
+            ois.close();
191
+        } catch (Exception e) {
192
+            e.printStackTrace();
193
+        }
194
+        return obj;
195
+    }
196
+}

+ 79 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ScreenTool.java

@@ -0,0 +1,79 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.app.Activity;
4
+import android.app.ActivityManager;
5
+import android.content.Context;
6
+import android.content.IntentFilter;
7
+import android.content.pm.ApplicationInfo;
8
+import android.content.pm.PackageInfo;
9
+import android.content.pm.PackageManager;
10
+import android.content.res.Resources;
11
+import android.graphics.Bitmap;
12
+import android.net.ConnectivityManager;
13
+import android.net.NetworkInfo;
14
+import android.os.Build;
15
+import android.os.Environment;
16
+import android.telephony.TelephonyManager;
17
+import android.util.DisplayMetrics;
18
+import android.view.Display;
19
+import android.view.View;
20
+import android.view.Window;
21
+import android.view.WindowManager;
22
+import android.widget.RelativeLayout;
23
+
24
+/**
25
+ * 创建人 mQ
26
+ * 创建时间 2019/5/20 0020 15:25
27
+ * 文件名称 ScreenTool
28
+ * 说明: 屏幕工具类
29
+ **/
30
+public class ScreenTool {
31
+    //获取屏幕的宽度
32
+    public static int getScreenWidth(Context context) {
33
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
34
+        Display defaultDisplay = wm.getDefaultDisplay();
35
+        int width = defaultDisplay.getWidth();
36
+        return width;
37
+    }
38
+
39
+    //获取屏幕的高度
40
+    public static int getScreenHeight(Context context) {
41
+        WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
42
+        Display defaultDisplay = wm.getDefaultDisplay();
43
+        int height = defaultDisplay.getHeight();
44
+
45
+        return height;
46
+    }
47
+
48
+    //获取状态栏的高度
49
+    public static int getStatusHeight(Context context) {
50
+        int statusHeight = -1;
51
+        //使用反射,可能会出现类找不到的异常ClassNotFoundException
52
+        try {
53
+            Class<?> clazz = Class.forName("com.android.internal.R$dimen");
54
+            Object object = clazz.newInstance();
55
+            String status_bar_height = clazz.getField("status_bar_height").get(object).toString();
56
+            int height = Integer.parseInt(status_bar_height);
57
+            //转化成px返回
58
+            statusHeight = context.getResources().getDimensionPixelSize(height);
59
+        } catch (Exception e) {
60
+            e.printStackTrace();
61
+        }
62
+        return statusHeight;
63
+    }
64
+
65
+    //获取当前屏幕截图,包括状态栏
66
+    public static Bitmap getSnapshot(Activity activity) {
67
+        Window window = activity.getWindow();
68
+        View view = window.getDecorView();
69
+        view.setDrawingCacheEnabled(true);
70
+        view.buildDrawingCache();
71
+        Bitmap bitmap = view.getDrawingCache();
72
+        int screenWidth = getScreenWidth(activity);
73
+        int screenHeight = getScreenHeight(activity);
74
+        Bitmap bp;
75
+        bp = Bitmap.createBitmap(bitmap, 0, 0, screenWidth, screenHeight);
76
+        view.destroyDrawingCache();
77
+        return bp;
78
+    }
79
+}

+ 242 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/StringTool.java

@@ -0,0 +1,242 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import java.io.BufferedReader;
4
+import java.io.IOException;
5
+import java.io.InputStream;
6
+import java.io.InputStreamReader;
7
+import java.text.DecimalFormat;
8
+import java.util.regex.Pattern;
9
+
10
+/**
11
+ * 创建人 mQ
12
+ * 创建时间 2019/5/20 0020 10:32
13
+ * 文件名称 StringTool
14
+ * 说明: 字符串工具类
15
+ **/
16
+public class StringTool {
17
+    private final static Pattern emailer = Pattern
18
+            .compile("\\w+([-+.]\\w+)*@\\w+([-.]\\w+)*\\.\\w+([-.]\\w+)*");
19
+
20
+    private final static Pattern IMG_URL = Pattern
21
+            .compile(".*?(gif|jpeg|png|jpg|bmp)");
22
+
23
+    private final static Pattern URL = Pattern
24
+            .compile("^(https|http)://.*?$(net|com|.com.cn|org|me|)");
25
+
26
+
27
+    /**
28
+     * 判断给定字符串是否空白串。
29
+     * 空白串是指由空格、制表符、回车符、换行符组成的字符串 若输入字符串为null或空字符串,返回true
30
+     *
31
+     * @param input
32
+     * @return boolean
33
+     */
34
+    public static boolean isEmpty(String input) {
35
+        if (null == input || "".equals(input) || input.equals("null"))
36
+            return true;
37
+
38
+        for (int i = 0; i < input.length(); i++) {
39
+            char c = input.charAt(i);
40
+            if (c != ' ' && c != '\t' && c != '\r' && c != '\n') {
41
+                return false;
42
+            }
43
+        }
44
+        return true;
45
+    }
46
+
47
+    public static boolean notEmpty(String input){
48
+        return !isEmpty(input);
49
+    }
50
+
51
+    /**
52
+     * 判断是不是一个合法的电子邮件地址
53
+     *
54
+     * @param email
55
+     * @return
56
+     */
57
+    public static boolean isEmail(String email) {
58
+        if (email == null || email.trim().length() == 0)
59
+            return false;
60
+        return emailer.matcher(email).matches();
61
+    }
62
+
63
+    /**
64
+     * 判断一个url是否为图片url
65
+     *
66
+     * @param url
67
+     * @return
68
+     */
69
+    public static boolean isImgUrl(String url) {
70
+        if (url == null || url.trim().length() == 0)
71
+            return false;
72
+        return IMG_URL.matcher(url).matches();
73
+    }
74
+
75
+    /**
76
+     * 判断是否为一个合法的url地址
77
+     *
78
+     * @param str
79
+     * @return
80
+     */
81
+    public static boolean isUrl(String str) {
82
+        if (str == null || str.trim().length() == 0)
83
+            return false;
84
+        return URL.matcher(str).matches();
85
+    }
86
+
87
+    /**
88
+     * 字符串转整数
89
+     *
90
+     * @param str
91
+     * @param defValue
92
+     * @return
93
+     */
94
+    public static int toInt(String str, int defValue) {
95
+        try {
96
+            return Integer.parseInt(str);
97
+        } catch (Exception e) {
98
+        }
99
+        return defValue;
100
+    }
101
+
102
+    /**
103
+     * 对象转整数
104
+     *
105
+     * @param obj
106
+     * @return 转换异常返回 0
107
+     */
108
+    public static int toInt(Object obj) {
109
+        if (obj == null)
110
+            return 0;
111
+        return toInt(obj.toString(), 0);
112
+    }
113
+
114
+    /**
115
+     * 对象转整数
116
+     *
117
+     * @param obj
118
+     * @return 转换异常返回 0
119
+     */
120
+    public static long toLong(String obj) {
121
+        try {
122
+            return Long.parseLong(obj);
123
+        } catch (Exception e) {
124
+        }
125
+        return 0;
126
+    }
127
+
128
+    /**
129
+     * 字符串转布尔值
130
+     *
131
+     * @param b
132
+     * @return 转换异常返回 false
133
+     */
134
+    public static boolean toBool(String b) {
135
+        try {
136
+            return Boolean.parseBoolean(b);
137
+        } catch (Exception e) {
138
+        }
139
+        return false;
140
+    }
141
+
142
+    public static String getString(String s) {
143
+        return s == null ? "" : s;
144
+    }
145
+
146
+    /**
147
+     * 将一个InputStream流转换成字符串
148
+     *
149
+     * @param is
150
+     * @return
151
+     */
152
+    public static String toConvertString(InputStream is) {
153
+        StringBuffer res = new StringBuffer();
154
+        InputStreamReader isr = new InputStreamReader(is);
155
+        BufferedReader read = new BufferedReader(isr);
156
+        try {
157
+            String line;
158
+            line = read.readLine();
159
+            while (line != null) {
160
+                res.append(line + "<br>");
161
+                line = read.readLine();
162
+            }
163
+        } catch (IOException e) {
164
+            e.printStackTrace();
165
+        } finally {
166
+            try {
167
+                if (null != isr) {
168
+                    isr.close();
169
+                    isr.close();
170
+                }
171
+                if (null != read) {
172
+                    read.close();
173
+                    read = null;
174
+                }
175
+                if (null != is) {
176
+                    is.close();
177
+                    is = null;
178
+                }
179
+            } catch (IOException e) {
180
+            }
181
+        }
182
+        return res.toString();
183
+    }
184
+
185
+    /***
186
+     * 截取字符串
187
+     *
188
+     * @param start
189
+     *            从那里开始,0算起
190
+     * @param num
191
+     *            截取多少个
192
+     * @param str
193
+     *            截取的字符串
194
+     * @return
195
+     */
196
+    public static String getSubString(int start, int num, String str) {
197
+        if (str == null) {
198
+            return "";
199
+        }
200
+        int leng = str.length();
201
+        if (start < 0) {
202
+            start = 0;
203
+        }
204
+        if (start > leng) {
205
+            start = leng;
206
+        }
207
+        if (num < 0) {
208
+            num = 1;
209
+        }
210
+        int end = start + num;
211
+        if (end > leng) {
212
+            end = leng;
213
+        }
214
+        return str.substring(start, end);
215
+    }
216
+
217
+    /**
218
+     * 是否是手机号
219
+     *
220
+     * @param input
221
+     * @return
222
+     */
223
+    public static boolean isPhoneNumberValid(String input) {
224
+        String regex = "(1[0-9][0-9]|15[0-9]|18[0-9])\\d{8}";
225
+        Pattern p = Pattern.compile(regex);
226
+        return p.matches(regex, input);//如果不是号码,则返回false,是号码则返回true
227
+    }
228
+
229
+    /**
230
+     * 保留一位小数
231
+     *
232
+     * @param number
233
+     * @return
234
+     */
235
+    public static String getDoubleOne(double number) {
236
+        try {
237
+            return new DecimalFormat("#.0").format(number);
238
+        } catch (Exception e) {
239
+        }
240
+        return null;
241
+    }
242
+}

+ 267 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ToastTool.java

@@ -0,0 +1,267 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.app.Application;
4
+import android.support.annotation.DrawableRes;
5
+import android.support.annotation.StringRes;
6
+import android.view.View;
7
+import android.widget.ImageView;
8
+import android.widget.LinearLayout;
9
+import android.widget.Toast;
10
+
11
+/**
12
+ * 创建人 mQ
13
+ * 创建时间 2019/5/20 0020 10:31
14
+ * 文件名称 ToastTool
15
+ * 说明: Toast工具类
16
+ **/
17
+public class ToastTool {
18
+    private static boolean isShow = true;//默认显示Toast
19
+    private static Application context;
20
+
21
+    /**
22
+     * 在Application中初始化
23
+     *
24
+     * @param application
25
+     */
26
+    public static void init(Application application) {
27
+        context = application;
28
+    }
29
+
30
+    /**
31
+     * 全局设置是否可显示Toast
32
+     *
33
+     * @param isShowToast
34
+     */
35
+    public static void setShow(boolean isShowToast) {
36
+        isShow = isShowToast;
37
+    }
38
+
39
+    /**
40
+     * 取消Toast显示
41
+     */
42
+    public static void cancelToast(Toast toast) {
43
+        if (null != toast && isShow) {
44
+            toast.cancel();
45
+        }
46
+    }
47
+
48
+    /**
49
+     * 短时间显示Toast 2秒
50
+     *
51
+     * @param msg 显示内容
52
+     */
53
+    public static  Toast showShort(CharSequence msg) {
54
+        Toast toast = null;
55
+        if (isShow) {
56
+            toast = Toast.makeText(context, msg, Toast.LENGTH_SHORT);
57
+            toast.show();
58
+        }
59
+        return toast;
60
+    }
61
+
62
+    /**
63
+     * 短时间显示Toast 2秒
64
+     *
65
+     * @param resId 显示内容
66
+     */
67
+    public static Toast showShort(@StringRes int resId) {
68
+        Toast toast = null;
69
+        if (isShow) {
70
+            toast = Toast.makeText(context, resId, Toast.LENGTH_SHORT);
71
+            toast.show();
72
+        }
73
+        return toast;
74
+    }
75
+
76
+    /**
77
+     * 长时间显示Toast 3.5秒
78
+     *
79
+     * @param msg
80
+     */
81
+    public static Toast showLong(CharSequence msg) {
82
+        Toast toast = null;
83
+        if (isShow) {
84
+            toast = Toast.makeText(context, msg, Toast.LENGTH_LONG);
85
+            toast.show();
86
+        }
87
+        return toast;
88
+    }
89
+
90
+    /**
91
+     * 长时间显示Toast 3.5秒
92
+     *
93
+     * @param resId
94
+     */
95
+    public static Toast showLong(@StringRes int resId) {
96
+        Toast toast = null;
97
+        if (isShow) {
98
+            toast = Toast.makeText(context, resId, Toast.LENGTH_LONG);
99
+            toast.show();
100
+        }
101
+        return toast;
102
+    }
103
+
104
+    /**
105
+     * 自定义Toast显示时间
106
+     *
107
+     * @param msg
108
+     * @param duration 毫秒
109
+     */
110
+    public static Toast show(CharSequence msg, int duration) {
111
+        Toast toast = null;
112
+        if (isShow) {
113
+            toast = Toast.makeText(context, msg, duration);
114
+            toast.show();
115
+        }
116
+        return toast;
117
+    }
118
+
119
+    /**
120
+     * 自定义Toast显示时间
121
+     *
122
+     * @param resId
123
+     * @param duration 毫秒
124
+     */
125
+    public static Toast show(@StringRes int resId, int duration) {
126
+        Toast toast = null;
127
+        if (isShow) {
128
+            toast = Toast.makeText(context, resId, duration);
129
+            toast.show();
130
+        }
131
+        return toast;
132
+    }
133
+
134
+    /**
135
+     * 自定义Toast显示位置
136
+     *
137
+     * @param msg
138
+     * @param duration 毫秒
139
+     * @param gravity
140
+     * @param xOffset
141
+     * @param yOffset
142
+     * @return
143
+     */
144
+    public static Toast showLocation(CharSequence msg, int duration, int gravity, int xOffset, int yOffset) {
145
+        Toast toast = null;
146
+        if (isShow) {
147
+            toast = Toast.makeText(context, msg, duration);
148
+            toast.setGravity(gravity, xOffset, yOffset);
149
+            toast.show();
150
+        }
151
+        return toast;
152
+    }
153
+
154
+    /**
155
+     * 自定义Toast显示位置
156
+     *
157
+     * @param resId
158
+     * @param duration 毫秒
159
+     * @param gravity
160
+     * @param xOffset
161
+     * @param yOffset
162
+     * @return
163
+     */
164
+    public static Toast showLocation(@StringRes int resId, int duration, int gravity, int xOffset, int yOffset) {
165
+        Toast toast = null;
166
+        if (isShow) {
167
+            toast = Toast.makeText(context, resId, duration);
168
+            toast.setGravity(gravity, xOffset, yOffset);
169
+            toast.show();
170
+        }
171
+        return toast;
172
+    }
173
+
174
+    /**
175
+     * 带图片的Toast  上面图片 下面文字
176
+     *
177
+     * @param msg
178
+     * @param duration
179
+     * @param imgId    图片资源id
180
+     * @return
181
+     */
182
+    public static Toast showToastAddImage(CharSequence msg, int duration, @DrawableRes int imgId) {
183
+        Toast toast = null;
184
+        if (isShow) {
185
+            toast = Toast.makeText(context, msg, duration);
186
+            LinearLayout toastView = (LinearLayout) toast.getView();
187
+            ImageView imageView = new ImageView(toastView.getContext());
188
+            imageView.setImageResource(imgId);
189
+            toastView.addView(imageView, 0);
190
+            toast.show();
191
+        }
192
+        return toast;
193
+    }
194
+
195
+    /**
196
+     * 带图片的Toast  上面图片 下面文字
197
+     *
198
+     * @param resId
199
+     * @param duration
200
+     * @param imgId    图片资源id
201
+     * @return
202
+     */
203
+    public static Toast showToastAddImage(@StringRes int resId, int duration, @DrawableRes int imgId) {
204
+        Toast toast = null;
205
+        if (isShow) {
206
+            toast = Toast.makeText(context, resId, duration);
207
+            LinearLayout toastView = (LinearLayout) toast.getView();
208
+            ImageView imageView = new ImageView(toastView.getContext());
209
+            imageView.setImageResource(imgId);
210
+            toastView.addView(imageView, 0);
211
+            toast.show();
212
+        }
213
+        return toast;
214
+    }
215
+
216
+    /**
217
+     * 自定义Toast的View
218
+     *
219
+     * @param duration
220
+     * @param view
221
+     */
222
+    public static Toast customToastView(int duration, View view) {
223
+        Toast toast = null;
224
+        if (isShow) {
225
+            toast = new Toast(context);
226
+            toast.setDuration(duration);
227
+            if (null == view) {
228
+                toast.setView(view);
229
+            }
230
+            toast.show();
231
+        }
232
+        return toast;
233
+    }
234
+
235
+
236
+    /**
237
+     * 完全自定义Toast
238
+     *
239
+     * @param duration
240
+     * @param view
241
+     * @param isGravity        是否设定Gravity  false后面三项不生效  true生效
242
+     * @param gravity
243
+     * @param xOffset
244
+     * @param yOffset
245
+     * @param isMargin         是否设定Margin  false后面两项不生效  true生效
246
+     * @param horizontalMargin
247
+     * @param verticalMargin
248
+     * @return
249
+     */
250
+    public static Toast customToastAll(int duration, View view, boolean isGravity, int gravity, int xOffset,
251
+                                int yOffset, boolean isMargin, float horizontalMargin, float verticalMargin) {
252
+        Toast toast = null;
253
+        if (isShow) {
254
+            toast = new Toast(context);
255
+            toast.setDuration(duration);
256
+            toast.setView(view);
257
+            if (isGravity)
258
+                toast.setGravity(gravity, xOffset, yOffset);
259
+            if (isMargin)
260
+                toast.setMargin(horizontalMargin, verticalMargin);
261
+            toast.show();
262
+        }
263
+        return toast;
264
+    }
265
+
266
+
267
+}

+ 154 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ValidatorTool.java

@@ -0,0 +1,154 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.content.Context;
4
+import android.view.View;
5
+import android.widget.AutoCompleteTextView;
6
+import android.widget.EditText;
7
+import android.widget.TextView;
8
+
9
+import java.util.ArrayList;
10
+import java.util.List;
11
+
12
+
13
+/**
14
+ * 创建人 mQ
15
+ * 创建时间 2019/5/20 0020 10:31
16
+ * 文件名称 ValidatorTool
17
+ * 说明: 控件验证工具类
18
+ *   验证控件文字是否为空 并给予error提示
19
+ **/
20
+public class ValidatorTool {
21
+
22
+    private Context mContext;
23
+    private boolean isShowDialog = false;//是否弹出提示
24
+    private List<View> viewList = new ArrayList<>();
25
+    private List<String> msgList = new ArrayList<>();
26
+    private List<Boolean> errorList = new ArrayList<>();
27
+
28
+    /**
29
+     * 构造方法
30
+     *
31
+     * @param mContext
32
+     */
33
+    public ValidatorTool(Context mContext) {
34
+        this.mContext = mContext;
35
+    }
36
+
37
+    /**
38
+     * 添加要验证的View和提示文字
39
+     *
40
+     * @param view
41
+     * @param msg
42
+     * @return
43
+     */
44
+    public ValidatorTool addIsEmptyView(View view, String msg) {
45
+        viewList.add(view);
46
+        msgList.add(msg);
47
+        return this;
48
+    }
49
+
50
+    /**
51
+     * 添加要验证的View和提示文字
52
+     *
53
+     * @param view
54
+     * @return
55
+     */
56
+    public ValidatorTool addIsEmptyView(View view) {
57
+        viewList.add(view);
58
+        String msg = "";
59
+        if (view instanceof EditText) {
60
+            msg = ((EditText) view).getHint().toString().trim();
61
+        } else if (view instanceof TextView) {
62
+            msg = ((TextView) view).getHint().toString().trim();
63
+        } else if (view instanceof AutoCompleteTextView) {
64
+            msg = ((AutoCompleteTextView) view).getHint().toString().trim();
65
+        }
66
+        msgList.add(msg);
67
+        return this;
68
+    }
69
+
70
+    //是否为空
71
+    private boolean isEmpty(View view) {
72
+        if (view instanceof EditText) {
73
+            String content = ((EditText) view).getText().toString().trim();
74
+            return StringTool.isEmpty(content);
75
+        } else if (view instanceof TextView) {
76
+            String content = ((TextView) view).getText().toString().trim();
77
+            return StringTool.isEmpty(content);
78
+        } else if (view instanceof AutoCompleteTextView) {
79
+            String content = ((AutoCompleteTextView) view).getText().toString().trim();
80
+            return StringTool.isEmpty(content);
81
+        }
82
+        return false;
83
+    }
84
+
85
+    //设置错误信息
86
+    private void setError(View view, String msg) {
87
+        if (view instanceof EditText) {
88
+            ((EditText) view).setError(msg);
89
+            view.requestFocus();
90
+        } else if (view instanceof TextView) {
91
+            ((TextView) view).setError(msg);
92
+            view.requestFocus();
93
+        } else if (view instanceof AutoCompleteTextView) {
94
+            ((AutoCompleteTextView) view).setError(msg);
95
+            view.requestFocus();
96
+        }
97
+    }
98
+
99
+    //清除错误信息
100
+    private void setErrorClear(View view) {
101
+        if (view instanceof EditText) {
102
+            ((EditText) view).setError(null, null);
103
+        } else if (view instanceof TextView) {
104
+            ((TextView) view).setError(null, null);
105
+        }
106
+    }
107
+
108
+    private void showDialog(String msg) {
109
+        if (isShowDialog) {
110
+//            AlertDialog.Builder builder = new AlertDialog.Builder(mContext);
111
+//            builder.setTitle("系统消息");
112
+//            builder.setMessage(msg);
113
+//            builder.create().show();
114
+        }
115
+    }
116
+
117
+    public void setIsShowDialog(boolean showDialog) {
118
+        isShowDialog = showDialog;
119
+    }
120
+
121
+    /**
122
+     * 开始验证
123
+     *
124
+     * @return
125
+     */
126
+    public boolean validator() {
127
+        errorList.clear();
128
+        //循环验证
129
+        for (int i = 0; i < viewList.size(); i++) {
130
+            View view = viewList.get(i);
131
+            String msg = msgList.get(i);
132
+
133
+            boolean isEmpty = isEmpty(view);
134
+
135
+            if (isEmpty) {
136
+                setError(view, msg);
137
+            } else {
138
+                setErrorClear(view);
139
+            }
140
+
141
+            errorList.add(isEmpty);
142
+        }
143
+
144
+        for (int i = 0; i < errorList.size(); i++) {
145
+            Boolean b = errorList.get(i);
146
+            if (b) {
147
+                viewList.get(i).requestFocus();
148
+                showDialog(msgList.get(i));//弹出第一个错误对话框
149
+                return false;
150
+            }
151
+        }
152
+        return true;
153
+    }
154
+}

+ 123 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/VersionTool.java

@@ -0,0 +1,123 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.app.ActivityManager;
4
+import android.content.Context;
5
+import android.content.Intent;
6
+import android.content.pm.ApplicationInfo;
7
+import android.content.pm.PackageInfo;
8
+import android.content.pm.PackageManager;
9
+import android.net.Uri;
10
+import android.os.Build;
11
+import android.telephony.TelephonyManager;
12
+
13
+import java.util.List;
14
+
15
+/**
16
+ * 创建人 mQ
17
+ * 创建时间 2019/5/20 0020 15:26
18
+ * 文件名称 VersionTool
19
+ * 说明: 获取App版本号
20
+ **/
21
+
22
+public class VersionTool {
23
+
24
+    //获取应用程序名称
25
+    public static String getAppName(Context context) {
26
+        try {
27
+            PackageManager pm = context.getPackageManager();
28
+            PackageInfo packageInfo = pm.getPackageInfo(context.getPackageName(), 0);
29
+            ApplicationInfo applicationInfo = packageInfo.applicationInfo;
30
+            //这种方式是可以的
31
+            //String alias = applicationInfo.loadLabel(pm).toString();
32
+            int labelRes = applicationInfo.labelRes;
33
+            String name = context.getResources().getString(labelRes);
34
+            return name;
35
+        } catch(PackageManager.NameNotFoundException e) {
36
+            e.printStackTrace();
37
+        }
38
+        return "";
39
+    }
40
+
41
+    //版本名
42
+    public static String getVersionName(Context context) {
43
+        PackageInfo pi = getPackageInfo(context);
44
+        if (pi != null)
45
+            return pi.versionName;
46
+        else
47
+            return "";
48
+    }
49
+
50
+    //版本号
51
+    public static int getVersionCode(Context context) {
52
+        PackageInfo pi = getPackageInfo(context);
53
+        if (pi != null)
54
+            return pi.versionCode;
55
+        else
56
+            return 0;
57
+    }
58
+
59
+    private static PackageInfo getPackageInfo(Context context) {
60
+        PackageInfo pi = null;
61
+
62
+        try {
63
+            PackageManager pm = context.getPackageManager();
64
+            pi = pm.getPackageInfo(context.getPackageName(),
65
+                    PackageManager.GET_CONFIGURATIONS);
66
+
67
+            return pi;
68
+        } catch(Exception e) {
69
+            e.printStackTrace();
70
+        }
71
+
72
+        return pi;
73
+    }
74
+
75
+    /**
76
+     * 程序是否在前台运行
77
+     */
78
+    public static boolean isAppOnForeground(Context context) {
79
+        ActivityManager activityManager
80
+                = (ActivityManager) context.getSystemService(
81
+                Context.ACTIVITY_SERVICE);
82
+        String packageName = context.getPackageName();
83
+
84
+        List<ActivityManager.RunningAppProcessInfo> appProcesses
85
+                = activityManager.getRunningAppProcesses();
86
+        if (appProcesses == null) return false;
87
+
88
+        for (ActivityManager.RunningAppProcessInfo appProcess : appProcesses) {
89
+            if (appProcess.processName.equals(packageName) &&
90
+                    appProcess.importance ==
91
+                            ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND) {
92
+                return true;
93
+            }
94
+        }
95
+
96
+        return false;
97
+    }
98
+
99
+    public static boolean isEmulator(Context mContext) {
100
+        String url = "tel:" + "123456";
101
+        Intent intent = new Intent();
102
+        intent.setData(Uri.parse(url));
103
+        intent.setAction(Intent.ACTION_DIAL);
104
+        // 是否可以处理跳转到拨号的 Intent
105
+        boolean canResolveIntent = intent.resolveActivity(mContext.getPackageManager()) != null;
106
+        return Build.FINGERPRINT.startsWith("generic")
107
+                || Build.FINGERPRINT.toLowerCase().contains("vbox")
108
+                || Build.FINGERPRINT.toLowerCase().contains("test-keys")
109
+                || Build.MODEL.contains("google_sdk")
110
+                || Build.MODEL.contains("Emulator")
111
+                || Build.SERIAL.equalsIgnoreCase("unknown")
112
+                || Build.SERIAL.equalsIgnoreCase("android")
113
+                || Build.MODEL.contains("Android SDK built for x86")
114
+                || Build.MANUFACTURER.contains("Genymotion")
115
+                || (Build.BRAND.startsWith("generic")
116
+                && Build.DEVICE.startsWith("generic"))
117
+                || "google_sdk".equals(Build.PRODUCT)
118
+                || ((TelephonyManager) mContext.getSystemService(Context.TELEPHONY_SERVICE)).getNetworkOperatorName().toLowerCase().equals("android")
119
+                || !canResolveIntent;
120
+    }
121
+
122
+
123
+}

+ 39 - 0
mylibrary/src/main/java/com/xyxsbj/mylibrary/tool/ViewTool.java

@@ -0,0 +1,39 @@
1
+package com.xyxsbj.mylibrary.tool;
2
+
3
+import android.view.View;
4
+
5
+/**
6
+ * 创建人 mQ
7
+ * 创建时间 2019/5/20 0020 15:27
8
+ * 文件名称 ViewTool
9
+ * 说明:
10
+ **/
11
+public class ViewTool {
12
+
13
+    /**
14
+     * 获取控件的高度
15
+     */
16
+    public static int getViewMeasuredHeight(View view) {
17
+        calculateViewMeasure(view);
18
+        return view.getMeasuredHeight();
19
+    }
20
+
21
+    /**
22
+     * 获取控件的宽度
23
+     */
24
+    public static int getViewMeasuredWidth(View view) {
25
+        calculateViewMeasure(view);
26
+        return view.getMeasuredWidth();
27
+    }
28
+
29
+    /**
30
+     * 测量控件的尺寸
31
+     */
32
+    private static void calculateViewMeasure(View view) {
33
+        int w = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
34
+        int h = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED);
35
+
36
+        view.measure(w, h);
37
+    }
38
+
39
+}

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

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

BIN
oaapp.jks


+ 0 - 0
settings.gradle


Some files were not shown because too many files changed in this diff