Compare View

switch
from
...
to
 
Commits (5)
Showing 36 changed files   Show diff stats
.idea/inspectionProfiles/Project_Default.xml
1 <component name="InspectionProjectProfileManager"> 1 <component name="InspectionProjectProfileManager">
2 <profile version="1.0"> 2 <profile version="1.0">
3 <option name="myName" value="Project Default" /> 3 <option name="myName" value="Project Default" />
4 <inspection_tool class="Deprecation" enabled="false" level="WARNING" enabled_by_default="false" /> 4 <inspection_tool class="Deprecation" enabled="false" level="WARNING" enabled_by_default="false" />
5 <inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false"> 5 <inspection_tool class="IgnoreResultOfCall" enabled="false" level="WARNING" enabled_by_default="false">
6 <option name="m_reportAllNonLibraryCalls" value="false" /> 6 <option name="m_reportAllNonLibraryCalls" value="false" />
7 <option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" /> 7 <option name="callCheckString" value="java.io.File,.*,java.io.InputStream,read|skip|available|markSupported,java.io.Reader,read|skip|ready|markSupported,java.lang.AbstractStringBuilder,capacity|codePointAt|codePointBefore|codePointCount|indexOf|lastIndexOf|offsetByCodePoints|substring|subSequence,java.lang.Boolean,.*,java.lang.Byte,.*,java.lang.Character,.*,java.lang.Double,.*,java.lang.Float,.*,java.lang.Integer,.*,java.lang.Long,.*,java.lang.Math,.*,java.lang.Object,equals|hashCode|toString,java.lang.Short,.*,java.lang.StrictMath,.*,java.lang.String,.*,java.lang.Thread,interrupted,java.math.BigDecimal,.*,java.math.BigInteger,.*,java.net.InetAddress,.*,java.net.URI,.*,java.nio.channels.AsynchronousChannelGroup,.*,java.nio.channels.Channel,isOpen,java.nio.channels.FileChannel,open|map|lock|tryLock|write,java.nio.channels.ScatteringByteChannel,read,java.nio.channels.SocketChannel,open|socket|isConnected|isConnectionPending,java.util.Arrays,.*,java.util.Collections,(?!addAll).*,java.util.List,of,java.util.Map,of|ofEntries|entry,java.util.Set,of,java.util.UUID,.*,java.util.concurrent.BlockingQueue,offer|remove,java.util.concurrent.CountDownLatch,await|getCount,java.util.concurrent.ExecutorService,awaitTermination|isShutdown|isTerminated,java.util.concurrent.ForkJoinPool,awaitQuiescence,java.util.concurrent.Semaphore,tryAcquire|availablePermits|isFair|hasQueuedThreads|getQueueLength|getQueuedThreads,java.util.concurrent.locks.Condition,await|awaitNanos|awaitUntil,java.util.concurrent.locks.Lock,tryLock|newCondition,java.util.regex.Matcher,pattern|toMatchResult|start|end|group|groupCount|matches|find|lookingAt|quoteReplacement|replaceAll|replaceFirst|regionStart|regionEnd|hasTransparentBounds|hasAnchoringBounds|hitEnd|requireEnd,java.util.regex.Pattern,.*,java.util.stream.BaseStream,.*,java.util.stream.DoubleStream,.*,java.util.stream.IntStream,.*,java.util.stream.LongStream,.*,java.util.stream.Stream,.*" />
8 </inspection_tool> 8 </inspection_tool>
9 <inspection_tool class="SameReturnValue" enabled="false" level="WARNING" enabled_by_default="false" />
10 <inspection_tool class="UnnecessaryLocalVariable" enabled="false" level="WARNING" enabled_by_default="false">
11 <option name="m_ignoreImmediatelyReturnedVariables" value="false" />
12 <option name="m_ignoreAnnotatedVariables" value="false" />
13 </inspection_tool>
9 <inspection_tool class="UnnecessaryLocalVariable" enabled="false" level="WARNING" enabled_by_default="false"> 14 </profile>
10 <option name="m_ignoreImmediatelyReturnedVariables" value="false" /> 15 </component>
1 apply plugin: 'com.android.application' 1 apply plugin: 'com.android.application'
2 2
3 3
4 def androidId = rootProject.ext.androidId 4 def androidId = rootProject.ext.androidId
5 def support = rootProject.ext.dependencies 5 def support = rootProject.ext.dependencies
6 def url = rootProject.ext.url 6 def url = rootProject.ext.url
7 7
8 8
9 android { 9 android {
10 signingConfigs { 10 signingConfigs {
11 11
12 config { 12 config {
13 keyAlias 'alias' 13 keyAlias 'alias'
14 keyPassword '123456' 14 keyPassword '123456'
15 storeFile file('key.jks') 15 storeFile file('key.jks')
16 storePassword '123456' 16 storePassword '123456'
17 } 17 }
18 debug { 18 debug {
19 } 19 }
20 } 20 }
21 compileSdk 32 21 compileSdk 32
22 22
23 defaultConfig { 23 defaultConfig {
24 applicationId "com.hjx.parent" 24 applicationId "com.hjx.parent"
25 minSdk 26 25 minSdk 26
26 targetSdk 32 26 targetSdk 32
27 versionCode 1012 27 versionCode 1012
28 versionName "1.0.12" 28 versionName "1.0.12"
29 29
30 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 30 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
31 } 31 }
32 32
33 android.applicationVariants.all { 33 android.applicationVariants.all {
34 variant -> 34 variant ->
35 variant.outputs.all { 35 variant.outputs.all {
36 //在这里修改apk文件名 36 //在这里修改apk文件名
37 outputFileName = "parent-${variant.name}-v${variant.versionName}.apk" 37 outputFileName = "parent-${variant.name}-v${variant.versionName}.apk"
38 } 38 }
39 } 39 }
40 buildTypes { 40 buildTypes {
41 debug { 41 debug {
42 debuggable true 42 debuggable true
43 minifyEnabled false 43 minifyEnabled false
44 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 44 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
45 signingConfig signingConfigs.config 45 signingConfig signingConfigs.config
46 } 46 }
47 release { 47 release {
48 debuggable true 48 debuggable true
49 minifyEnabled false 49 minifyEnabled false
50 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 50 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
51 signingConfig signingConfigs.config 51 signingConfig signingConfigs.config
52 } 52 }
53 } 53 }
54 lintOptions { 54 lintOptions {
55 checkReleaseBuilds false 55 checkReleaseBuilds false
56 abortOnError false 56 abortOnError false
57 } 57 }
58 buildFeatures { 58 buildFeatures {
59 viewBinding true 59 viewBinding true
60 dataBinding true 60 dataBinding true
61 } 61 }
62 compileOptions { 62 compileOptions {
63 sourceCompatibility JavaVersion.VERSION_1_8 63 sourceCompatibility JavaVersion.VERSION_1_8
64 targetCompatibility JavaVersion.VERSION_1_8 64 targetCompatibility JavaVersion.VERSION_1_8
65 } 65 }
66 } 66 }
67 67
68 dependencies { 68 dependencies {
69 support.each { k, v -> implementation v } 69 support.each { k, v -> implementation v }
70 api project(path: ':libs:common') 70 api project(path: ':libs:common')
71 implementation 'androidx.appcompat:appcompat:1.5.1' 71 implementation 'androidx.appcompat:appcompat:1.5.1'
72 implementation 'com.google.android.material:material:1.6.1' 72 implementation 'com.google.android.material:material:1.6.1'
73 implementation 'androidx.constraintlayout:constraintlayout:2.1.4' 73 implementation 'androidx.constraintlayout:constraintlayout:2.1.4'
74 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50' 74 implementation 'com.github.CymChad:BaseRecyclerViewAdapterHelper:2.9.50'
75 implementation 'com.github.ForgetAll:LoadingDialog:1.1.2' 75 implementation 'com.github.ForgetAll:LoadingDialog:1.1.2'
76 implementation 'com.github.DL-ZhangTeng:ImagePicker:1.5.0' 76 implementation 'com.github.DL-ZhangTeng:ImagePicker:1.5.0'
77 //使用的三方 77 //使用的三方
78 implementation 'com.yalantis:ucrop:2.2.0' 78 implementation 'com.yalantis:ucrop:2.2.0'
79 implementation 'com.github.DL-ZhangTeng:RequestPermission:1.3.0' 79 implementation 'com.github.DL-ZhangTeng:RequestPermission:1.3.0'
80 implementation 'com.github.DL-ZhangTeng:Utils:2.2.0' 80 implementation 'com.github.DL-ZhangTeng:Utils:2.2.0'
81 81
82 // rx 82 // rx
83 implementation("com.trello.rxlifecycle2:rxlifecycle:2.2.2") 83 implementation("com.trello.rxlifecycle2:rxlifecycle:2.2.2")
84 implementation("com.trello.rxlifecycle2:rxlifecycle-android:2.2.2") 84 implementation("com.trello.rxlifecycle2:rxlifecycle-android:2.2.2")
85 85
86 implementation("com.github.PhilJay:MPAndroidChart:v3.1.0") 86 implementation("com.github.PhilJay:MPAndroidChart:v3.1.0")
87 implementation("com.contrarywind:Android-PickerView:4.1.9") 87 implementation("com.contrarywind:Android-PickerView:4.1.9")
88 88
89 implementation 'com.google.android:flexbox:1.0.0' 89 implementation 'com.google.android:flexbox:1.0.0'
90 90
91 // 沉浸式状态栏和他的Kotlin拓展 91 // 沉浸式状态栏和他的Kotlin拓展
92 implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2' 92 implementation 'com.geyifeng.immersionbar:immersionbar:3.2.2'
93 implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2' 93 implementation 'com.geyifeng.immersionbar:immersionbar-ktx:3.2.2'
94 94
95 // 图片查看 95 // 图片查看
96 implementation 'com.github.chrisbanes:PhotoView:2.0.0' 96 implementation 'com.github.chrisbanes:PhotoView:2.0.0'
97 97
98 implementation 'com.jakewharton:butterknife:10.2.3' 98 implementation 'com.jakewharton:butterknife:10.2.3'
99 annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3' 99 annotationProcessor 'com.jakewharton:butterknife-compiler:10.2.3'
100
101
102 /** 鲁班压缩 */
103 implementation 'top.zibin:Luban:1.1.8'
104
100 105 }
app/src/main/AndroidManifest.xml
1 <?xml version="1.0" encoding="utf-8"?> 1 <?xml version="1.0" encoding="utf-8"?>
2 <manifest xmlns:android="http://schemas.android.com/apk/res/android" 2 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
3 xmlns:tools="http://schemas.android.com/tools" 3 xmlns:tools="http://schemas.android.com/tools"
4 package="com.hjx.parent" 4 package="com.hjx.parent"
5 tools:ignore="LockedOrientationActivity"> 5 tools:ignore="LockedOrientationActivity">
6 6
7 7
8 <uses-feature 8 <uses-feature
9 android:name="android.hardware.camera" 9 android:name="android.hardware.camera"
10 android:required="false" /> 10 android:required="false" />
11 11
12 <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" /> 12 <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
13 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 --> 13 <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" /> <!-- 允许程序改变网络链接状态 -->
14 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 允许程序访问访问WIFI网络状态信息 --> 14 <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <!-- 允许程序访问访问WIFI网络状态信息 -->
15 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许程序改变WIFI链接状态 --> 15 <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" /> <!-- 允许程序改变WIFI链接状态 -->
16 <!-- 6.0系统需要添加权限才能获得wifi列表 --> 16 <!-- 6.0系统需要添加权限才能获得wifi列表 -->
17 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" /> 17 <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
18 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" /> 18 <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
19 <uses-permission android:name="android.permission.INTERNET" /> 19 <uses-permission android:name="android.permission.INTERNET" />
20 <uses-permission android:name="android.permission.RECORD_AUDIO" /> 20 <uses-permission android:name="android.permission.RECORD_AUDIO" />
21 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> 21 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
22 22
23 <uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> 23 <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
24 <uses-permission android:name="android.permission.READ_PHONE_STATE" /> 24 <uses-permission android:name="android.permission.READ_PHONE_STATE" />
25 <uses-permission android:name="android.permission.WAKE_LOCK" /> 25 <uses-permission android:name="android.permission.WAKE_LOCK" />
26 <uses-permission android:name="android.permission.CAMERA" /> 26 <uses-permission android:name="android.permission.CAMERA" />
27 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" /> 27 <uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
28 <uses-permission android:name="android.permission.VIBRATE" /> 28 <uses-permission android:name="android.permission.VIBRATE" />
29 <uses-permission 29 <uses-permission
30 android:name="android.permission.WRITE_EXTERNAL_STORAGE" 30 android:name="android.permission.WRITE_EXTERNAL_STORAGE"
31 tools:ignore="ScopedStorage" /> 31 tools:ignore="ScopedStorage" />
32 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" /> 32 <uses-permission android:name="android.permission.REQUEST_INSTALL_PACKAGES" />
33 <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" /> 33 <uses-permission android:name="android.permission.GET_PACKAGE_SIZE" />
34 34
35 <uses-permission 35 <uses-permission
36 android:name="android.permission.MANAGE_EXTERNAL_STORAGE" 36 android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
37 tools:ignore="ScopedStorage" /> 37 tools:ignore="ScopedStorage" />
38 38
39 <application 39 <application
40 android:name=".App" 40 android:name=".App"
41 android:allowBackup="true" 41 android:allowBackup="true"
42 android:icon="@mipmap/icon" 42 android:icon="@mipmap/icon"
43 android:label="@string/app_name" 43 android:label="@string/app_name"
44 android:networkSecurityConfig="@xml/network_security_config" 44 android:networkSecurityConfig="@xml/network_security_config"
45 android:supportsRtl="true" 45 android:supportsRtl="true"
46 android:theme="@style/AppTheme"> 46 android:theme="@style/AppTheme">
47 <activity 47 <activity
48 android:name=".LoginActivity" 48 android:name=".LoginActivity"
49 android:exported="true" 49 android:exported="true"
50 android:screenOrientation="portrait" 50 android:screenOrientation="portrait"
51 android:theme="@style/ThemeSplash"> 51 android:theme="@style/ThemeSplash">
52 </activity> 52 </activity>
53 <activity 53 <activity
54 android:name=".MainActivity" 54 android:name=".MainActivity"
55 android:launchMode="singleTask" 55 android:launchMode="singleTask"
56 android:screenOrientation="portrait" /> 56 android:screenOrientation="portrait" />
57 <activity 57 <activity
58 android:name=".RegisterActivity" 58 android:name=".RegisterActivity"
59 android:screenOrientation="portrait" 59 android:screenOrientation="portrait"
60 android:theme="@style/ThemeSplash" /> 60 android:theme="@style/ThemeSplash" />
61 <activity 61 <activity
62 android:name=".UserActivity" 62 android:name=".UserActivity"
63 android:screenOrientation="portrait" /> 63 android:screenOrientation="portrait" />
64 <activity 64 <activity
65 android:name=".YinsiActivity" 65 android:name=".YinsiActivity"
66 android:screenOrientation="portrait" /> 66 android:screenOrientation="portrait" />
67 <activity 67 <activity
68 android:name=".QRActivity" 68 android:name=".QRActivity"
69 android:screenOrientation="portrait" /> 69 android:screenOrientation="portrait" />
70 <activity 70 <activity
71 android:name=".AddStudentActivity" 71 android:name=".AddStudentActivity"
72 android:screenOrientation="portrait" /> 72 android:screenOrientation="portrait" />
73 <activity 73 <activity
74 android:name=".NickActivity" 74 android:name=".NickActivity"
75 android:screenOrientation="portrait" /> 75 android:screenOrientation="portrait" />
76 <activity 76 <activity
77 android:name=".SexActivity" 77 android:name=".SexActivity"
78 android:screenOrientation="portrait" /> 78 android:screenOrientation="portrait" />
79 <activity 79 <activity
80 android:name=".NianActivity" 80 android:name=".NianActivity"
81 android:screenOrientation="portrait" /> 81 android:screenOrientation="portrait" />
82 <activity 82 <activity
83 android:name=".ShenActivity" 83 android:name=".ShenActivity"
84 android:screenOrientation="portrait" /> 84 android:screenOrientation="portrait" />
85 <activity 85 <activity
86 android:name=".UserAgreementActivity" 86 android:name=".UserAgreementActivity"
87 android:screenOrientation="portrait" /> 87 android:screenOrientation="portrait" />
88 <activity 88 <activity
89 android:name=".AccountActivity" 89 android:name=".AccountActivity"
90 android:screenOrientation="portrait" /> 90 android:screenOrientation="portrait" />
91 91
92 <activity 92 <activity
93 android:name=".ChangePwdActivity" 93 android:name=".ChangePwdActivity"
94 android:screenOrientation="portrait" /> 94 android:screenOrientation="portrait" />
95 <activity 95 <activity
96 android:name=".EditStudentActivity" 96 android:name=".EditStudentActivity"
97 android:screenOrientation="portrait" /> 97 android:screenOrientation="portrait" />
98 <activity 98 <activity
99 android:name=".ChooseActivity" 99 android:name=".ChooseActivity"
100 android:screenOrientation="portrait" /> 100 android:screenOrientation="portrait" />
101 <activity 101 <activity
102 android:name=".AddTeacherActivity" 102 android:name=".AddTeacherActivity"
103 android:screenOrientation="portrait" /> 103 android:screenOrientation="portrait" />
104 <activity 104 <activity
105 android:name=".ErrorBookActivity" 105 android:name=".ErrorBookActivity"
106 android:screenOrientation="portrait" /> 106 android:screenOrientation="portrait" />
107 <activity 107 <activity
108 android:name=".ImageActivity" 108 android:name=".ImageActivity"
109 android:screenOrientation="portrait" /> 109 android:screenOrientation="portrait" />
110 <activity 110 <activity
111 android:name=".ImageEditActivity" 111 android:name=".ImageEditActivity"
112 android:screenOrientation="portrait" /> 112 android:screenOrientation="portrait" />
113 <activity 113 <activity
114 android:name=".ImageSelectActivity" 114 android:name=".ImageSelectActivity"
115 android:screenOrientation="portrait" /> 115 android:screenOrientation="portrait" />
116 <activity 116 <activity
117 android:name=".AddSuccessActivity" 117 android:name=".AddSuccessActivity"
118 android:screenOrientation="portrait" /> 118 android:screenOrientation="portrait" />
119 <activity 119 <activity
120 android:name=".ErrorListActivity" 120 android:name=".ErrorListActivity"
121 android:screenOrientation="portrait" /> 121 android:screenOrientation="portrait" />
122 <activity 122 <activity
123 android:name=".ErrorDetailActivity" 123 android:name=".ErrorDetailActivity"
124 android:screenOrientation="portrait" /> 124 android:screenOrientation="portrait" />
125 <activity 125 <activity
126 android:name=".TeacherChooseActivity" 126 android:name=".TeacherChooseActivity"
127 android:screenOrientation="portrait" /> 127 android:screenOrientation="portrait" />
128 <activity 128 <activity
129 android:name=".TeacherMainActivity" 129 android:name=".TeacherMainActivity"
130 android:screenOrientation="portrait" /> 130 android:screenOrientation="portrait" />
131 <activity android:name=".StuHomeworkActivity" /> 131 <activity android:name=".StuHomeworkActivity" />
132 <activity android:name=".HomeworkDetailActivity" /> 132 <activity android:name=".HomeworkDetailActivity" />
133 <activity android:name=".HomeworkSelectActivity" /> 133 <activity android:name=".HomeworkSelectActivity" />
134 <activity android:name=".HomeworkFeedbackActivity" /> 134 <activity android:name=".HomeworkFeedbackActivity" />
135 <activity android:name=".HomeworkTopicActivity" /> 135 <activity android:name=".HomeworkTopicActivity" />
136 <activity android:name=".HomeworkShareActivity" /> 136 <activity android:name=".HomeworkShareActivity" />
137 <activity android:name=".HuyouDetailActivity" /> 137 <activity android:name=".HuyouDetailActivity" />
138 <activity android:name=".SmsLoginActivity" 138 <activity android:name=".SmsLoginActivity"
139 android:exported="true" 139 android:exported="true"
140 android:screenOrientation="portrait" 140 android:screenOrientation="portrait"
141 android:theme="@style/ThemeSplash"> 141 android:theme="@style/ThemeSplash">
142 <intent-filter> 142 <intent-filter>
143 <action android:name="android.intent.action.MAIN" /> 143 <action android:name="android.intent.action.MAIN" />
144 <category android:name="android.intent.category.LAUNCHER" /> 144 <category android:name="android.intent.category.LAUNCHER" />
145 </intent-filter> 145 </intent-filter>
146 </activity> 146 </activity>
147 <activity android:name=".JudgeActivity" />
147 <activity android:name=".JudgeActivity" /> 148
148 149 <provider
149 <provider 150 android:name="androidx.core.content.FileProvider"
150 android:name="androidx.core.content.FileProvider" 151 android:authorities="com.hjx.parent.fileprovider"
151 android:authorities="com.hjx.parent.fileprovider" 152 android:exported="false"
152 android:exported="false" 153 android:grantUriPermissions="true"
153 android:grantUriPermissions="true" 154 tools:replace="android:authorities">
154 tools:replace="android:authorities"> 155 <meta-data
155 <meta-data 156 android:name="android.support.FILE_PROVIDER_PATHS"
156 android:name="android.support.FILE_PROVIDER_PATHS" 157 android:resource="@xml/file_provider_paths"
157 android:resource="@xml/file_provider_paths" 158 tools:replace="android:resource" />
158 tools:replace="android:resource" /> 159 </provider>
159 </provider> 160 </application>
160 </application> 161
161 162 </manifest>
app/src/main/java/com/hjx/parent/ImageActivity.java
1 package com.hjx.parent; 1 package com.hjx.parent;
2 2
3 import android.annotation.SuppressLint; 3 import android.annotation.SuppressLint;
4 import android.app.Dialog; 4 import android.app.Dialog;
5 import android.content.Intent; 5 import android.content.Intent;
6 import android.graphics.Bitmap; 6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory; 7 import android.graphics.BitmapFactory;
8 import android.graphics.Rect; 8 import android.graphics.Rect;
9 import android.net.Uri; 9 import android.net.Uri;
10 import android.os.Bundle; 10 import android.os.Bundle;
11 import android.os.Handler; 11 import android.os.Handler;
12 import android.provider.MediaStore; 12 import android.provider.MediaStore;
13 import android.text.TextUtils; 13 import android.text.TextUtils;
14 import android.util.Log; 14 import android.util.Log;
15 import android.view.KeyEvent; 15 import android.view.KeyEvent;
16 import android.view.View; 16 import android.view.View;
17 17
18 18
19 import androidx.annotation.Nullable; 19 import androidx.annotation.Nullable;
20 import androidx.core.content.FileProvider; 20 import androidx.core.content.FileProvider;
21 import androidx.viewpager2.widget.ViewPager2; 21 import androidx.viewpager2.widget.ViewPager2;
22 22
23 import com.google.gson.Gson; 23 import com.google.gson.Gson;
24 import com.google.gson.JsonObject; 24 import com.google.gson.JsonObject;
25 import com.hjx.parent.adapter.ImageAdapter; 25 import com.hjx.parent.adapter.ImageAdapter;
26 import com.hjx.parent.databinding.ActivityImageBinding; 26 import com.hjx.parent.databinding.ActivityImageBinding;
27 import com.hjx.parent.databinding.ItemImageBinding;
27 import com.hjx.parent.databinding.ItemImageBinding; 28 import com.hjx.parent.dialog.AddHomeworkDialog;
28 import com.hjx.parent.dialog.AddHomeworkDialog; 29 import com.hjx.parent.dialog.ErrorInputDialog;
29 import com.hjx.parent.dialog.ErrorInputDialog; 30 import com.hjx.parent.dialog.PhotoViewDialog;
30 import com.hjx.parent.dialog.PhotoViewDialog; 31 import com.hjx.parent.dialog.TipDialog;
31 import com.hjx.parent.dialog.TipDialog; 32 import com.hjx.parent.rx.BaseRxActivity;
33 import com.hjx.parent.utils.CutUtil;
32 import com.hjx.parent.rx.BaseRxActivity; 34 import com.prws.common.bean.CutPicBean;
33 import com.hjx.parent.utils.CutUtil; 35 import com.prws.common.bean.ImageBean;
34 import com.prws.common.bean.CutPicBean; 36 import com.prws.common.bean.TopicBean;
35 import com.prws.common.bean.ImageBean; 37 import com.prws.common.net.NetWorks;
36 import com.prws.common.bean.TopicBean; 38 import com.prws.common.utils.BitmapUtils;
37 import com.prws.common.net.NetWorks; 39 import com.prws.common.utils.CommonUtil;
38 import com.prws.common.utils.BitmapUtils; 40 import com.xiasuhuei321.loadingdialog.view.LoadingDialog;
39 import com.prws.common.utils.CommonUtil; 41
40 import com.xiasuhuei321.loadingdialog.view.LoadingDialog; 42 import java.io.File;
41 43 import java.util.ArrayList;
42 import java.io.File; 44 import java.util.List;
45 import java.util.stream.Collectors;
43 import java.util.ArrayList; 46
44 import java.util.List; 47 import io.reactivex.Observer;
48 import io.reactivex.Single;
45 49 import io.reactivex.disposables.Disposable;
46 import io.reactivex.Observer;
47 import io.reactivex.disposables.Disposable;
48 import retrofit2.Call;
49 import retrofit2.Callback; 50
50 import retrofit2.Response; 51 public class ImageActivity extends BaseRxActivity<ActivityImageBinding> implements View.OnClickListener {
51 52
52 public class ImageActivity extends BaseRxActivity<ActivityImageBinding> implements View.OnClickListener { 53 private final List<String> images = new ArrayList<>();
53 54 private ImageAdapter imageAdapter;
54 private List<String> images = new ArrayList<>(); 55 private List<ImageBean> list = new ArrayList<>();
55 private ImageAdapter imageAdapter; 56 private String filePath;
56 private List<ImageBean> list = new ArrayList<>(); 57
57 private String filePath; 58 private int type = 0;
58 59 private AddHomeworkDialog addHomeworkDialog;
59 private int type = 0; 60
61 @SuppressLint("CheckResult")
60 private AddHomeworkDialog addHomeworkDialog; 62 @Override
61 63 public void initView(Bundle savedInstanceState) {
62 @Override 64 type = getIntent().getIntExtra("type", 0);
63 public void initView(Bundle savedInstanceState) { 65 binding.tvSave.setText(type == 0 ? "保存错题" : "录入题目");
64 type = getIntent().getIntExtra("type", 0); 66
65 binding.tvSave.setText(type == 0 ? "保存错题" : "录入题目"); 67 List<String> originList = getIntent().getStringArrayListExtra("images");
68 List<String> originListFinal = originList == null ? new ArrayList<>() : originList;
69 Single.fromCallable(() -> CutUtil.compressAllSync(this, originListFinal, 200))
70 .map(it -> it.stream().map(File::getAbsolutePath).collect(Collectors.toList()))
71 .compose(transformSingle())
72 .subscribe((it, throwable) -> {
73 if (throwable != null) Log.e(getClass().getName(), "", throwable);
74 images.clear();
75 if (it == null) {
76 images.addAll(originListFinal);
77 } else {
78 images.addAll(it);
79 }
80 start();
81 });
82 }
83
84 private void start() {
66 85 if (images == null || images.size() <= 1) {
67 images = getIntent().getStringArrayListExtra("images"); 86 binding.rlPrevious.setVisibility(View.GONE);
68 if (images == null || images.size() <= 1) { 87 binding.rlNext.setVisibility(View.GONE);
69 binding.rlPrevious.setVisibility(View.GONE); 88 }
70 binding.rlNext.setVisibility(View.GONE); 89 for (String s : images) {
71 } 90 String filepath = context.getExternalFilesDir("images").getPath() + "/" + System.currentTimeMillis() + CommonUtil.getStr() + ".jpg";
72 for (String s : images) { 91 ImageBean imageBean = new ImageBean();
73 String filepath = context.getExternalFilesDir("images").getPath() + "/" + System.currentTimeMillis() + CommonUtil.getStr() + ".jpg"; 92 Bitmap bitmap = BitmapUtils.getimage(s);
74 ImageBean imageBean = new ImageBean(); 93 CommonUtil.saveBitmapToUri(bitmap, filepath);
75 Bitmap bitmap = BitmapUtils.getimage(s); 94 imageBean.setPath(filepath);
76 CommonUtil.saveBitmapToUri(bitmap, filepath); 95 imageBean.source = filepath;
77 imageBean.setPath(filepath); 96 list.add(imageBean);
78 imageBean.source = filepath; 97 }
79 list.add(imageBean); 98 imageAdapter = new ImageAdapter(this, list);
80 } 99 binding.viewPager.setAdapter(imageAdapter);
81 imageAdapter = new ImageAdapter(this, list); 100 binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() {
82 binding.viewPager.setAdapter(imageAdapter); 101 @Override
83 binding.viewPager.registerOnPageChangeCallback(new ViewPager2.OnPageChangeCallback() { 102 public void onPageSelected(int position) {
84 @Override 103 if (list.get(position).getCuts() == null) {
85 public void onPageSelected(int position) {
86 if (list.get(position).getCuts() == null) {
87 // binding.ivPrevious.setEnabled(false); 104 clearText();
88 // binding.ivNext.setEnabled(false); 105 }
89 clearText(); 106 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size());
90 } 107 if (position == 0) {
91 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size()); 108 binding.ivPrevious.setImageResource(R.mipmap.ic_previous_gray);
92 if (position == 0) {
93 binding.ivPrevious.setImageResource(R.mipmap.ic_previous_gray); 109 } else {
94 // binding.ivPrevious.setEnabled(true); 110 binding.ivPrevious.setImageResource(R.mipmap.ic_previous);
95 } else {
96 binding.ivPrevious.setImageResource(R.mipmap.ic_previous); 111 }
97 // binding.ivPrevious.setEnabled(false); 112 if (position == list.size() - 1) {
98 } 113 binding.ivNext.setImageResource(R.mipmap.ic_next_gray);
99 if (position == list.size() - 1) {
100 binding.ivNext.setImageResource(R.mipmap.ic_next_gray); 114 } else {
101 // binding.ivNext.setEnabled(true); 115 binding.ivNext.setImageResource(R.mipmap.ic_next);
102 } else {
103 binding.ivNext.setImageResource(R.mipmap.ic_next); 116 }
104 // binding.ivNext.setEnabled(false); 117 super.onPageSelected(position);
105 } 118 }
106 super.onPageSelected(position); 119 });
107 } 120 binding.rlNext.setOnClickListener(this);
108 }); 121 binding.rlPrevious.setOnClickListener(this);
109 binding.rlNext.setOnClickListener(this); 122 binding.ivBack.setOnClickListener(this);
110 binding.rlPrevious.setOnClickListener(this); 123 binding.tvPhoto.setOnClickListener(this);
111 binding.ivBack.setOnClickListener(this); 124 binding.tvAdd.setOnClickListener(this);
112 binding.tvPhoto.setOnClickListener(this); 125 binding.llEdit.setOnClickListener(this);
113 binding.tvAdd.setOnClickListener(this); 126 binding.tvSave.setOnClickListener(this);
114 binding.llEdit.setOnClickListener(this); 127 binding.btnShowSource.setOnClickListener(v -> {
115 binding.tvSave.setOnClickListener(this); 128 if (list.isEmpty()) return;
116 binding.btnShowSource.setOnClickListener(v -> { 129 ImageBean data = list.get(binding.viewPager.getCurrentItem());
117 if (list.isEmpty()) return; 130 new PhotoViewDialog(this).show(data.source);
118 ImageBean data = list.get(binding.viewPager.getCurrentItem()); 131 });
132
133 binding.btnJudge.setVisibility(type == 0 ? View.VISIBLE : View.GONE);
134 binding.btnJudge.setOnClickListener(v -> {
135 goJudge();
136 });
137 }
138
139 private void goJudge() {
140 if (list.isEmpty()) return;
141 int position = binding.viewPager.getCurrentItem();
142 ImageBean imageBean = list.get(position);
143 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath());
144 if (bitmap == null || imageBean.getCuts() == null) {
145 showToast("请先框选题目");
146 return;
147 }
148 ItemImageBinding ib = imageAdapter.viewArray.get(position);
149 if (ib == null) {
150 showToast("出错");
151 return;
152 }
153 View view = ib.ivPic;
154 float[] size = CutUtil.measureBitmap(view, bitmap);
155
156 ArrayList<Rect> rects = new ArrayList<>();
157 for (ImageBean.Cut cut: imageBean.getCuts()) {
158 if (cut.getRect1() == null) continue;
159 Rect rectV = cut.getRect1();
160 rects.add(getRectB(rectV, bitmap, size));
161 }
162 if (list.isEmpty()) {
163 showToast("请先框选题目");
164 return;
165 }
166
167 Intent intent = new Intent(this, JudgeActivity.class);
168 intent.putExtra("path", imageBean.getPath());
169 intent.putParcelableArrayListExtra("rects", rects);
170
171 startActivity(intent);
172 }
173
174 private Rect getRectB(Rect rectV, Bitmap bitmap, float[] measuredSize) {
175 float realW = measuredSize[0];
176 float realH = measuredSize[1];
177 float offsetX = measuredSize[2];
178 float offsetY = measuredSize[3];
179 float percentX = bitmap.getWidth() / realW;
180 float percentY = bitmap.getHeight() / realH;
181
182 float left = (rectV.left - offsetX) * percentX;
183 float right = (rectV.right - offsetX) * percentX;
184 float top = (rectV.top - offsetY) * percentY;
185 float bottom = (rectV.bottom - offsetY) * percentY;
186 Rect rectB = new Rect((int) left, (int) top, (int) right, (int) bottom);
187 return rectB;
119 new PhotoViewDialog(this).show(data.source); 188 }
120 }); 189
121 190 public void clearText() {
122 binding.btnJudge.setVisibility(type == 0 ? View.VISIBLE : View.GONE); 191 int index = binding.viewPager.getCurrentItem();
123 binding.btnJudge.setOnClickListener(v -> { 192 showLoadingDialog(getString(R.string.loading_text), new LoadingDialog.DismissListener() {
124 goJudge(); 193 @Override
125 }); 194 public void dimiss() {
126 } 195 // binding.ivPrevious.setEnabled(index != 0);
127 196 // binding.ivNext.setEnabled(index != list.size() - 1);
128 private void goJudge() { 197 }
129 if (list.isEmpty()) return; 198 });
130 int position = binding.viewPager.getCurrentItem(); 199 Log.i("clearText", list.get(index).getPath());
131 ImageBean imageBean = list.get(position); 200 String base64 = BitmapUtils.imageToBase64(list.get(index).getPath(), false);
132 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath()); 201 NetWorks.baiduEnhance(base64, new Observer<JsonObject>() {
133 if (bitmap == null || imageBean.getCuts() == null) { 202 @Override
134 showToast("请先框选题目"); 203 public void onSubscribe(Disposable d) {
135 return; 204
136 } 205 }
137 ItemImageBinding ib = imageAdapter.viewArray.get(position); 206
138 if (ib == null) { 207 @Override
139 showToast("出错"); 208 public void onNext(JsonObject jsonObject) {
140 return; 209 if (jsonObject != null && jsonObject.get("image_processed") != null) {
141 } 210 String image = jsonObject.get("image_processed").getAsString();
142 View view = ib.ivPic; 211 if (image != null) {
143 float[] size = CutUtil.measureBitmap(view, bitmap); 212 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
144 213 CommonUtil.saveBitmapToUri(BitmapUtils.stringToBitmap(image), filepath);
145 ArrayList<Rect> rects = new ArrayList<>(); 214 list.get(index).setPath(filepath);
146 for (ImageBean.Cut cut: imageBean.getCuts()) { 215 if (list.get(index).getCuts() == null) {
147 if (cut.getRect1() == null) continue; 216 list.get(index).setCuts(new ArrayList<>());
148 Rect rectV = cut.getRect1(); 217 }
149 rects.add(getRectB(rectV, bitmap, size)); 218 imageAdapter.notifyItemChanged(index);
150 } 219 cut(filepath);
151 if (list.isEmpty()) { 220 } else {
152 showToast("请先框选题目"); 221 loadFail("去除字迹失败");
153 return; 222 }
154 } 223 } else {
155 224 loadFail("去除字迹失败");
156 Intent intent = new Intent(this, JudgeActivity.class); 225 }
157 intent.putExtra("path", imageBean.getPath()); 226 }
158 intent.putParcelableArrayListExtra("rects", rects); 227
159 228 @Override
160 startActivity(intent); 229 public void onError(Throwable e) {
161 } 230 e.printStackTrace();
162 231 loadFail("去除字迹失败");
163 private Rect getRectB(Rect rectV, Bitmap bitmap, float[] measuredSize) { 232 }
164 float realW = measuredSize[0]; 233
165 float realH = measuredSize[1]; 234 @Override
166 float offsetX = measuredSize[2]; 235 public void onComplete() {
167 float offsetY = measuredSize[3]; 236
168 float percentX = bitmap.getWidth() / realW; 237 }
169 float percentY = bitmap.getHeight() / realH; 238 });
170 239 }
171 float left = (rectV.left - offsetX) * percentX; 240
172 float right = (rectV.right - offsetX) * percentX; 241 public void cut(String path) {
173 float top = (rectV.top - offsetY) * percentY; 242 String base64 = BitmapUtils.imageToBase64WithUrlEncode(path);
174 float bottom = (rectV.bottom - offsetY) * percentY; 243 Log.i("figLoaction", path);
175 Rect rectB = new Rect((int) left, (int) top, (int) right, (int) bottom); 244 NetWorks.cut(base64, new Observer<CutPicBean>() {
176 return rectB; 245 @Override
177 } 246 public void onSubscribe(Disposable d) {
178 247
179 public void clearText() { 248 }
180 int index = binding.viewPager.getCurrentItem(); 249
181 showLoadingDialog(getString(R.string.loading_text), new LoadingDialog.DismissListener() { 250 @Override
182 @Override 251 public void onNext(CutPicBean cutPicBean) {
183 public void dimiss() { 252 if (cutPicBean != null) {
184 // binding.ivPrevious.setEnabled(index != 0); 253 if (cutPicBean.getDirection() != 0) {
185 // binding.ivNext.setEnabled(index != list.size() - 1); 254 rotatingImage(cutPicBean);
186 } 255 } else {
187 }); 256 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) {
188 Log.i("clearText", list.get(index).getPath()); 257 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>();
189 String base64 = BitmapUtils.imageToBase64(list.get(index).getPath()); 258 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) {
190 NetWorks.removeWriting(base64, new Observer<JsonObject>() { 259 figLoactions.add(cutLocation.getFig_location());
191 @Override 260 }
192 public void onSubscribe(Disposable d) { 261 new Handler().postDelayed(new Runnable() {
193 262 @Override
194 } 263 public void run() {
195 264 getRects(figLoactions);
196 @Override 265 }
197 public void onNext(JsonObject jsonObject) { 266 }, 1000);
198 if (jsonObject != null && jsonObject.get("image_processed") != null) { 267 } else {
199 String image = jsonObject.get("image_processed").getAsString(); 268 cancelLoadingDialog();
200 if (image != null) { 269 }
201 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 270 }
202 CommonUtil.saveBitmapToUri(BitmapUtils.stringToBitmap(image), filepath); 271 } else {
203 list.get(index).setPath(filepath); 272 loadFail("自动切题失败");
204 if (list.get(index).getCuts() == null) { 273 }
205 list.get(index).setCuts(new ArrayList<>()); 274 }
206 } 275
207 imageAdapter.notifyItemChanged(index); 276 @Override
208 cut(filepath); 277 public void onError(Throwable e) {
209 } else { 278 loadFail("自动切题失败");
210 loadFail("去除字迹失败"); 279 }
211 } 280
212 } else { 281 @Override
213 loadFail("去除字迹失败"); 282 public void onComplete() {
214 } 283
215 } 284 }
216 285 });
217 @Override 286 }
218 public void onError(Throwable e) { 287
219 e.printStackTrace(); 288 private void getRects(List<CutPicBean.FigLoaction> figLoactions) {
220 loadFail("去除字迹失败"); 289 Log.i("figLoaction", new Gson().toJson(figLoactions));
221 } 290 int index = binding.viewPager.getCurrentItem();
222 291 List<ImageBean.Cut> cuts = new ArrayList<>();
223 @Override 292 for (CutPicBean.FigLoaction figLoaction : figLoactions) {
224 public void onComplete() { 293 ImageBean.Cut cut = new ImageBean.Cut();
225 294 cut.setRect(figLoaction);
226 } 295 cut.setSelect(false);
227 }); 296 cuts.add(cut);
228 } 297 }
229 298 list.get(index).setCuts(cuts);
230 public void cut(String path) { 299 imageAdapter.notifyItemChanged(index);
231 String base64 = BitmapUtils.imageToBase64(path); 300 cancelLoadingDialog();
232 Log.i("figLoaction", path); 301 }
233 NetWorks.cut(base64, new Observer<CutPicBean>() { 302
234 @Override 303 private void rotatingImage(CutPicBean cutPicBean) {
235 public void onSubscribe(Disposable d) { 304 int index = binding.viewPager.getCurrentItem();
236 305 Bitmap bitmap = BitmapFactory.decodeFile(list.get(index).getPath());
237 } 306 int angle = 0;
238 307 switch (cutPicBean.getDirection()) {
239 @Override 308 case 1:
240 public void onNext(CutPicBean cutPicBean) { 309 angle = 90;
241 if (cutPicBean != null) { 310 break;
242 if (cutPicBean.getDirection() != 0) { 311 case 2:
243 rotatingImage(cutPicBean); 312 angle = 180;
244 } else { 313 break;
245 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) { 314 case 3:
246 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>(); 315 angle = 270;
247 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) { 316 break;
248 figLoactions.add(cutLocation.getFig_location()); 317 }
249 } 318 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) {
250 new Handler().postDelayed(new Runnable() { 319 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>();
251 @Override 320 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) {
252 public void run() { 321 figLoactions.add(cutLocation.getFig_location());
253 getRects(figLoactions); 322 }
254 } 323 figLoactions = CommonUtil.rotaingLocation(angle, figLoactions, bitmap.getWidth(), bitmap.getHeight());
255 }, 1000); 324 bitmap = CommonUtil.rotaingImageView(angle, bitmap);
256 } else { 325 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
257 cancelLoadingDialog(); 326 CommonUtil.saveBitmapToUri(bitmap, filepath);
258 } 327 list.get(index).setPath(filepath);
259 } 328 imageAdapter.notifyItemChanged(index);
260 } else { 329 List<CutPicBean.FigLoaction> finalFigLoactions = figLoactions;
261 loadFail("自动切题失败"); 330 new Handler().postDelayed(new Runnable() {
262 } 331 @Override
263 } 332 public void run() {
264 333 getRects(finalFigLoactions);
265 @Override 334 }
266 public void onError(Throwable e) { 335 }, 500);
267 loadFail("自动切题失败"); 336 } else {
268 } 337 cancelLoadingDialog();
269 338 }
270 @Override 339 }
271 public void onComplete() { 340
272 341 @Override
273 } 342 protected ActivityImageBinding getViewBinding() {
274 }); 343 return ActivityImageBinding.inflate(getLayoutInflater());
275 } 344 }
276 345
277 private void getRects(List<CutPicBean.FigLoaction> figLoactions) { 346 @SuppressLint("SetTextI18n")
278 Log.i("figLoaction", new Gson().toJson(figLoactions)); 347 public void refreshNum() {
279 int index = binding.viewPager.getCurrentItem(); 348 int num = 0;
280 List<ImageBean.Cut> cuts = new ArrayList<>(); 349 for (ImageBean imageBean : list) {
281 for (CutPicBean.FigLoaction figLoaction : figLoactions) { 350 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) {
282 ImageBean.Cut cut = new ImageBean.Cut(); 351 for (ImageBean.Cut cut : imageBean.getCuts()) {
283 cut.setRect(figLoaction); 352 if (cut.isSelect()) {
284 cut.setSelect(false); 353 num++;
285 cuts.add(cut); 354 }
286 } 355 }
287 list.get(index).setCuts(cuts); 356 }
288 imageAdapter.notifyItemChanged(index); 357 }
289 cancelLoadingDialog(); 358 String btnText = type == 0 ? "保存错题" : "录入题目";
290 } 359 if (num > 0) {
291 360 binding.tvSave.setEnabled(true);
292 private void rotatingImage(CutPicBean cutPicBean) { 361 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_5);
293 int index = binding.viewPager.getCurrentItem(); 362 binding.tvSave.setText(btnText + "(" + num + ")");
294 Bitmap bitmap = BitmapFactory.decodeFile(list.get(index).getPath()); 363 } else {
295 int angle = 0; 364 binding.tvSave.setEnabled(false);
296 switch (cutPicBean.getDirection()) { 365 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_light_5);
297 case 1: 366 binding.tvSave.setText(btnText);
298 angle = 90; 367 }
299 break; 368 }
300 case 2: 369
301 angle = 180; 370 @Override
302 break; 371 public void onClick(View v) {
303 case 3: 372 switch (v.getId()) {
304 angle = 270; 373 case R.id.iv_back:
305 break; 374 back();
306 } 375 break;
307 if (cutPicBean.getQus_figure() != null && cutPicBean.getQus_figure().size() > 0) { 376 case R.id.rl_next:
308 List<CutPicBean.FigLoaction> figLoactions = new ArrayList<>(); 377 if (binding.viewPager.getCurrentItem() + 1 < list.size()) {
309 for (CutPicBean.CutLocation cutLocation : cutPicBean.getQus_figure()) { 378 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() + 1);
310 figLoactions.add(cutLocation.getFig_location()); 379 }
311 } 380 break;
312 figLoactions = CommonUtil.rotaingLocation(angle, figLoactions, bitmap.getWidth(), bitmap.getHeight()); 381 case R.id.rl_previous:
313 bitmap = CommonUtil.rotaingImageView(angle, bitmap); 382 if (binding.viewPager.getCurrentItem() != 0) {
314 String filepath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 383 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() - 1);
315 CommonUtil.saveBitmapToUri(bitmap, filepath); 384 }
316 list.get(index).setPath(filepath); 385 break;
317 imageAdapter.notifyItemChanged(index); 386 case R.id.ll_edit:
318 List<CutPicBean.FigLoaction> finalFigLoactions = figLoactions; 387 Intent intent = new Intent(context, ImageEditActivity.class);
319 new Handler().postDelayed(new Runnable() { 388 intent.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath());
320 @Override 389 startActivityForResult(intent, 1001);
321 public void run() { 390 break;
322 getRects(finalFigLoactions); 391 case R.id.tv_photo:
323 } 392 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
324 }, 500); 393 //确保有相机来处理Intent
325 } else { 394 filePath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
326 cancelLoadingDialog(); 395 File photoFile = new File(filePath);
327 } 396 if (photoFile != null) {
328 } 397 //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri
329 398 Uri photoUri = FileProvider.getUriForFile(activity, "com.hjx.parent.fileprovider", photoFile);
330 @Override 399 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
331 protected ActivityImageBinding getViewBinding() { 400 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri);
332 return ActivityImageBinding.inflate(getLayoutInflater()); 401 activity.startActivityForResult(takePictureIntent, 1002);
333 } 402 }
334 403 break;
335 @SuppressLint("SetTextI18n") 404 case R.id.tv_add:
336 public void refreshNum() { 405 Intent intent1 = new Intent(context, ImageSelectActivity.class);
337 int num = 0; 406 intent1.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath());
338 for (ImageBean imageBean : list) { 407 intent1.putExtra("source", list.get(binding.viewPager.getCurrentItem()).source);
339 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) { 408 startActivityForResult(intent1, 1001);
340 for (ImageBean.Cut cut : imageBean.getCuts()) { 409 break;
341 if (cut.isSelect()) { 410 case R.id.tv_save:
342 num++; 411 List<TopicBean> topicBeans = new ArrayList<>();
343 } 412 for (ImageBean imageBean : list) {
344 } 413 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) {
345 } 414 for (ImageBean.Cut cut : imageBean.getCuts()) {
346 } 415 if (cut.isSelect()) {
347 String btnText = type == 0 ? "保存错题" : "录入题目"; 416 TopicBean bean = new TopicBean();
348 if (num > 0) { 417 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
349 binding.tvSave.setEnabled(true); 418 BitmapUtils.saveBitmap(cut.getBitmap(), path);
350 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_5); 419 bean.setPath(path);
351 binding.tvSave.setText(btnText + "(" + num + ")"); 420 topicBeans.add(bean);
352 } else { 421 }
353 binding.tvSave.setEnabled(false); 422 }
354 binding.tvSave.setBackgroundResource(R.drawable.bg_soild_blue_light_5); 423 }
355 binding.tvSave.setText(btnText); 424 }
356 } 425 save(topicBeans);
357 } 426 break;
358 427 }
359 @Override 428 }
360 public void onClick(View v) { 429
361 switch (v.getId()) { 430 private void save(List<TopicBean> topicBeans) {
362 case R.id.iv_back: 431 if (type == 0) {
363 back(); 432 ErrorInputDialog dialog = new ErrorInputDialog(this, topicBeans);
364 break; 433 dialog.show();
365 case R.id.rl_next: 434 } else {
366 if (binding.viewPager.getCurrentItem() + 1 < list.size()) { 435 List<String> paths = new ArrayList<>();
367 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() + 1); 436 for (TopicBean it: topicBeans) {
368 } 437 paths.add(it.getPath());
369 break; 438 }
370 case R.id.rl_previous: 439 if (addHomeworkDialog == null) {
371 if (binding.viewPager.getCurrentItem() != 0) { 440 addHomeworkDialog = new AddHomeworkDialog(this);
372 binding.viewPager.setCurrentItem(binding.viewPager.getCurrentItem() - 1); 441 }
373 } 442 addHomeworkDialog.show(paths, student -> {
374 break; 443 Intent intent = new Intent(context, AddSuccessActivity.class);
375 case R.id.ll_edit: 444 intent.putExtra("type", type);
376 Intent intent = new Intent(context, ImageEditActivity.class); 445 intent.putExtra("studentJson", new Gson().toJson(student));
377 intent.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath()); 446 startActivity(intent);
378 startActivityForResult(intent, 1001); 447 finish();
379 break; 448 });
380 case R.id.tv_photo: 449 }
381 Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE); 450 }
382 //确保有相机来处理Intent 451
383 filePath = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 452 @Override
384 File photoFile = new File(filePath); 453 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
385 if (photoFile != null) { 454 super.onActivityResult(requestCode, resultCode, data);
386 //适配Android 7.0文件权限,通过FileProvider创建一个content类型的Uri 455 if (requestCode == 1001) {
387 Uri photoUri = FileProvider.getUriForFile(activity, "com.hjx.parent.fileprovider", photoFile); 456 if (resultCode == 1002) {
388 takePictureIntent.addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION); 457 if (list.size() > 1) {
389 takePictureIntent.putExtra(MediaStore.EXTRA_OUTPUT, photoUri); 458 list.remove(binding.viewPager.getCurrentItem());
390 activity.startActivityForResult(takePictureIntent, 1002); 459 if (list.size() <= 1) {
391 } 460 binding.rlPrevious.setVisibility(View.GONE);
392 break; 461 binding.rlNext.setVisibility(View.GONE);
393 case R.id.tv_add: 462 }
394 Intent intent1 = new Intent(context, ImageSelectActivity.class); 463 imageAdapter.notifyItemRemoved(binding.viewPager.getCurrentItem());
395 intent1.putExtra("path", list.get(binding.viewPager.getCurrentItem()).getPath()); 464 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size());
396 intent1.putExtra("source", list.get(binding.viewPager.getCurrentItem()).source); 465 refreshNum();
397 startActivityForResult(intent1, 1001); 466 } else {
398 break; 467 finish();
399 case R.id.tv_save: 468 }
400 List<TopicBean> topicBeans = new ArrayList<>(); 469 } else if (resultCode == 1003) {
401 for (ImageBean imageBean : list) { 470 int position = binding.viewPager.getCurrentItem();
402 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) { 471 String src = list.get(position).source;
403 for (ImageBean.Cut cut : imageBean.getCuts()) { 472 list.remove(position);
404 if (cut.isSelect()) { 473 String path = data.getStringExtra("path");
405 TopicBean bean = new TopicBean(); 474 ImageBean imageBean = new ImageBean();
406 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg"; 475 imageBean.setPath(path);
407 BitmapUtils.saveBitmap(cut.getBitmap(), path); 476 imageBean.source = src;
408 bean.setPath(path); 477 list.add(position, imageBean);
409 topicBeans.add(bean); 478 imageAdapter.notifyItemChanged(position);
410 } 479 clearText();
411 } 480 refreshNum();
412 } 481 } else if (resultCode == 1004) {
413 } 482 Rect rect = data.getParcelableExtra("cut");
414 save(topicBeans); 483 if (rect != null) {
415 break; 484 int position = binding.viewPager.getCurrentItem();
416 } 485 ImageBean.Cut cut = new ImageBean.Cut();
417 } 486 cut.setRect1(rect);
418 487 cut.setSelect(false);
419 private void save(List<TopicBean> topicBeans) { 488 if (list.get(position).getCuts() != null) {
420 if (type == 0) { 489 list.get(position).getCuts().add(cut);
421 ErrorInputDialog dialog = new ErrorInputDialog(this, topicBeans); 490 } else {
422 dialog.show(); 491 List<ImageBean.Cut> cuts =new ArrayList<>();
423 } else { 492 cuts.add(cut);
424 List<String> paths = new ArrayList<>(); 493 list.get(position).setCuts(cuts);
425 for (TopicBean it: topicBeans) { 494 }
426 paths.add(it.getPath()); 495 imageAdapter.notifyItemChanged(position);
427 } 496 refreshNum();
428 if (addHomeworkDialog == null) { 497 }
429 addHomeworkDialog = new AddHomeworkDialog(this); 498 } else if (resultCode == 1005) {
430 } 499 int i = data.getIntExtra("position", 0);
431 addHomeworkDialog.show(paths, student -> { 500 int position = binding.viewPager.getCurrentItem();
432 Intent intent = new Intent(context, AddSuccessActivity.class); 501 Rect rect = data.getParcelableExtra("cut");
433 intent.putExtra("type", type); 502 if (rect != null) {
434 intent.putExtra("studentJson", new Gson().toJson(student)); 503 ImageBean.Cut cut = new ImageBean.Cut();
435 startActivity(intent); 504 cut.setRect1(rect);
436 finish(); 505 cut.setSelect(false);
437 }); 506 list.get(position).getCuts().remove(i);
438 } 507 list.get(position).getCuts().add(i, cut);
439 } 508 imageAdapter.notifyItemChanged(position);
440 509 refreshNum();
441 @Override 510 } else {
442 protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) { 511 list.get(position).getCuts().remove(i);
443 super.onActivityResult(requestCode, resultCode, data); 512 imageAdapter.notifyItemChanged(position);
444 if (requestCode == 1001) { 513 refreshNum();
445 if (resultCode == 1002) { 514 }
446 if (list.size() > 1) { 515 }
447 list.remove(binding.viewPager.getCurrentItem()); 516 } else if (requestCode == 1002 && resultCode == RESULT_OK && !TextUtils.isEmpty(filePath)) {
448 if (list.size() <= 1) { 517 Bitmap b = BitmapUtils.compress(BitmapFactory.decodeFile(filePath));
449 binding.rlPrevious.setVisibility(View.GONE); 518 String path = context.getExternalFilesDir("images").getPath() + "/" + String.valueOf(System.currentTimeMillis()) + CommonUtil.getStr() + ".jpg";
450 binding.rlNext.setVisibility(View.GONE); 519 CommonUtil.saveBitmapToUri(b, path);
451 } 520 int position = binding.viewPager.getCurrentItem();
452 imageAdapter.notifyItemRemoved(binding.viewPager.getCurrentItem()); 521 list.remove(position);
453 binding.tvTitle.setText((binding.viewPager.getCurrentItem() + 1) + "/" + list.size()); 522 ImageBean imageBean = new ImageBean();
454 refreshNum(); 523 imageBean.setPath(path);
455 } else { 524 imageBean.source = path;
456 finish(); 525 list.add(position, imageBean);
457 } 526 imageAdapter.notifyItemChanged(position);
458 } else if (resultCode == 1003) { 527 clearText();
459 int position = binding.viewPager.getCurrentItem(); 528 refreshNum();
460 String src = list.get(position).source; 529 }
461 list.remove(position); 530 }
462 String path = data.getStringExtra("path"); 531
463 ImageBean imageBean = new ImageBean(); 532 private void back() {
464 imageBean.setPath(path); 533 showTipDialog("温馨提示", "是否确认退出?", "取消", "确定", new TipDialog.TipDialogInterface() {
465 imageBean.source = src; 534 @Override
466 list.add(position, imageBean); 535 public void onConfirm(Dialog dialog) {
467 imageAdapter.notifyItemChanged(position); 536 dialog.dismiss();
468 clearText(); 537 finish();
469 refreshNum(); 538 }
470 } else if (resultCode == 1004) { 539
471 Rect rect = data.getParcelableExtra("cut"); 540 @Override
472 if (rect != null) { 541 public void onCancel(Dialog dialog) {
473 int position = binding.viewPager.getCurrentItem(); 542 dialog.dismiss();
474 ImageBean.Cut cut = new ImageBean.Cut(); 543 }
475 cut.setRect1(rect); 544 });
476 cut.setSelect(false); 545 }
477 if (list.get(position).getCuts() != null) { 546
478 list.get(position).getCuts().add(cut); 547 @Override
app/src/main/java/com/hjx/parent/JudgeActivity.java
File was created 1 package com.hjx.parent;
2
3 import android.annotation.SuppressLint;
4 import android.graphics.Bitmap;
5 import android.graphics.Rect;
6 import android.os.Bundle;
7 import android.util.Log;
8
9 import com.bumptech.glide.Glide;
10 import com.hjx.parent.api.JudgeRepository;
11 import com.hjx.parent.databinding.ActivityJudgeBinding;
12 import com.hjx.parent.databinding.LayoutJudgeRectBinding;
13 import com.hjx.parent.rx.BaseRxActivity;
14 import com.hjx.parent.utils.CutUtil;
15
16 import java.io.File;
17 import java.util.ArrayList;
18 import java.util.List;
19
20 import io.reactivex.Observable;
21 import io.reactivex.Single;
22 import top.zibin.luban.Luban;
23
24 public class JudgeActivity extends BaseRxActivity<ActivityJudgeBinding> {
25
26 private Bitmap bitmap;
27
28 private final List<JudgeCut> mList = new ArrayList<>();
29
30 @SuppressLint("CheckResult")
31 @Override
32 public void initView(Bundle savedInstanceState) {
33 binding.ivBack.setOnClickListener(v -> {
34 onBackPressed();
35 });
36 String path = getIntent().getStringExtra("path");
37 if (path == null) return;
38 final ArrayList<Rect> rects = getIntent().getParcelableArrayListExtra("rects");
39 if (rects == null) return;
40
41 Single.just(path)
42 .map(origin -> Luban.with(this).load(origin).ignoreBy(300).get().get(0))
43 .map(file -> Glide.with(this).asBitmap().load(file).submit().get())
44 .compose(transformSingle())
45 .subscribe((bitmap, th) -> {
46 if (th != null) th.printStackTrace();
47 if (bitmap == null) return;
48 this.bitmap = bitmap;
49
50 binding.ivPic.setImageBitmap(bitmap);
51 CutUtil.onLayoutReady(binding.ivPic, v -> {
52 prepareRects(rects);
53 });
54 });
55 binding.btnSelectAll.setOnClickListener(v -> {
56 if (mList.isEmpty()) return;
57 mList.forEach(it -> it.vb.getRoot().setSelected(true));
58 checkCount();
59 });
60 }
61
62 private void prepareRects(List<Rect> rects) {
63 mList.clear();
64 binding.flRects.removeAllViews();
65 float[] measuredSize = CutUtil.measureBitmap(binding.ivPic, bitmap);
66 for (int i = 0; i < rects.size(); i++) {
67 Rect it = rects.get(i);
68 Bitmap bitmap = CutUtil.cut(this.bitmap, it.left, it.top, it.width(), it.height(), this);
69 Rect rect = measureRect(it, measuredSize);
70 LayoutJudgeRectBinding vb = showRect(rect);
71 mList.add(new JudgeCut(i, bitmap, rect, vb));
72 }
73
74 judge();
75 }
76
77 @SuppressLint("CheckResult")
78 private void judge() {
79 showLoadingDialog("");
80 Observable.fromIterable(mList)
81 .map(it -> {
82 if (it.url != null && !it.url.isEmpty()) return it;
83 String base64 = CutUtil.bitmapToBase64(it.bitmap, true);
84 it.url = base64;
85 return it;
86 })
87 .flatMap(it -> JudgeRepository.singleJudge(it.url)
88 .map(result -> {
89 it.correctResult = result;
90 return it;
91 })
92 .toObservable()
93 )
94 .compose(transform())
95 .subscribe(it -> {
96 if (it.correctResult == 1) {
97 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_correct);
98 } else if (it.correctResult == 2) {
99 it.vb.ivResult.setImageResource(R.drawable.png_ic_judge_wrong);
100 }
101 it.vb.getRoot().setSelected(it.correctResult != 1);
102 checkCount();
103 }, th -> {
104 cancelLoadingDialog();
105 Log.e(getClass().getName(), "", th);
106 }, this::cancelLoadingDialog)
107 ;
108 }
109
110 private LayoutJudgeRectBinding showRect(Rect rect) {
111 LayoutJudgeRectBinding vb = LayoutJudgeRectBinding.inflate(getLayoutInflater(), binding.flRects, false);
112
113 vb.getRoot().setMinimumWidth(rect.width());
114 vb.getRoot().setMinimumHeight(rect.height());
115 vb.getRoot().setTranslationX((float) rect.left);
116 vb.getRoot().setTranslationY((float) rect.top);
117 vb.getRoot().setOnClickListener(v -> {
118 v.setSelected(!v.isSelected());
119 checkCount();
120 });
121 binding.flRects.addView(vb.getRoot());
122
123 return vb;
124 }
125
126 @SuppressLint("SetTextI18n")
127 private void checkCount() {
128 int count = (int) mList.stream().filter(it -> it.vb.getRoot().isSelected()).count();
129 if (count == 0) binding.btnAdd.setText("加入错题");
130 else binding.btnAdd.setText("加入错题(" + count + ")");
131 binding.btnAdd.setEnabled(count > 0);
132 }
133
134 /** bitmapRect 转换为 viewRect */
135 private Rect measureRect(Rect rect, float[] measuredSize) {
136 float realW = measuredSize[0];
137 float realH = measuredSize[1];
138 float offsetX = measuredSize[2];
139 float offsetY = measuredSize[3];
140 float percentX = realW / bitmap.getWidth();
141 float percentY = realH / bitmap.getHeight();
142
143 float left = rect.left * percentX + offsetX;
144 float right = rect.right * percentX + offsetX;
145 float top = rect.top * percentY + offsetY;
146 float bottom = rect.bottom * percentY + offsetY;
147 return new Rect((int) left, (int) top, (int) right, (int) bottom);
148 }
149
150 @Override
151 protected ActivityJudgeBinding getViewBinding() {
152 return ActivityJudgeBinding.inflate(getLayoutInflater());
153 }
154
155 static class JudgeCut {
156 final int index;
157 final Bitmap bitmap;
158 final Rect rect;
159 final LayoutJudgeRectBinding vb;
160
161 String url;
162
163 /** 0:未批改;1:正确;2:错误;3:未作答 */
164 int correctResult = 0;
165
166 public JudgeCut(int index, Bitmap bitmap, Rect rect, LayoutJudgeRectBinding vb) {
167 this.index = index;
168 this.bitmap = bitmap;
169 this.rect = rect;
170 this.vb = vb;
171 }
172 }
173 }
1 package com.hjx.parent; 174
app/src/main/java/com/hjx/parent/adapter/ImageAdapter.java
1 package com.hjx.parent.adapter; 1 package com.hjx.parent.adapter;
2 2
3 import android.content.Context; 3 import android.content.Context;
4 import android.content.Intent; 4 import android.content.Intent;
5 import android.graphics.Bitmap; 5 import android.graphics.Bitmap;
6 import android.graphics.BitmapFactory; 6 import android.graphics.BitmapFactory;
7 import android.graphics.Rect; 7 import android.graphics.Rect;
8 import android.graphics.RectF; 8 import android.graphics.RectF;
9 import android.util.Log; 9 import android.util.Log;
10 import android.util.SparseArray;
10 import android.util.SparseArray; 11 import android.view.LayoutInflater;
11 import android.view.LayoutInflater; 12 import android.view.View;
12 import android.view.View; 13 import android.view.ViewGroup;
13 import android.view.ViewGroup; 14 import android.widget.ImageView;
14 import android.widget.ImageView; 15 import android.widget.RelativeLayout;
15 import android.widget.RelativeLayout; 16
16 17 import androidx.annotation.NonNull;
17 import androidx.annotation.NonNull; 18 import androidx.recyclerview.widget.RecyclerView;
18 import androidx.recyclerview.widget.RecyclerView; 19
19 20 import com.google.gson.Gson;
20 import com.google.gson.Gson; 21 import com.hjx.parent.ImageActivity;
21 import com.hjx.parent.ImageActivity; 22 import com.hjx.parent.ImageSelectActivity;
22 import com.hjx.parent.ImageSelectActivity; 23 import com.hjx.parent.R;
23 import com.hjx.parent.R; 24 import com.hjx.parent.databinding.ItemImageBinding;
24 import com.hjx.parent.databinding.ItemImageBinding; 25 import com.prws.common.bean.ImageBean;
25 import com.prws.common.bean.ImageBean; 26 import com.prws.common.utils.CommonUtil;
26 import com.prws.common.utils.CommonUtil; 27
27 28 import java.util.List;
28 import java.util.List; 29
29 30 public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageHolder> {
31 public SparseArray<ItemImageBinding> viewArray = new SparseArray<>();
32
30 public class ImageAdapter extends RecyclerView.Adapter<ImageAdapter.ImageHolder> { 33 private List<ImageBean> list;
31 public SparseArray<ItemImageBinding> viewArray = new SparseArray<>(); 34 private ImageActivity context;
32 35
36
33 private List<ImageBean> list; 37 public ImageAdapter(ImageActivity context, List<ImageBean> list) {
34 private ImageActivity context; 38 this.context = context;
35 39 this.list = list;
36 40 }
37 public ImageAdapter(ImageActivity context, List<ImageBean> list) { 41
38 this.context = context; 42 @NonNull
39 this.list = list; 43 @Override
40 } 44 public ImageHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
41 45 ItemImageBinding itemImageBinding = ItemImageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false);
42 @NonNull 46 return new ImageHolder(itemImageBinding);
43 @Override 47 }
44 public ImageHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) { 48
45 ItemImageBinding itemImageBinding = ItemImageBinding.inflate(LayoutInflater.from(parent.getContext()), parent, false); 49 @Override
46 return new ImageHolder(itemImageBinding); 50 public void onBindViewHolder(@NonNull ImageHolder holder, int position) {
51 viewArray.put(position, holder.binding);
52
47 } 53 ImageBean imageBean = list.get(position);
48 54 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath());
49 @Override 55 float imageHeight = bitmap.getHeight();
50 public void onBindViewHolder(@NonNull ImageHolder holder, int position) { 56 float imageWidth = bitmap.getWidth();
51 viewArray.put(position, holder.binding); 57 float viewHeight = CommonUtil.getScreenHeight(context) - CommonUtil.dpToPx(context, 250);
52 58 float viewWidth = CommonUtil.getScreenWidth(context) - CommonUtil.dpToPx(context, 60);
53 ImageBean imageBean = list.get(position); 59
54 Bitmap bitmap = BitmapFactory.decodeFile(imageBean.getPath()); 60 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(holder.binding.ivPic.getLayoutParams());
55 float imageHeight = bitmap.getHeight(); 61 if (imageHeight / imageWidth > viewHeight / viewWidth) {
56 float imageWidth = bitmap.getWidth(); 62 if (viewHeight > imageHeight) {
57 float viewHeight = CommonUtil.getScreenHeight(context) - CommonUtil.dpToPx(context, 250); 63 layoutParams.height = (int) imageHeight;
58 float viewWidth = CommonUtil.getScreenWidth(context) - CommonUtil.dpToPx(context, 60); 64 layoutParams.width = (int) imageWidth;
59 65 } else {
60 RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(holder.binding.ivPic.getLayoutParams()); 66 layoutParams.height = (int) viewHeight;
61 if (imageHeight / imageWidth > viewHeight / viewWidth) { 67 layoutParams.width = (int) ((float) (imageWidth / imageHeight) * viewHeight);
62 if (viewHeight > imageHeight) { 68 }
63 layoutParams.height = (int) imageHeight; 69 } else {
64 layoutParams.width = (int) imageWidth; 70 if (viewWidth > imageWidth) {
65 } else { 71 layoutParams.height = (int) imageHeight;
66 layoutParams.height = (int) viewHeight; 72 layoutParams.width = (int) imageWidth;
67 layoutParams.width = (int) ((float) (imageWidth / imageHeight) * viewHeight); 73 } else {
68 } 74 layoutParams.height = (int) ((float) (imageHeight / imageWidth) * viewWidth);
69 } else { 75 layoutParams.width = (int) viewWidth;
70 if (viewWidth > imageWidth) { 76 }
71 layoutParams.height = (int) imageHeight; 77 }
72 layoutParams.width = (int) imageWidth; 78 layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT);
73 } else { 79 holder.binding.ivPic.setLayoutParams(layoutParams);
74 layoutParams.height = (int) ((float) (imageHeight / imageWidth) * viewWidth); 80 holder.binding.ivPic.setImageBitmap(bitmap);
75 layoutParams.width = (int) viewWidth; 81
76 } 82
77 } 83 RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(holder.binding.rlPic.getLayoutParams());
78 layoutParams.addRule(RelativeLayout.CENTER_IN_PARENT); 84 if (imageHeight / imageWidth > viewHeight / viewWidth) {
79 holder.binding.ivPic.setLayoutParams(layoutParams); 85 if (viewHeight > imageHeight) {
80 holder.binding.ivPic.setImageBitmap(bitmap); 86 layoutParams1.height = (int) imageHeight;
81 87 layoutParams1.width = (int) imageWidth;
82 88 } else {
83 RelativeLayout.LayoutParams layoutParams1 = new RelativeLayout.LayoutParams(holder.binding.rlPic.getLayoutParams()); 89 layoutParams1.height = (int) viewHeight;
84 if (imageHeight / imageWidth > viewHeight / viewWidth) { 90 layoutParams1.width = (int) ((float) (imageWidth / imageHeight) * viewHeight);
85 if (viewHeight > imageHeight) { 91 }
86 layoutParams1.height = (int) imageHeight; 92 } else {
87 layoutParams1.width = (int) imageWidth; 93 if (viewWidth > imageWidth) {
88 } else { 94 layoutParams1.height = (int) imageHeight;
89 layoutParams1.height = (int) viewHeight; 95 layoutParams1.width = (int) imageWidth;
90 layoutParams1.width = (int) ((float) (imageWidth / imageHeight) * viewHeight); 96 } else {
91 } 97 layoutParams1.height = (int) ((float) (imageHeight / imageWidth) * viewWidth);
92 } else { 98 layoutParams1.width = (int) viewWidth;
93 if (viewWidth > imageWidth) { 99 }
94 layoutParams1.height = (int) imageHeight; 100 }
95 layoutParams1.width = (int) imageWidth; 101 Log.i("figLoaction", "height=" + layoutParams1.height + " width=" + layoutParams1.width);
96 } else { 102 layoutParams1.addRule(RelativeLayout.CENTER_IN_PARENT);
97 layoutParams1.height = (int) ((float) (imageHeight / imageWidth) * viewWidth); 103 holder.binding.rlPic.setLayoutParams(layoutParams1);
98 layoutParams1.width = (int) viewWidth; 104 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) {
99 } 105 holder.binding.rlPic.removeAllViews();
100 } 106 for (int i = 0; i < imageBean.getCuts().size(); i++) {
101 Log.i("figLoaction", "height=" + layoutParams1.height + " width=" + layoutParams1.width); 107 View view = LayoutInflater.from(context).inflate(R.layout.layout_select, null);
102 layoutParams1.addRule(RelativeLayout.CENTER_IN_PARENT); 108 Rect rect;
103 holder.binding.rlPic.setLayoutParams(layoutParams1); 109 if (imageBean.getCuts().get(i).getRect1() != null) {
104 if (imageBean.getCuts() != null && imageBean.getCuts().size() > 0) { 110 rect = imageBean.getCuts().get(i).getRect1();
105 holder.binding.rlPic.removeAllViews(); 111 } else {
106 for (int i = 0; i < imageBean.getCuts().size(); i++) { 112 rect = CommonUtil.getRect(imageBean.getCuts().get(i).getRect(), bitmap, layoutParams1.height, layoutParams1.width);
107 View view = LayoutInflater.from(context).inflate(R.layout.layout_select, null); 113 imageBean.getCuts().get(i).setRect1(rect);
108 Rect rect; 114 }
109 if (imageBean.getCuts().get(i).getRect1() != null) { 115 Log.i("figLoaction", new Gson().toJson(rect));
110 rect = imageBean.getCuts().get(i).getRect1(); 116 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(rect.right - rect.left, rect.bottom - rect.top);
111 } else { 117 params.setMargins(rect.left, rect.top, 0, 0);
112 rect = CommonUtil.getRect(imageBean.getCuts().get(i).getRect(), bitmap, layoutParams1.height, layoutParams1.width); 118 holder.binding.rlPic.addView(view, params);
113 imageBean.getCuts().get(i).setRect1(rect); 119 RelativeLayout rl_add = view.findViewById(R.id.rl_add);
114 } 120 ImageView iv_state = view.findViewById(R.id.iv_state);
115 Log.i("figLoaction", new Gson().toJson(rect)); 121 ImageView iv_edit = view.findViewById(R.id.iv_edit);
116 RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(rect.right - rect.left, rect.bottom - rect.top); 122 int finalI = i;
117 params.setMargins(rect.left, rect.top, 0, 0); 123 if (imageBean.getCuts().get(i).isSelect()) {
118 holder.binding.rlPic.addView(view, params); 124 rl_add.setBackgroundResource(R.drawable.bg_cut_select);
119 RelativeLayout rl_add = view.findViewById(R.id.rl_add); 125 iv_state.setImageResource(R.mipmap.ic_selected);
120 ImageView iv_state = view.findViewById(R.id.iv_state); 126 } else {
121 ImageView iv_edit = view.findViewById(R.id.iv_edit); 127 rl_add.setBackgroundResource(R.drawable.bg_cut_unselect);
122 int finalI = i; 128 iv_state.setImageResource(R.mipmap.ic_add);
123 if (imageBean.getCuts().get(i).isSelect()) { 129 }
124 rl_add.setBackgroundResource(R.drawable.bg_cut_select); 130 rl_add.setOnClickListener(new View.OnClickListener() {
125 iv_state.setImageResource(R.mipmap.ic_selected); 131 @Override
126 } else { 132 public void onClick(View v) {
127 rl_add.setBackgroundResource(R.drawable.bg_cut_unselect); 133 Bitmap b = Bitmap.createBitmap(bitmap, v.getLeft() * bitmap.getWidth() / holder.binding.ivPic.getWidth(), v.getTop() * bitmap.getHeight() / holder.binding.ivPic.getHeight(), (v.getRight() - v.getLeft()) * bitmap.getWidth() / holder.binding.ivPic.getWidth(), (v.getBottom() - v.getTop()) * bitmap.getHeight() / holder.binding.ivPic.getHeight());
128 iv_state.setImageResource(R.mipmap.ic_add); 134 if (imageBean.getCuts().get(finalI).isSelect()) {
129 } 135 imageBean.getCuts().get(finalI).setSelect(false);
130 rl_add.setOnClickListener(new View.OnClickListener() { 136 rl_add.setBackgroundResource(R.drawable.bg_cut_unselect);
131 @Override 137 iv_state.setImageResource(R.mipmap.ic_add);
132 public void onClick(View v) { 138 } else {
133 Bitmap b = Bitmap.createBitmap(bitmap, v.getLeft() * bitmap.getWidth() / holder.binding.ivPic.getWidth(), v.getTop() * bitmap.getHeight() / holder.binding.ivPic.getHeight(), (v.getRight() - v.getLeft()) * bitmap.getWidth() / holder.binding.ivPic.getWidth(), (v.getBottom() - v.getTop()) * bitmap.getHeight() / holder.binding.ivPic.getHeight()); 139 imageBean.getCuts().get(finalI).setSelect(true);
134 if (imageBean.getCuts().get(finalI).isSelect()) { 140 imageBean.getCuts().get(finalI).setBitmap(b);
135 imageBean.getCuts().get(finalI).setSelect(false); 141 rl_add.setBackgroundResource(R.drawable.bg_cut_select);
136 rl_add.setBackgroundResource(R.drawable.bg_cut_unselect); 142 iv_state.setImageResource(R.mipmap.ic_selected);
137 iv_state.setImageResource(R.mipmap.ic_add); 143 }
138 } else { 144 context.refreshNum();
139 imageBean.getCuts().get(finalI).setSelect(true); 145 }
140 imageBean.getCuts().get(finalI).setBitmap(b); 146 });
141 rl_add.setBackgroundResource(R.drawable.bg_cut_select); 147 iv_edit.setOnClickListener(new View.OnClickListener() {
142 iv_state.setImageResource(R.mipmap.ic_selected); 148 @Override
143 } 149 public void onClick(View v) {
144 context.refreshNum(); 150 Intent intent = new Intent(context, ImageSelectActivity.class);
145 } 151 intent.putExtra("rect", rect);
146 }); 152 intent.putExtra("path", imageBean.getPath());
147 iv_edit.setOnClickListener(new View.OnClickListener() { 153 intent.putExtra("position", finalI);
148 @Override 154 context.startActivityForResult(intent, 1001);
149 public void onClick(View v) { 155 }
150 Intent intent = new Intent(context, ImageSelectActivity.class); 156 });
151 intent.putExtra("rect", rect); 157 }
152 intent.putExtra("path", imageBean.getPath()); 158 } else {
153 intent.putExtra("position", finalI); 159 holder.binding.rlPic.removeAllViews();
154 context.startActivityForResult(intent, 1001); 160 }
155 } 161 }
156 }); 162
157 } 163 @Override
158 } else { 164 public int getItemCount() {
159 holder.binding.rlPic.removeAllViews(); 165 return list.size();
160 } 166 }
161 } 167
162 168 static class ImageHolder extends RecyclerView.ViewHolder {
163 @Override 169 ItemImageBinding binding;
164 public int getItemCount() { 170
165 return list.size(); 171 public ImageHolder(@NonNull ItemImageBinding itemView) {
166 } 172 super(itemView.getRoot());
167 173 binding = itemView;
168 static class ImageHolder extends RecyclerView.ViewHolder { 174 }
169 ItemImageBinding binding; 175 }
170 176 }
171 public ImageHolder(@NonNull ItemImageBinding itemView) { 177
app/src/main/java/com/hjx/parent/api/ChatApi.java
File was created 1 package com.hjx.parent.api;
2
3 import io.reactivex.Single;
4 import retrofit2.http.Body;
5 import retrofit2.http.Header;
6 import retrofit2.http.POST;
7 import retrofit2.http.Url;
8
9 public interface ChatApi {
10 @POST
11 Single<ChatResponse> aiChat(
12 @Url String url,
13 @Header("Authorization") String token,
14 @Body ChatRequest body
15 );
16
17 }
1 package com.hjx.parent.api; 18
app/src/main/java/com/hjx/parent/api/ChatChoices.java
File was created 1 package com.hjx.parent.api;
2
3 import com.google.gson.annotations.SerializedName;
4
5 public class ChatChoices {
6
7 public ChatMessage message;
8 public int index;
9 @SerializedName("finish_reason")
10 public String finishReason;
11 public String logprobs;
12
13 }
1 package com.hjx.parent.api; 14
app/src/main/java/com/hjx/parent/api/ChatError.java
File was created 1 package com.hjx.parent.api;
2
3 public class ChatError {
4 String code;
5 String message;
6 String param;
7 String type;
8 }
1 package com.hjx.parent.api; 9
app/src/main/java/com/hjx/parent/api/ChatMessage.java
File was created 1 package com.hjx.parent.api;
2
3 import java.util.ArrayList;
4 import java.util.List;
5 import java.util.Objects;
6
7 public class ChatMessage {
8 public ChatMessage() {
9 }
10 public ChatMessage(String role, Object content) {
11 this.role = role;
12 this.content = content;
13 }
14
15 public String role;
16 public Object content;
17
18 public static ChatMessage fromImage(String role, String text, String... urls) {
19 List<ContentItem> items = new ArrayList<>();
20 if (text != null && !text.isEmpty()) {
21 items.add(new ContentItem(ContentItem.TYPE_TEXT, text));
22 }
23 for (String it: urls) {
24 ContentItem.ContentImage image = new ContentItem.ContentImage(it);
25 items.add(new ContentItem(ContentItem.TYPE_IMAGE, image));
26 }
27 return new ChatMessage(role, items);
28 }
29
30 public String getTextContent() {
31 if (content == null) return null;
32 if (content instanceof String) return (String) content;
33 ContentItem item = firstText();
34 return item == null ? null : item.text;
35 }
36
37 private ContentItem firstText() {
38 if (!(content instanceof List<?>)) return null;
39 List<?> anyList = (List<?>) content;
40 return anyList.stream()
41 .map(ContentItem::reSerialize)
42 .filter(Objects::nonNull)
43 .findFirst().orElse(null);
44 }
45 }
1 package com.hjx.parent.api; 46
app/src/main/java/com/hjx/parent/api/ChatRequest.java
File was created 1 package com.hjx.parent.api;
2
3 import java.util.List;
4
5 public class ChatRequest {
6 public String model;
7 public List<ChatMessage> messages;
8 public boolean stream;
9
10 public ChatRequest(String model, List<ChatMessage> messages) {
11 this.model = model;
12 this.messages = messages;
13 this.stream = false;
14 }
15 }
1 package com.hjx.parent.api; 16
app/src/main/java/com/hjx/parent/api/ChatResponse.java
File was created 1 package com.hjx.parent.api;
2
3 import com.google.gson.annotations.SerializedName;
4
5 import java.util.List;
6
7 public class ChatResponse {
8 public List<ChatChoices> choices;
9 public String created;
10 public String id;
11 public String model;
12 @SerializedName("service_tier")
13 public String serviceTier;
14 @SerializedName("object")
15 public String obj;
16 public ChatUsage usage;
17
18 public ChatError error;
19 }
1 package com.hjx.parent.api; 20
app/src/main/java/com/hjx/parent/api/ChatUsage.java
File was created 1 package com.hjx.parent.api;
2
3 import com.google.gson.annotations.SerializedName;
4
5 public class ChatUsage {
6 @SerializedName("completion_tokens")
7 public int completionTokens;
8 @SerializedName("prompt_tokens")
9 public int promptTokens;
10 @SerializedName("total_tokens")
11 public int totalTokens;
12 @SerializedName("prompt_tokens_details")
13 public PromptTokensDetails promptTokensDetails;
14 @SerializedName("completion_tokens_details")
15 public CompletionTokensDetails completionTokensDetails;
16 }
1 package com.hjx.parent.api; 17
app/src/main/java/com/hjx/parent/api/CompletionTokensDetails.java
File was created 1 package com.hjx.parent.api;
2
3 public class CompletionTokensDetails {
4 public int reasoningTokens;
5 }
1 package com.hjx.parent.api; 6
app/src/main/java/com/hjx/parent/api/ContentItem.java
File was created 1 package com.hjx.parent.api;
2
3 import com.google.gson.Gson;
4 import com.google.gson.annotations.SerializedName;
5
6 public class ContentItem {
7 public static final String TYPE_TEXT = "text";
8 public static final String TYPE_IMAGE = "image_url";
9
10
11 public ContentItem() {
12 }
13 public ContentItem(String type, String text) {
14 this.type = type;
15 this.text = text;
16 }
17 public ContentItem(String type, ContentImage imageUrl) {
18 this.type = type;
19 this.imageUrl = imageUrl;
20 }
21
22 public String type;
23 public String text;
24 @SerializedName("image_url")
25 public ContentImage imageUrl;
26
27 public static class ContentImage {
28 public ContentImage(String url) {
29 this.url = url;
30 }
31
32 public String url;
33 }
34
35
36 private static final Gson gson = new Gson();
37 static ContentItem reSerialize(Object any) {
38 if (any == null) return null;
39 try {
40 String json = gson.toJson(any);
41 ContentItem it = gson.fromJson(json, ContentItem.class);
42 return it;
43 } catch (Throwable t) {
44 t.printStackTrace();
45 }
46 return null;
47 }
48 }
1 package com.hjx.parent.api; 49
app/src/main/java/com/hjx/parent/api/JudgeRepository.java
File was created 1 package com.hjx.parent.api;
2
3 import android.annotation.SuppressLint;
4
5 import com.google.gson.Gson;
6 import com.prws.common.net.NetWorks;
7
8 import java.util.ArrayList;
9 import java.util.List;
10
11 import io.reactivex.Single;
12 import retrofit2.Retrofit;
13
14 public class JudgeRepository {
15 private static final Gson gson = new Gson();
16 private static final ChatApi api;
17 static {
18 Retrofit retrofit = NetWorks.retrofit;
19 api = retrofit.create(ChatApi.class);
20 }
21
22
23 public static Single<Integer> singleJudge(String url) {
24 List<ChatMessage> messages = new ArrayList<>();
25 messages.add(ChatMessage.fromImage("system", setting, url));
26
27 return api.aiChat(JudgeRepository.url, token, new ChatRequest(model, messages))
28 .map(response -> {
29 if (response.choices == null) return null;
30 return response.choices.stream().findFirst()
31 .map(it -> it.message)
32 .map(ChatMessage::getTextContent)
33 .orElse(null);
34 })
35 .map(json -> {
36 JudgeResult result = gson.fromJson(json, JudgeResult.class);
37 return result.result;
38 })
39 ;
40 }
41
42
43 private static final String model = "doubao-1-5-thinking-vision-pro-250428";
44 private static final String url = "https://ark.cn-beijing.volces.com/api/v3/chat/completions";
45 private static final String token = "Bearer a877087e-bb74-471b-8f2a-01e6b2220699";
46 private static final String setting =
47 "批改图片中的题目, 判断作答是否正确,并以Json格式返回结果,需要包含以下字段: \n" +
48 "result(批改结果, 枚举 0:不确定; 1:正确; 2:错误; 3:未作答).\n" +
49 "Json示例(供参考,无需复制): {\"result\": 1}\n" +
50 "一个图片中一般只会有一个题目, 返回一个结果即可.";
51
52 private static class JudgeResult {
53 public int result;
54 }
55 }
1 package com.hjx.parent.api; 56
app/src/main/java/com/hjx/parent/api/PromptTokensDetails.java
File was created 1 package com.hjx.parent.api;
2
3 public class PromptTokensDetails {
4 public int cachedTokens;
5 }
1 package com.hjx.parent.api; 6
app/src/main/java/com/hjx/parent/utils/CutUtil.java
File was created 1 package com.hjx.parent.utils;
2
3 import android.content.Context;
4 import android.graphics.Bitmap;
5 import android.graphics.Canvas;
6 import android.graphics.Color;
7 import android.graphics.Paint;
8 import android.util.Base64;
9 import android.view.View;
10 import android.view.ViewTreeObserver;
11
12 import com.bumptech.glide.Glide;
13 import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool;
14 import com.hjx.parent.function.Function1;
15
16 import java.io.ByteArrayOutputStream;
17 import java.io.File;
18 import java.io.IOException;
19 import java.util.List;
20
21 import top.zibin.luban.Luban;
22
23 public class CutUtil {
24
25 public static float[] measureBitmap(View view, Bitmap bitmap) {
26 float realW;
27 float realH;
28 float offsetX;
29 float offsetY;
30
31 float vp = 1f * view.getWidth() / view.getHeight();
32 float bp = 1f * bitmap.getWidth() / bitmap.getHeight();
33
34 if (vp > bp) {
35 realW = view.getHeight() * bp;
36 realH = (float) view.getHeight();
37 offsetY = 0f;
38 offsetX = (view.getWidth() - realW) * 0.5f;
39 } else if (vp < bp) {
40 realW = (float) view.getWidth();
41 realH = view.getWidth() * (1f / bp);
42 offsetX = 0f;
43 offsetY = (view.getHeight() - realH) * 0.5f;
44 } else {
45 realW = (float) view.getWidth();
46 realH = (float) view.getHeight();
47 offsetX = 0f;
48 offsetY = 0f;
49 }
50
51 return new float[]{realW, realH, offsetX, offsetY};
52 }
53
54 public static Bitmap cut(Bitmap source, float x, float y, int w, int h, Context context) {
55 // 获取 Glide 的 BitmapPool
56 BitmapPool bitmapPool = Glide.get(context).getBitmapPool();
57
58 // 从 BitmapPool 中获取可复用的 Bitmap
59 Bitmap result = bitmapPool.get(w, h, source.getConfig() != null ? source.getConfig() : Bitmap.Config.ARGB_8888);
60
61 // 填充白色背景
62 result.eraseColor(Color.WHITE);
63
64 // 创建画布并绘制
65 Canvas canvas = new Canvas(result);
66 Paint paint = new Paint();
67 canvas.drawBitmap(source, -x, -y, paint);
68
69 return result;
70 }
71
72 public static void onLayoutReady(final View view, final Function1<View> action) {
73 view.getViewTreeObserver().addOnGlobalLayoutListener(
74 new ViewTreeObserver.OnGlobalLayoutListener() {
75 @Override
76 public void onGlobalLayout() {
77 view.getViewTreeObserver().removeOnGlobalLayoutListener(this);
78 action.invoke(view);
79 }
80 }
81 );
82 }
83
84 public static byte[] bitmapToByteArray(Bitmap bitmap) {
85 ByteArrayOutputStream output = new ByteArrayOutputStream();
86 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, output);
87 return output.toByteArray();
88 }
89
90 public static String bitmapToBase64(Bitmap bitmap, Boolean usePrefix) {
91 String base64 = Base64.encodeToString(bitmapToByteArray(bitmap), Base64.NO_WRAP);
92 if (usePrefix) return "data:image/jpeg;base64," + base64;
93 else return base64;
94 }
95
96 public static List<File> compressAllSync(Context context, List<String> originList, int ignore) throws IOException {
97 return Luban.with(context).ignoreBy(ignore)
98 .setTargetDir(context.getExternalCacheDir().getAbsolutePath())
99 .load(originList)
100 .get();
101 }
102 }
1 package com.hjx.parent.utils; 103
app/src/main/res/drawable/bg_judge_cut.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:state_selected="true">
4 <shape>
5 <solid android:color="#1A1C90F3"/>
6 <stroke android:color="#1C90F3" android:width="1px"/>
7 </shape>
8 </item>
9 <item>
10 <shape>
11 <solid android:color="#33000000"/>
12 <stroke android:color="#666666" android:width="1px"/>
13 </shape>
14 </item>
15 </selector>
app/src/main/res/drawable/check_circle_12.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:width="12dp" android:height="12dp">
4 <selector>
5 <item android:state_checked="true"
6 android:drawable="@drawable/png_ic_check_circle"/>
7 <item>
8 <shape>
9 <corners android:radius="20dp"/>
10 <stroke android:width="1.5dp" android:color="#333"/>
11 </shape>
12 </item>
13 </selector>
14 </item>
15 </layer-list>
app/src/main/res/drawable/ic_add.png

1.12 KB

app/src/main/res/drawable/ic_judge_rect_select.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <selector xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:drawable="@drawable/png_rect_selected" android:state_selected="true"/>
4 <item android:drawable="@drawable/png_rect_add"/>
5 </selector>
app/src/main/res/drawable/ic_rect_20.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <layer-list xmlns:android="http://schemas.android.com/apk/res/android">
3 <item android:drawable="@drawable/png_ic_rect"
4 android:width="20dp" android:height="20dp"/>
5 </layer-list>
app/src/main/res/drawable/png_ic_check_circle.png

1.05 KB

app/src/main/res/drawable/png_ic_judge_correct.png

1.09 KB

app/src/main/res/drawable/png_ic_judge_wrong.png

1.12 KB

app/src/main/res/drawable/png_ic_rect.png

1.72 KB

app/src/main/res/drawable/png_rect_add.png

1.12 KB

app/src/main/res/drawable/png_rect_selected.png

902 Bytes

app/src/main/res/layout/activity_image.xml
1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" 1 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
2 xmlns:tools="http://schemas.android.com/tools"
2 xmlns:tools="http://schemas.android.com/tools" 3 android:layout_width="match_parent"
3 android:layout_width="match_parent" 4 android:layout_height="match_parent"
4 android:layout_height="match_parent" 5 xmlns:app="http://schemas.android.com/apk/res-auto"
6 android:orientation="vertical"
7 tools:ignore="HardcodedText">
5 xmlns:app="http://schemas.android.com/apk/res-auto" 8
6 android:orientation="vertical" 9 <RelativeLayout
7 tools:ignore="HardcodedText"> 10 android:layout_width="match_parent"
8 11 android:layout_height="40dp"
9 <RelativeLayout 12 android:background="@color/white">
10 android:layout_width="match_parent" 13
11 android:layout_height="40dp" 14 <TextView
12 android:background="@color/white"> 15 android:id="@+id/tv_title"
13 16 android:layout_width="wrap_content"
14 <TextView 17 android:layout_height="wrap_content"
15 android:id="@+id/tv_title" 18 android:layout_centerInParent="true"
16 android:layout_width="wrap_content" 19 android:textColor="#333333"
17 android:layout_height="wrap_content" 20 android:textSize="18sp" />
18 android:layout_centerInParent="true" 21
19 android:textColor="#333333" 22 <ImageView
20 android:textSize="18sp" /> 23 android:id="@+id/iv_back"
21 24 android:layout_width="30dp"
22 <ImageView 25 android:layout_height="36dp"
23 android:id="@+id/iv_back" 26 android:layout_centerVertical="true"
24 android:layout_width="30dp" 27 android:layout_marginLeft="5dp"
25 android:layout_height="36dp" 28 android:padding="10dp"
26 android:layout_centerVertical="true" 29 android:src="@mipmap/icon_back" />
27 android:layout_marginLeft="5dp" 30
28 android:padding="10dp" 31 <TextView
29 android:src="@mipmap/icon_back" /> 32 android:id="@+id/tv_photo"
30 33 android:layout_width="wrap_content"
31 <TextView 34 android:layout_height="wrap_content"
32 android:id="@+id/tv_photo" 35 android:layout_centerVertical="true"
33 android:layout_width="wrap_content" 36 android:layout_toRightOf="@+id/iv_back"
34 android:layout_height="wrap_content" 37 android:text="重拍"
35 android:layout_centerVertical="true" 38 android:textColor="#333333"
36 android:layout_toRightOf="@+id/iv_back" 39 android:textSize="14sp" />
37 android:text="重拍" 40
38 android:textColor="#333333" 41 <TextView
39 android:textSize="14sp" /> 42 android:id="@+id/btnShowSource"
40 43 android:layout_width="wrap_content"
41 <TextView 44 android:layout_height="wrap_content"
42 android:id="@+id/btnShowSource" 45 android:layout_alignParentRight="true"
43 android:layout_width="wrap_content" 46 android:layout_centerVertical="true"
44 android:layout_height="wrap_content" 47 android:layout_marginRight="15dp"
45 android:layout_alignParentRight="true" 48 android:text="查看原图"
46 android:layout_centerVertical="true" 49 android:textColor="#333333"
47 android:layout_marginRight="15dp" 50 android:textSize="14sp" />
48 android:text="查看原图" 51 </RelativeLayout>
49 android:textColor="#333333" 52
50 android:textSize="14sp" /> 53 <TextView
51 </RelativeLayout> 54 android:layout_width="match_parent"
52 55 android:layout_height="35dp"
53 <TextView 56 android:background="#C7DFF5"
54 android:layout_width="match_parent" 57 android:gravity="center"
55 android:layout_height="35dp" 58 android:text="已为您自动框选题目,点击“+”添加题目"
56 android:background="#C7DFF5" 59 android:textColor="#1C90F3"
57 android:gravity="center" 60 android:textSize="13sp" />
58 android:text="已为您自动框选题目,点击“+”添加题目" 61
59 android:textColor="#1C90F3" 62 <RelativeLayout
60 android:textSize="13sp" /> 63 android:layout_width="match_parent"
61 64 android:layout_height="match_parent"
62 <RelativeLayout 65 android:background="#F8F8F8">
63 android:layout_width="match_parent" 66
64 android:layout_height="match_parent" 67 <androidx.viewpager2.widget.ViewPager2
65 android:background="#F8F8F8"> 68 android:id="@+id/viewPager"
66 69 android:layout_width="match_parent"
67 <androidx.viewpager2.widget.ViewPager2 70 android:layout_height="match_parent"
68 android:id="@+id/viewPager" 71 android:layout_above="@+id/rl_previous" />
69 android:layout_width="match_parent" 72
70 android:layout_height="match_parent" 73 <RelativeLayout
71 android:layout_above="@+id/rl_previous" /> 74 android:id="@+id/rl_previous"
72 75 android:layout_width="30dp"
73 <RelativeLayout 76 android:layout_height="30dp"
74 android:id="@+id/rl_previous" 77 android:layout_above="@+id/rl_bottom"
75 android:layout_width="30dp" 78 android:layout_marginLeft="15dp"
76 android:layout_height="30dp" 79 android:layout_marginBottom="15dp"
77 android:layout_above="@+id/rl_bottom" 80 android:background="@drawable/bg_solid_white">
78 android:layout_marginLeft="15dp" 81
79 android:layout_marginBottom="15dp" 82 <ImageView
80 android:background="@drawable/bg_solid_white"> 83 android:id="@+id/iv_previous"
81 84 android:layout_width="10dp"
82 <ImageView 85 android:layout_height="18dp"
83 android:id="@+id/iv_previous" 86 android:layout_centerInParent="true"
84 android:layout_width="10dp" 87 android:src="@mipmap/ic_previous_gray" />
85 android:layout_height="18dp" 88 </RelativeLayout>
86 android:layout_centerInParent="true" 89
87 android:src="@mipmap/ic_previous_gray" /> 90 <RelativeLayout
88 </RelativeLayout> 91 android:id="@+id/rl_next"
89 92 android:layout_width="30dp"
90 <RelativeLayout 93 android:layout_height="30dp"
91 android:id="@+id/rl_next" 94 android:layout_above="@+id/rl_bottom"
92 android:layout_width="30dp" 95 android:layout_alignParentRight="true"
93 android:layout_height="30dp" 96 android:layout_marginRight="15dp"
94 android:layout_above="@+id/rl_bottom" 97 android:layout_marginBottom="15dp"
95 android:layout_alignParentRight="true" 98 android:background="@drawable/bg_solid_white">
96 android:layout_marginRight="15dp" 99
97 android:layout_marginBottom="15dp" 100 <ImageView
98 android:background="@drawable/bg_solid_white"> 101 android:id="@+id/iv_next"
99 102 android:layout_width="10dp"
100 <ImageView 103 android:layout_height="18dp"
101 android:id="@+id/iv_next" 104 android:layout_centerInParent="true"
102 android:layout_width="10dp" 105 android:src="@mipmap/ic_next_gray" />
103 android:layout_height="18dp" 106 </RelativeLayout>
104 android:layout_centerInParent="true" 107
105 android:src="@mipmap/ic_next_gray" /> 108 <LinearLayout
106 </RelativeLayout> 109 android:id="@+id/rl_bottom"
110 android:orientation="horizontal"
111 android:gravity="center_vertical"
107 112 android:layout_width="match_parent"
108 <LinearLayout 113 android:layout_height="70dp"
109 android:id="@+id/rl_bottom" 114 android:layout_alignParentBottom="true"
110 android:orientation="horizontal" 115 android:background="@color/white">
111 android:gravity="center_vertical" 116
112 android:layout_width="match_parent" 117 <LinearLayout
113 android:layout_height="70dp" 118 android:id="@+id/ll_edit"
114 android:layout_alignParentBottom="true" 119 android:layout_width="wrap_content"
115 android:background="@color/white"> 120 android:layout_height="wrap_content"
116 121 android:layout_marginStart="15dp"
117 <LinearLayout
118 android:id="@+id/ll_edit" 122 android:orientation="vertical">
119 android:layout_width="wrap_content" 123
120 android:layout_height="wrap_content" 124 <ImageView
121 android:layout_marginStart="15dp" 125 android:layout_width="20dp"
122 android:orientation="vertical"> 126 android:layout_height="20dp"
123 127 android:layout_gravity="center_horizontal"
124 <ImageView 128 android:src="@mipmap/ic_pic_edit" />
125 android:layout_width="20dp" 129
126 android:layout_height="20dp" 130 <TextView
127 android:layout_gravity="center_horizontal" 131 android:layout_width="wrap_content"
128 android:src="@mipmap/ic_pic_edit" /> 132 android:layout_height="wrap_content"
129 133 android:layout_marginTop="5dp"
130 <TextView 134 android:text="图片编辑"
135 android:textColor="#333"
131 android:layout_width="wrap_content" 136 android:textSize="11sp" />
132 android:layout_height="wrap_content" 137 </LinearLayout>
133 android:layout_marginTop="5dp" 138
134 android:text="图片编辑" 139 <androidx.appcompat.widget.AppCompatTextView
135 android:textColor="#333" 140 android:id="@+id/tv_add"
136 android:textSize="11sp" /> 141 android:text="手动框选"
137 </LinearLayout> 142 android:textSize="11sp"
138 143 android:textColor="#333"
139 <androidx.appcompat.widget.AppCompatTextView 144 android:gravity="center_horizontal"
140 android:id="@+id/tv_add" 145 android:drawableTop="@drawable/ic_rect_20"
146 android:drawablePadding="5dp"
147 android:layout_marginStart="12dp"
148 android:layout_width="wrap_content"
149 android:layout_height="wrap_content" />
150
151 <Space style="@style/empty_space"/>
152
153 <TextView
154 android:id="@+id/btnJudge"
155 android:layout_width="112dp"
156 android:layout_height="36dp"
141 android:text="手动框选" 157 android:background="@drawable/bg_soild_orange_5"
142 android:textSize="11sp" 158 android:gravity="center"
143 android:textColor="#333" 159 android:text="去批改"
144 android:gravity="center_horizontal" 160 android:textColor="@color/white"
145 android:drawableTop="@drawable/ic_rect_20" 161 android:textSize="16sp" />
146 android:drawablePadding="5dp" 162
147 android:layout_marginStart="12dp" 163 <TextView
148 android:layout_width="wrap_content" 164 android:id="@+id/tv_save"
149 android:layout_height="wrap_content" /> 165 android:layout_width="112dp"
150 166 android:layout_height="36dp"
151 <Space style="@style/empty_space"/> 167 android:layout_marginHorizontal="15dp"
152
153 <TextView
154 android:id="@+id/btnJudge" 168 android:background="@drawable/bg_soild_blue_light_5"
155 android:layout_width="112dp" 169 android:enabled="false"
156 android:layout_height="36dp" 170 android:gravity="center"
157 android:background="@drawable/bg_soild_orange_5" 171 android:text="保存错题"
158 android:gravity="center" 172 android:textColor="@color/white"
159 android:text="去批改" 173 android:textSize="16sp" />
app/src/main/res/layout/activity_judge.xml
File was created 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:orientation="vertical"
6 android:layout_width="match_parent"
7 android:layout_height="match_parent"
8 tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription">
9
10 <androidx.appcompat.widget.Toolbar
11 android:background="@color/white"
12 app:contentInsetStart="0dp"
13 android:layout_width="match_parent"
14 android:layout_height="40dp">
15 <ImageView
16 android:id="@+id/ivBack"
17 android:layout_width="30dp"
18 android:layout_height="36dp"
19 android:layout_centerVertical="true"
20 android:layout_marginStart="5dp"
21 android:padding="10dp"
22 android:src="@mipmap/icon_back" />
23 </androidx.appcompat.widget.Toolbar>
24
25 <FrameLayout
26 android:background="@color/white"
27 android:padding="8dp"
28 android:layout_margin="16dp"
29 android:layout_width="match_parent"
30 android:layout_height="0px"
31 android:layout_weight="1">
32 <ImageView
33 android:id="@+id/ivPic"
34 android:layout_width="match_parent"
35 android:layout_height="match_parent"/>
36 <FrameLayout
37 android:id="@+id/flRects"
38 android:layout_width="match_parent"
39 android:layout_height="match_parent" />
40 </FrameLayout>
41
42 <LinearLayout
43 android:orientation="horizontal"
44 android:gravity="center_vertical"
45 android:paddingHorizontal="16dp"
46 android:background="@color/white"
47 android:layout_width="match_parent"
48 android:layout_height="64dp">
49 <androidx.appcompat.widget.AppCompatTextView
50 android:id="@+id/btnSelectAll"
51 android:text="全选"
52 android:textSize="16sp"
53 android:textColor="#333"
54 android:gravity="center_vertical"
55 android:paddingHorizontal="8dp"
56 android:paddingVertical="4dp"
57 android:layout_width="wrap_content"
58 android:layout_height="wrap_content"/>
59
60 <Space style="@style/empty_space"/>
61 <TextView
62 android:id="@+id/btnAdd"
63 android:text="加入错题"
64 android:textSize="16sp"
65 android:textColor="@color/white"
66 android:gravity="center"
67 android:background="@drawable/shape_radius_5"
68 android:backgroundTint="#1C90F3"
69 android:layout_width="112dp"
70 android:layout_height="36dp"/>
71 </LinearLayout>
72
73 </LinearLayout>
app/src/main/res/layout/layout_judge_rect.xml
File was created 1 <?xml version="1.0" encoding="utf-8"?>
2 <FrameLayout 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:orientation="vertical"
6 android:background="@drawable/bg_judge_cut"
7 android:minWidth="160dp"
8 android:minHeight="48dp"
9 android:layout_width="wrap_content"
10 android:layout_height="wrap_content"
11 tools:ignore="UseCompoundDrawables,HardcodedText,SmallSp,ContentDescription">
12
13 <ImageView
14 android:id="@+id/ivResult"
15 tools:src="@drawable/png_ic_judge_correct"
16 android:layout_gravity="end"
17 android:layout_margin="8dp"
18 android:layout_width="12dp"
19 android:layout_height="12dp"/>
20
21 <ImageView
22 android:src="@drawable/ic_judge_rect_select"
23 android:layout_gravity="center"
24 android:layout_width="12dp"
25 android:layout_height="12dp"/>
26
27 </FrameLayout>
libs/common/build.gradle
1 apply plugin: 'com.android.library' 1 apply plugin: 'com.android.library'
2 2
3 3
4 def androidId = rootProject.ext.androidId 4 def androidId = rootProject.ext.androidId
5 def support = rootProject.ext.dependencies 5 def support = rootProject.ext.dependencies
6 def url = rootProject.ext.url 6 def url = rootProject.ext.url
7 7
8 8
9 android { 9 android {
10 compileSdkVersion androidId.compileSdkVersion 10 compileSdkVersion androidId.compileSdkVersion
11 11
12 12
13 defaultConfig { 13 defaultConfig {
14 minSdkVersion androidId.minSdkVersion 14 minSdkVersion androidId.minSdkVersion
15 targetSdkVersion androidId.targetSdkVersion 15 targetSdkVersion androidId.targetSdkVersion
16 versionCode androidId.versionCode 16 versionCode androidId.versionCode
17 versionName androidId.versionName 17 versionName androidId.versionName
18 18
19 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" 19 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
20 20
21 buildConfigField("String", "APIKey1", "\"eCa3YzEjTBBiNjlXcNnjnldP\"") 21 buildConfigField("String", "APIKey", "\"oj9XT8AOeTeLkdqaEX7RJA0N\"")
22 buildConfigField("String", "SecretKey1", "\"KnZPmjF0ZzmxWV964mzmm6yuDljnETLt\"") 22 buildConfigField("String", "SecretKey", "\"AfUFmACkfbd0RMuk11qbw1TW5LtxtJHK\"")
23 buildConfigField("String", "APIKey1", "\"oj9XT8AOeTeLkdqaEX7RJA0N\"")
24 buildConfigField("String", "SecretKey1", "\"AfUFmACkfbd0RMuk11qbw1TW5LtxtJHK\"")
23 } 25 }
24 26
25 buildTypes { 27 buildTypes {
26 debug { 28 debug {
27 minifyEnabled false 29 minifyEnabled false
28 buildConfigField("String", "SERVER_URL", "\"${url.server_url}\"") 30 buildConfigField("String", "SERVER_URL", "\"${url.server_url}\"")
29 buildConfigField("String", "APIKey", "\"OmmSqorNFXjVHXlZWhHAyGyQ\"")
30 buildConfigField("String", "SecretKey", "\"Uwjz4XGi89RN4Mvl5mievKpjqpGgUy6D\"")
31 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 31 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
32 } 32 }
33 release { 33 release {
34 minifyEnabled false 34 minifyEnabled false
35 buildConfigField("String", "SERVER_URL", "\"${url.server_url_online}\"") 35 buildConfigField("String", "SERVER_URL", "\"${url.server_url_online}\"")
36 buildConfigField("String", "APIKey", "\"OmmSqorNFXjVHXlZWhHAyGyQ\"")
37 buildConfigField("String", "SecretKey", "\"Uwjz4XGi89RN4Mvl5mievKpjqpGgUy6D\"")
38 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' 36 proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
39 } 37 }
40 } 38 }
41 39
42 compileOptions { 40 compileOptions {
43 sourceCompatibility JavaVersion.VERSION_1_8 41 sourceCompatibility JavaVersion.VERSION_1_8
44 targetCompatibility JavaVersion.VERSION_1_8 42 targetCompatibility JavaVersion.VERSION_1_8
45 } 43 }
46 } 44 }
47 45
48 dependencies { 46 dependencies {
49 implementation fileTree(include: ['*.jar'], dir: 'libs') 47 implementation fileTree(include: ['*.jar'], dir: 'libs')
50 48
51 49
52 support.each { k, v -> implementation v } 50 support.each { k, v -> implementation v }
53 51
54 // 抓包, OkHttp拦截 52 // 抓包, OkHttp拦截
55 def chuckerVersion = "3.5.2" 53 def chuckerVersion = "3.5.2"
56 debugImplementation("com.github.chuckerteam.chucker:library:$chuckerVersion") { 54 debugImplementation("com.github.chuckerteam.chucker:library:$chuckerVersion") {
57 exclude module: 'lifecycle-viewmodel-ktx' 55 exclude module: 'lifecycle-viewmodel-ktx'
58 } 56 }
59 releaseImplementation("com.github.chuckerteam.chucker:library-no-op:$chuckerVersion") { 57 releaseImplementation("com.github.chuckerteam.chucker:library-no-op:$chuckerVersion") {
60 exclude module: 'lifecycle-viewmodel-ktx' 58 exclude module: 'lifecycle-viewmodel-ktx'
61 } 59 }
62 60
63 implementation 'com.jakewharton:butterknife:10.2.3' 61 implementation 'com.jakewharton:butterknife:10.2.3'
libs/common/src/main/java/com/prws/common/net/NetWorks.java
1 package com.prws.common.net; 1 package com.prws.common.net;
2 2
3 3
4 import com.google.gson.Gson; 4 import com.google.gson.Gson;
5 import com.google.gson.JsonObject; 5 import com.google.gson.JsonObject;
6 import com.prws.common.BuildConfig; 6 import com.prws.common.BuildConfig;
7 import com.prws.common.bean.CutPicBean; 7 import com.prws.common.bean.CutPicBean;
8 import com.prws.common.bean.GradeAndSubject; 8 import com.prws.common.bean.GradeAndSubject;
9 import com.prws.common.bean.PageInfo; 9 import com.prws.common.bean.PageInfo;
10 import com.prws.common.bean.ResponseResult; 10 import com.prws.common.bean.ResponseResult;
11 import com.prws.common.bean.ScheduleBean; 11 import com.prws.common.bean.ScheduleBean;
12 import com.prws.common.bean.Student; 12 import com.prws.common.bean.Student;
13 import com.prws.common.bean.Teacher; 13 import com.prws.common.bean.Teacher;
14 import com.prws.common.bean.TopicBean; 14 import com.prws.common.bean.TopicBean;
15 import com.prws.common.bean.UpdateBean; 15 import com.prws.common.bean.UpdateBean;
16 import com.prws.common.bean.User; 16 import com.prws.common.bean.User;
17 import com.prws.common.bean.baidu.BaiduInput; 17 import com.prws.common.bean.baidu.BaiduInput;
18 import com.prws.common.bean.homework.HomeWork; 18 import com.prws.common.bean.homework.HomeWork;
19 import com.prws.common.bean.homework.HomeworkDetail; 19 import com.prws.common.bean.homework.HomeworkDetail;
20 import com.prws.common.bean.homework.HomeworkList; 20 import com.prws.common.bean.homework.HomeworkList;
21 import com.prws.common.bean.homework.StDetail; 21 import com.prws.common.bean.homework.StDetail;
22 import com.prws.common.utils.BitmapUtils; 22 import com.prws.common.utils.BitmapUtils;
23 import com.prws.common.utils.SharedPreferencesUtil; 23 import com.prws.common.utils.SharedPreferencesUtil;
24 24
25 import java.io.File; 25 import java.io.File;
26 import java.util.HashMap; 26 import java.util.HashMap;
27 import java.util.LinkedHashMap;
27 import java.util.List; 28 import java.util.List;
28 import java.util.Map; 29 import java.util.Map;
29 30
30 import io.reactivex.Observable; 31 import io.reactivex.Observable;
31 import io.reactivex.Observer; 32 import io.reactivex.Observer;
32 import io.reactivex.Single; 33 import io.reactivex.Single;
33 import io.reactivex.android.schedulers.AndroidSchedulers; 34 import io.reactivex.android.schedulers.AndroidSchedulers;
34 import io.reactivex.schedulers.Schedulers; 35 import io.reactivex.schedulers.Schedulers;
35 import okhttp3.MediaType; 36 import okhttp3.MediaType;
36 import okhttp3.MultipartBody; 37 import okhttp3.MultipartBody;
37 import okhttp3.RequestBody; 38 import okhttp3.RequestBody;
38 import okhttp3.ResponseBody; 39 import okhttp3.ResponseBody;
39 import retrofit2.Call; 40 import retrofit2.Call;
40 import retrofit2.Callback; 41 import retrofit2.Callback;
42 import retrofit2.Retrofit;
41 import retrofit2.Retrofit; 43 import retrofit2.http.Body;
42 import retrofit2.http.Body; 44 import retrofit2.http.GET;
43 import retrofit2.http.GET; 45 import retrofit2.http.Header;
44 import retrofit2.http.Header; 46 import retrofit2.http.Headers;
45 import retrofit2.http.Headers; 47 import retrofit2.http.Multipart;
46 import retrofit2.http.Multipart; 48 import retrofit2.http.POST;
47 import retrofit2.http.POST; 49 import retrofit2.http.PUT;
48 import retrofit2.http.PUT; 50 import retrofit2.http.Part;
49 import retrofit2.http.Part; 51 import retrofit2.http.PartMap;
50 import retrofit2.http.PartMap; 52 import retrofit2.http.Query;
51 import retrofit2.http.Query; 53 import retrofit2.http.Url;
52 import retrofit2.http.Url; 54
53 55 /**
54 /** 56 * 类名称:NetWorks
55 * 类名称:NetWorks 57 * 创建人:
56 * 创建人: 58 * <p>
57 * <p> 59 * 类描述:网络请求的操作类
58 * 类描述:网络请求的操作类 60 */
59 */ 61 public class NetWorks extends RetrofitUtils {
60 public class NetWorks extends RetrofitUtils { 62 //服务器路径
61 //服务器路径 63 public static final Retrofit retrofit = getMachineRetrofit(BuildConfig.SERVER_URL);
64 public static final NetService service_url = retrofit.create(NetService.class);
62 public static final Retrofit retrofit = getMachineRetrofit(BuildConfig.SERVER_URL); 65
63 public static final NetService service_url = retrofit.create(NetService.class); 66 //设缓存有效期为1天
64 67 protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1;
65 //设缓存有效期为1天 68 //查询缓存的Cache-Control设置,使用缓存
66 protected static final long CACHE_STALE_SEC = 60 * 60 * 24 * 1; 69 protected static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC;
67 //查询缓存的Cache-Control设置,使用缓存 70 //查询网络的Cache-Control设置。不使用缓存
68 protected static final String CACHE_CONTROL_CACHE = "only-if-cached, max-stale=" + CACHE_STALE_SEC; 71 protected static final String CACHE_CONTROL_NETWORK = "max-age=0";
69 //查询网络的Cache-Control设置。不使用缓存 72
70 protected static final String CACHE_CONTROL_NETWORK = "max-age=0"; 73
71 74 public interface NetService {
72 75
73 public interface NetService { 76
74 77 @GET("/api/v1/user/logout")
75 78 Observable<ResponseBody> logout();
76 @GET("/api/v1/user/logout") 79
77 Observable<ResponseBody> logout(); 80 @Multipart
78 81 @POST("/api/v1/user/upLoadAvatar")
79 @Multipart 82 Observable<ResponseBody> upLoadAvatar(@Header("Authorization") String token, @Part List<MultipartBody.Part> partLis);
80 @POST("/api/v1/user/upLoadAvatar") 83
81 Observable<ResponseBody> upLoadAvatar(@Header("Authorization") String token, @Part List<MultipartBody.Part> partLis); 84
82 85 @Headers("Content-Type: application/json")
83 86 @POST("/api/v1/user/editUser")
84 @Headers("Content-Type: application/json") 87 Observable<ResponseBody> editUser(@Header("Authorization") String token, @Body RequestBody body);
85 @POST("/api/v1/user/editUser") 88
86 Observable<ResponseBody> editUser(@Header("Authorization") String token, @Body RequestBody body); 89 @Headers("Content-Type: application/json")
87 90 @POST("/api/v1/user/changePassword")
88 @Headers("Content-Type: application/json") 91 Observable<ResponseBody> changePassword(@Header("Authorization") String token, @Body RequestBody body);
89 @POST("/api/v1/user/changePassword") 92
90 Observable<ResponseBody> changePassword(@Header("Authorization") String token, @Body RequestBody body); 93
91 94 @GET("/api/v1/user/searchById")
92 95 Observable<ResponseBody> searchById(@Header("Authorization") String token, @Query("userId") String userId);
93 @GET("/api/v1/user/searchById") 96
94 Observable<ResponseBody> searchById(@Header("Authorization") String token, @Query("userId") String userId); 97
95 98 @Headers("Content-Type: application/json")
96 99 @POST("/api/v1/login/userLogin")
97 @Headers("Content-Type: application/json") 100 Observable<ResponseBody> login(@Body RequestBody body);
98 @POST("/api/v1/login/userLogin") 101
99 Observable<ResponseBody> login(@Body RequestBody body); 102 @GET("/api/v1/resource/listGradeAndSubject")
100 103 Observable<ResponseResult<List<GradeAndSubject>>> listGradeAndSubject(@Header("Authorization") String token);
101 @GET("/api/v1/resource/listGradeAndSubject") 104
102 Observable<ResponseResult<List<GradeAndSubject>>> listGradeAndSubject(@Header("Authorization") String token); 105
103 106 @GET("/api/v1/manager/generalQrCode")
104 107 Observable<ResponseBody> generalQrCode();
105 @GET("/api/v1/manager/generalQrCode") 108
106 Observable<ResponseBody> generalQrCode(); 109 @GET("/api/v1/parent/scanAndLogin")
107 110 Observable<ResponseBody> scanAndLogin(@Header("Authorization") String token, @Query("code") String code, @Query("stuId") String stuId);
108 @GET("/api/v1/parent/scanAndLogin") 111
109 Observable<ResponseBody> scanAndLogin(@Header("Authorization") String token, @Query("code") String code, @Query("stuId") String stuId); 112 @GET("/api/v1/parent/getChildrenList")
110 113 Observable<ResponseBody> getChildrenList(@Header("Authorization") String token);
111 @GET("/api/v1/parent/getChildrenList") 114
112 Observable<ResponseBody> getChildrenList(@Header("Authorization") String token); 115
113 116 @Headers("Content-Type: application/json")
114 117 @POST("/api/v1/parent/registerParent")
115 @Headers("Content-Type: application/json") 118 Observable<ResponseBody> registerParent(@Body RequestBody body);
116 @POST("/api/v1/parent/registerParent") 119
117 Observable<ResponseBody> registerParent(@Body RequestBody body); 120
118 121 @GET("/api/v1/parent/listChildren")
119 122 Observable<ResponseBody> listChildren(@Header("Authorization") String token);
120 @GET("/api/v1/parent/listChildren") 123
121 Observable<ResponseBody> listChildren(@Header("Authorization") String token); 124
122 125 @Headers("Content-Type: application/json")
123 126 @POST("/api/v1/parent/registerStudent")
124 @Headers("Content-Type: application/json") 127 Observable<ResponseBody> registerStudent(@Header("Authorization") String token, @Body RequestBody body);
125 @POST("/api/v1/parent/registerStudent") 128
126 Observable<ResponseBody> registerStudent(@Header("Authorization") String token, @Body RequestBody body); 129 @Headers("Content-Type: application/json")
127 130 @POST("/api/v1/parent/bindTeacher")
128 @Headers("Content-Type: application/json") 131 Observable<ResponseBody> bindTeacher(@Header("Authorization") String token, @Body RequestBody body);
129 @POST("/api/v1/parent/bindTeacher") 132
130 Observable<ResponseBody> bindTeacher(@Header("Authorization") String token, @Body RequestBody body); 133 @Multipart
131 134 @POST("/api/v1/user/upLoadAvatar")
132 @Multipart 135 Observable<ResponseResult<Map<String, String>>> uploadAvatar(@Header("Authorization") String token, @Part() MultipartBody.Part file);
133 @POST("/api/v1/user/upLoadAvatar") 136
134 Observable<ResponseResult<Map<String, String>>> uploadAvatar(@Header("Authorization") String token, @Part() MultipartBody.Part file); 137
135 138 @Multipart
136 139 @POST("/api/v1/student/editStudentAvatar")
137 @Multipart 140 Observable<ResponseResult<Map<String, String>>> uploadAvatar(@Header("Authorization") String token, @Part() MultipartBody.Part file, @PartMap Map<String, Object> map);
138 @POST("/api/v1/student/editStudentAvatar") 141
139 Observable<ResponseResult<Map<String, String>>> uploadAvatar(@Header("Authorization") String token, @Part() MultipartBody.Part file, @PartMap Map<String, Object> map); 142 @Headers("Content-Type: application/json")
140 143 @POST("/api/v1/parent/editChild")
141 @Headers("Content-Type: application/json") 144 Observable<ResponseResult> editStudent(@Header("Authorization") String token, @Body RequestBody body);
142 @POST("/api/v1/parent/editChild") 145
143 Observable<ResponseResult> editStudent(@Header("Authorization") String token, @Body RequestBody body); 146 @GET("/api/v1/student/getStudyPlanForThisWeek")
144 147 Observable<ResponseResult<ScheduleBean>> getWeekPlan(@Header("Authorization") String token, @Query("stuId") String stuId);
145 @GET("/api/v1/student/getStudyPlanForThisWeek") 148
146 Observable<ResponseResult<ScheduleBean>> getWeekPlan(@Header("Authorization") String token, @Query("stuId") String stuId); 149 @GET("api/v1/parent/searchTeacher")
147 150 Observable<ResponseResult<Teacher>> searchTeacher(@Header("Authorization") String token, @Query("phone") String phone);
148 @GET("api/v1/parent/searchTeacher") 151
149 Observable<ResponseResult<Teacher>> searchTeacher(@Header("Authorization") String token, @Query("phone") String phone); 152 @POST("api/v1/question/listErrorBook")
150 153 Observable<ResponseResult<PageInfo<TopicBean>>> getError(@Header("Authorization") String token, @Body Map<String, Object> body);
151 @POST("api/v1/question/listErrorBook") 154
152 Observable<ResponseResult<PageInfo<TopicBean>>> getError(@Header("Authorization") String token, @Body Map<String, Object> body); 155 @POST
153 156 Observable<JsonObject> removeWriting(@Url String url, @Body RequestBody body);
154 @POST 157
158 @POST("https://aip.baidubce.com/rest/2.0/ocr/v1/doc_crop_enhance")
159 Observable<JsonObject> baiduEnhance(
160 @Query("access_token") String token,
161 @Body Object any
162 );
163
155 Observable<JsonObject> removeWriting(@Url String url, @Body RequestBody body); 164 @POST
156 165 Observable<CutPicBean> cut(@Url String url, @Body RequestBody body);
157 @POST 166
158 Observable<CutPicBean> cut(@Url String url, @Body RequestBody body); 167 @POST
159 168 Observable<JsonObject> getBaiduToken(@Url String url);
160 @POST 169
161 Observable<JsonObject> getBaiduToken(@Url String url); 170 @Multipart
162 171 @POST("api/v1/pad/addErrorBook")
163 @Multipart 172 Observable<ResponseResult> addError(@Part() MultipartBody.Part file, @PartMap Map<String, Object> map);
164 @POST("api/v1/pad/addErrorBook") 173
165 Observable<ResponseResult> addError(@Part() MultipartBody.Part file, @PartMap Map<String, Object> map); 174 @POST("api/v1/pad/deleteStuErrorBook")
166 175 Observable<ResponseResult> deleteError(@Header("Authorization") String token, @Body List<String> map);
167 @POST("api/v1/pad/deleteStuErrorBook") 176
168 Observable<ResponseResult> deleteError(@Header("Authorization") String token, @Body List<String> map); 177 @PUT("api/v1/pad/updateStuErrorBookInfo")
169 178 Observable<ResponseResult> updateError(@Header("Authorization") String token, @Body List<HashMap<String, Object>> map);
170 @PUT("api/v1/pad/updateStuErrorBookInfo") 179
171 Observable<ResponseResult> updateError(@Header("Authorization") String token, @Body List<HashMap<String, Object>> map); 180 @POST("api/v1/question/editErrorBook")
172 181 Observable<ResponseResult> editError(@Header("Authorization") String Authorization, @Body Map<String, Object> map);
173 @POST("api/v1/question/editErrorBook") 182
174 Observable<ResponseResult> editError(@Header("Authorization") String Authorization, @Body Map<String, Object> map); 183 @GET("api/v1/resource/checkUpdate")
175 184 Call<ResponseResult<UpdateBean>> checkUpdate(@Query("version") int version, @Query("packageName") String packageName, @Query("type") int type);
176 @GET("api/v1/resource/checkUpdate") 185
177 Call<ResponseResult<UpdateBean>> checkUpdate(@Query("version") int version, @Query("packageName") String packageName, @Query("type") int type); 186 @GET("api/v1/teacher/getStudentList")
178 187 Observable<ResponseBody> getStudentList(@Header("Authorization") String token, @Query("userId") String id);
179 @GET("api/v1/teacher/getStudentList") 188
180 Observable<ResponseBody> getStudentList(@Header("Authorization") String token, @Query("userId") String id); 189 @GET("api/v1/teacher/getStudentList")
181 190 Single<ResponseResult<List<Student>>> getStudentList2(@Header("Authorization") String token, @Query("userId") String id);
182 @GET("api/v1/teacher/getStudentList") 191
183 Single<ResponseResult<List<Student>>> getStudentList2(@Header("Authorization") String token, @Query("userId") String id); 192 @GET("api/v1/answer/listRecordForTeacher")
184 193 Observable<ResponseBody> getRecordList(@Header("Authorization") String token, @Query("userId") String id);
185 @GET("api/v1/answer/listRecordForTeacher") 194
186 Observable<ResponseBody> getRecordList(@Header("Authorization") String token, @Query("userId") String id); 195 @GET("api/v1/homework/listHomeworkByStuId")
187 196 Single<ResponseResult<List<HomeworkList>>> getStudentHomework(@Header("Authorization") String token, @Query("stuId") String stuId);
188 @GET("api/v1/homework/listHomeworkByStuId") 197
189 Single<ResponseResult<List<HomeworkList>>> getStudentHomework(@Header("Authorization") String token, @Query("stuId") String stuId); 198 @POST
190 199 Single<BaiduInput> inputImage(@Url String url, @Body RequestBody body);
191 @POST 200
192 Single<BaiduInput> inputImage(@Url String url, @Body RequestBody body); 201 @Multipart
193 202 @POST("api/v1/homework/uploadHomework")
194 @Multipart 203 Single<ResponseResult> uploadImage(@Header("Authorization") String token, @Part() MultipartBody.Part file, @Query("brief") String id);
195 @POST("api/v1/homework/uploadHomework") 204
196 Single<ResponseResult> uploadImage(@Header("Authorization") String token, @Part() MultipartBody.Part file, @Query("brief") String id); 205 @POST("api/v1/homework/uploadHomeworkAction")
197 206 Single<ResponseResult> uploadHomework(@Header("Authorization") String token, @Body Object map);
198 @POST("api/v1/homework/uploadHomeworkAction") 207
199 Single<ResponseResult> uploadHomework(@Header("Authorization") String token, @Body Object map); 208 @GET("api/v1/homework/removeHomework")
200 209 Single<ResponseResult<Boolean>> deleteHomework(
201 @GET("api/v1/homework/removeHomework") 210 @Header("Authorization") String token,
202 Single<ResponseResult<Boolean>> deleteHomework( 211 @Query("homeworkId") String homeworkId
203 @Header("Authorization") String token, 212 );
204 @Query("homeworkId") String homeworkId 213
205 ); 214 @GET("api/v1/homework/listHomeworkById")
206 215 Single<ResponseResult<List<HomeWork>>> getHomeworkDetail(@Header("Authorization") String token, @Query("homeworkId") String homeworkId);
207 @GET("api/v1/homework/listHomeworkById") 216
208 Single<ResponseResult<List<HomeWork>>> getHomeworkDetail(@Header("Authorization") String token, @Query("homeworkId") String homeworkId); 217 @POST("api/v1/homework/uploadHomeworkFeedback")
209 218 Single<ResponseResult> uploadHomeworkFeedback(@Header("Authorization") String token, @Body Map<String, Object> map);
210 @POST("api/v1/homework/uploadHomeworkFeedback") 219
211 Single<ResponseResult> uploadHomeworkFeedback(@Header("Authorization") String token, @Body Map<String, Object> map); 220 @POST("api/v1/homework/editHomeworkInfo")
212 221 Single<ResponseResult<Boolean>> editHomework(
213 @POST("api/v1/homework/editHomeworkInfo") 222 @Header("Authorization") String token,
214 Single<ResponseResult<Boolean>> editHomework( 223 @Body Object body
215 @Header("Authorization") String token, 224 );
216 @Body Object body 225
217 ); 226 @GET("api/v1/homework/listHomeworkDetailByStuId")
218 227 Single<ResponseResult<HomeworkDetail>> getHomeworkCompleteDetail(
219 @GET("api/v1/homework/listHomeworkDetailByStuId") 228 @Header("Authorization") String token,
220 Single<ResponseResult<HomeworkDetail>> getHomeworkCompleteDetail( 229 @Query("stuId") String stuId,
221 @Header("Authorization") String token, 230 @Query("homeworkId") String homeworkId,
222 @Query("stuId") String stuId, 231 // type 固定传true
223 @Query("homeworkId") String homeworkId, 232 @Query("type") boolean type
224 // type 固定传true 233 );
225 @Query("type") boolean type 234
226 ); 235 @GET("api/v1/homework/listHomeworkStatistics")
227 236 Single<ResponseResult<List<StDetail>>> getHuyouList(
228 @GET("api/v1/homework/listHomeworkStatistics") 237 @Header("Authorization") String token,
229 Single<ResponseResult<List<StDetail>>> getHuyouList( 238 @Query("stuId") String stuId,
230 @Header("Authorization") String token, 239 @Query("type") int type //0: 周报, 1:阶段总结
231 @Query("stuId") String stuId, 240 );
232 @Query("type") int type //0: 周报, 1:阶段总结 241
233 ); 242 @GET("api/v1/homework/listHomeworkStatisticsDetailForStudent")
234 243 Single<ResponseResult<StDetail>> getHuyouDetail(
235 @GET("api/v1/homework/listHomeworkStatisticsDetailForStudent") 244 @Header("Authorization") String token,
236 Single<ResponseResult<StDetail>> getHuyouDetail( 245 @Query("homeworkStatisticsId") String homeworkId
237 @Header("Authorization") String token, 246 );
238 @Query("homeworkStatisticsId") String homeworkId 247
239 ); 248 @GET("api/v1/demo/generalStatisticsHomework")
240 249 Single<ResponseResult<Object>> generalHuyou();
241 @GET("api/v1/demo/generalStatisticsHomework") 250
242 Single<ResponseResult<Object>> generalHuyou(); 251 @POST("api/v1/homework/generalHomeworkStageStatistics")
243 252 Single<ResponseResult<Boolean>> generalStageHuyou(
244 @POST("api/v1/homework/generalHomeworkStageStatistics") 253 @Header("Authorization") String token,
245 Single<ResponseResult<Boolean>> generalStageHuyou( 254 @Body Object body
246 @Header("Authorization") String token, 255 );
247 @Body Object body 256
248 ); 257 @GET("api/v1/homework/removeHomeworkStatistics")
249 258 Single<ResponseResult<Boolean>> deleteHuyou(
250 @GET("api/v1/homework/removeHomeworkStatistics") 259 @Header("Authorization") String token,
251 Single<ResponseResult<Boolean>> deleteHuyou( 260 @Query("homeworkStatisticsId") String homeworkId
252 @Header("Authorization") String token, 261 );
253 @Query("homeworkStatisticsId") String homeworkId 262
254 ); 263 @GET("api/v1/login/smsCode")
255 264 Single<ResponseResult<String>> smsCode(@Query("mobile") String mobile);
256 @GET("api/v1/login/smsCode") 265
257 Single<ResponseResult<String>> smsCode(@Query("mobile") String mobile); 266 @POST("api/v1/login/smsLogin")
258 267 Single<ResponseResult<User>> smsLogin(@Body Object body);
259 @POST("api/v1/login/smsLogin") 268
260 Single<ResponseResult<User>> smsLogin(@Body Object body); 269 }
261 270
262 } 271 public static String getUserId() {
263 272 return (String) SharedPreferencesUtil.getData("userId", "");
264 public static String getUserId() { 273 }
265 return (String) SharedPreferencesUtil.getData("userId", ""); 274
266 } 275 public static String getHeader() {
267 276 return (String) SharedPreferencesUtil.getData("token", "");
268 public static String getHeader() { 277 }
269 return (String) SharedPreferencesUtil.getData("token", ""); 278
270 } 279 public static String getBaiduToken() {
271 280 return (String) SharedPreferencesUtil.getData("baiduToken", "");
272 public static String getBaiduToken() { 281 }
273 return (String) SharedPreferencesUtil.getData("baiduToken", ""); 282
274 } 283 public static Single<BaiduInput> inputImage(String filePath, String id) {
275 284 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
276 public static Single<BaiduInput> inputImage(String filePath, String id) { 285 String base64 = BitmapUtils.fileToBase64(filePath);
277 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); 286 File file = new File(filePath);
278 String base64 = BitmapUtils.fileToBase64(filePath); 287 RequestBody body = RequestBody.create(mediaType, "image=" + base64 + "&brief={\"name\":\"" + file.getName() + "\", \"id\":\"" + id + "\"}");
279 File file = new File(filePath); 288 return getBaiduTokenOcr().map(jsonObject -> jsonObject.get("access_token").getAsString())
280 RequestBody body = RequestBody.create(mediaType, "image=" + base64 + "&brief={\"name\":\"" + file.getName() + "\", \"id\":\"" + id + "\"}"); 289 .flatMap(token -> {
281 return getBaiduTokenOcr().map(jsonObject -> jsonObject.get("access_token").getAsString()) 290 return service_url.inputImage("https://aip.baidubce.com/rest/2.0/realtime_search/same_hq/add?access_token=" + token, body);
282 .flatMap(token -> { 291 });
283 return service_url.inputImage("https://aip.baidubce.com/rest/2.0/realtime_search/same_hq/add?access_token=" + token, body); 292 }
284 }); 293
285 } 294 public static Single<ResponseResult> uploadImage(String path, String id) {
286 295 File file = new File(path);
287 public static Single<ResponseResult> uploadImage(String path, String id) { 296 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file);
288 File file = new File(path); 297 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
289 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file); 298 return service_url.uploadImage(getHeader(), part, id);
290 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody); 299 }
291 return service_url.uploadImage(getHeader(), part, id); 300
292 } 301
293 302 public static void checkUpdate(int code, String packageName, Callback<ResponseResult<UpdateBean>> callback) {
294 303 service_url.checkUpdate(code, packageName, 0).enqueue(callback);
295 public static void checkUpdate(int code, String packageName, Callback<ResponseResult<UpdateBean>> callback) { 304 }
296 service_url.checkUpdate(code, packageName, 0).enqueue(callback); 305
297 } 306 public static void addError(String path, Map<String, String> param, Observer<ResponseResult> observer) {
298 307 File file = new File(path);
299 public static void addError(String path, Map<String, String> param, Observer<ResponseResult> observer) { 308 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file);
300 File file = new File(path); 309 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
301 RequestBody requestBody = RequestBody.create(MediaType.parse("image/jpg"), file); 310 Map<String, Object> map = new HashMap<>();
302 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody); 311 map.put("condition", param);
303 Map<String, Object> map = new HashMap<>(); 312 setSubscribe(service_url.addError(part, map), observer);
304 map.put("condition", param); 313 }
305 setSubscribe(service_url.addError(part, map), observer); 314
306 } 315
307 316 public static void cut(String base64, Observer<CutPicBean> observer) {
308 317 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
309 public static void cut(String base64, Observer<CutPicBean> observer) { 318 RequestBody body = RequestBody.create(mediaType, "image=" + base64 + "&detect_direction=true");
310 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); 319 setSubscribe(service_url.cut("https://aip.baidubce.com/rest/2.0/ocr/v1/paper_cut_edu?access_token=" + getBaiduToken(), body), observer);
311 RequestBody body = RequestBody.create(mediaType, "image=" + base64 + "&detect_direction=true"); 320 }
312 setSubscribe(service_url.cut("https://aip.baidubce.com/rest/2.0/ocr/v1/paper_cut_edu?access_token=" + getBaiduToken(), body), observer); 321
313 } 322 public static void editError(Map<String, Object> map, Observer<ResponseResult> observer) {
314 323 setSubscribe(service_url.editError(getHeader(), map), observer);
315 public static void editError(Map<String, Object> map, Observer<ResponseResult> observer) { 324 }
316 setSubscribe(service_url.editError(getHeader(), map), observer); 325
317 } 326 public static void editError(List<HashMap<String, Object>> map, Observer<ResponseResult> observer) {
318 327 setSubscribe(service_url.updateError(getHeader(), map), observer);
319 public static void editError(List<HashMap<String, Object>> map, Observer<ResponseResult> observer) { 328 }
320 setSubscribe(service_url.updateError(getHeader(), map), observer); 329
321 } 330 public static void deleteError(List<String> map, Observer<ResponseResult> observer) {
322 331 setSubscribe(service_url.deleteError(getHeader(), map), observer);
323 public static void deleteError(List<String> map, Observer<ResponseResult> observer) { 332 }
324 setSubscribe(service_url.deleteError(getHeader(), map), observer); 333
325 } 334 public static void getBaiduToken(Observer<JsonObject> observer) {
326 335 setSubscribe(service_url.getBaiduToken("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + BuildConfig.APIKey + "&client_secret=" + BuildConfig.SecretKey), observer);
327 public static void getBaiduToken(Observer<JsonObject> observer) { 336 }
328 setSubscribe(service_url.getBaiduToken("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + BuildConfig.APIKey + "&client_secret=" + BuildConfig.SecretKey), observer); 337
329 } 338 public static Single<JsonObject> getBaiduTokenOcr() {
330 339 return service_url.getBaiduToken("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + BuildConfig.APIKey1 + "&client_secret=" + BuildConfig.SecretKey1).firstOrError();
331 public static Single<JsonObject> getBaiduTokenOcr() { 340 }
332 return service_url.getBaiduToken("https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id=" + BuildConfig.APIKey1 + "&client_secret=" + BuildConfig.SecretKey1).firstOrError(); 341
333 } 342 public static void removeWriting(String base64, Observer<JsonObject> observer) {
334 343 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");
335 public static void removeWriting(String base64, Observer<JsonObject> observer) { 344 RequestBody body = RequestBody.create(mediaType, "image=" + base64);
336 MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded"); 345 setSubscribe(service_url.removeWriting(("https://aip.baidubce.com/rest/2.0/ocr/v1/remove_handwriting?access_token=" + getBaiduToken()), body), observer);
337 RequestBody body = RequestBody.create(mediaType, "image=" + base64); 346 }
338 setSubscribe(service_url.removeWriting(("https://aip.baidubce.com/rest/2.0/ocr/v1/remove_handwriting?access_token=" + getBaiduToken()), body), observer); 347
348 public static void baiduEnhance(String base64, Observer<JsonObject> observer) {
349 Map<String, Object> body = new LinkedHashMap<>();
350 body.put("image", base64);
351 body.put("scan_type", 3);
352 body.put("enhance_type", 3);
353 setSubscribe(service_url.baiduEnhance(getBaiduToken(), body), observer);
354 }
355
339 } 356 public static void searchTeacher(String phone, Observer<ResponseResult<Teacher>> observer) {
340 357 setSubscribe(service_url.searchTeacher(getHeader(), phone), observer);
341 public static void searchTeacher(String phone, Observer<ResponseResult<Teacher>> observer) { 358 }
342 setSubscribe(service_url.searchTeacher(getHeader(), phone), observer); 359
343 } 360 public static void logout(Observer<ResponseBody> observer) {
344 361 setSubscribe(service_url.logout(), observer);
345 public static void logout(Observer<ResponseBody> observer) { 362 }
346 setSubscribe(service_url.logout(), observer); 363
347 } 364 public static void editStudent(RequestBody body, Observer<ResponseResult> observable) {
348 365 setSubscribe(service_url.editStudent(getHeader(), body), observable);
349 public static void editStudent(RequestBody body, Observer<ResponseResult> observable) { 366 }
350 setSubscribe(service_url.editStudent(getHeader(), body), observable); 367
351 } 368 public static void getWeekPlan(String id, Observer<ResponseResult<ScheduleBean>> observer) {
352 369 setSubscribe(service_url.getWeekPlan(getHeader(), id), observer);
353 public static void getWeekPlan(String id, Observer<ResponseResult<ScheduleBean>> observer) { 370 }
354 setSubscribe(service_url.getWeekPlan(getHeader(), id), observer); 371
355 } 372 public static void uploadStudentAvatar(File file, String stuId, Observer<ResponseResult<Map<String, String>>> observer) {
356 373 RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
357 public static void uploadStudentAvatar(File file, String stuId, Observer<ResponseResult<Map<String, String>>> observer) { 374 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
358 RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); 375 Map<String, Object> map = new HashMap<>();
359 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody); 376 map.put("stuId", stuId);
360 Map<String, Object> map = new HashMap<>(); 377 setSubscribe(service_url.uploadAvatar(getHeader(), part, map), observer);
361 map.put("stuId", stuId); 378 }
362 setSubscribe(service_url.uploadAvatar(getHeader(), part, map), observer); 379
363 } 380 public static void uploadAvatar(File file, Observer<ResponseResult<Map<String, String>>> observer) {
364 381 RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file);
365 public static void uploadAvatar(File file, Observer<ResponseResult<Map<String, String>>> observer) { 382 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody);
366 RequestBody requestBody = RequestBody.create(MediaType.parse("multipart/form-data"), file); 383 setSubscribe(service_url.uploadAvatar(getHeader(), part), observer);
367 MultipartBody.Part part = MultipartBody.Part.createFormData("file", file.getName(), requestBody); 384 }
368 setSubscribe(service_url.uploadAvatar(getHeader(), part), observer); 385
369 } 386 public static void upLoadAvatar(List<MultipartBody.Part> partLis, Observer<ResponseBody> observer) {
370 387 setSubscribe(service_url.upLoadAvatar(getHeader(), partLis), observer);
371 public static void upLoadAvatar(List<MultipartBody.Part> partLis, Observer<ResponseBody> observer) { 388 }
372 setSubscribe(service_url.upLoadAvatar(getHeader(), partLis), observer); 389
373 } 390
374 391 public static void editUser(RequestBody body, Observer<ResponseBody> observer) {
375 392 setSubscribe(service_url.editUser(getHeader(), body), observer);
376 public static void editUser(RequestBody body, Observer<ResponseBody> observer) { 393 }
377 setSubscribe(service_url.editUser(getHeader(), body), observer); 394
378 } 395 public static void changePassword(RequestBody body, Observer<ResponseBody> observer) {
379 396 setSubscribe(service_url.changePassword(getHeader(), body), observer);
380 public static void changePassword(RequestBody body, Observer<ResponseBody> observer) { 397 }
381 setSubscribe(service_url.changePassword(getHeader(), body), observer); 398
382 } 399
383 400 public static void searchById(String userId, Observer<ResponseBody> observer) {
384 401 setSubscribe(service_url.searchById(getHeader(), userId), observer);
385 public static void searchById(String userId, Observer<ResponseBody> observer) { 402 }
386 setSubscribe(service_url.searchById(getHeader(), userId), observer); 403
387 } 404
388 405 public static void login(RequestBody body, Observer<ResponseBody> observer) {
389 406 setSubscribe(service_url.login(body), observer);
390 public static void login(RequestBody body, Observer<ResponseBody> observer) { 407 }
391 setSubscribe(service_url.login(body), observer); 408
392 } 409 public static void listGradeAndSubject(Observer<ResponseResult<List<GradeAndSubject>>> observer) {
393 410 setSubscribe(service_url.listGradeAndSubject(getHeader()), observer);
394 public static void listGradeAndSubject(Observer<ResponseResult<List<GradeAndSubject>>> observer) { 411 }
395 setSubscribe(service_url.listGradeAndSubject(getHeader()), observer); 412
396 } 413
397 414 public static void scanAndLogin(String code, String stuId, Observer<ResponseBody> observer) {
398 415 setSubscribe(service_url.scanAndLogin(getHeader(), code, stuId), observer);
399 public static void scanAndLogin(String code, String stuId, Observer<ResponseBody> observer) { 416 }
400 setSubscribe(service_url.scanAndLogin(getHeader(), code, stuId), observer); 417
401 } 418 public static void getChildrenList(Observer<ResponseBody> observer) {
402 419 setSubscribe(service_url.getChildrenList(getHeader()), observer);
403 public static void getChildrenList(Observer<ResponseBody> observer) { 420 }
404 setSubscribe(service_url.getChildrenList(getHeader()), observer); 421
405 } 422
406 423 public static void registerParent(RequestBody body, Observer<ResponseBody> observer) {
407 424 setSubscribe(service_url.registerParent(body), observer);
408 public static void registerParent(RequestBody body, Observer<ResponseBody> observer) { 425 }
409 setSubscribe(service_url.registerParent(body), observer); 426
410 } 427
411 428 public static void listChildren(Observer<ResponseBody> observer) {
412 429 setSubscribe(service_url.listChildren(getHeader()), observer);
413 public static void listChildren(Observer<ResponseBody> observer) { 430 }
414 setSubscribe(service_url.listChildren(getHeader()), observer); 431
415 } 432 public static void listStudent(Observer<ResponseBody> observer) {
416 433 setSubscribe(service_url.getStudentList(getHeader(), (String) SharedPreferencesUtil.getData("userId", "")), observer);
417 public static void listStudent(Observer<ResponseBody> observer) { 434 }
418 setSubscribe(service_url.getStudentList(getHeader(), (String) SharedPreferencesUtil.getData("userId", "")), observer); 435
419 } 436 public static Single<ResponseResult<List<Student>>> listStudent() {
420 437 return service_url.getStudentList2(getHeader(), getUserId());
421 public static Single<ResponseResult<List<Student>>> listStudent() { 438 }
422 return service_url.getStudentList2(getHeader(), getUserId()); 439
423 } 440 public static void listRecord(Observer<ResponseBody> observer) {
424 441 setSubscribe(service_url.getRecordList(getHeader(), (String) SharedPreferencesUtil.getData("userId", "")), observer);
425 public static void listRecord(Observer<ResponseBody> observer) { 442 }
426 setSubscribe(service_url.getRecordList(getHeader(), (String) SharedPreferencesUtil.getData("userId", "")), observer); 443
427 } 444
428 445 public static void registerStudent(RequestBody body, Observer<ResponseBody> observer) {
429 446 setSubscribe(service_url.registerStudent(getHeader(), body), observer);
430 public static void registerStudent(RequestBody body, Observer<ResponseBody> observer) { 447 }
431 setSubscribe(service_url.registerStudent(getHeader(), body), observer); 448
432 } 449 public static void bindTeacher(RequestBody body, Observer<ResponseBody> observer) {
433 450 setSubscribe(service_url.bindTeacher(getHeader(), body), observer);
434 public static void bindTeacher(RequestBody body, Observer<ResponseBody> observer) { 451 }
435 setSubscribe(service_url.bindTeacher(getHeader(), body), observer); 452
436 } 453 public static void getError(Map map, Observer<ResponseResult<PageInfo<TopicBean>>> observer) {
437 454 setSubscribe(service_url.getError(getHeader(), map), observer);
438 public static void getError(Map map, Observer<ResponseResult<PageInfo<TopicBean>>> observer) { 455 }
439 setSubscribe(service_url.getError(getHeader(), map), observer); 456
440 } 457
441 458 public static RequestBody getMapRequestBody(Map map) {
442 459 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(map));
443 public static RequestBody getMapRequestBody(Map map) { 460 }
444 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(map)); 461
445 } 462
446 463 public static RequestBody getArrayRequestBody(List list) {
447 464 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(list));
448 public static RequestBody getArrayRequestBody(List list) { 465 }
449 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(list)); 466
450 } 467 public static RequestBody getFileRequestBody(File file) {
451 468 return RequestBody.create(MediaType.parse("application/octet-stream"), file);
452 public static RequestBody getFileRequestBody(File file) { 469 }
453 return RequestBody.create(MediaType.parse("application/octet-stream"), file); 470
454 } 471 public static RequestBody getFileRequestBody(byte[] bytes) {
455 472 return RequestBody.create(MediaType.parse("multipart/form-data"), bytes);
456 public static RequestBody getFileRequestBody(byte[] bytes) { 473 }
457 return RequestBody.create(MediaType.parse("multipart/form-data"), bytes); 474
458 } 475 public static RequestBody getObjectRequestBody(Object obj) {
459 476 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(obj));
460 public static RequestBody getObjectRequestBody(Object obj) { 477 }
461 return RequestBody.create(MediaType.parse("text/plain"), new Gson().toJson(obj)); 478
462 } 479 public static RequestBody getStringRequestBody(String str) {
463 480 return RequestBody.create(MediaType.parse("text/plain"), str);
464 public static RequestBody getStringRequestBody(String str) { 481 }
465 return RequestBody.create(MediaType.parse("text/plain"), str); 482
466 } 483
467 484 /**
468 485 * 插入观察者
469 /** 486 *
470 * 插入观察者 487 * @param observable
471 * 488 * @param observer
472 * @param observable 489 * @param <T>
473 * @param observer 490 */
474 * @param <T> 491 public static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) {
475 */ 492 observable.subscribeOn(Schedulers.io())//子线程访问网络
476 public static <T> void setSubscribe(Observable<T> observable, Observer<T> observer) { 493 .observeOn(AndroidSchedulers.mainThread())//回调到主线程
477 observable.subscribeOn(Schedulers.io())//子线程访问网络 494 .subscribe(observer);
478 .observeOn(AndroidSchedulers.mainThread())//回调到主线程 495 }
479 .subscribe(observer); 496
480 } 497 }
481 498
libs/common/src/main/java/com/prws/common/net/SignInterceptor.java
1 package com.prws.common.net; 1 package com.prws.common.net;
2 2
3 import androidx.annotation.NonNull;
4
5 import com.prws.common.BuildConfig;
3 import androidx.annotation.NonNull; 6 import com.prws.common.utils.SharedPreferencesUtil;
4 7
5 import com.prws.common.BuildConfig; 8 import org.apache.commons.codec.binary.Hex;
6 import com.prws.common.utils.SharedPreferencesUtil; 9 import org.apache.commons.codec.digest.DigestUtils;
7 10
8 import org.apache.commons.codec.binary.Hex; 11 import java.io.IOException;
9 import org.apache.commons.codec.digest.DigestUtils; 12 import java.util.Date;
10 13 import java.util.Random;
11 import java.io.IOException; 14
12 import java.util.Date; 15 import okhttp3.Interceptor;
13 import java.util.Random; 16 import okhttp3.Request;
14 17 import okhttp3.Response;
15 import okhttp3.Interceptor; 18
16 import okhttp3.Request; 19 public class SignInterceptor implements Interceptor {
20 @NonNull
17 import okhttp3.Response; 21 @Override
18 22 public Response intercept(Chain chain) throws IOException {
19 public class SignInterceptor implements Interceptor { 23 String host = BuildConfig.SERVER_URL;
20 @NonNull 24 if (!chain.request().url().toString().startsWith(host)) {
21 @Override 25 return chain.proceed(chain.request());
22 public Response intercept(Chain chain) throws IOException { 26 }
23 String host = BuildConfig.SERVER_URL; 27
24 if (!chain.request().url().toString().startsWith(host)) {
25 return chain.proceed(chain.request());
26 } 28 String token = (String) SharedPreferencesUtil.getData("token","");
27 29 Request.Builder requestBuilder = chain.request().newBuilder();
28 String token = (String) SharedPreferencesUtil.getData("token",""); 30 if (token != null && token.length() > 0) {
29 Request.Builder requestBuilder = chain.request().newBuilder(); 31 requestBuilder = chain.request().newBuilder()
30 if (token != null && token.length() > 0) { 32 .header("Authorization", token);
31 requestBuilder = chain.request().newBuilder() 33 }
32 .header("Authorization", token);
33 }
libs/common/src/main/java/com/prws/common/utils/BitmapUtils.java
1 package com.prws.common.utils; 1 package com.prws.common.utils;
2 2
3 import android.graphics.Bitmap; 3 import android.graphics.Bitmap;
4 import android.graphics.BitmapFactory; 4 import android.graphics.BitmapFactory;
5 import android.graphics.Canvas; 5 import android.graphics.Canvas;
6 import android.graphics.Matrix; 6 import android.graphics.Matrix;
7 import android.hardware.Camera; 7 import android.hardware.Camera;
8 import android.text.TextUtils; 8 import android.text.TextUtils;
9 import android.util.Base64; 9 import android.util.Base64;
10 import android.view.View; 10 import android.view.View;
11 11
12 import java.io.ByteArrayInputStream; 12 import java.io.ByteArrayInputStream;
13 import java.io.ByteArrayOutputStream; 13 import java.io.ByteArrayOutputStream;
14 import java.io.File; 14 import java.io.File;
15 import java.io.FileInputStream; 15 import java.io.FileInputStream;
16 import java.io.FileNotFoundException; 16 import java.io.FileNotFoundException;
17 import java.io.FileOutputStream; 17 import java.io.FileOutputStream;
18 import java.io.IOException; 18 import java.io.IOException;
19 import java.io.InputStream; 19 import java.io.InputStream;
20 import java.net.URLEncoder; 20 import java.net.URLEncoder;
21 21
22 public class BitmapUtils { 22 public class BitmapUtils {
23 23
24 public static Bitmap compress(Bitmap image) { 24 public static Bitmap compress(Bitmap image) {
25 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 25 ByteArrayOutputStream baos = new ByteArrayOutputStream();
26 image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中 26 image.compress(Bitmap.CompressFormat.JPEG, 100, baos);//质量压缩方法,这里100表示不压缩,把压缩后的数据存放到baos中
27 int options = 100; 27 int options = 100;
28 while (baos.toByteArray().length / 1024 > 2000) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩 28 while (baos.toByteArray().length / 1024 > 2000) { //循环判断如果压缩后图片是否大于100kb,大于继续压缩
29 baos.reset();//重置baos即清空baos 29 baos.reset();//重置baos即清空baos
30 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中 30 image.compress(Bitmap.CompressFormat.JPEG, options, baos);//这里压缩options%,把压缩后的数据存放到baos中
31 options -= 10;//每次都减少10 31 options -= 10;//每次都减少10
32 } 32 }
33 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中 33 ByteArrayInputStream isBm = new ByteArrayInputStream(baos.toByteArray());//把压缩后的数据baos存放到ByteArrayInputStream中
34 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片 34 Bitmap bitmap = BitmapFactory.decodeStream(isBm, null, null);//把ByteArrayInputStream数据生成图片
35 return bitmap; 35 return bitmap;
36 } 36 }
37 37
38 public static Bitmap getimage(String srcPath) { 38 public static Bitmap getimage(String srcPath) {
39 BitmapFactory.Options newOpts = new BitmapFactory.Options(); 39 BitmapFactory.Options newOpts = new BitmapFactory.Options();
40 //开始读入图片,此时把options.inJustDecodeBounds 设回true了 40 //开始读入图片,此时把options.inJustDecodeBounds 设回true了
41 newOpts.inJustDecodeBounds = true; 41 newOpts.inJustDecodeBounds = true;
42 Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空 42 Bitmap bitmap = BitmapFactory.decodeFile(srcPath, newOpts);//此时返回bm为空
43 43
44 newOpts.inJustDecodeBounds = false; 44 newOpts.inJustDecodeBounds = false;
45 int w = newOpts.outWidth; 45 int w = newOpts.outWidth;
46 int h = newOpts.outHeight; 46 int h = newOpts.outHeight;
47 float hh = 2000f;//这里设置高度为800f 47 float hh = 2000f;//这里设置高度为800f
48 float ww = 2000f;//这里设置宽度为480f 48 float ww = 2000f;//这里设置宽度为480f
49 //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可 49 //缩放比。由于是固定比例缩放,只用高或者宽其中一个数据进行计算即可
50 int be = 1;//be=1表示不缩放 50 int be = 1;//be=1表示不缩放
51 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放 51 if (w > h && w > ww) {//如果宽度大的话根据宽度固定大小缩放
52 be = (int) (newOpts.outWidth / ww); 52 be = (int) (newOpts.outWidth / ww);
53 } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放 53 } else if (w < h && h > hh) {//如果高度高的话根据宽度固定大小缩放
54 be = (int) (newOpts.outHeight / hh); 54 be = (int) (newOpts.outHeight / hh);
55 } 55 }
56 if (be <= 0) 56 if (be <= 0)
57 be = 1; 57 be = 1;
58 newOpts.inSampleSize = be;//设置缩放比例 58 newOpts.inSampleSize = be;//设置缩放比例
59 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了 59 //重新读入图片,注意此时已经把options.inJustDecodeBounds 设回false了
60 bitmap = BitmapFactory.decodeFile(srcPath, newOpts); 60 bitmap = BitmapFactory.decodeFile(srcPath, newOpts);
61 return compress(bitmap);//压缩好比例大小后再进行质量压缩 61 return compress(bitmap);//压缩好比例大小后再进行质量压缩
62 } 62 }
63 63
64 64
65 /** 65 /**
66 * 注释:设置拍照图片正确方向 66 * 注释:设置拍照图片正确方向
67 * 67 *
68 * @param id 68 * @param id
69 * @param bitmap 69 * @param bitmap
70 * @return 70 * @return
71 */ 71 */
72 public static Bitmap setTakePicktrueOrientation(int id, Bitmap bitmap) { 72 public static Bitmap setTakePicktrueOrientation(int id, Bitmap bitmap) {
73 //如果返回的图片宽度小于高度,说明FrameWork层已经做过处理直接返回即可 73 //如果返回的图片宽度小于高度,说明FrameWork层已经做过处理直接返回即可
74 try { 74 try {
75 if (bitmap.getWidth() < bitmap.getHeight()) { 75 if (bitmap.getWidth() < bitmap.getHeight()) {
76 return bitmap; 76 return bitmap;
77 } 77 }
78 Camera.CameraInfo info = new Camera.CameraInfo(); 78 Camera.CameraInfo info = new Camera.CameraInfo();
79 Camera.getCameraInfo(id, info); 79 Camera.getCameraInfo(id, info);
80 bitmap = rotaingImageView(id, info.orientation, bitmap); 80 bitmap = rotaingImageView(id, info.orientation, bitmap);
81 } catch (Exception e) { 81 } catch (Exception e) {
82 82
83 } 83 }
84 return bitmap; 84 return bitmap;
85 } 85 }
86 86
87 /** 87 /**
88 * 把相机拍照返回照片转正 88 * 把相机拍照返回照片转正
89 * 89 *
90 * @param angle 旋转角度 90 * @param angle 旋转角度
91 * @return bitmap 图片 91 * @return bitmap 图片
92 */ 92 */
93 private static Bitmap rotaingImageView(int id, int angle, Bitmap bitmap) { 93 private static Bitmap rotaingImageView(int id, int angle, Bitmap bitmap) {
94 //矩阵 94 //矩阵
95 Matrix matrix = new Matrix(); 95 Matrix matrix = new Matrix();
96 matrix.postRotate(angle); 96 matrix.postRotate(angle);
97 //加入翻转 把相机拍照返回照片转正 97 //加入翻转 把相机拍照返回照片转正
98 if (id == 1) { 98 if (id == 1) {
99 matrix.postScale(-1, 1); 99 matrix.postScale(-1, 1);
100 } 100 }
101 // 创建新的图片 101 // 创建新的图片
102 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0, 102 Bitmap resizedBitmap = Bitmap.createBitmap(bitmap, 0, 0,
103 bitmap.getWidth(), bitmap.getHeight(), matrix, true); 103 bitmap.getWidth(), bitmap.getHeight(), matrix, true);
104 return resizedBitmap; 104 return resizedBitmap;
105 } 105 }
106 106
107 /** 107 /**
108 * 注释:保存图片 108 * 注释:保存图片
109 * 109 *
110 * @param bitmap 110 * @param bitmap
111 * @param path 111 * @param path
112 * @return 112 * @return
113 */ 113 */
114 public static boolean saveBitmap(Bitmap bitmap, String path) { 114 public static boolean saveBitmap(Bitmap bitmap, String path) {
115 115
116 try { 116 try {
117 File file = new File(path); 117 File file = new File(path);
118 File parent = file.getParentFile(); 118 File parent = file.getParentFile();
119 if (!parent.exists()) { 119 if (!parent.exists()) {
120 parent.mkdirs(); 120 parent.mkdirs();
121 } 121 }
122 FileOutputStream fos = new FileOutputStream(file); 122 FileOutputStream fos = new FileOutputStream(file);
123 boolean b = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); 123 boolean b = bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
124 fos.flush(); 124 fos.flush();
125 fos.close(); 125 fos.close();
126 return b; 126 return b;
127 } catch (Exception e) { 127 } catch (Exception e) {
128 e.printStackTrace(); 128 e.printStackTrace();
129 } 129 }
130 return false; 130 return false;
131 } 131 }
132 132
133 public static Bitmap routeBitmap(Bitmap bitmap) { 133 public static Bitmap routeBitmap(Bitmap bitmap) {
134 Matrix matrix = new Matrix(); 134 Matrix matrix = new Matrix();
135 matrix.preRotate(90f); 135 matrix.preRotate(90f);
136 Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false); 136 Bitmap bitmap1 = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, false);
137 return bitmap1; 137 return bitmap1;
138 } 138 }
139 139
140 public static String fileToBase64(String path) { 140 public static String fileToBase64(String path) {
141 File file = new File(path); 141 File file = new File(path);
142 String base64 = null; 142 String base64 = null;
143 InputStream in = null; 143 InputStream in = null;
144 try { 144 try {
145 in = new FileInputStream(file); 145 in = new FileInputStream(file);
146 byte[] bytes = new byte[in.available()]; 146 byte[] bytes = new byte[in.available()];
147 int length = in.read(bytes); 147 int length = in.read(bytes);
148 base64 = Base64.encodeToString(bytes, 0, length, Base64.DEFAULT); 148 base64 = Base64.encodeToString(bytes, 0, length, Base64.DEFAULT);
149 } catch (FileNotFoundException e) { 149 } catch (FileNotFoundException e) {
150 e.printStackTrace(); 150 e.printStackTrace();
151 } catch (IOException e) { 151 } catch (IOException e) {
152 e.printStackTrace(); 152 e.printStackTrace();
153 } finally { 153 } finally {
154 try { 154 try {
155 if (in != null) { 155 if (in != null) {
156 in.close(); 156 in.close();
157 } 157 }
158 } catch (IOException e) { 158 } catch (IOException e) {
159 e.printStackTrace(); 159 e.printStackTrace();
160 } 160 }
161 } 161 }
162 return toURLEncoded(base64); 162 return toURLEncoded(base64);
163 } 163 }
164 164
165 165
166 /** 166 /**
167 * 将图片转换成Base64编码的字符串 167 * 将图片转换成Base64编码的字符串
168 */ 168 */
169 public static String imageToBase64(String path) { 169 public static String imageToBase64WithUrlEncode(String path) {
170 return imageToBase64(path, true);
171 }
172
173 public static String imageToBase64(String path, boolean urlEncode) {
174
170 if (TextUtils.isEmpty(path)) { 175 if (TextUtils.isEmpty(path)) {
171 return null; 176 return null;
172 } 177 }
173 InputStream is = null; 178 InputStream is = null;
174 byte[] data = null; 179 byte[] data = null;
175 String result = null; 180 String result = null;
176 try { 181 try {
177 is = new FileInputStream(path); 182 is = new FileInputStream(path);
178 //创建一个字符流大小的数组。 183 //创建一个字符流大小的数组。
179 data = new byte[is.available()]; 184 data = new byte[is.available()];
180 //写入数组 185 //写入数组
181 is.read(data); 186 is.read(data);
182 //用默认的编码格式进行编码 187 //用默认的编码格式进行编码
183 result = Base64.encodeToString(data, Base64.NO_CLOSE); 188 result = Base64.encodeToString(data, Base64.NO_CLOSE);
184 } catch (Exception e) { 189 } catch (Exception e) {
185 e.printStackTrace(); 190 e.printStackTrace();
186 } finally { 191 } finally {
187 if (null != is) { 192 if (null != is) {
188 try { 193 try {
189 is.close(); 194 is.close();
190 } catch (IOException e) { 195 } catch (IOException e) {
191 e.printStackTrace(); 196 e.printStackTrace();
192 } 197 }
193 } 198 }
194 199
195 } 200 }
196 return toURLEncoded(result); 201 if (urlEncode) return toURLEncoded(result);
202 else return result;
197 } 203 }
198 204
199 205
200 public static String toURLEncoded(String paramString) { 206 public static String toURLEncoded(String paramString) {
201 if (paramString == null || paramString.equals("")) { 207 if (paramString == null || paramString.equals("")) {
202 return ""; 208 return "";
203 } 209 }
204 try { 210 try {
205 String str = new String(paramString.getBytes(), "UTF-8"); 211 String str = new String(paramString.getBytes(), "UTF-8");
206 str = URLEncoder.encode(str, "UTF-8"); 212 str = URLEncoder.encode(str, "UTF-8");
207 return str; 213 return str;
208 } catch (Exception localException) { 214 } catch (Exception localException) {
209 } 215 }
210 return ""; 216 return "";
211 } 217 }
212 218
213 public static Bitmap stringToBitmap(String string) { 219 public static Bitmap stringToBitmap(String string) {
214 Bitmap bitmap = null; 220 Bitmap bitmap = null;
215 try { 221 try {
216 byte[] bitmapArray = Base64.decode(string, Base64.DEFAULT); 222 byte[] bitmapArray = Base64.decode(string, Base64.DEFAULT);
217 bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length); 223 bitmap = BitmapFactory.decodeByteArray(bitmapArray, 0, bitmapArray.length);
218 } catch (Exception e) { 224 } catch (Exception e) {
219 e.printStackTrace(); 225 e.printStackTrace();
220 } 226 }
221 return bitmap; 227 return bitmap;
222 } 228 }
223 229
224 /** 230 /**
225 * 将图片转成byte数组 231 * 将图片转成byte数组
226 * 232 *
227 * @param bitmap 图片 233 * @param bitmap 图片
228 * @return 图片的字节数组 234 * @return 图片的字节数组
229 */ 235 */
230 public static String bitmap2Byte(Bitmap bitmap) { 236 public static String bitmap2Byte(Bitmap bitmap) {
231 if (null == bitmap) throw new NullPointerException(); 237 if (null == bitmap) throw new NullPointerException();
232 // if (null == bitmap) return null; 238 // if (null == bitmap) return null;
233 ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 239 ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
234 //把bitmap100%高质量压缩 到 output对象里 240 //把bitmap100%高质量压缩 到 output对象里
235 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream); 241 bitmap.compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
236 return byte2Base64(outputStream.toByteArray()); 242 return byte2Base64(outputStream.toByteArray());
237 } 243 }
238 244
239 /** 245 /**
240 * 将图片转成byte数组 246 * 将图片转成byte数组
241 * 247 *
242 * @param imageByte 图片 248 * @param imageByte 图片
243 * @return Base64 String 249 * @return Base64 String
244 */ 250 */
245 public static String byte2Base64(byte[] imageByte) { 251 public static String byte2Base64(byte[] imageByte) {
246 if (null == imageByte) return null; 252 if (null == imageByte) return null;
247 return Base64.encodeToString(imageByte, Base64.DEFAULT); 253 return Base64.encodeToString(imageByte, Base64.DEFAULT);
248 } 254 }
249 255
250 public static Bitmap shotView(View v) { 256 public static Bitmap shotView(View v) {
251 Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565); 257 Bitmap bitmap = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.RGB_565);
252 Canvas canvas = new Canvas(bitmap); 258 Canvas canvas = new Canvas(bitmap);
253 v.draw(canvas); 259 v.draw(canvas);
254 return bitmap; 260 return bitmap;
255 } 261 }
256 262
257 263
258 } 264 }
259 265