├── .gitignore
├── README.md
├── apk
└── VirtualXposed_0.9.8.apk
├── app
├── build.gradle
├── libs
│ ├── XposedBridgeAPI-89.jar
│ ├── core_3.2.0.jar
│ ├── jsoup-1.7.2.jar
│ ├── myjson-1.5.jar
│ ├── nanohttpd-2.3.1-SNAPSHOT.jar
│ ├── org.apache.http.legacy.jar
│ └── xUtils-2.6.14.jar
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ └── xposed_init
│ ├── java
│ └── com
│ │ └── tools
│ │ └── payhelper
│ │ ├── AlarmReceiver.java
│ │ ├── AlipayHook.java
│ │ ├── CustomApplcation.java
│ │ ├── DaemonService.java
│ │ ├── HideModule.java
│ │ ├── Main.java
│ │ ├── MainActivity.java
│ │ ├── QQHook.java
│ │ ├── QQPlugHook.java
│ │ ├── SettingActivity.java
│ │ ├── WebServer.java
│ │ ├── WechatHook.java
│ │ ├── http
│ │ ├── CookieJarManager.java
│ │ ├── HttpRequest.java
│ │ ├── HttpUrl.java
│ │ ├── ParamField.java
│ │ ├── request
│ │ │ └── HttpParams.java
│ │ └── result
│ │ │ └── BaseResult.java
│ │ ├── tcp
│ │ ├── TcpCheck.java
│ │ ├── TcpConnection.java
│ │ ├── TcpSettingActivity.java
│ │ └── VerifyData.java
│ │ ├── threadpool
│ │ ├── ThreadPoolProxy.java
│ │ └── ThreadPoolProxyFactory.java
│ │ └── utils
│ │ ├── AbSharedUtil.java
│ │ ├── BitmapUtil.java
│ │ ├── CrashHandler.java
│ │ ├── DBHelper.java
│ │ ├── DBManager.java
│ │ ├── ExecutorManager.java
│ │ ├── ImageUtils.java
│ │ ├── JsonHelper.java
│ │ ├── LauncherLimitUtils.java
│ │ ├── LogToFile.java
│ │ ├── LogUtils.java
│ │ ├── Logger.java
│ │ ├── MD5.java
│ │ ├── OrderBean.java
│ │ ├── PayHelperUtils.java
│ │ ├── QQDBHelper.java
│ │ ├── QQDBManager.java
│ │ ├── QRUtils.java
│ │ ├── QrCodeBean.java
│ │ ├── StringUtils.java
│ │ ├── Tag.java
│ │ ├── TimeUtils.java
│ │ └── XmlToJson.java
│ └── res
│ ├── drawable-hdpi
│ ├── btn_back_grey.png
│ └── ic_launcher.png
│ ├── drawable-ldpi
│ └── ic_launcher.png
│ ├── drawable-mdpi
│ └── ic_launcher.png
│ ├── drawable-xhdpi
│ └── ic_launcher.png
│ ├── drawable-xxhdpi
│ └── ic_launcher.png
│ ├── drawable
│ └── button.xml
│ ├── layout
│ ├── activity_main.xml
│ ├── activity_setting.xml
│ └── activity_tcp_setting.xml
│ ├── menu
│ └── main.xml
│ ├── values-sw600dp
│ └── dimens.xml
│ ├── values-sw720dp-land
│ └── dimens.xml
│ ├── values-v11
│ └── styles.xml
│ ├── values-v14
│ └── styles.xml
│ └── values
│ ├── dimens.xml
│ ├── jpush_style.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── import-summary.txt
├── keystore
└── key.key
├── local.properties
└── settings.gradle
/.gitignore:
--------------------------------------------------------------------------------
1 | *.iml
2 | .gradle
3 | /local.properties
4 | /.idea
5 | .DS_Store
6 | /build
7 | /captures
8 | .externalNativeBuild
9 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PayHelper6.6.7_NewAPI
2 | The demo of Xposed.
3 |
--------------------------------------------------------------------------------
/apk/VirtualXposed_0.9.8.apk:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/apk/VirtualXposed_0.9.8.apk
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | static def buildTime() {
4 | return new Date().format("yyyy-MM-dd", TimeZone.getTimeZone("UTC"))
5 | }
6 |
7 | android {
8 | compileSdkVersion 25
9 |
10 | defaultConfig {
11 | applicationId "com.tools.payhelper1"
12 | minSdkVersion 15
13 | targetSdkVersion 28
14 | versionCode 2
15 | versionName "2.0.0"
16 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
17 | buildConfigField "String", "BUILD_TIME", "\"${buildTime()}\""
18 | }
19 | buildTypes {
20 | release {
21 | minifyEnabled false
22 | proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
23 | }
24 | }
25 | compileOptions {
26 | sourceCompatibility JavaVersion.VERSION_1_8
27 | targetCompatibility JavaVersion.VERSION_1_8
28 | }
29 | }
30 |
31 | dependencies {
32 | // implementation 'com.android.support:appcompat-v7:28.0.0'
33 | implementation 'com.android.support:support-v4:25.3.1'
34 | implementation files('libs/XposedBridgeAPI-89.jar')
35 | implementation files('libs/core_3.2.0.jar')
36 | implementation files('libs/jsoup-1.7.2.jar')
37 | implementation files('libs/myjson-1.5.jar')
38 | implementation files('libs/nanohttpd-2.3.1-SNAPSHOT.jar')
39 | implementation files('libs/org.apache.http.legacy.jar')
40 | implementation files('libs/xUtils-2.6.14.jar')
41 |
42 |
43 | implementation rootProject.ext.lib_okhttp_okhttp
44 | implementation rootProject.ext.lib_okhttp_okio
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/app/libs/XposedBridgeAPI-89.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/XposedBridgeAPI-89.jar
--------------------------------------------------------------------------------
/app/libs/core_3.2.0.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/core_3.2.0.jar
--------------------------------------------------------------------------------
/app/libs/jsoup-1.7.2.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/jsoup-1.7.2.jar
--------------------------------------------------------------------------------
/app/libs/myjson-1.5.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/myjson-1.5.jar
--------------------------------------------------------------------------------
/app/libs/nanohttpd-2.3.1-SNAPSHOT.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/nanohttpd-2.3.1-SNAPSHOT.jar
--------------------------------------------------------------------------------
/app/libs/org.apache.http.legacy.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/org.apache.http.legacy.jar
--------------------------------------------------------------------------------
/app/libs/xUtils-2.6.14.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/libs/xUtils-2.6.14.jar
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
26 |
30 |
31 |
32 |
33 |
34 |
35 |
40 |
45 |
46 |
51 |
52 |
55 |
58 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/app/src/main/assets/xposed_init:
--------------------------------------------------------------------------------
1 | com.tools.payhelper.Main
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/AlarmReceiver.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import java.util.List;
4 |
5 | import com.tools.payhelper.utils.DBManager;
6 | import com.tools.payhelper.utils.OrderBean;
7 | import com.tools.payhelper.utils.PayHelperUtils;
8 |
9 | import android.content.BroadcastReceiver;
10 | import android.content.Context;
11 | import android.content.Intent;
12 |
13 | /**
14 | *
15 |
16 | * @ClassName: AlarmReceiver
17 |
18 | * @Description: TODO(这里用一句话描述这个类的作用)
19 |
20 | * @author SuXiaoliang
21 |
22 | * @date 2018年6月23日 下午1:25:47
23 |
24 | *
25 | */
26 |
27 | public class AlarmReceiver extends BroadcastReceiver{
28 |
29 | @Override
30 | public void onReceive(Context context, Intent intent) {
31 | try {
32 | DBManager dbManager=new DBManager(context);
33 | List orderBeans=dbManager.FindAllOrders();
34 | for (OrderBean orderBean : orderBeans) {
35 | PayHelperUtils.notify(context, orderBean.getType(), orderBean.getNo(), orderBean.getMoney(), orderBean.getMark(), orderBean.getDt());
36 | }
37 | long currentTimeMillis=System.currentTimeMillis()/1000;
38 | long currentTimeMillis2=Long.parseLong(PayHelperUtils.getcurrentTimeMillis(context));
39 | long currentTimeMillis3=currentTimeMillis-currentTimeMillis2;
40 | if(currentTimeMillis3>120 && currentTimeMillis2!=0){
41 | PayHelperUtils.sendmsg(context, "轮询任务出现异常,重启中...");
42 | PayHelperUtils.startAlipayMonitor(context);
43 | PayHelperUtils.sendmsg(context, "轮询任务重启成功");
44 | }
45 | } catch (Exception e) {
46 | PayHelperUtils.sendmsg(context, "AlarmReceiver异常->>"+e.getMessage());
47 | }
48 | }
49 |
50 | }
51 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/AlipayHook.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 |
4 |
5 | import java.lang.reflect.Field;
6 | import java.util.Map;
7 |
8 | import org.json.JSONObject;
9 |
10 | import com.tools.payhelper.utils.LogToFile;
11 | import com.tools.payhelper.utils.PayHelperUtils;
12 | import com.tools.payhelper.utils.StringUtils;
13 |
14 | import android.app.Activity;
15 | import android.content.Context;
16 | import android.content.Intent;
17 | import android.os.Bundle;
18 | import android.widget.Button;
19 | import de.robv.android.xposed.XC_MethodHook;
20 | import de.robv.android.xposed.XC_MethodReplacement;
21 | import de.robv.android.xposed.XposedBridge;
22 | import de.robv.android.xposed.XposedHelpers;
23 |
24 | /**
25 | *
26 |
27 | * @ClassName: AlipayHook
28 |
29 | * @Description: TODO(这里用一句话描述这个类的作用)
30 |
31 | * @author SuXiaoliang
32 |
33 | * @date 2018年6月23日 下午1:25:54
34 |
35 | *
36 | */
37 |
38 | public class AlipayHook {
39 |
40 | public static String BILLRECEIVED_ACTION = "com.tools.payhelper.billreceived";
41 | public static String QRCODERECEIVED_ACTION = "com.tools.payhelper.qrcodereceived";
42 | public static String SAVEALIPAYCOOKIE_ACTION = "com.tools.payhelper.savealipaycookie";
43 |
44 | public void hook(final ClassLoader classLoader,final Context context) {
45 | securityCheckHook(classLoader);
46 | try {
47 | Class> insertTradeMessageInfo = XposedHelpers.findClass("com.alipay.android.phone.messageboxstatic.biz.dao.TradeDao", classLoader);
48 | XposedBridge.hookAllMethods(insertTradeMessageInfo, "insertMessageInfo", new XC_MethodHook() {
49 | @Override
50 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
51 | try {
52 | XposedBridge.log("======支付宝个人账号订单start=========");
53 |
54 | //更新cookie
55 | Intent cookieBroadCastIntent = new Intent();
56 | String alipaycookie=PayHelperUtils.getCookieStr(classLoader);
57 | cookieBroadCastIntent.putExtra("alipaycookie", alipaycookie);
58 | cookieBroadCastIntent.setAction(SAVEALIPAYCOOKIE_ACTION);
59 | context.sendBroadcast(cookieBroadCastIntent);
60 |
61 | //获取content字段
62 | // String content=(String) XposedHelpers.getObjectField(param.args[0], "content");
63 | // XposedBridge.log(content);
64 | //获取全部字段
65 | Object object = param.args[0];
66 | String MessageInfo = (String) XposedHelpers.callMethod(object, "toString");
67 | XposedBridge.log(MessageInfo);
68 | String content=StringUtils.getTextCenter(MessageInfo, "content='", "'");
69 | if(content.contains("二维码收款") || content.contains("收到一笔转账")){
70 | JSONObject jsonObject=new JSONObject(content);
71 | String money=jsonObject.getString("content").replace("¥", "");
72 | String mark=jsonObject.getString("assistMsg2");
73 | String tradeNo=StringUtils.getTextCenter(MessageInfo,"tradeNO=","&");
74 | XposedBridge.log("收到支付宝支付订单:"+tradeNo+"=="+money+"=="+mark);
75 |
76 | Intent broadCastIntent = new Intent();
77 | broadCastIntent.putExtra("bill_no", tradeNo);
78 | broadCastIntent.putExtra("bill_money", money);
79 | broadCastIntent.putExtra("bill_mark", mark);
80 | broadCastIntent.putExtra("bill_type", "alipay");
81 | broadCastIntent.setAction(BILLRECEIVED_ACTION);
82 | context.sendBroadcast(broadCastIntent);
83 | }
84 | XposedBridge.log("======支付宝个人账号订单end=========");
85 | } catch (Exception e) {
86 | XposedBridge.log(e.getMessage());
87 | }
88 | super.beforeHookedMethod(param);
89 | }
90 | });
91 | Class> insertServiceMessageInfo = XposedHelpers.findClass("com.alipay.android.phone.messageboxstatic.biz.dao.ServiceDao", classLoader);
92 | XposedBridge.hookAllMethods(insertServiceMessageInfo, "insertMessageInfo", new XC_MethodHook() {
93 | @Override
94 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
95 | try {
96 | XposedBridge.log("======支付宝商家服务订单start=========");
97 |
98 | //更新cookie
99 | Intent cookieBroadCastIntent = new Intent();
100 | String alipaycookie=PayHelperUtils.getCookieStr(classLoader);
101 | cookieBroadCastIntent.putExtra("alipaycookie", alipaycookie);
102 | cookieBroadCastIntent.setAction(SAVEALIPAYCOOKIE_ACTION);
103 | context.sendBroadcast(cookieBroadCastIntent);
104 |
105 | Object object = param.args[0];
106 | String MessageInfo = (String) XposedHelpers.callMethod(object, "toString");
107 | String content=StringUtils.getTextCenter(MessageInfo, "extraInfo='", "'").replace("\\", "");
108 | XposedBridge.log(content);
109 | if(content.contains("店员通")){
110 | String money=StringUtils.getTextCenter(content, "mainAmount\":\"", "\",\"mainTitle");
111 | String time=StringUtils.getTextCenter(content, "gmtCreate\":", ",gmtValid");
112 | String no=PayHelperUtils.getOrderId();
113 | Intent broadCastIntent = new Intent();
114 | broadCastIntent.putExtra("bill_no", no);
115 | broadCastIntent.putExtra("bill_money", money);
116 | broadCastIntent.putExtra("bill_mark", "");
117 | broadCastIntent.putExtra("bill_time", time);
118 | broadCastIntent.putExtra("bill_type", "alipay_dy");
119 | broadCastIntent.setAction(BILLRECEIVED_ACTION);
120 | context.sendBroadcast(broadCastIntent);
121 | }else if(content.contains("收钱到账") || content.contains("收款到账")){
122 | LogToFile.i("payhelper", "Hook到商家服务通知,开始调用getBill获取订单详细信息");
123 | String userId=PayHelperUtils.getAlipayUserId(classLoader);
124 | PayHelperUtils.getBill(context,alipaycookie,userId);
125 | }
126 | XposedBridge.log("======支付宝商家服务订单end=========");
127 | } catch (Exception e) {
128 | PayHelperUtils.sendmsg(context, e.getMessage());
129 | }
130 | super.beforeHookedMethod(param);
131 | }
132 | });
133 |
134 | // hook设置金额和备注的onCreate方法,自动填写数据并点击
135 | XposedHelpers.findAndHookMethod("com.alipay.mobile.payee.ui.PayeeQRSetMoneyActivity", classLoader, "onCreate", Bundle.class, new XC_MethodHook() {
136 | @Override
137 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
138 | XposedBridge.log("========支付宝设置金额start=========");
139 |
140 | //更新cookie
141 | Intent cookieBroadCastIntent = new Intent();
142 | String alipaycookie=PayHelperUtils.getCookieStr(classLoader);
143 | cookieBroadCastIntent.putExtra("alipaycookie", alipaycookie);
144 | cookieBroadCastIntent.setAction(SAVEALIPAYCOOKIE_ACTION);
145 | context.sendBroadcast(cookieBroadCastIntent);
146 |
147 | Field jinErField = XposedHelpers.findField(param.thisObject.getClass(), "b");
148 | final Object jinErView = jinErField.get(param.thisObject);
149 | Field beiZhuField = XposedHelpers.findField(param.thisObject.getClass(), "c");
150 | final Object beiZhuView = beiZhuField.get(param.thisObject);
151 | Intent intent = ((Activity) param.thisObject).getIntent();
152 | String mark=intent.getStringExtra("mark");
153 | String money=intent.getStringExtra("money");
154 | //设置支付宝金额和备注
155 | XposedHelpers.callMethod(jinErView, "setText", money);
156 | XposedHelpers.callMethod(beiZhuView, "setText", mark);
157 | //点击确认
158 | Field quRenField = XposedHelpers.findField(param.thisObject.getClass(), "e");
159 | final Button quRenButton = (Button) quRenField.get(param.thisObject);
160 | quRenButton.performClick();
161 | XposedBridge.log("=========支付宝设置金额end========");
162 | }
163 | });
164 |
165 | // hook获得二维码url的回调方法
166 | XposedHelpers.findAndHookMethod("com.alipay.mobile.payee.ui.PayeeQRSetMoneyActivity", classLoader, "a",
167 | XposedHelpers.findClass("com.alipay.transferprod.rpc.result.ConsultSetAmountRes", classLoader), new XC_MethodHook() {
168 | @Override
169 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
170 | XposedBridge.log("=========支付宝生成完成start========");
171 | Field moneyField = XposedHelpers.findField(param.thisObject.getClass(), "g");
172 | String money = (String) moneyField.get(param.thisObject);
173 |
174 | Field markField = XposedHelpers.findField(param.thisObject.getClass(), "c");
175 | Object markObject = markField.get(param.thisObject);
176 | String mark=(String) XposedHelpers.callMethod(markObject, "getUbbStr");
177 |
178 | Object consultSetAmountRes = param.args[0];
179 | Field consultField = XposedHelpers.findField(consultSetAmountRes.getClass(), "qrCodeUrl");
180 | String payurl = (String) consultField.get(consultSetAmountRes);
181 | XposedBridge.log(money+" "+mark+" "+payurl);
182 |
183 | if(money!=null){
184 | XposedBridge.log("调用增加数据方法==>支付宝");
185 | Intent broadCastIntent = new Intent();
186 | broadCastIntent.putExtra("money", money);
187 | broadCastIntent.putExtra("mark", mark);
188 | broadCastIntent.putExtra("type", "alipay");
189 | broadCastIntent.putExtra("payurl", payurl);
190 | broadCastIntent.setAction(QRCODERECEIVED_ACTION);
191 | context.sendBroadcast(broadCastIntent);
192 | }
193 | XposedBridge.log("=========支付宝生成完成end========");
194 | }
195 | });
196 |
197 | // hook获取loginid
198 | XposedHelpers.findAndHookMethod("com.alipay.mobile.quinox.LauncherActivity", classLoader, "onResume",
199 | new XC_MethodHook() {
200 | @Override
201 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
202 | PayHelperUtils.isFirst=true;
203 | String loginid=PayHelperUtils.getAlipayLoginId(classLoader);
204 | PayHelperUtils.sendLoginId(loginid, "alipay", context);
205 | }
206 | });
207 |
208 | //拦截“人气大爆发,一会再试试”
209 | XposedHelpers.findAndHookMethod("com.alipay.mobile.antui.basic.AUDialog", classLoader, "show",
210 | new XC_MethodHook() {
211 |
212 | @Override
213 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
214 | Context mContext=(Context) XposedHelpers.getObjectField(param.thisObject, "mContext");
215 | if (mContext.getClass().getSimpleName().equals("PayeeQRSetMoneyActivity")){
216 | XposedHelpers.setObjectField(param.thisObject, "mContext", null);
217 | }
218 | }
219 |
220 | });
221 |
222 | //拦截设置cookie
223 | XposedHelpers.findAndHookMethod("com.alipay.mobile.common.transport.http.GwCookieCacheHelper", classLoader, "setCookies",String.class,Map.class,
224 | new XC_MethodHook() {
225 |
226 | @Override
227 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
228 | String domain=param.args[0].toString();
229 | Map cookie=(Map)param.args[1];
230 | String ck=(String) XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.alipay.mobile.common.transport.http.GwCookieCacheHelper", classLoader), "toCookieString",cookie);
231 | if(ck.contains("ALIPAYJSESSIONID")){
232 | //更新cookie
233 | Intent cookieBroadCastIntent = new Intent();
234 | cookieBroadCastIntent.putExtra("alipaycookie", ck);
235 | cookieBroadCastIntent.setAction(SAVEALIPAYCOOKIE_ACTION);
236 | context.sendBroadcast(cookieBroadCastIntent);
237 | }
238 | }
239 |
240 | });
241 | } catch (Error | Exception e) {
242 | PayHelperUtils.sendmsg(context, e.getMessage());
243 | }
244 | }
245 |
246 | private void securityCheckHook(ClassLoader classLoader) {
247 | try {
248 | Class> securityCheckClazz = XposedHelpers.findClass("com.alipay.mobile.base.security.CI", classLoader);
249 | XposedHelpers.findAndHookMethod(securityCheckClazz, "a", String.class, String.class, String.class, new XC_MethodHook() {
250 | @Override
251 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
252 | Object object = param.getResult();
253 | XposedHelpers.setBooleanField(object, "a", false);
254 | param.setResult(object);
255 | super.afterHookedMethod(param);
256 | }
257 | });
258 |
259 | XposedHelpers.findAndHookMethod(securityCheckClazz, "a", Class.class, String.class, String.class, new XC_MethodReplacement() {
260 | @Override
261 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
262 | return (byte) 1;
263 | }
264 | });
265 | XposedHelpers.findAndHookMethod(securityCheckClazz, "a", ClassLoader.class, String.class, new XC_MethodReplacement() {
266 | @Override
267 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
268 | return (byte) 1;
269 | }
270 | });
271 | XposedHelpers.findAndHookMethod(securityCheckClazz, "a", new XC_MethodReplacement() {
272 | @Override
273 | protected Object replaceHookedMethod(MethodHookParam param) throws Throwable {
274 | return false;
275 | }
276 | });
277 |
278 | } catch (Error | Exception e) {
279 | e.printStackTrace();
280 | }
281 | }
282 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/CustomApplcation.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 |
4 | import com.tools.payhelper.utils.CrashHandler;
5 | import com.tools.payhelper.utils.LogUtils;
6 |
7 | import android.app.Application;
8 | import android.content.Context;
9 |
10 | /**
11 | * @author SuXiaoliang
12 | * @ClassName: CustomApplcation
13 | * @Description: TODO(这里用一句话描述这个类的作用)
14 | * @date 2018年6月23日 下午1:26:02
15 | */
16 |
17 | public class CustomApplcation extends Application {
18 |
19 | public static CustomApplcation mInstance;
20 | private static Context context;
21 |
22 | @Override
23 | public void onCreate() {
24 | super.onCreate();
25 | // 崩溃记录
26 | context = getApplicationContext();
27 | CrashHandler crashHandler = CrashHandler.getInstance();
28 | crashHandler.init(context);
29 | LogUtils.init(context, true, false);
30 | mInstance = this;
31 | }
32 |
33 | public static CustomApplcation getInstance() {
34 | return mInstance;
35 | }
36 |
37 | public static Context getContext() {
38 | return context;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/DaemonService.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import com.tools.payhelper.utils.AbSharedUtil;
4 | import com.tools.payhelper.utils.PayHelperUtils;
5 |
6 | import android.app.AlarmManager;
7 | import android.app.Notification;
8 | import android.app.NotificationManager;
9 | import android.app.PendingIntent;
10 | import android.app.Service;
11 | import android.content.Intent;
12 | import android.content.IntentFilter;
13 | import android.os.Build;
14 | import android.os.IBinder;
15 | import android.os.SystemClock;
16 | import android.support.annotation.Nullable;
17 | import de.robv.android.xposed.XposedBridge;
18 |
19 | /**
20 | *
21 |
22 | * @ClassName: DaemonService
23 |
24 | * @Description: TODO(这里用一句话描述这个类的作用)
25 |
26 | * @author SuXiaoliang
27 |
28 | * @date 2018年6月23日 下午1:26:14
29 |
30 | *
31 | */
32 | public class DaemonService extends Service {
33 | public static String NOTIFY_ACTION = "com.tools.payhelper.notify";
34 | private static final String TAG = "DaemonService";
35 | public static final int NOTICE_ID = 100;
36 |
37 | @Nullable
38 | @Override
39 | public IBinder onBind(Intent intent) {
40 | return null;
41 | }
42 |
43 |
44 | @Override
45 | public void onCreate() {
46 | super.onCreate();
47 | //如果API大于18,需要弹出一个可见通知
48 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
49 | Notification.Builder builder = new Notification.Builder(this);
50 | builder.setSmallIcon(R.drawable.ic_launcher);
51 | builder.setContentTitle("收款助手");
52 | builder.setContentText("收款助手正在运行中...");
53 | builder.setAutoCancel(false);
54 | builder.setOngoing(true);
55 | startForeground(NOTICE_ID,builder.build());
56 | }else{
57 | startForeground(NOTICE_ID,new Notification());
58 | }
59 | PayHelperUtils.sendmsg(getApplicationContext(), "启动定时任务");
60 |
61 | AlarmManager manager = (AlarmManager) getSystemService(ALARM_SERVICE);
62 | int time=AbSharedUtil.getInt(getApplicationContext(), "time");
63 | int triggerTime = 3 * 60 * 1000;
64 | if(time!=0){
65 | triggerTime = time * 1000;
66 | }
67 | Intent i = new Intent(NOTIFY_ACTION);
68 | PendingIntent pi = PendingIntent.getBroadcast(this, 0, i, PendingIntent.FLAG_UPDATE_CURRENT);
69 | manager.setRepeating(AlarmManager.RTC_WAKEUP , System.currentTimeMillis(), triggerTime, pi);
70 |
71 | }
72 |
73 | @Override
74 | public int onStartCommand(Intent intent, int flags, int startId) {
75 | // 如果Service被终止
76 | // 当资源允许情况下,重启service
77 | return START_STICKY;
78 | }
79 |
80 |
81 | @Override
82 | public void onDestroy() {
83 | super.onDestroy();
84 | // 如果Service被杀死,干掉通知
85 | if(Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2){
86 | NotificationManager mManager = (NotificationManager)getSystemService(NOTIFICATION_SERVICE);
87 | mManager.cancel(NOTICE_ID);
88 | }
89 | // 重启自己
90 | Intent intent = new Intent(getApplicationContext(),DaemonService.class);
91 | startService(intent);
92 | }
93 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/HideModule.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import android.app.ActivityManager;
4 | import android.content.pm.ApplicationInfo;
5 | import android.content.pm.PackageInfo;
6 |
7 | import java.util.ArrayList;
8 | import java.util.List;
9 |
10 | import de.robv.android.xposed.XC_MethodHook;
11 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
12 |
13 | import static de.robv.android.xposed.XposedBridge.log;
14 | import static de.robv.android.xposed.XposedHelpers.findAndHookMethod;
15 |
16 | /**
17 | *
18 |
19 | * @ClassName: HideModule
20 |
21 | * @Description: TODO(这里用一句话描述这个类的作用)
22 |
23 | * @author SuXiaoliang
24 |
25 | * @date 2018年6月23日 下午1:26:20
26 |
27 | *
28 | */
29 | public class HideModule {
30 |
31 | static void hideModule(XC_LoadPackage.LoadPackageParam loadPackageParam) {
32 | findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledApplications", int.class, new XC_MethodHook() {
33 | @Override
34 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
35 | List applicationList = (List) param.getResult();
36 | List resultapplicationList = new ArrayList<>();
37 | for (ApplicationInfo applicationInfo : applicationList) {
38 | String packageName = applicationInfo.packageName;
39 | if (isTarget(packageName)) {
40 | log("Hid package: " + packageName);
41 | } else {
42 | resultapplicationList.add(applicationInfo);
43 | }
44 | }
45 | param.setResult(resultapplicationList);
46 | }
47 | });
48 | findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getInstalledPackages", int.class, new XC_MethodHook() {
49 | @Override
50 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
51 | List packageInfoList = (List) param.getResult();
52 | List resultpackageInfoList = new ArrayList<>();
53 |
54 | for (PackageInfo packageInfo : packageInfoList) {
55 | String packageName = packageInfo.packageName;
56 | if (isTarget(packageName)) {
57 | log("Hid package: " + packageName);
58 | } else {
59 | resultpackageInfoList.add(packageInfo);
60 | }
61 | }
62 | param.setResult(resultpackageInfoList);
63 | }
64 | });
65 | findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getPackageInfo", String.class, int.class, new XC_MethodHook() {
66 | @Override
67 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
68 | String packageName = (String) param.args[0];
69 | if (isTarget(packageName)) {
70 | param.args[0] = Main.QQ_PACKAGE;
71 | log("Fake package: " + packageName + " as " + Main.QQ_PACKAGE);
72 | }
73 | }
74 | });
75 | findAndHookMethod("android.app.ApplicationPackageManager", loadPackageParam.classLoader, "getApplicationInfo", String.class, int.class, new XC_MethodHook() {
76 | @Override
77 | protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
78 | String packageName = (String) param.args[0];
79 | if (isTarget(packageName)) {
80 | param.args[0] = Main.QQ_PACKAGE;
81 | log("Fake package: " + packageName + " as " + Main.QQ_PACKAGE);
82 | }
83 | }
84 | });
85 | findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningServices", int.class, new XC_MethodHook() {
86 | @Override
87 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
88 | List serviceInfoList = (List) param.getResult();
89 | List resultList = new ArrayList<>();
90 |
91 | for (ActivityManager.RunningServiceInfo runningServiceInfo : serviceInfoList) {
92 | String serviceName = runningServiceInfo.process;
93 | if (isTarget(serviceName)) {
94 | log("Hid service: " + serviceName);
95 | } else {
96 | resultList.add(runningServiceInfo);
97 | }
98 | }
99 | param.setResult(resultList);
100 | }
101 | });
102 | findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningTasks", int.class, new XC_MethodHook() {
103 | @Override
104 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
105 | List serviceInfoList = (List) param.getResult();
106 | List resultList = new ArrayList<>();
107 |
108 | for (ActivityManager.RunningTaskInfo runningTaskInfo : serviceInfoList) {
109 | String taskName = runningTaskInfo.baseActivity.flattenToString();
110 | if (isTarget(taskName)) {
111 | log("Hid task: " + taskName);
112 | } else {
113 | resultList.add(runningTaskInfo);
114 | }
115 | }
116 | param.setResult(resultList);
117 | }
118 | });
119 | findAndHookMethod("android.app.ActivityManager", loadPackageParam.classLoader, "getRunningAppProcesses", new XC_MethodHook() {
120 | @Override
121 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
122 | List runningAppProcessInfos = (List) param.getResult();
123 | List resultList = new ArrayList<>();
124 |
125 | for (ActivityManager.RunningAppProcessInfo runningAppProcessInfo : runningAppProcessInfos) {
126 | String processName = runningAppProcessInfo.processName;
127 | if (isTarget(processName)) {
128 | log("Hid process: " + processName);
129 | } else {
130 | resultList.add(runningAppProcessInfo);
131 | }
132 | }
133 | param.setResult(resultList);
134 | }
135 | });
136 | }
137 |
138 | private static boolean isTarget(String name) {
139 | return name.contains("payhelper") || name.contains("xposed");
140 | }
141 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/Main.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import java.io.File;
4 |
5 | import com.tools.payhelper.utils.PayHelperUtils;
6 | import com.tools.payhelper.utils.QQDBManager;
7 |
8 | import android.app.Application;
9 | import android.content.BroadcastReceiver;
10 | import android.content.Context;
11 | import android.content.ContextWrapper;
12 | import android.content.Intent;
13 | import android.content.IntentFilter;
14 | import android.content.pm.ApplicationInfo;
15 | import android.net.Uri;
16 | import android.text.TextUtils;
17 | import dalvik.system.BaseDexClassLoader;
18 | import de.robv.android.xposed.IXposedHookLoadPackage;
19 | import de.robv.android.xposed.XC_MethodHook;
20 | import de.robv.android.xposed.XposedBridge;
21 | import de.robv.android.xposed.XposedHelpers;
22 | import de.robv.android.xposed.callbacks.XC_LoadPackage;
23 |
24 | /**
25 | *
26 |
27 | * @ClassName: Main
28 |
29 | * @Description: TODO(这里用一句话描述这个类的作用)
30 |
31 | * @author SuXiaoliang
32 |
33 | * @date 2018年6月23日 下午1:26:26
34 |
35 | *
36 | */
37 | public class Main implements IXposedHookLoadPackage {
38 | public static String WECHAT_PACKAGE = "com.tencent.mm";
39 | public static String ALIPAY_PACKAGE = "com.eg.android.AlipayGphone";
40 | public static String QQ_PACKAGE = "com.tencent.mobileqq";
41 | public static String QQ_WALLET_PACKAGE = "com.qwallet";
42 | public static boolean WECHAT_PACKAGE_ISHOOK = false;
43 | public static boolean ALIPAY_PACKAGE_ISHOOK = false;
44 | public static boolean QQ_PACKAGE_ISHOOK = false;
45 | public static boolean QQ_WALLET_ISHOOK = false;
46 |
47 |
48 | @Override
49 | public void handleLoadPackage(final XC_LoadPackage.LoadPackageParam lpparam)
50 | throws Throwable {
51 | if (lpparam.appInfo == null || (lpparam.appInfo.flags & (ApplicationInfo.FLAG_SYSTEM |
52 | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0) {
53 | return;
54 | }
55 | final String packageName = lpparam.packageName;
56 | final String processName = lpparam.processName;
57 | if (WECHAT_PACKAGE.equals(packageName)) {
58 | try {
59 | XposedHelpers.findAndHookMethod(ContextWrapper.class, "attachBaseContext", Context.class, new XC_MethodHook() {
60 | @Override
61 | protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
62 | super.afterHookedMethod(param);
63 | Context context = (Context) param.args[0];
64 | ClassLoader appClassLoader = context.getClassLoader();
65 | if(WECHAT_PACKAGE.equals(processName) && !WECHAT_PACKAGE_ISHOOK){
66 | WECHAT_PACKAGE_ISHOOK=true;
67 | //注册广播
68 | StartWechatReceived stratWechat=new StartWechatReceived();
69 | IntentFilter intentFilter = new IntentFilter();
70 | intentFilter.addAction("com.payhelper.wechat.start");
71 | context.registerReceiver(stratWechat, intentFilter);
72 | XposedBridge.log("handleLoadPackage: " + packageName);
73 | PayHelperUtils.sendmsg(context, "微信Hook成功,当前微信版本:"+PayHelperUtils.getVerName(context));
74 | new WechatHook().hook(appClassLoader,context);
75 | }
76 | }
77 | });
78 | } catch (Throwable e) {
79 | XposedBridge.log(e);
80 | }
81 | }else if(ALIPAY_PACKAGE.equals(packageName)){
82 | try {
83 | XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
84 | @Override
85 | protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
86 | super.afterHookedMethod(param);
87 | Context context = (Context) param.args[0];
88 | ClassLoader appClassLoader = context.getClassLoader();
89 | if(ALIPAY_PACKAGE.equals(processName) && !ALIPAY_PACKAGE_ISHOOK){
90 | ALIPAY_PACKAGE_ISHOOK=true;
91 | //注册广播
92 | StartAlipayReceived startAlipay=new StartAlipayReceived();
93 | IntentFilter intentFilter = new IntentFilter();
94 | intentFilter.addAction("com.payhelper.alipay.start");
95 | context.registerReceiver(startAlipay, intentFilter);
96 | XposedBridge.log("handleLoadPackage: " + packageName);
97 | PayHelperUtils.sendmsg(context, "支付宝Hook成功,当前支付宝版本:"+PayHelperUtils.getVerName(context));
98 | new AlipayHook().hook(appClassLoader,context);
99 | }
100 | }
101 | });
102 | }catch (Throwable e) {
103 | XposedBridge.log(e);
104 | }
105 | }else if(QQ_PACKAGE.equals(packageName)){
106 | try {
107 | XposedHelpers.findAndHookMethod(Application.class, "attach", Context.class, new XC_MethodHook() {
108 | @Override
109 | protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
110 | super.afterHookedMethod(param);
111 | Context context = (Context) param.args[0];
112 | ClassLoader appClassLoader = context.getClassLoader();
113 | if(QQ_PACKAGE.equals(processName) && !QQ_PACKAGE_ISHOOK){
114 | QQ_PACKAGE_ISHOOK=true;
115 | //注册广播
116 | StartQQReceived startQQ=new StartQQReceived();
117 | IntentFilter intentFilter = new IntentFilter();
118 | intentFilter.addAction("com.payhelper.qq.start");
119 | context.registerReceiver(startQQ, intentFilter);
120 | XposedBridge.log("handleLoadPackage: " + packageName);
121 | PayHelperUtils.sendmsg(context, "QQHook成功,当前QQ版本:"+PayHelperUtils.getVerName(context));
122 | new QQHook().hook(appClassLoader,context);
123 | }
124 | }
125 | });
126 |
127 | XposedHelpers.findAndHookConstructor("dalvik.system.BaseDexClassLoader",
128 | lpparam.classLoader, String.class, File.class, String.class, ClassLoader.class, new XC_MethodHook() {
129 | @Override
130 | protected void afterHookedMethod(XC_MethodHook.MethodHookParam param) throws Throwable {
131 |
132 | if (param.args[0].toString().contains("qwallet_plugin.apk")) {
133 | ClassLoader classLoader = (BaseDexClassLoader) param.thisObject;
134 | new QQPlugHook().hook(classLoader);
135 | }
136 | }
137 | });
138 | }catch (Exception e) {
139 | XposedBridge.log(e);
140 | }
141 | }
142 | }
143 |
144 |
145 | //自定义启动微信广播
146 | class StartWechatReceived extends BroadcastReceiver {
147 | @Override
148 | public void onReceive(Context context, Intent intent) {
149 | XposedBridge.log("启动微信Activity");
150 | try {
151 | Intent intent2=new Intent(context, XposedHelpers.findClass("com.tencent.mm.plugin.collect.ui.CollectCreateQRCodeUI", context.getClassLoader()));
152 | intent2.putExtra("mark", intent.getStringExtra("mark"));
153 | intent2.putExtra("money", intent.getStringExtra("money"));
154 | intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
155 | context.startActivity(intent2);
156 | XposedBridge.log("启动微信成功");
157 | } catch (Exception e) {
158 | XposedBridge.log("启动微信失败:"+e.getMessage());
159 | }
160 | }
161 | }
162 | //自定义启动支付宝广播
163 | class StartAlipayReceived extends BroadcastReceiver {
164 | @Override
165 | public void onReceive(Context context, Intent intent) {
166 | XposedBridge.log("启动支付宝Activity");
167 | Intent intent2=new Intent(context, XposedHelpers.findClass("com.alipay.mobile.payee.ui.PayeeQRSetMoneyActivity", context.getClassLoader()));
168 | intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
169 | intent2.putExtra("mark", intent.getStringExtra("mark"));
170 | intent2.putExtra("money", intent.getStringExtra("money"));
171 | context.startActivity(intent2);
172 | }
173 | }
174 |
175 | //自定义启动QQ广播
176 | class StartQQReceived extends BroadcastReceiver {
177 | @Override
178 | public void onReceive(Context context, Intent intent) {
179 | XposedBridge.log("启动QQActivity");
180 | try {
181 | // PayHelperUtils.sendmsg(context, "启动QQActivity"+l);
182 |
183 | String money=intent.getStringExtra("money");
184 | String mark=intent.getStringExtra("mark");
185 | if(!TextUtils.isEmpty(money) && !TextUtils.isEmpty(mark)){
186 | QQDBManager qqdbManager=new QQDBManager(context);
187 | qqdbManager.addQQMark(intent.getStringExtra("money"),intent.getStringExtra("mark"));
188 | long l=System.currentTimeMillis();
189 | String url="mqqapi://wallet/open?src_type=web&viewtype=0&version=1&view=7&entry=1&seq=" + l;
190 | Intent intent2=new Intent(Intent.ACTION_VIEW, Uri.parse(url));
191 | intent2.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
192 | context.startActivity(intent2);
193 | }
194 |
195 | // PayHelperUtils.sendmsg(context, "启动成功"+l);
196 | } catch (Exception e) {
197 | PayHelperUtils.sendmsg(context, "StartQQReceived异常"+e.getMessage());
198 | }
199 | }
200 | }
201 | }
202 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/QQHook.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 |
4 |
5 | import com.tools.payhelper.utils.PayHelperUtils;
6 | import com.tools.payhelper.utils.StringUtils;
7 |
8 | import android.app.Activity;
9 | import android.content.Context;
10 | import android.content.Intent;
11 | import de.robv.android.xposed.XC_MethodHook;
12 | import de.robv.android.xposed.XposedBridge;
13 | import de.robv.android.xposed.XposedHelpers;
14 |
15 | /**
16 | *
17 |
18 | * @ClassName: QQHook
19 |
20 | * @Description: TODO(这里用一句话描述这个类的作用)
21 |
22 | * @author SuXiaoliang
23 |
24 | * @date 2018年6月23日 下午1:26:39
25 |
26 | *
27 | */
28 |
29 | public class QQHook {
30 |
31 | public static String BILLRECEIVED_ACTION = "com.tools.payhelper.billreceived";
32 |
33 | public void hook(final ClassLoader classLoader,final Context context) {
34 | try {
35 | XposedHelpers.findAndHookMethod("com.tencent.mobileqq.app.MessageHandlerUtils", classLoader, "a",
36 | "com.tencent.mobileqq.app.QQAppInterface",
37 | "com.tencent.mobileqq.data.MessageRecord", Boolean.TYPE, new XC_MethodHook() {
38 | @Override
39 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
40 | byte[] msgData= (byte[]) XposedHelpers.getObjectField(param.args[1], "msgData");
41 | Class> clazz=XposedHelpers.findClass("com.tencent.mobileqq.structmsg.StructMsgFactory", classLoader);
42 | Object object=XposedHelpers.callStaticMethod(clazz, "a", msgData);
43 | if(object!=null){
44 | String xml=(String) XposedHelpers.callMethod(object, "getXml");
45 | XposedBridge.log(xml);
46 | PayHelperUtils.sendmsg(context, xml);
47 | if(xml.contains("转账金额")){
48 | XposedBridge.log("=========qq钱包收到订单start========");
49 | String tradeno=StringUtils.getTextCenter(xml, "transId=", "\"");
50 | String money=StringUtils.getTextCenter(xml, "转账金额:", "");
51 | String mark=StringUtils.getTextCenter(xml, "转账留言:", "");
52 | XposedBridge.log("收到qq支付订单:"+tradeno+"=="+money+"=="+mark);
53 | Intent broadCastIntent = new Intent();
54 | broadCastIntent.putExtra("bill_no", tradeno);
55 | broadCastIntent.putExtra("bill_money", money);
56 | broadCastIntent.putExtra("bill_mark", mark);
57 | broadCastIntent.putExtra("bill_type", "qq");
58 | broadCastIntent.setAction(BILLRECEIVED_ACTION);
59 | context.sendBroadcast(broadCastIntent);
60 | XposedBridge.log("=========qq钱包收到订单start========");
61 | }
62 | }
63 | }
64 | }
65 | );
66 | XposedHelpers.findAndHookMethod("com.tencent.mobileqq.activity.SplashActivity", classLoader, "doOnResume",
67 | new XC_MethodHook() {
68 | @Override
69 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
70 | Activity activity=(Activity) param.thisObject;
71 | String loginid=PayHelperUtils.getQQLoginId(activity);
72 | PayHelperUtils.sendLoginId(loginid, "qq", activity);
73 | }
74 | }
75 | );
76 | } catch (Exception e) {
77 | PayHelperUtils.sendmsg(context, "QQHook异常");
78 | }
79 | /*XposedHelpers.findAndHookMethod("com.tencent.mobileqq.activity.SplashActivity", classLoader, "doOnCreate",
80 | Bundle.class, new XC_MethodHook() {
81 | @Override
82 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
83 | Activity activity=(Activity) param.thisObject;
84 | PayHelperUtils.sendmsg(activity, "SplashActivity---->doOnCreate");
85 | ClassLoader walletClassLoader = (ClassLoader) XposedHelpers.callStaticMethod(XposedHelpers.findClass("com.tencent.mobileqq.pluginsdk.PluginStatic", classLoader), "getOrCreateClassLoader", context, "qwallet_plugin.apk");
86 | if(walletClassLoader!=null){
87 | PayHelperUtils.sendmsg(context, "walletClassLoader不为空");
88 | }else{
89 | PayHelperUtils.sendmsg(context, "walletClassLoader为空");
90 | }
91 | }
92 | }
93 | );
94 | XposedHelpers.findAndHookMethod("com.tencent.mobileqq.activity.JumpActivity", classLoader, "doOnCreate",
95 | Bundle.class, new XC_MethodHook() {
96 | @Override
97 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
98 | Activity activity=(Activity) param.thisObject;
99 | PayHelperUtils.sendmsg(activity, "JumpActivity---->doOnCreate");
100 | Intent intent=(Intent) XposedHelpers.callMethod(param.thisObject, "getIntent");
101 | String url=intent.getDataString();
102 | PayHelperUtils.sendmsg(activity, url);
103 | }
104 | }
105 | );*/
106 | }
107 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/QQPlugHook.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 |
4 |
5 | import java.util.Map;
6 | import java.util.Map.Entry;
7 |
8 | import org.json.JSONObject;
9 |
10 | import com.tools.payhelper.utils.PayHelperUtils;
11 | import com.tools.payhelper.utils.QQDBManager;
12 | import com.tools.payhelper.utils.QrCodeBean;
13 |
14 | import android.app.Activity;
15 | import android.content.Context;
16 | import android.content.Intent;
17 | import android.os.Bundle;
18 | import android.text.TextUtils;
19 | import android.view.View;
20 | import android.widget.Button;
21 | import de.robv.android.xposed.XC_MethodHook;
22 | import de.robv.android.xposed.XposedBridge;
23 | import de.robv.android.xposed.XposedHelpers;
24 |
25 | /**
26 | *
27 |
28 | * @ClassName: QQPlugHook
29 |
30 | * @Description: TODO(这里用一句话描述这个类的作用)
31 |
32 | * @author SuXiaoliang
33 |
34 | * @date 2018年6月23日 下午1:26:46
35 |
36 | *
37 | */
38 |
39 | public class QQPlugHook {
40 |
41 | public static String QRCODERECEIVED_ACTION = "com.tools.payhelper.qrcodereceived";
42 |
43 | public void hook(final ClassLoader classLoader) {
44 | XposedHelpers.findAndHookMethod("com.tenpay.sdk.activity.QrcodePayActivity", classLoader, "onCreate",
45 | Bundle.class, new XC_MethodHook() {
46 | @Override
47 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
48 | XposedBridge.log("=========qq钱包打开付款start========");
49 | Activity activity=(Activity) param.thisObject;
50 | // PayHelperUtils.sendmsg(activity, "QrcodePayActivity---->>onCreate");
51 | XposedHelpers.setIntField(param.thisObject, "n", 1);
52 | XposedHelpers.setBooleanField(param.thisObject, "o", true);
53 | XposedHelpers.callMethod(param.thisObject, "d");
54 | View view=new View(activity);
55 | view.setId(2131363428);
56 | XposedHelpers.callMethod(param.thisObject, "onClick", view);
57 | XposedBridge.log("=========qq钱包打开付款end========");
58 | }
59 | }
60 | );
61 |
62 | XposedHelpers.findAndHookMethod("com.tenpay.sdk.activity.QrcodeSettingActivity", classLoader, "onCreate",
63 | Bundle.class, new XC_MethodHook() {
64 | @Override
65 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
66 | XposedBridge.log("=========qq钱包设置金额start========");
67 | Activity activity=(Activity) param.thisObject;
68 | QQDBManager qqdbManager=new QQDBManager(activity);
69 | QrCodeBean qrCodeBean=qqdbManager.GetQQMark();
70 | String money=qrCodeBean.getMoney();
71 | String mark=qrCodeBean.getMark();
72 | if(!TextUtils.isEmpty(money) && !TextUtils.isEmpty(mark)){
73 | qqdbManager.updateOrder(money, mark);
74 | Object d= XposedHelpers.getObjectField(param.thisObject, "d");
75 | XposedHelpers.callMethod(d, "setText",money);
76 | Object e= XposedHelpers.getObjectField(param.thisObject, "e");
77 | XposedHelpers.callMethod(e, "setText",mark);
78 | Button c= (Button) XposedHelpers.getObjectField(param.thisObject, "c");
79 | c.performClick();
80 | }
81 | XposedBridge.log("=========qq钱包设置金额end========");
82 | }
83 | }
84 | );
85 | /*XposedHelpers.findAndHookMethod("com.tenpay.sdk.activity.NetBaseActivity", classLoader, "a",
86 | String.class,Map.class, new XC_MethodHook() {
87 | @Override
88 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
89 | Activity activity=(Activity) param.thisObject;
90 | Map map=(Map) param.args[1];
91 | String url=(String) param.args[0];
92 | StringBuffer buffer=new StringBuffer();
93 | for (Entry entry : map.entrySet()) {
94 | buffer.append(entry.getKey());
95 | buffer.append("=");
96 | buffer.append(entry.getValue());
97 | buffer.append("&");
98 | }
99 | PayHelperUtils.sendmsg(activity, "NetBaseActivity---->>a");
100 | PayHelperUtils.sendmsg(activity, url+buffer.substring(0, buffer.toString().length()-1));
101 | }
102 | }
103 | );
104 | XposedHelpers.findAndHookMethod("com.tenpay.sdk.h.y", classLoader, "c",
105 | String.class, new XC_MethodHook() {
106 | @Override
107 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
108 | String header=(String) param.args[0];
109 | XposedBridge.log(header);
110 | }
111 | }
112 | );
113 | XposedHelpers.findAndHookMethod("com.tenpay.sdk.activity.QrcodePayActivity", classLoader, "a",
114 | String.class,JSONObject.class, new XC_MethodHook() {
115 | @Override
116 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
117 | Activity activity=(Activity) param.thisObject;
118 | JSONObject jsonObject=(JSONObject) param.args[1];
119 | PayHelperUtils.sendmsg(activity, jsonObject.toString());
120 | }
121 | }
122 | );*/
123 | XposedHelpers.findAndHookMethod("com.tenpay.sdk.activity.QrcodePayActivity", classLoader, "c",
124 | String.class, new XC_MethodHook() {
125 | @Override
126 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
127 | XposedBridge.log("=========qq钱包生成完成start========");
128 | Activity activity=(Activity) param.thisObject;
129 | String payurl="https://i.qianbao.qq.com/wallet/sqrcode.htm?m=tenpay&f=wallet&";
130 |
131 | String u= (String) XposedHelpers.getObjectField(param.thisObject, "eb");
132 | String n= (String) XposedHelpers.getObjectField(param.thisObject, "ec");
133 | String ac= (String) param.args[0];
134 | payurl+="u="+u+"&a=1"+"&n="+n+"&ac="+ac;
135 |
136 | String money=(String) XposedHelpers.getObjectField(param.thisObject, "aa");
137 | String mark=(String) XposedHelpers.getObjectField(param.thisObject, "ab");
138 |
139 | if(!TextUtils.isEmpty(money) && !TextUtils.isEmpty(mark) && ac.length()>64){
140 | XposedBridge.log("调用增加数据方法==>QQ");
141 | Intent broadCastIntent = new Intent();
142 | broadCastIntent.putExtra("money", money+"");
143 | broadCastIntent.putExtra("mark", mark);
144 | broadCastIntent.putExtra("type", "qq");
145 | broadCastIntent.putExtra("payurl", payurl);
146 | broadCastIntent.setAction(QRCODERECEIVED_ACTION);
147 | activity.sendBroadcast(broadCastIntent);
148 | int activitys=PayHelperUtils.isActivityTop(activity);
149 | if(activitys>2){
150 | activity.finish();
151 | }
152 | }
153 | XposedBridge.log("=========qq钱包生成完成end========");
154 | }
155 | }
156 | );
157 | }
158 |
159 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/SettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import com.tools.payhelper.utils.AbSharedUtil;
4 |
5 | import android.app.Activity;
6 | import android.os.Bundle;
7 | import android.text.TextUtils;
8 | import android.view.View;
9 | import android.view.View.OnClickListener;
10 | import android.view.WindowManager;
11 | import android.widget.Button;
12 | import android.widget.EditText;
13 | import android.widget.RelativeLayout;
14 | import android.widget.Toast;
15 |
16 | /**
17 | *
18 |
19 | * @ClassName: SettingActivity
20 |
21 | * @Description: TODO(这里用一句话描述这个类的作用)
22 |
23 | * @author SuXiaoliang
24 |
25 | * @date 2018年6月23日 下午1:26:51
26 |
27 | *
28 | */
29 | public class SettingActivity extends Activity implements OnClickListener{
30 |
31 | private EditText et_returnurl,et_notifyurl,et_signkey,et_wxid;
32 | private Button bt_save,bt_back;
33 | private RelativeLayout rl_back;
34 |
35 | @Override
36 | protected void onCreate(Bundle savedInstanceState) {
37 | super.onCreate(savedInstanceState);
38 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
39 | setContentView(R.layout.activity_setting);
40 | et_returnurl=(EditText) findViewById(R.id.returnurl);
41 | et_notifyurl=(EditText) findViewById(R.id.notifyurl);
42 | et_signkey=(EditText) findViewById(R.id.signkey);
43 | et_wxid=(EditText) findViewById(R.id.et_wxid);
44 | if(!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "returnurl"))){
45 | et_returnurl.setText(AbSharedUtil.getString(getApplicationContext(), "returnurl"));
46 | }
47 | if(!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "notifyurl"))){
48 | et_notifyurl.setText(AbSharedUtil.getString(getApplicationContext(), "notifyurl"));
49 | }
50 | if(!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "signkey"))){
51 | et_signkey.setText(AbSharedUtil.getString(getApplicationContext(), "signkey"));
52 | }
53 | if(!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "account"))){
54 | et_wxid.setText(AbSharedUtil.getString(getApplicationContext(), "account"));
55 | }
56 |
57 | bt_save=(Button) findViewById(R.id.save);
58 | bt_back=(Button) findViewById(R.id.back);
59 | rl_back=(RelativeLayout) findViewById(R.id.rl_back);
60 | bt_back.setOnClickListener(this);
61 | bt_save.setOnClickListener(this);
62 | rl_back.setOnClickListener(this);
63 | }
64 | @Override
65 | protected void onDestroy() {
66 | super.onDestroy();
67 | }
68 | @Override
69 | protected void onResume() {
70 | super.onResume();
71 | }
72 | @Override
73 | public void onClick(View v) {
74 | switch (v.getId()) {
75 | case R.id.save:
76 | String returnurl=et_returnurl.getText().toString();
77 | // if(TextUtils.isEmpty(returnurl)){
78 | // Toast.makeText(getApplicationContext(), "同步跳转地址不能为空!", Toast.LENGTH_LONG).show();
79 | // return;
80 | // }else{
81 | AbSharedUtil.putString(getApplicationContext(), "returnurl", returnurl);
82 | // }
83 | String notifyurl=et_notifyurl.getText().toString();
84 | // if(TextUtils.isEmpty(notifyurl)){
85 | // Toast.makeText(getApplicationContext(), "异步通知地址不能为空!", Toast.LENGTH_LONG).show();
86 | // return;
87 | // }else{
88 | AbSharedUtil.putString(getApplicationContext(), "notifyurl", notifyurl);
89 | // }
90 | String signkey=et_signkey.getText().toString();
91 | // if(TextUtils.isEmpty(signkey)){
92 | // Toast.makeText(getApplicationContext(), "signkey不能为空!", Toast.LENGTH_LONG).show();
93 | // return;
94 | // }else{
95 | AbSharedUtil.putString(getApplicationContext(), "signkey", signkey);
96 | // }
97 | String wxid=et_wxid.getText().toString();
98 | if(!TextUtils.isEmpty(wxid)){
99 | AbSharedUtil.putString(getApplicationContext(), "account", wxid);
100 | }
101 | Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_LONG).show();
102 | finish();
103 | break;
104 | case R.id.back:
105 | finish();
106 | break;
107 | case R.id.rl_back:
108 | finish();
109 | break;
110 | default:
111 | break;
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/WebServer.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 | import java.util.Map;
6 |
7 | import org.json.JSONObject;
8 |
9 | import com.tools.payhelper.utils.AbSharedUtil;
10 | import com.tools.payhelper.utils.BitmapUtil;
11 | import com.tools.payhelper.utils.DBManager;
12 | import com.tools.payhelper.utils.LogUtils;
13 | import com.tools.payhelper.utils.OrderBean;
14 | import com.tools.payhelper.utils.PayHelperUtils;
15 | import com.tools.payhelper.utils.QrCodeBean;
16 |
17 | import android.content.Context;
18 | import android.graphics.Bitmap;
19 | import android.text.TextUtils;
20 | import fi.iki.elonen.NanoHTTPD;
21 |
22 | /**
23 | *
24 |
25 | * @ClassName: WebServer
26 |
27 | * @Description: TODO(这里用一句话描述这个类的作用)
28 |
29 | * @author SuXiaoliang
30 |
31 | * @date 2018年6月23日 下午1:26:56
32 |
33 | *
34 | */
35 | public class WebServer extends NanoHTTPD {
36 |
37 | public static final String TAG = WebServer.class.getSimpleName();
38 | private static final String REQUEST_ROOT = "/";
39 | private static final String REQUEST_WECHAT = "/wechat";
40 | private static final String REQUEST_GETPAY = "/getpay";
41 | private static final String REQUEST_QUERY = "/query";
42 | private static final String REQUEST_GETRESULT = "/getresult";
43 | public static String MSGRECEIVED_ACTION = "com.tools.payhelper.msgreceived";
44 | private Context context;
45 |
46 | public WebServer(Context context,int serverport) {
47 | super(serverport);
48 | this.context = context;
49 | }
50 |
51 | @Override
52 | public Response serve(IHTTPSession session) {
53 | LogUtils.d("OnRequest: " + session.getUri());
54 | try {
55 | if (REQUEST_ROOT.equals(session.getUri())) {
56 | return responseRootPage(session);
57 | } else if (REQUEST_WECHAT.equals(session.getUri())) {
58 | @SuppressWarnings("deprecation")
59 | Map params = session.getParms();
60 | String money = params.get("money");
61 | String mark = params.get("mark");
62 | String type=params.get("type");
63 | if(type==null || type.equals("")){
64 | type="wechat";
65 | }
66 | double m=Double.parseDouble(money);
67 | if(type.equals("alipay")){
68 | if(m>50000){
69 | return responseText(session, "支付宝最大支持单笔50000元支付!");
70 | }
71 | }else if(type.equals("wechat")){
72 | if(m>15000){
73 | return responseText(session, "微信最大支持单笔15000元支付!");
74 | }
75 | }else if(type.equals("qq")){
76 | if(m>30000){
77 | return responseText(session, "QQ最大支持单笔30000元支付!");
78 | }
79 | if(mark.length()>12){
80 | return responseText(session, "QQ备注长度不能超过12位!");
81 | }
82 | }
83 |
84 | if(type.equals("alipay") && !PayHelperUtils.isAppRunning(context, "com.eg.android.AlipayGphone")){
85 | PayHelperUtils.startAPP(context, "com.eg.android.AlipayGphone");
86 | }else if(type.equals("wechat") && !PayHelperUtils.isAppRunning(context, "com.tencent.mm")){
87 | PayHelperUtils.startAPP(context, "com.tencent.mm");
88 | }else if(type.equals("qq") && !PayHelperUtils.isAppRunning(context, "com.tencent.mobileqq")){
89 | PayHelperUtils.startAPP(context, "com.tencent.mobileqq");
90 | }
91 |
92 | List qrCodeBeans=new ArrayList();
93 | DBManager dbManager=new DBManager(CustomApplcation.getInstance().getApplicationContext());
94 | PayHelperUtils.sendAppMsg(money, mark, type, context);
95 | int times=0;
96 | while (times<30 && qrCodeBeans.size()==0) {
97 | qrCodeBeans=dbManager.FindQrCodes(money, mark, type);
98 | times++;
99 | Thread.sleep(500);
100 | }
101 | if(qrCodeBeans.size()==0){
102 | PayHelperUtils.startAPP();
103 | return responseText(session,"获取超时....");
104 | }else{
105 | String payurl=qrCodeBeans.get(0).getPayurl();
106 | PayHelperUtils.startAPP();
107 | return responseQRCode(session, payurl,mark);
108 | }
109 | } else if (REQUEST_GETPAY.equals(session.getUri())) {
110 | @SuppressWarnings("deprecation")
111 | JSONObject jsonObject=new JSONObject();
112 | Map params = session.getParms();
113 | String money = params.get("money");
114 | String mark = params.get("mark");
115 | String type=params.get("type");
116 | if(type==null || type.equals("")){
117 | type="wechat";
118 | }
119 | String account="";
120 | double m=Double.parseDouble(money);
121 | if(type.equals("alipay")){
122 | account=AbSharedUtil.getString(context, "alipay");
123 | if(m>50000){
124 | jsonObject.put("msg", "支付宝最大支持单笔50000元支付!");
125 | return responseJson(session,jsonObject.toString());
126 | }
127 | }else if(type.equals("wechat")){
128 | account=AbSharedUtil.getString(context, "wechat");
129 | if(m>15000){
130 | jsonObject.put("msg", "微信最大支持单笔15000元支付!");
131 | return responseJson(session,jsonObject.toString());
132 | }
133 | }else if(type.equals("qq")){
134 | account=AbSharedUtil.getString(context, "qq");
135 | if(m>30000){
136 | return responseText(session, "QQ最大支持单笔30000元支付!");
137 | }
138 | if(mark.length()>12){
139 | return responseText(session, "QQ备注长度不能超过12位!");
140 | }
141 | }
142 |
143 | if(type.equals("alipay") && !PayHelperUtils.isAppRunning(context, "com.eg.android.AlipayGphone")){
144 | PayHelperUtils.startAPP(context, "com.eg.android.AlipayGphone");
145 | }else if(type.equals("wechat") && !PayHelperUtils.isAppRunning(context, "com.tencent.mm")){
146 | PayHelperUtils.startAPP(context, "com.tencent.mm");
147 | }else if(type.equals("qq") && !PayHelperUtils.isAppRunning(context, "com.tencent.mobileqq")){
148 | PayHelperUtils.startAPP(context, "com.tencent.mobileqq");
149 | }
150 |
151 | List qrCodeBeans=new ArrayList();
152 | DBManager dbManager=new DBManager(CustomApplcation.getInstance().getApplicationContext());
153 | PayHelperUtils.sendAppMsg(money, mark, type, context);
154 | int times=0;
155 | while (times<30 && qrCodeBeans.size()==0) {
156 | qrCodeBeans=dbManager.FindQrCodes(money, mark, type);
157 | times++;
158 | Thread.sleep(500);
159 | }
160 |
161 | LogUtils.d("size = " + qrCodeBeans.size());
162 |
163 | if(qrCodeBeans.size()==0){
164 | PayHelperUtils.startAPP();
165 | jsonObject.put("msg", "获取超时");
166 | return responseJson(session,jsonObject.toString());
167 | }else{
168 | String payurl=qrCodeBeans.get(0).getPayurl();
169 | PayHelperUtils.startAPP();
170 | jsonObject.put("msg", "获取成功");
171 | jsonObject.put("payurl", payurl);
172 | jsonObject.put("mark", mark);
173 | jsonObject.put("money", money);
174 | jsonObject.put("type", type);
175 | if(!TextUtils.isEmpty(account)){
176 | jsonObject.put("account", account);
177 | }
178 |
179 | LogUtils.d(jsonObject.toString());
180 | return responseJson(session,jsonObject.toString());
181 | }
182 | } else if (REQUEST_QUERY.equals(session.getUri())) {
183 | @SuppressWarnings("deprecation")
184 | Map params = session.getParms();
185 | String mark = params.get("no");
186 | List orderBeans=new ArrayList();
187 | DBManager dbManager=new DBManager(CustomApplcation.getInstance().getApplicationContext());
188 | orderBeans=dbManager.FindOrders(mark);
189 | if(orderBeans!=null && orderBeans.size()>0){
190 | String dt=orderBeans.get(0).getDt();
191 | String paytime=PayHelperUtils.stampToDate(dt);
192 | return responseText(session,"当前订单已支付,支付时间:"+paytime+"....");
193 | }else{
194 | return responseText(session,"当前订单未支付....");
195 | }
196 | } else if (REQUEST_GETRESULT.equals(session.getUri())) {
197 | @SuppressWarnings("deprecation")
198 | Map params = session.getParms();
199 | String mark = params.get("trade_no");
200 | List orderBeans=new ArrayList();
201 | DBManager dbManager=new DBManager(CustomApplcation.getInstance().getApplicationContext());
202 | orderBeans=dbManager.FindOrders(mark);
203 | JSONObject jsonObject=new JSONObject();
204 | String returnurl=AbSharedUtil.getString(context, "returnurl");
205 | if(orderBeans!=null && orderBeans.size()>0){
206 | String dt=orderBeans.get(0).getDt();
207 | String money=orderBeans.get(0).getMoney();
208 | String paytime=PayHelperUtils.stampToDate(dt);
209 | jsonObject.put("msg", "支付成功");
210 | jsonObject.put("paytime", paytime);
211 | jsonObject.put("money", money);
212 | if(!TextUtils.isEmpty(returnurl)){
213 | jsonObject.put("returnurl", returnurl);
214 | }
215 | return responseJson(session, jsonObject.toString());
216 | }else{
217 | jsonObject.put("msg", "未支付");
218 | return responseJson(session, jsonObject.toString());
219 | }
220 | }else{
221 | return response404(session, session.getUri());
222 | }
223 | } catch (Exception e) {
224 | return response404(session, e.getMessage());
225 | }
226 | }
227 |
228 | public Response responseRootPage(IHTTPSession session) {
229 | StringBuilder builder = new StringBuilder();
230 | builder.append("");
231 | builder.append("Hello World!");
232 | builder.append("\n");
233 | return newFixedLengthResponse(builder.toString());
234 | }
235 |
236 | public Response responseQRCode(IHTTPSession session,String QRText,String no) {
237 | Bitmap bitmap=BitmapUtil.createQRImage(QRText, 240, null);
238 | String imgbase64=BitmapUtil.bitmapToBase64(bitmap);
239 | imgbase64="\"data:image/gif;base64," + imgbase64 + "\"";
240 | StringBuilder builder = new StringBuilder();
241 | builder.append("");
242 | builder.append("");
243 | builder.append("二维码生成测试
");
244 | builder.append("
");
246 | builder.append("");
247 | String url="http://"+session.getHeaders().get("host");
248 | builder.append("获取成功,查询订单是否支付:
查询");
249 | builder.append("
");
250 | builder.append("\n");
251 | LogUtils.i(builder.toString());
252 | return newFixedLengthResponse(Response.Status.OK, "text/html;charset=UTF-8", builder.toString());
253 | }
254 | public Response responseText(IHTTPSession session, String text) {
255 | StringBuilder builder = new StringBuilder();
256 | builder.append("");
257 | builder.append("");
258 | builder.append(text);
259 | builder.append("
");
260 | builder.append("\n");
261 | LogUtils.i(builder.toString());
262 | return newFixedLengthResponse(Response.Status.OK, "text/html;charset=UTF-8", builder.toString());
263 | }
264 | public Response responseJson(IHTTPSession session, String json) {
265 | LogUtils.i(json);
266 | return newFixedLengthResponse(Response.Status.OK, "application/json;charset=UTF-8", json);
267 | }
268 |
269 | public Response response404(IHTTPSession session, String url) {
270 | StringBuilder builder = new StringBuilder();
271 | builder.append("");
272 | builder.append("Sorry, Can't Found " + url + " !");
273 | builder.append("\n");
274 | return newFixedLengthResponse(builder.toString());
275 | }
276 |
277 | protected String getQuotaStr(String text) {
278 | return "\"" + text + "\"";
279 | }
280 | }
281 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/WechatHook.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper;
2 |
3 | import java.lang.reflect.Field;
4 |
5 | import org.json.JSONObject;
6 |
7 | import com.tools.payhelper.utils.PayHelperUtils;
8 | import com.tools.payhelper.utils.XmlToJson;
9 |
10 | import android.app.Activity;
11 | import android.content.ContentValues;
12 | import android.content.Context;
13 | import android.content.Intent;
14 | import android.text.TextUtils;
15 | import android.widget.Button;
16 | import de.robv.android.xposed.XC_MethodHook;
17 | import de.robv.android.xposed.XposedBridge;
18 | import de.robv.android.xposed.XposedHelpers;
19 | import de.robv.android.xposed.XC_MethodHook.MethodHookParam;
20 |
21 | /**
22 | *
23 |
24 | * @ClassName: WechatHook
25 |
26 | * @Description: TODO(这里用一句话描述这个类的作用)
27 |
28 | * @author SuXiaoliang
29 |
30 | * @date 2018年6月23日 下午1:27:01
31 |
32 | *
33 | */
34 | public class WechatHook {
35 |
36 | public static String BILLRECEIVED_ACTION = "com.tools.payhelper.billreceived";
37 | public static String QRCODERECEIVED_ACTION = "com.tools.payhelper.qrcodereceived";
38 |
39 | protected void hook(final ClassLoader appClassLoader,final Context context) {
40 | // TODO Auto-generated method stub
41 |
42 | XposedHelpers.findAndHookMethod("com.tencent.wcdb.database.SQLiteDatabase",appClassLoader, "insert",String.class, String.class, ContentValues.class,
43 | new XC_MethodHook() {
44 |
45 | @Override
46 | protected void beforeHookedMethod(MethodHookParam param)
47 | throws Throwable {
48 | try {
49 | ContentValues contentValues = (ContentValues) param.args[2];
50 | String tableName = (String) param.args[0];
51 | if (TextUtils.isEmpty(tableName) || !tableName.equals("message")) {
52 | return;
53 | }
54 | Integer type = contentValues.getAsInteger("type");
55 | if (null == type) {
56 | return;
57 | }
58 | if(type==318767153){
59 | JSONObject msg=new XmlToJson.Builder(contentValues.getAsString("content")).build().getJSONObject("msg");
60 | XposedBridge.log(msg.toString());
61 | if(!msg.toString().contains("零钱提现")){
62 | XposedBridge.log("=========微信收到订单start========");
63 | String money=msg.getJSONObject("appmsg").getJSONObject("mmreader").getJSONObject("template_detail").getJSONObject("line_content").getJSONObject("topline").getJSONObject("value").getString("word");
64 | money=money.replace("¥", "");
65 | String mark=msg.getJSONObject("appmsg").getJSONObject("mmreader").getJSONObject("template_detail").getJSONObject("line_content").getJSONObject("lines").getJSONArray("line").getJSONObject(0).getJSONObject("value").getString("word");
66 | String pay_outtradeno="";
67 | try {
68 | pay_outtradeno=msg.getJSONObject("appmsg").getJSONObject("ext_pay_info").getString("pay_outtradeno");
69 | } catch (Exception e) {
70 | pay_outtradeno=msg.getJSONObject("appmsg").getString("template_id");
71 | }
72 | XposedBridge.log("收到微信支付订单:"+pay_outtradeno+"=="+money+"=="+mark);
73 | Intent broadCastIntent = new Intent();
74 | broadCastIntent.putExtra("bill_no", pay_outtradeno);
75 | broadCastIntent.putExtra("bill_money", money);
76 | broadCastIntent.putExtra("bill_mark", mark);
77 | broadCastIntent.putExtra("bill_type", "wechat");
78 | broadCastIntent.setAction(BILLRECEIVED_ACTION);
79 | context.sendBroadcast(broadCastIntent);
80 | XposedBridge.log("=========微信收到订单start========");
81 | }
82 | }
83 | } catch (Exception e) {
84 | XposedBridge.log(e.getMessage());
85 | }
86 | }
87 |
88 | @Override
89 | protected void afterHookedMethod(MethodHookParam param)
90 | throws Throwable {
91 | }
92 | });
93 |
94 | //hook请求参数
95 | // try {
96 | // XposedHelpers.findAndHookMethod("com.tencent.mm.wallet_core.c.i",appClassLoader, "E", Map.class,
97 | // new XC_MethodHook() {
98 | //
99 | // @Override
100 | // protected void beforeHookedMethod(MethodHookParam param)
101 | // throws Throwable {
102 | // Map map=(Map) param.args[0];
103 | // XposedBridge.log(map.toString());
104 | // }
105 | //
106 | // @Override
107 | // protected void afterHookedMethod(MethodHookParam param)
108 | // throws Throwable {
109 | // }
110 | // });
111 | // } catch (Exception e) {
112 | // }
113 |
114 | //hook更改请求参数
115 | // try {
116 | // XposedHelpers.findAndHookConstructor("com.tencent.mm.plugin.collect.b.s", appClassLoader, double.class,String.class,String.class,new XC_MethodHook() {
117 | //
118 | // @Override
119 | // protected void beforeHookedMethod(MethodHookParam param)
120 | // throws Throwable {
121 | // String mark="备注啦啦啦";
122 | // param.args[2]=mark;
123 | // XposedBridge.log("拦截请求修改参数:mark="+param.args[2].toString()+"money="+String.valueOf(param.args[0])+"type="+param.args[1].toString());
124 | // }
125 | //
126 | // @Override
127 | // protected void afterHookedMethod(MethodHookParam param)
128 | // throws Throwable {
129 | // }
130 | // });
131 | // } catch (Exception e) {
132 | // }
133 | //获取请求返回数据
134 | /*try {
135 | Class> bfj=XposedHelpers.findClass("com.tencent.mm.protocal.c.bfj", appClassLoader);
136 | XposedHelpers.findAndHookMethod("com.tencent.mm.platformtools.aa",appClassLoader, "b", bfj,
137 | new XC_MethodHook() {
138 |
139 | @Override
140 | protected void beforeHookedMethod(MethodHookParam param)
141 | throws Throwable {
142 | }
143 |
144 | @Override
145 | protected void afterHookedMethod(MethodHookParam param)
146 | throws Throwable {
147 | if(param.args[0]!=null){
148 | String result=param.getResult().toString();
149 | XposedBridge.log("拦截返回数据=="+result);
150 | }
151 | }
152 | });
153 |
154 | } catch (Exception e) {
155 | }*/
156 | try {
157 | Class> clazz=XposedHelpers.findClass("com.tencent.mm.plugin.collect.b.s", appClassLoader);
158 | XposedBridge.hookAllMethods(clazz, "a", new XC_MethodHook() {
159 |
160 | @Override
161 | protected void beforeHookedMethod(MethodHookParam param)
162 | throws Throwable {
163 | }
164 |
165 | @Override
166 | protected void afterHookedMethod(MethodHookParam param)
167 | throws Throwable {
168 | XposedBridge.log("=========微信生成完成start========");
169 | if(PayHelperUtils.getVerName(context).equals("6.6.7")){
170 | Field moneyField = XposedHelpers.findField(param.thisObject.getClass(), "hUL");
171 | double money = (double) moneyField.get(param.thisObject);
172 |
173 | Field markField = XposedHelpers.findField(param.thisObject.getClass(), "desc");
174 | String mark = (String) markField.get(param.thisObject);
175 |
176 | Field payurlField = XposedHelpers.findField(param.thisObject.getClass(), "hUK");
177 | String payurl = (String) payurlField.get(param.thisObject);
178 |
179 | XposedBridge.log(money+" "+mark+" "+payurl);
180 |
181 | XposedBridge.log("调用增加数据方法==>微信");
182 | Intent broadCastIntent = new Intent();
183 | broadCastIntent.putExtra("money", money+"");
184 | broadCastIntent.putExtra("mark", mark);
185 | broadCastIntent.putExtra("type", "wechat");
186 | broadCastIntent.putExtra("payurl", payurl);
187 | broadCastIntent.setAction(QRCODERECEIVED_ACTION);
188 | context.sendBroadcast(broadCastIntent);
189 | }else if(PayHelperUtils.getVerName(context).equals("6.6.6")){
190 | Field moneyField = XposedHelpers.findField(param.thisObject.getClass(), "llG");
191 | double money = (double) moneyField.get(param.thisObject);
192 |
193 | Field markField = XposedHelpers.findField(param.thisObject.getClass(), "desc");
194 | String mark = (String) markField.get(param.thisObject);
195 |
196 | Field payurlField = XposedHelpers.findField(param.thisObject.getClass(), "llF");
197 | String payurl = (String) payurlField.get(param.thisObject);
198 |
199 | XposedBridge.log(money+" "+mark+" "+payurl);
200 |
201 | XposedBridge.log("调用增加数据方法==>微信");
202 | Intent broadCastIntent = new Intent();
203 | broadCastIntent.putExtra("money", money+"");
204 | broadCastIntent.putExtra("mark", mark);
205 | broadCastIntent.putExtra("type", "wechat");
206 | broadCastIntent.putExtra("payurl", payurl);
207 | broadCastIntent.setAction(QRCODERECEIVED_ACTION);
208 | context.sendBroadcast(broadCastIntent);
209 | }
210 | XposedBridge.log("=========微信生成完成end========");
211 | }
212 | });
213 |
214 | } catch (Exception e) {
215 | PayHelperUtils.sendmsg(context, "异常"+e.getMessage());
216 | }
217 | try {
218 | XposedHelpers.findAndHookMethod("com.tencent.mm.plugin.collect.ui.CollectCreateQRCodeUI",appClassLoader, "initView",
219 | new XC_MethodHook() {
220 |
221 | @Override
222 | protected void beforeHookedMethod(MethodHookParam param)
223 | throws Throwable {
224 | }
225 |
226 | @Override
227 | protected void afterHookedMethod(MethodHookParam param)
228 | throws Throwable {
229 | //微信6.6.7新版修复
230 | XposedBridge.log("=========微信设置金额start========");
231 | if(PayHelperUtils.getVerName(context).equals("6.6.7")){
232 | Intent intent = ((Activity) param.thisObject).getIntent();
233 | String mark=intent.getStringExtra("mark");
234 | String money=intent.getStringExtra("money");
235 | //获取WalletFormView控件
236 | Field WalletFormViewField = XposedHelpers.findField(param.thisObject.getClass(), "hXD");
237 | Object WalletFormView = WalletFormViewField.get(param.thisObject);
238 | Class> WalletFormViewClass=XposedHelpers.findClass("com.tencent.mm.wallet_core.ui.formview.WalletFormView", appClassLoader);
239 | //获取金额控件
240 | Field AefField = XposedHelpers.findField(WalletFormViewClass, "uZy");
241 | Object AefView = AefField.get(WalletFormView);
242 | //call设置金额方法
243 | XposedHelpers.callMethod(AefView, "setText", money);
244 | //call设置备注方法
245 | Class> clazz=XposedHelpers.findClass("com.tencent.mm.plugin.collect.ui.CollectCreateQRCodeUI", appClassLoader);
246 | XposedHelpers.callStaticMethod(clazz, "a", param.thisObject,mark);
247 | XposedHelpers.callStaticMethod(clazz, "c", param.thisObject);
248 | //点击确定
249 | Button click=(Button)XposedHelpers.callMethod(param.thisObject, "findViewById",2131756838);
250 | click.performClick();
251 | }else if(PayHelperUtils.getVerName(context).equals("6.6.6")){
252 | Intent intent = ((Activity) param.thisObject).getIntent();
253 | String mark=intent.getStringExtra("mark");
254 | String money=intent.getStringExtra("money");
255 | //获取WalletFormView控件
256 | Field WalletFormViewField = XposedHelpers.findField(param.thisObject.getClass(), "loz");
257 | Object WalletFormView = WalletFormViewField.get(param.thisObject);
258 | Class> WalletFormViewClass=XposedHelpers.findClass("com.tencent.mm.wallet_core.ui.formview.WalletFormView", appClassLoader);
259 | //获取金额控件
260 | Field AefField = XposedHelpers.findField(WalletFormViewClass, "Aef");
261 | Object AefView = AefField.get(WalletFormView);
262 | //call设置金额方法
263 | XposedHelpers.callMethod(AefView, "setText", money);
264 | //call设置备注方法
265 | Class> clazz=XposedHelpers.findClass("com.tencent.mm.plugin.collect.ui.CollectCreateQRCodeUI", appClassLoader);
266 | XposedHelpers.callStaticMethod(clazz, "a", param.thisObject,mark);
267 | XposedHelpers.callStaticMethod(clazz, "c", param.thisObject);
268 | //点击确定
269 | Button click=(Button)XposedHelpers.callMethod(param.thisObject, "findViewById",2131756780);
270 | click.performClick();
271 | }
272 | XposedBridge.log("=========微信设置金额start========");
273 | // Field MoneyField = XposedHelpers.findField(WalletFormViewClass, "jyA");
274 | // Object MoneyView = MoneyField.get(WalletFormView);
275 | ////
276 | // Field MarkField = XposedHelpers.findField(WalletFormViewClass, "qdA");
277 | // Object MarkView = MarkField.get(WalletFormView);
278 | //
279 | // Field qdDField = XposedHelpers.findField(WalletFormViewClass, "qdD");
280 | // Object qdDView = qdDField.get(WalletFormView);
281 |
282 | // XposedHelpers.callMethod(MoneyView, "setText", "1");
283 | // XposedHelpers.callMethod(MarkView, "setText", "2");
284 | // XposedHelpers.callMethod(qdDView, "setText", "3");
285 |
286 | // Button click=(Button)XposedHelpers.callMethod(param.thisObject, "findViewById",2131756780);
287 | // click.performClick();
288 | // Field quRenField = XposedHelpers.findField(param.thisObject.getClass(), "loA");
289 | // Button quRenButton = (Button) quRenField.get(param.thisObject);
290 | // quRenButton.performClick();
291 | // XposedHelpers.callMethod(constructor.newInstance(0.01d,"1","test"));
292 | // Class clazz = XposedHelpers.findClass("com.tencent.mm.plugin.collect.b.s",context.getClassLoader());
293 | // Constructor constructor = clazz.getConstructor(double.class,String.class,String.class);
294 | // Object object=constructor.newInstance(10,"1","test");
295 | // Class> test = XposedHelpers.findClass("com.tencent.mm.wallet_core.ui.WalletBaseUI", context.getClassLoader());
296 | // XposedHelpers.callMethod(test.newInstance(), "a", object,true,true);
297 | }
298 | });
299 | } catch (Exception e) {
300 | PayHelperUtils.sendmsg(context, "异常"+e.getMessage());
301 | }
302 | try {
303 | // hook获取loginid
304 | XposedHelpers.findAndHookMethod("com.tencent.mm.ui.LauncherUI", appClassLoader, "onResume",
305 | new XC_MethodHook() {
306 | @Override
307 | protected void afterHookedMethod(MethodHookParam param) throws Throwable {
308 | String loginid=PayHelperUtils.getWechatLoginId(context);
309 | loginid=loginid.replace("+86", "");
310 | PayHelperUtils.sendLoginId(loginid, "wechat", context);
311 | }
312 | });
313 | } catch (Exception e) {
314 | }
315 | }
316 | }
317 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/http/CookieJarManager.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.http;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import okhttp3.Cookie;
7 | import okhttp3.CookieJar;
8 |
9 |
10 | /**
11 | * Cookie管理类
12 | */
13 | public class CookieJarManager implements CookieJar {
14 |
15 | /**
16 | * 保存cookie
17 | */
18 | private List mCookieList = new ArrayList();
19 | /**
20 | * 这里注册需要你保存Cookie的URL
21 | */
22 | private String COOKIE_URL[] = new String[]{
23 | };
24 |
25 | /**
26 | * 是否保存cookie
27 | *
28 | * @param url
29 | * 请求URL
30 | * @return true 保存
31 | */
32 | private boolean isSaveCookie(String url){
33 | for(String cookieUrl : COOKIE_URL){
34 | if(url.contains(cookieUrl)){
35 | return true;
36 | }
37 | }
38 | return false;
39 | }
40 |
41 |
42 | @Override
43 | public void saveFromResponse(okhttp3.HttpUrl httpUrl, List list) {
44 | String url = httpUrl.uri().toString();
45 | if(isSaveCookie(url)){
46 | // mCookieList.clear(); // 这里只保存一次cookie
47 | mCookieList.addAll(list);
48 | }
49 | }
50 |
51 | @Override
52 | public List loadForRequest(okhttp3.HttpUrl httpUrl) {
53 | return mCookieList;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/http/HttpUrl.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.http;
2 |
3 | public class HttpUrl {
4 |
5 | public static final String BASE_URL = "http://127.0.0.1:8080/";
6 |
7 | /**
8 | * 登录
9 | */
10 | public static final String URL_LOGIN = BASE_URL + "login";
11 |
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/http/ParamField.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.http;
2 |
3 | import java.lang.annotation.ElementType;
4 | import java.lang.annotation.Retention;
5 | import java.lang.annotation.RetentionPolicy;
6 | import java.lang.annotation.Target;
7 |
8 | @Retention(RetentionPolicy.RUNTIME)
9 | @Target(ElementType.FIELD)
10 | public @interface ParamField {
11 | String value() default "";
12 | }
13 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/http/request/HttpParams.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.http.request;
2 |
3 | import java.io.Serializable;
4 |
5 |
6 |
7 | public interface HttpParams extends Serializable {
8 |
9 |
10 |
11 | }
12 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/http/result/BaseResult.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.http.result;
2 |
3 |
4 | import java.io.Serializable;
5 |
6 | /**
7 | * 返回数据基类
8 | */
9 | public class BaseResult implements Serializable {
10 |
11 | public Error error;
12 | public String value;
13 |
14 | @Override
15 | public String toString() {
16 | return "BaseResult{" +
17 | "error=" + error +
18 | ", value='" + value + '\'' +
19 | '}';
20 | }
21 |
22 | public static class Error {
23 | public String errorCode;
24 | public String message;
25 | public String errorType;
26 | @Override
27 | public String toString() {
28 | return "Error{" +
29 | "errorCode='" + errorCode + '\'' +
30 | ", message='" + message + '\'' +
31 | ", errorType='" + errorType + '\'' +
32 | '}';
33 | }
34 | }
35 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/tcp/TcpCheck.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.tcp;
2 |
3 | public class TcpCheck {
4 |
5 | public Verify data;
6 |
7 | public static class Verify {
8 | public String key;
9 | public Verify(String key) {
10 | this.key = key;
11 | }
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/tcp/TcpConnection.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.tcp;
2 |
3 | import com.tools.payhelper.utils.JsonHelper;
4 | import com.tools.payhelper.utils.LogUtils;
5 |
6 | import java.io.BufferedReader;
7 | import java.io.BufferedWriter;
8 | import java.io.DataInputStream;
9 | import java.io.IOException;
10 | import java.io.InputStream;
11 | import java.io.InputStreamReader;
12 | import java.io.OutputStreamWriter;
13 | import java.io.PrintWriter;
14 | import java.io.Reader;
15 | import java.io.Writer;
16 | import java.net.Socket;
17 | import java.net.SocketTimeoutException;
18 |
19 |
20 | public class TcpConnection extends Thread {
21 |
22 | // auto.1899pay.com 8011
23 |
24 | private Socket mSocket;
25 | private BufferedReader mBufferedReader = null;
26 | private PrintWriter mPrintWriter = null;
27 |
28 | private String mIpAddress;
29 | private int mIpPort;
30 | private String mVerify;
31 |
32 | private OnTcpResultListener mOnTcpResultListener;
33 | private long mLastHeartBeatTimestamp;
34 | private HeartBeatThread mHeartBeatThread;
35 |
36 | private static TcpConnection instance = null;
37 | public static TcpConnection getInstance() {
38 | if (instance == null) {
39 | instance = new TcpConnection();
40 | }
41 | return instance;
42 | }
43 |
44 | public void init(String address, int port, String verify) {
45 | this.mIpAddress = address;
46 | this.mIpPort = port;
47 | this.mVerify = verify;
48 | this.mLastHeartBeatTimestamp = System.currentTimeMillis();
49 | }
50 |
51 | @Override
52 | public void run() {
53 | super.run();
54 | connect();
55 | try {
56 | while (mSocket != null && !mSocket.isClosed() && mSocket.isConnected()) {
57 | if (!mSocket.isInputShutdown()) {
58 | try {
59 | InputStream inputStream = mSocket.getInputStream();
60 | DataInputStream input = new DataInputStream(inputStream);
61 | byte[] b = new byte[2 * 1024];
62 | int length = 0;
63 | while ((length = input.read(b)) != -1) {
64 | String msg = new String(b, 0, length, "utf-8").replace("\0", "");
65 | LogUtils.d("length = " + length + ", msg = " + msg);
66 | if (!msg.isEmpty() && mOnTcpResultListener != null) {
67 | mOnTcpResultListener.onReceive(msg);
68 | }
69 | }
70 | } catch (SocketTimeoutException e) {
71 | e.printStackTrace();
72 | }
73 | }
74 | }
75 | } catch (Exception e) {
76 | LogUtils.e(e.toString());
77 | e.printStackTrace();
78 | mOnTcpResultListener.onFailed(e.toString());
79 | }
80 | }
81 |
82 | private void connect() {
83 | try {
84 | mSocket = new Socket(mIpAddress, mIpPort);
85 | mSocket.setSoTimeout(3000);
86 | mBufferedReader = new BufferedReader(new InputStreamReader(mSocket
87 | .getInputStream()));
88 | mPrintWriter = new PrintWriter(new BufferedWriter(new OutputStreamWriter(
89 | mSocket.getOutputStream())), true);
90 | LogUtils.i("Connect success");
91 | if (mOnTcpResultListener != null) {
92 | mOnTcpResultListener.onConnected();
93 | }
94 |
95 | // verify
96 | String data = JsonHelper.toJson(VerifyData.createVerifyData(mVerify));
97 | send(data);
98 | LogUtils.i("Send verify success, " + data);
99 |
100 | // heart beat
101 | mHeartBeatThread = new HeartBeatThread();
102 | mHeartBeatThread.start();
103 | } catch (IOException e) {
104 | LogUtils.e(e.toString());
105 | mOnTcpResultListener.onFailed(e.toString());
106 | e.printStackTrace();
107 | }
108 | }
109 |
110 | private void closeInputStream(InputStream inputStream) {
111 | if (inputStream != null) {
112 | try {
113 | inputStream.close();
114 | } catch (IOException e) {
115 | e.printStackTrace();
116 | }
117 | }
118 | }
119 |
120 | private void closeReader(Reader reader) {
121 | if (reader != null) {
122 | try {
123 | reader.close();
124 | } catch (IOException e) {
125 | e.printStackTrace();
126 | }
127 | }
128 | }
129 |
130 | private void closeWriter(Writer writer) {
131 | if (writer != null) {
132 | try {
133 | writer.close();
134 | } catch (IOException e) {
135 | e.printStackTrace();
136 | }
137 | }
138 | }
139 |
140 | private void closeSocket(Socket socket) {
141 | if (socket != null) {
142 | try {
143 | socket.close();
144 | } catch (IOException e) {
145 | e.printStackTrace();
146 | }
147 | }
148 | }
149 |
150 | public interface OnTcpResultListener {
151 |
152 | void onConnected();
153 |
154 | void onReceive(String data);
155 |
156 | void onFailed(String error);
157 | }
158 |
159 | public OnTcpResultListener getOnTcpResultListener() {
160 | return mOnTcpResultListener;
161 | }
162 |
163 | public void setOnTcpResultListener(OnTcpResultListener listener) {
164 | this.mOnTcpResultListener = listener;
165 | }
166 |
167 | public void send(String msg) {
168 | LogUtils.d("msg: " + msg);
169 | if (mPrintWriter != null) {
170 | mPrintWriter.write(msg);
171 | mPrintWriter.flush();
172 | }
173 | }
174 |
175 | public void close() {
176 | LogUtils.i("close");
177 | closeReader(mBufferedReader);
178 | closeWriter(mPrintWriter);
179 | closeSocket(mSocket);
180 | if (mHeartBeatThread != null) {
181 | mHeartBeatThread.interrupt();
182 | mHeartBeatThread = null;
183 | }
184 | instance = null;
185 | }
186 |
187 | private class HeartBeatThread extends Thread {
188 |
189 | @Override
190 | public void run() {
191 | super.run();
192 | while (mSocket != null && !mSocket.isClosed() && mSocket.isConnected()) {
193 | long currentTimestamp = System.currentTimeMillis();
194 | if (mLastHeartBeatTimestamp + 20 * 1000 < currentTimestamp ) {
195 | String data = JsonHelper.toJson(VerifyData.createHeartBeatData());
196 | send(data);
197 | LogUtils.d("Heart beat, " + data);
198 | mLastHeartBeatTimestamp = currentTimestamp;
199 | }
200 | }
201 | }
202 | }
203 |
204 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/tcp/TcpSettingActivity.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.tcp;
2 |
3 | import android.app.Activity;
4 | import android.os.Bundle;
5 | import android.text.TextUtils;
6 | import android.view.View;
7 | import android.view.View.OnClickListener;
8 | import android.view.WindowManager;
9 | import android.widget.Button;
10 | import android.widget.EditText;
11 | import android.widget.RelativeLayout;
12 | import android.widget.Toast;
13 |
14 | import com.tools.payhelper.R;
15 | import com.tools.payhelper.utils.AbSharedUtil;
16 |
17 |
18 | public class TcpSettingActivity extends Activity implements OnClickListener {
19 |
20 | private EditText et_ip, et_port, et_verify;
21 | private Button bt_save, bt_back;
22 | private RelativeLayout rl_back;
23 |
24 | @Override
25 | protected void onCreate(Bundle savedInstanceState) {
26 | super.onCreate(savedInstanceState);
27 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
28 | setContentView(R.layout.activity_tcp_setting);
29 | et_ip = (EditText) findViewById(R.id.et_ip);
30 | et_port = (EditText) findViewById(R.id.et_port);
31 | et_verify = (EditText) findViewById(R.id.et_verify);
32 | if (!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "tcp_ip"))) {
33 | et_ip.setText(AbSharedUtil.getString(getApplicationContext(), "tcp_ip"));
34 | } else {
35 | et_ip.setText("auto.1899pay.com");
36 | }
37 | if (AbSharedUtil.getInt(getApplicationContext(), "tcp_port") != 0) {
38 | et_port.setText("" + AbSharedUtil.getInt(getApplicationContext(), "tcp_port"));
39 | } else {
40 | et_port.setText("8011");
41 | }
42 | if (!TextUtils.isEmpty(AbSharedUtil.getString(getApplicationContext(), "tcp_verify"))) {
43 | et_verify.setText("" + AbSharedUtil.getString(getApplicationContext(), "tcp_verify"));
44 | } else {
45 | et_verify.setText("5");
46 | }
47 |
48 | bt_save = (Button) findViewById(R.id.save);
49 | bt_back = (Button) findViewById(R.id.back);
50 | rl_back = (RelativeLayout) findViewById(R.id.rl_back);
51 | bt_back.setOnClickListener(this);
52 | bt_save.setOnClickListener(this);
53 | rl_back.setOnClickListener(this);
54 | }
55 |
56 | @Override
57 | protected void onDestroy() {
58 | super.onDestroy();
59 | }
60 |
61 | @Override
62 | protected void onResume() {
63 | super.onResume();
64 | }
65 |
66 | @Override
67 | public void onClick(View v) {
68 | switch (v.getId()) {
69 | case R.id.save:
70 | String tcp_ip = et_ip.getText().toString();
71 | if (TextUtils.isEmpty(tcp_ip)) {
72 | Toast.makeText(getApplicationContext(), "IP不能为空!", Toast.LENGTH_LONG).show();
73 | return;
74 | } else {
75 | AbSharedUtil.putString(getApplicationContext(), "tcp_ip", tcp_ip);
76 | }
77 | String tcp_port = et_port.getText().toString();
78 | if (TextUtils.isEmpty(tcp_port)) {
79 | Toast.makeText(getApplicationContext(), "PORT不能为空!", Toast.LENGTH_LONG).show();
80 | return;
81 | } else {
82 | AbSharedUtil.putInt(getApplicationContext(), "tcp_port", Integer.valueOf(tcp_port));
83 | }
84 | String tcp_verify = et_verify.getText().toString();
85 | if (TextUtils.isEmpty(tcp_verify)) {
86 | Toast.makeText(getApplicationContext(), "认证信息不能为空!", Toast.LENGTH_LONG).show();
87 | return;
88 | } else {
89 | AbSharedUtil.putString(getApplicationContext(), "tcp_verify", tcp_verify);
90 | }
91 | Toast.makeText(getApplicationContext(), "保存成功", Toast.LENGTH_LONG).show();
92 | finish();
93 | break;
94 | case R.id.back:
95 | finish();
96 | break;
97 | case R.id.rl_back:
98 | finish();
99 | break;
100 | default:
101 | break;
102 | }
103 | }
104 | }
105 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/tcp/VerifyData.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.tcp;
2 |
3 | import com.tools.payhelper.utils.JsonHelper;
4 |
5 | /**
6 | * @since Create on 2018/11/8.
7 | */
8 | public class VerifyData {
9 |
10 | public static final int TYPE_Frist = 9; //第一次验证
11 | public static final int TYPE_Ping = 0; //心跳 20s/次
12 | public static final int TYPE_KeyOK = 1; //验证成功
13 | public static final int TYPE_KeyNO = 2; //验证失败
14 | public static final int TYPE_ResOK = 3; //获取数据成功
15 | public static final int TYPE_ResNO = 4; //获取数据失败
16 | public static final int TYPE_Interactive = 5; // 交互
17 | public static final int TYPE_SuccTransaction = 6; // 付款的订单
18 |
19 |
20 | /**
21 | * 服务器-》 首次验证key 返回 Type
22 | * 客户端-》 验证Type 状态
23 | */
24 | public int type;
25 | public int restype;
26 | public String res;
27 | /**
28 | * 例:服务器-》 InOutData:{ money:1000,mark:k18dsfsd0,type:alipay}
29 | * 客户端-》 InOutData: {data:{key:asdasda}} 等待服务器的数据,并发送心跳IntoData:{ping:0}
30 | */
31 | public InOut InOutData;
32 |
33 | public static class InOut {
34 | public String key;
35 | public String data;
36 |
37 | public static InOut verify(String verify) {
38 | InOut d = new InOut();
39 | d.key = verify;
40 | return d;
41 | }
42 | public static InOut heartBeat() {
43 | InOut d = new InOut();
44 | d.data = "0";
45 | return d;
46 | }
47 | public static InOut pay(String data) {
48 | InOut d = new InOut();
49 | d.data = data;
50 | return d;
51 | }
52 | }
53 |
54 | public static class PayResult {
55 | public String no;
56 | public String money;
57 | public String mark;
58 | public String type;
59 | public String dt;
60 | public String account;
61 | public String sign;
62 |
63 | public PayResult(String no, String money, String mark, String type, String dt, String account, String sign) {
64 | this.no = no;
65 | this.money = money;
66 | this.mark = mark;
67 | this.type = type;
68 | this.dt = dt;
69 | this.account = account;
70 | this.sign = sign;
71 | }
72 | }
73 |
74 | public static class PayCodeData {
75 | public String msg;
76 | public String payurl;
77 | public String mark;
78 | public String money;
79 | public String account;
80 | }
81 |
82 | public static VerifyData createVerifyData(String verify) {
83 | VerifyData data = new VerifyData();
84 | data.type = TYPE_Frist;
85 | data.InOutData = InOut.verify(verify);
86 | return data;
87 | }
88 |
89 | public static VerifyData createHeartBeatData() {
90 | VerifyData data = new VerifyData();
91 | data.type = TYPE_Ping;
92 | data.InOutData = InOut.heartBeat();
93 | return data;
94 | }
95 |
96 | public static VerifyData createPayData(String payData) {
97 | VerifyData data = new VerifyData();
98 | data.type = TYPE_Interactive;
99 | data.InOutData = InOut.pay(payData);
100 | return data;
101 | }
102 |
103 | public static VerifyData createPayResultData(String no, String money, String mark, String type, String dt, String account, String sign) {
104 | VerifyData data = new VerifyData();
105 | data.type = TYPE_SuccTransaction;
106 | data.InOutData = InOut.pay(JsonHelper.toJson(new PayResult(no, money, mark, type, dt, account, sign)));
107 | return data;
108 | }
109 |
110 |
111 | }
112 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/threadpool/ThreadPoolProxy.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.threadpool;
2 |
3 | import java.util.concurrent.BlockingQueue;
4 | import java.util.concurrent.Executors;
5 | import java.util.concurrent.Future;
6 | import java.util.concurrent.LinkedBlockingDeque;
7 | import java.util.concurrent.RejectedExecutionHandler;
8 | import java.util.concurrent.ThreadFactory;
9 | import java.util.concurrent.ThreadPoolExecutor;
10 | import java.util.concurrent.TimeUnit;
11 |
12 | public class ThreadPoolProxy {
13 |
14 | ThreadPoolExecutor mExecutor;
15 | private int mCorePoolSize;
16 | private int mMaximumPoolSize;
17 |
18 | /**
19 | * @param corePoolSize 核心池的大小
20 | * @param maximumPoolSize 最大线程数
21 | */
22 | public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
23 | mCorePoolSize = corePoolSize;
24 | mMaximumPoolSize = maximumPoolSize;
25 | }
26 |
27 | /**
28 | * 初始化ThreadPoolExecutor
29 | * 双重检查加锁,只有在第一次实例化的时候才启用同步机制,提高了性能
30 | */
31 | private void initThreadPoolExecutor() {
32 | if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
33 | synchronized (ThreadPoolProxy.class) {
34 | if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
35 | long keepAliveTime = 3000;
36 | TimeUnit unit = TimeUnit.MILLISECONDS;
37 | BlockingQueue workQueue = new LinkedBlockingDeque<>();
38 | ThreadFactory threadFactory = Executors.defaultThreadFactory();
39 | RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
40 |
41 | mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
42 | threadFactory, handler);
43 | }
44 | }
45 | }
46 | }
47 | /**
48 | 执行任务和提交任务的区别?
49 | 1.有无返回值
50 | execute->没有返回值
51 | submit-->有返回值
52 | 2.Future的具体作用?
53 | 1.有方法可以接收一个任务执行完成之后的结果,其实就是get方法,get方法是一个阻塞方法
54 | 2.get方法的签名抛出了异常===>可以处理任务执行过程中可能遇到的异常
55 | */
56 | /**
57 | * 执行任务
58 | */
59 | public void execute(Runnable task) {
60 | initThreadPoolExecutor();
61 | mExecutor.execute(task);
62 | }
63 |
64 | /**
65 | * 提交任务
66 | */
67 | public Future submit(Runnable task) {
68 | initThreadPoolExecutor();
69 | return mExecutor.submit(task);
70 | }
71 |
72 | /**
73 | * 移除任务
74 | */
75 | public void remove(Runnable task) {
76 | initThreadPoolExecutor();
77 | mExecutor.remove(task);
78 | }
79 |
80 | public ThreadPoolExecutor getExecutor() {
81 | return mExecutor;
82 | }
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/threadpool/ThreadPoolProxyFactory.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.threadpool;
2 |
3 | public class ThreadPoolProxyFactory {
4 | static ThreadPoolProxy mNormalThreadPoolProxy;
5 | static ThreadPoolProxy mDownLoadThreadPoolProxy;
6 |
7 | /**
8 | * 得到普通线程池代理对象mNormalThreadPoolProxy
9 | */
10 | public static ThreadPoolProxy getNormalThreadPoolProxy() {
11 | if (mNormalThreadPoolProxy == null) {
12 | synchronized (ThreadPoolProxyFactory.class) {
13 | if (mNormalThreadPoolProxy == null) {
14 | mNormalThreadPoolProxy = new ThreadPoolProxy(5, 5);
15 | }
16 | }
17 | }
18 | return mNormalThreadPoolProxy;
19 | }
20 |
21 | /**
22 | * 得到下载线程池代理对象mDownLoadThreadPoolProxy
23 | */
24 | public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
25 | if (mDownLoadThreadPoolProxy == null) {
26 | synchronized (ThreadPoolProxyFactory.class) {
27 | if (mDownLoadThreadPoolProxy == null) {
28 | mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
29 | }
30 | }
31 | }
32 | return mDownLoadThreadPoolProxy;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/AbSharedUtil.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.content.Context;
4 | import android.content.SharedPreferences;
5 | import android.content.SharedPreferences.Editor;
6 |
7 | //TODO: Auto-generated Javadoc
8 |
9 | /**
10 | * © 2012 amsoft.cn
11 | * 名称:AbSharedUtil.java
12 | * 描述:保存到 SharedPreferences 的数据.
13 | *
14 | * @author 还如一梦中
15 | * @version v1.0
16 | * @date:2014-10-09 下午11:52:13
17 | */
18 | public class AbSharedUtil {
19 |
20 | private static final String SHARED_PATH = "bbplayer";
21 |
22 | public static SharedPreferences getDefaultSharedPreferences(Context context) {
23 | return context.getSharedPreferences(SHARED_PATH, Context.MODE_PRIVATE);
24 | }
25 |
26 | public static void putInt(Context context,String key, int value) {
27 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
28 | Editor edit = sharedPreferences.edit();
29 | edit.putInt(key, value);
30 | edit.commit();
31 | }
32 |
33 | public static int getInt(Context context,String key) {
34 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
35 | return sharedPreferences.getInt(key, 0);
36 | }
37 |
38 | public static void putString(Context context,String key, String value) {
39 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
40 | Editor edit = sharedPreferences.edit();
41 | edit.putString(key, value);
42 | edit.commit();
43 | }
44 |
45 | public static String getString(Context context,String key) {
46 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
47 | return sharedPreferences.getString(key,null);
48 | }
49 |
50 | public static void putBoolean(Context context,String key, boolean value) {
51 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
52 | Editor edit = sharedPreferences.edit();
53 | edit.putBoolean(key, value);
54 | edit.commit();
55 | }
56 |
57 | public static boolean getBoolean(Context context,String key,boolean defValue) {
58 | SharedPreferences sharedPreferences = getDefaultSharedPreferences(context);
59 | return sharedPreferences.getBoolean(key,defValue);
60 | }
61 |
62 | }
63 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/BitmapUtil.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import static android.graphics.Color.BLACK;
4 |
5 | import java.io.ByteArrayOutputStream;
6 | import java.io.IOException;
7 | import java.util.HashMap;
8 | import java.util.Hashtable;
9 | import java.util.Map;
10 |
11 | import com.google.zxing.BarcodeFormat;
12 | import com.google.zxing.EncodeHintType;
13 | import com.google.zxing.MultiFormatWriter;
14 | import com.google.zxing.WriterException;
15 | import com.google.zxing.common.BitMatrix;
16 | import com.google.zxing.qrcode.QRCodeWriter;
17 | import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
18 |
19 | import android.annotation.SuppressLint;
20 | import android.graphics.Bitmap;
21 | import android.graphics.Bitmap.CompressFormat;
22 | import android.graphics.Canvas;
23 | import android.util.Base64;
24 |
25 | /**
26 | * Created by 1 on 2017/5/19.
27 | */
28 | public class BitmapUtil {
29 | //生成二维码图片(不带图片)
30 | public static Bitmap createQRCode(String url, int widthAndHeight)
31 | throws WriterException {
32 | Hashtable hints = new Hashtable();
33 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
34 | BitMatrix matrix = new MultiFormatWriter().encode("lvu",
35 | BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
36 |
37 | int width = matrix.getWidth();
38 | int height = matrix.getHeight();
39 | int[] pixels = new int[width * height];
40 | //画黑点
41 | for (int y = 0; y < height; y++) {
42 | for (int x = 0; x < width; x++) {
43 | if (matrix.get(x, y)) {
44 | pixels[y * width + x] = BLACK; //0xff000000
45 | }
46 | }
47 | }
48 | Bitmap bitmap = Bitmap.createBitmap(width, height,
49 | Bitmap.Config.ARGB_8888);
50 | bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
51 | return bitmap;
52 | }
53 |
54 |
55 | //带图片的二维码
56 | public static Bitmap createQRImage(String content, int heightPix, Bitmap logoBm) {
57 | try {
58 | //配置参数
59 | Map hints = new HashMap();
60 | hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
61 | //容错级别
62 | hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
63 | // 图像数据转换,使用了矩阵转换
64 | BitMatrix bitMatrix = new QRCodeWriter().encode(content, BarcodeFormat.QR_CODE, heightPix, heightPix, hints);
65 | int[] pixels = new int[heightPix * heightPix];
66 | // 下面这里按照二维码的算法,逐个生成二维码的图片,
67 | // 两个for循环是图片横列扫描的结果
68 | for (int y = 0; y < heightPix; y++) {
69 | for (int x = 0; x < heightPix; x++) {
70 | if (bitMatrix.get(x, y)) {
71 | pixels[y * heightPix + x] = 0xff000000;
72 | } else {
73 | pixels[y * heightPix + x] = 0xffffffff;
74 | }
75 | }
76 | }
77 |
78 | // 生成二维码图片的格式,使用ARGB_8888
79 | Bitmap bitmap = Bitmap.createBitmap(heightPix, heightPix, Bitmap.Config.ARGB_8888);
80 | bitmap.setPixels(pixels, 0, heightPix, 0, 0, heightPix, heightPix);
81 |
82 | if (logoBm != null) {
83 | bitmap = addLogo(bitmap, logoBm);
84 | }
85 |
86 | //必须使用compress方法将bitmap保存到文件中再进行读取。直接返回的bitmap是没有任何压缩的,内存消耗巨大!
87 | return bitmap;
88 | } catch (WriterException e) {
89 | e.printStackTrace();
90 | }
91 |
92 | return null;
93 | }
94 |
95 | @SuppressLint("NewApi")
96 | public static String bitmapToBase64(Bitmap bitmap) {
97 |
98 | // 要返回的字符串
99 | String reslut = null;
100 |
101 | ByteArrayOutputStream baos = null;
102 |
103 | try {
104 |
105 | if (bitmap != null) {
106 |
107 | baos = new ByteArrayOutputStream();
108 | /**
109 | * 压缩只对保存有效果bitmap还是原来的大小
110 | */
111 | bitmap.compress(CompressFormat.JPEG, 30, baos);
112 |
113 | baos.flush();
114 | baos.close();
115 | // 转换为字节数组
116 | byte[] byteArray = baos.toByteArray();
117 |
118 | // 转换为字符串
119 | reslut = Base64.encodeToString(byteArray, Base64.DEFAULT);
120 | } else {
121 | return null;
122 | }
123 | } catch (IOException e) {
124 | e.printStackTrace();
125 | } finally {
126 |
127 | try {
128 | if (baos != null) {
129 | baos.close();
130 | }
131 | } catch (IOException e) {
132 | e.printStackTrace();
133 | }
134 |
135 | }
136 | return reslut;
137 |
138 | }
139 |
140 | /**
141 | * 在二维码中间添加Logo图案
142 | */
143 | private static Bitmap addLogo(Bitmap src, Bitmap logo) {
144 | if (src == null) {
145 | return null;
146 | }
147 |
148 | if (logo == null) {
149 | return src;
150 | }
151 |
152 | //获取图片的宽高
153 | int srcWidth = src.getWidth();
154 | int srcHeight = src.getHeight();
155 | int logoWidth = logo.getWidth();
156 | int logoHeight = logo.getHeight();
157 |
158 | if (srcWidth == 0 || srcHeight == 0) {
159 | return null;
160 | }
161 |
162 | if (logoWidth == 0 || logoHeight == 0) {
163 | return src;
164 | }
165 |
166 | //logo大小为二维码整体大小的1/5
167 | float scaleFactor = srcWidth * 1.0f / 5 / logoWidth;
168 | Bitmap bitmap = Bitmap.createBitmap(srcWidth, srcHeight, Bitmap.Config.ARGB_8888);
169 | try {
170 | Canvas canvas = new Canvas(bitmap);
171 | canvas.drawBitmap(src, 0, 0, null);
172 | canvas.scale(scaleFactor, scaleFactor, srcWidth / 2, srcHeight / 2);
173 | canvas.drawBitmap(logo, (srcWidth - logoWidth) / 2, (srcHeight - logoHeight) / 2, null);
174 |
175 | canvas.save(Canvas.ALL_SAVE_FLAG);
176 | canvas.restore();
177 | } catch (Exception e) {
178 | bitmap = null;
179 | e.getStackTrace();
180 | }
181 |
182 | return bitmap;
183 | }
184 |
185 |
186 | }
187 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/CrashHandler.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.io.File;
4 | import java.io.FileOutputStream;
5 | import java.io.PrintWriter;
6 | import java.io.StringWriter;
7 | import java.io.Writer;
8 | import java.lang.Thread.UncaughtExceptionHandler;
9 | import java.lang.reflect.Field;
10 | import java.text.DateFormat;
11 | import java.text.SimpleDateFormat;
12 | import java.util.Date;
13 | import java.util.HashMap;
14 | import java.util.Map;
15 |
16 | import android.content.Context;
17 | import android.content.pm.PackageInfo;
18 | import android.content.pm.PackageManager;
19 | import android.content.pm.PackageManager.NameNotFoundException;
20 | import android.os.Build;
21 | import android.os.Environment;
22 | import android.os.Looper;
23 | import android.util.Log;
24 |
25 | /**
26 | * UncaughtException处理�?,当程序发生Uncaught异常的时�?,有该类来接管程序,并记录发送错误报�?.
27 | *
28 | * @author user
29 | *
30 | */
31 | public class CrashHandler implements
32 | UncaughtExceptionHandler {
33 |
34 | public static final String TAG = "CrashHandler";
35 |
36 | // 系统默认的UncaughtException处理�?
37 | private Thread.UncaughtExceptionHandler mDefaultHandler;
38 | // CrashHandler实例
39 | private static CrashHandler INSTANCE = new CrashHandler();
40 | // 程序的Context对象
41 | private Context mContext;
42 | // 用来存储设备信息和异常信�?
43 | private Map infos = new HashMap();
44 |
45 | // 用于格式化日�?,作为日志文件名的�?部分
46 | private DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss");
47 |
48 | /** 保证只有�?个CrashHandler实例 */
49 | private CrashHandler() {
50 |
51 | }
52 |
53 | /** 获取CrashHandler实例 ,单例模式 */
54 | public static CrashHandler getInstance() {
55 | return INSTANCE;
56 | }
57 |
58 | /**
59 | * 初始�?
60 | *
61 | * @param context
62 | */
63 | public void init(Context context) {
64 | mContext = context;
65 | // 获取系统默认的UncaughtException处理�?
66 | mDefaultHandler = Thread.getDefaultUncaughtExceptionHandler();
67 | // 设置该CrashHandler为程序的默认处理�?
68 | Thread.setDefaultUncaughtExceptionHandler(this);
69 | }
70 |
71 | /**
72 | * 当UncaughtException发生时会转入该函数来处理
73 | */
74 | @Override
75 | public void uncaughtException(Thread thread, Throwable ex) {
76 | if (!handleException(ex) && mDefaultHandler != null) {
77 | // 如果用户没有处理则让系统默认的异常处理器来处�?
78 | mDefaultHandler.uncaughtException(thread, ex);
79 | } else {
80 | try {
81 | Thread.sleep(3000);
82 | } catch (InterruptedException e) {
83 | Log.e(TAG, "error : ", e);
84 | }
85 | // �?出程�?
86 | android.os.Process.killProcess(android.os.Process.myPid());
87 | System.exit(1);
88 | }
89 | }
90 |
91 | /**
92 | * 自定义错误处�?,收集错误信息 发�?�错误报告等操作均在此完�?.
93 | *
94 | * @param ex
95 | * @return true:如果处理了该异常信息;否则返回false.
96 | */
97 | @SuppressWarnings("deprecation")
98 | private boolean handleException(Throwable ex) {
99 | if (ex == null) {
100 | return false;
101 | }
102 | // 使用Toast来显示异常信�?
103 | new Thread() {
104 | @Override
105 | public void run() {
106 | Looper.prepare();
107 | Looper.loop();
108 | }
109 | }.start();
110 | // 收集设备参数信息
111 | collectDeviceInfo(mContext);
112 | // 保存日志文件
113 | saveCrashInfo2File(ex);
114 | android.os.Process.killProcess(android.os.Process.myPid());
115 | // System.exit(0);
116 | return true;
117 | }
118 |
119 | /**
120 | * 收集设备参数信息
121 | *
122 | * @param ctx
123 | */
124 | public void collectDeviceInfo(Context ctx) {
125 | try {
126 | PackageManager pm = ctx.getPackageManager();
127 | PackageInfo pi = pm.getPackageInfo(ctx.getPackageName(),
128 | PackageManager.GET_ACTIVITIES);
129 | if (pi != null) {
130 | String versionName = pi.versionName == null ? "null"
131 | : pi.versionName;
132 | String versionCode = pi.versionCode + "";
133 | infos.put("versionName", versionName);
134 | infos.put("versionCode", versionCode);
135 | }
136 | } catch (NameNotFoundException e) {
137 | Log.e(TAG, "an error occured when collect package info", e);
138 | }
139 | Field[] fields = Build.class.getDeclaredFields();
140 | for (Field field : fields) {
141 | try {
142 | field.setAccessible(true);
143 | infos.put(field.getName(), field.get(null).toString());
144 | Log.d(TAG, field.getName() + " : " + field.get(null));
145 | } catch (Exception e) {
146 | Log.e(TAG, "an error occured when collect crash info", e);
147 | }
148 | }
149 | }
150 |
151 | /**
152 | * 保存错误信息到文件中
153 | *
154 | * @param ex
155 | * @return 返回文件名称,便于将文件传送到服务�?
156 | */
157 | private String saveCrashInfo2File(Throwable ex) {
158 |
159 | StringBuffer sb = new StringBuffer();
160 | for (Map.Entry entry : infos.entrySet()) {
161 | String key = entry.getKey();
162 | String value = entry.getValue();
163 | sb.append(key + "=" + value + "\n");
164 | }
165 | Writer writer = new StringWriter();
166 | PrintWriter printWriter = new PrintWriter(writer);
167 | ex.printStackTrace(printWriter);
168 | Throwable cause = ex.getCause();
169 | while (cause != null) {
170 | cause.printStackTrace(printWriter);
171 | cause = cause.getCause();
172 | }
173 | printWriter.close();
174 | String result = writer.toString();
175 | sb.append(result);
176 | try {
177 | long timestamp = System.currentTimeMillis();
178 | String time = formatter.format(new Date());
179 | String fileName = "crash-" + time + "-" + timestamp + ".log";
180 | if (Environment.getExternalStorageState().equals(
181 | Environment.MEDIA_MOUNTED)) {
182 | String path = Environment.getExternalStorageDirectory().getAbsolutePath()+"/PayHelper/crash/";
183 | File dir = new File(path);
184 | if (!dir.exists()) {
185 | dir.mkdirs();
186 | }
187 | // // 文件传到服务�?
188 | // upload(Base64.encodeToString(sb.toString().getBytes(),
189 | // Base64.DEFAULT));
190 | FileOutputStream fos = new FileOutputStream(path + fileName);
191 | fos.write(sb.toString().getBytes());
192 | fos.close();
193 | }
194 | return fileName;
195 | } catch (Exception e) {
196 | Log.e(TAG, "an error occured while writing file...", e);
197 | }
198 | return null;
199 | }
200 | }
201 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/DBHelper.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | *
9 |
10 | * @ClassName: DBHelper
11 |
12 | * @Description: TODO(这里用一句话描述这个类的作用)
13 |
14 | * @author SuXiaoliang
15 |
16 | * @date 2018年6月23日 下午1:27:16
17 |
18 | *
19 | */
20 | public class DBHelper extends SQLiteOpenHelper{
21 | public DBHelper(Context context) {
22 | super(context, "trade.db", null, 1);
23 | }
24 |
25 | @Override
26 | public void onCreate(SQLiteDatabase db) {
27 | db.execSQL("CREATE TABLE IF NOT EXISTS qrcode" +
28 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, money varchar, mark varchar, type varchar, payurl varchar, dt varchar)");
29 | db.execSQL("CREATE TABLE IF NOT EXISTS payorder" +
30 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, money varchar, mark varchar, type varchar, tradeno varchar, dt varchar, result varchar, time integer)");
31 | db.execSQL("CREATE TABLE IF NOT EXISTS tradeno" +
32 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, tradeno varchar, status varchar)");
33 | db.execSQL("CREATE TABLE IF NOT EXISTS config" +
34 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, name varchar, value varchar)");
35 | }
36 |
37 | @Override
38 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
39 | // TODO Auto-generated method stub
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/DBManager.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.text.DecimalFormat;
4 | import java.util.ArrayList;
5 |
6 | import android.content.Context;
7 | import android.database.Cursor;
8 | import android.database.sqlite.SQLiteDatabase;
9 |
10 | /**
11 | *
12 |
13 | * @ClassName: DBManager
14 |
15 | * @Description: TODO(这里用一句话描述这个类的作用)
16 |
17 | * @author SuXiaoliang
18 |
19 | * @date 2018年6月23日 下午1:27:22
20 |
21 | *
22 | */
23 | public class DBManager {
24 | private SQLiteDatabase db;
25 | private DBHelper helper;
26 | public DBManager(Context context){
27 | helper = new DBHelper(context);
28 | db = helper.getWritableDatabase();
29 | }
30 |
31 | public void addQrCode(QrCodeBean qrCodeBean) {
32 | db.beginTransaction();// 开始事务
33 | try {
34 | String dt=System.currentTimeMillis()/1000+"";
35 | db.execSQL("INSERT INTO qrcode VALUES(null,?,?,?,?,?)", new Object[] { qrCodeBean.getMoney(), qrCodeBean.getMark(), qrCodeBean.getType(), qrCodeBean.getPayurl(), dt });
36 | db.setTransactionSuccessful();// 事务成功
37 | } finally {
38 | db.endTransaction();// 结束事务
39 | }
40 | }
41 | public void addOrder(OrderBean ordereBean) {
42 | db.beginTransaction();// 开始事务
43 | try {
44 | String dt=System.currentTimeMillis()/1000+"";
45 | db.execSQL("INSERT INTO payorder VALUES(null,?,?,?,?,?,?,?)", new Object[] { ordereBean.getMoney(), ordereBean.getMark(), ordereBean.getType(), ordereBean.getNo(), dt ,ordereBean.getResult() , ordereBean.getTime() });
46 | db.setTransactionSuccessful();// 事务成功
47 | } finally {
48 | db.endTransaction();// 结束事务
49 | }
50 | }
51 | public void addTradeNo(String tradeNo,String status) {
52 | db.beginTransaction();// 开始事务
53 | try {
54 | db.execSQL("INSERT INTO tradeno VALUES(null,?,?)", new Object[] { tradeNo, status});
55 | db.setTransactionSuccessful();// 事务成功
56 | } finally {
57 | db.endTransaction();// 结束事务
58 | }
59 | }
60 |
61 | public void addConfig(String name,String value) {
62 | db.beginTransaction();// 开始事务
63 | try {
64 | db.execSQL("INSERT INTO config VALUES(null,?,?)", new Object[] { name,value });
65 | db.setTransactionSuccessful();// 事务成功
66 | } finally {
67 | db.endTransaction();// 结束事务
68 | }
69 | }
70 |
71 | public void updateConfig(String name,String value) {
72 | db.beginTransaction();// 开始事务
73 | try {
74 | db.execSQL("UPDATE config SET value=? WHERE name=?", new Object[] {value, name});
75 | db.setTransactionSuccessful();// 事务成功
76 | } finally {
77 | db.endTransaction();// 结束事务
78 | }
79 | }
80 |
81 | public void saveOrUpdateConfig(String name,String value) {
82 | if(getConfig(name).equals("null")){
83 | addConfig(name, value);
84 | }else{
85 | updateConfig(name, value);
86 | }
87 | }
88 |
89 | public String getConfig(String name) {
90 | String sql = "SELECT * FROM config WHERE name='"+name+"'";
91 | Cursor c = ExecSQLForCursor(sql);
92 | String value="null";
93 | if(c.moveToNext()){
94 | value=c.getString(c.getColumnIndex("value"));
95 | }
96 | c.close();
97 | return value;
98 | }
99 |
100 | public boolean isExistTradeNo(String tradeNo) {
101 | boolean isExist=false;
102 | String sql = "SELECT * FROM tradeno WHERE tradeno='"+tradeNo+"'";
103 | Cursor c = ExecSQLForCursor(sql);
104 | if(c.getCount()>0){
105 | isExist=true;
106 | }
107 | c.close();
108 | return isExist;
109 | }
110 |
111 | public boolean isNotifyTradeNo(String tradeNo) {
112 | boolean isExist=false;
113 | String sql = "SELECT * FROM tradeno WHERE tradeno='"+tradeNo+"'";
114 | Cursor c = ExecSQLForCursor(sql);
115 | if(c.moveToNext()){
116 | String status=c.getString(c.getColumnIndex("status"));
117 | if(status.equals("1"))
118 | isExist=true;
119 | }
120 | c.close();
121 | return isExist;
122 | }
123 |
124 | public void updateTradeNo(String tradeNo,String status) {
125 | db.beginTransaction();// 开始事务
126 | try {
127 | db.execSQL("UPDATE tradeno SET status=? WHERE tradeno=?", new Object[] {status, tradeNo});
128 | db.setTransactionSuccessful();// 事务成功
129 | } finally {
130 | db.endTransaction();// 结束事务
131 | }
132 | }
133 |
134 | public void updateOrder(String no,String result) {
135 | db.beginTransaction();// 开始事务
136 | try {
137 | db.execSQL("UPDATE payorder SET result=?,time=time+1 WHERE tradeno=?", new Object[] {result, no});
138 | db.setTransactionSuccessful();// 事务成功
139 | } finally {
140 | db.endTransaction();// 结束事务
141 | }
142 | }
143 |
144 | public ArrayList FindQrCodes(String money,String mark,String type) {
145 | DecimalFormat df = new DecimalFormat("0.00");
146 | money=df.format(Double.parseDouble(money));
147 | String sql = "SELECT * FROM qrcode WHERE money =" + "'" + money + "' and mark='"+mark+"' and type='"+type+"'";
148 | ArrayList list = new ArrayList();
149 | Cursor c = ExecSQLForCursor(sql);
150 | while (c.moveToNext()) {
151 | QrCodeBean info = new QrCodeBean();
152 | info.setMoney(c.getString(c.getColumnIndex("money")));
153 | info.setMark(c.getString(c.getColumnIndex("mark")));
154 | info.setType(c.getString(c.getColumnIndex("type")));
155 | info.setPayurl(c.getString(c.getColumnIndex("payurl")));
156 | info.setDt(c.getString(c.getColumnIndex("dt")));
157 | list.add(info);
158 | }
159 | c.close();
160 | return list;
161 | }
162 | public ArrayList FindQrCodes(String mark,String type) {
163 | String sql = "SELECT * FROM qrcode WHERE mark='"+mark+"'";
164 | ArrayList list = new ArrayList();
165 | Cursor c = ExecSQLForCursor(sql);
166 | while (c.moveToNext()) {
167 | QrCodeBean info = new QrCodeBean();
168 | info.setMoney(c.getString(c.getColumnIndex("money")));
169 | info.setMark(c.getString(c.getColumnIndex("mark")));
170 | info.setType(c.getString(c.getColumnIndex("type")));
171 | info.setPayurl(c.getString(c.getColumnIndex("payurl")));
172 | info.setDt(c.getString(c.getColumnIndex("dt")));
173 | list.add(info);
174 | }
175 | c.close();
176 | return list;
177 | }
178 | public ArrayList FindOrders(String money,String mark,String type) {
179 | String sql = "SELECT * FROM payorder WHERE money =" + "'" + money + "' and mark='"+mark+"' and type='"+type+"'";
180 | ArrayList list = new ArrayList();
181 | Cursor c = ExecSQLForCursor(sql);
182 | while (c.moveToNext()) {
183 | OrderBean info = new OrderBean();
184 | info.setMoney(c.getString(c.getColumnIndex("money")));
185 | info.setMark(c.getString(c.getColumnIndex("mark")));
186 | info.setType(c.getString(c.getColumnIndex("type")));
187 | info.setNo(c.getString(c.getColumnIndex("tradeno")));
188 | info.setDt(c.getString(c.getColumnIndex("dt")));
189 | info.setResult(c.getString(c.getColumnIndex("result")));
190 | info.setTime(c.getInt(c.getColumnIndex("time")));
191 | list.add(info);
192 | }
193 | c.close();
194 | return list;
195 | }
196 | public ArrayList FindOrders(String mark) {
197 | String sql = "SELECT * FROM payorder WHERE mark='"+mark+"'";
198 | ArrayList list = new ArrayList();
199 | Cursor c = ExecSQLForCursor(sql);
200 | while (c.moveToNext()) {
201 | OrderBean info = new OrderBean();
202 | info.setMoney(c.getString(c.getColumnIndex("money")));
203 | info.setMark(c.getString(c.getColumnIndex("mark")));
204 | info.setType(c.getString(c.getColumnIndex("type")));
205 | info.setNo(c.getString(c.getColumnIndex("tradeno")));
206 | info.setDt(c.getString(c.getColumnIndex("dt")));
207 | info.setResult(c.getString(c.getColumnIndex("result")));
208 | info.setTime(c.getInt(c.getColumnIndex("time")));
209 | list.add(info);
210 | }
211 | c.close();
212 | return list;
213 | }
214 | public ArrayList FindOrdersByNo(String no) {
215 | String sql = "SELECT * FROM payorder WHERE tradeno='"+no+"'";
216 | ArrayList list = new ArrayList();
217 | Cursor c = ExecSQLForCursor(sql);
218 | while (c.moveToNext()) {
219 | OrderBean info = new OrderBean();
220 | info.setMoney(c.getString(c.getColumnIndex("money")));
221 | info.setMark(c.getString(c.getColumnIndex("mark")));
222 | info.setType(c.getString(c.getColumnIndex("type")));
223 | info.setNo(c.getString(c.getColumnIndex("tradeno")));
224 | info.setDt(c.getString(c.getColumnIndex("dt")));
225 | info.setResult(c.getString(c.getColumnIndex("result")));
226 | info.setTime(c.getInt(c.getColumnIndex("time")));
227 | list.add(info);
228 | }
229 | c.close();
230 | return list;
231 | }
232 | public ArrayList FindAllOrders() {
233 | String sql = "SELECT * FROM payorder where result <> 'success' and time<3 ";
234 | ArrayList list = new ArrayList();
235 | Cursor c = ExecSQLForCursor(sql);
236 | while (c.moveToNext()) {
237 | OrderBean info = new OrderBean();
238 | info.setMoney(c.getString(c.getColumnIndex("money")));
239 | info.setMark(c.getString(c.getColumnIndex("mark")));
240 | info.setType(c.getString(c.getColumnIndex("type")));
241 | info.setNo(c.getString(c.getColumnIndex("tradeno")));
242 | info.setDt(c.getString(c.getColumnIndex("dt")));
243 | info.setResult(c.getString(c.getColumnIndex("result")));
244 | info.setTime(c.getInt(c.getColumnIndex("time")));
245 | list.add(info);
246 | }
247 | c.close();
248 | return list;
249 | }
250 |
251 | /**
252 | * 执行SQL,返回一个游标
253 | *
254 | * @param sql
255 | * @return
256 | */
257 | private Cursor ExecSQLForCursor(String sql) {
258 | Cursor c = db.rawQuery(sql, null);
259 | return c;
260 | }
261 | }
262 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/ExecutorManager.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.os.AsyncTask;
4 | import android.os.Handler;
5 | import android.os.Looper;
6 |
7 | import java.util.concurrent.Executor;
8 |
9 | import static android.os.AsyncTask.THREAD_POOL_EXECUTOR;
10 |
11 |
12 | public class ExecutorManager {
13 | private static Executor mParallelExecutor = THREAD_POOL_EXECUTOR;
14 | private static Executor mSerialExecutor = AsyncTask.SERIAL_EXECUTOR;
15 | private static Handler sHandler = new Handler(Looper.getMainLooper());
16 |
17 | private ExecutorManager() {
18 | mParallelExecutor = THREAD_POOL_EXECUTOR;
19 | mSerialExecutor = AsyncTask.SERIAL_EXECUTOR;
20 | }
21 |
22 | public static void runOnUIThread(Runnable runnable) {
23 | sHandler.post(runnable);
24 | }
25 |
26 | public static void executeTask(Runnable task) {
27 | executeTask(task, true);
28 | }
29 |
30 | public static void executeTaskSerially(Runnable task) {
31 | executeTask(task, false);
32 | }
33 |
34 | public static void executeTask(Runnable task, boolean parallel) {
35 | if (parallel) {
36 | mParallelExecutor.execute(task);
37 | return;
38 | }
39 | mSerialExecutor.execute(task);
40 | }
41 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/JsonHelper.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 |
4 | import java.lang.reflect.Type;
5 |
6 | import com.google.myjson.Gson;
7 | import com.google.myjson.JsonElement;
8 | import com.google.myjson.JsonObject;
9 |
10 | /**
11 | * JsonHelper
12 | *
13 | * @author wrbug
14 | * @since 2017/9/29
15 | */
16 | public class JsonHelper {
17 | private static Gson sGson = new Gson();
18 |
19 | public static String toJson(Object o) {
20 | if (o == null) {
21 | return "";
22 | }
23 | return sGson.toJson(o);
24 | }
25 |
26 |
27 | public static JsonObject fromJson(Object json) {
28 | return fromJson(json, JsonObject.class);
29 | }
30 |
31 | public static T fromJson(Object json, Class tClass) {
32 | try {
33 |
34 | if (json == null) {
35 | return null;
36 | }
37 | if (json instanceof JsonElement) {
38 | return sGson.fromJson((JsonElement) json, tClass);
39 | }
40 | return sGson.fromJson(json.toString(), tClass);
41 | } catch (Throwable t) {
42 |
43 | }
44 | return null;
45 | }
46 |
47 | public static T fromJson(Object json, Type tClass) {
48 | try {
49 | if (json == null) {
50 | return null;
51 | }
52 | if (json instanceof JsonElement) {
53 | return sGson.fromJson((JsonElement) json, tClass);
54 | }
55 | return sGson.fromJson(json.toString(), tClass);
56 |
57 | } catch (Throwable t) {
58 |
59 | }
60 | return null;
61 | }
62 |
63 | public static Gson getGson() {
64 | return sGson;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/LauncherLimitUtils.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 |
4 | import com.tools.payhelper.BuildConfig;
5 |
6 | public class LauncherLimitUtils {
7 |
8 | public static void checkLauncherLimit(int dayAfter) {
9 | long limitTimestamp = TimeUtils.getTimeStampByTimeString(BuildConfig.BUILD_TIME, "yyyy-MM-dd")
10 | + dayAfter * TimeUtils.MILLISECONDS_PER_DAY;
11 | if (System.currentTimeMillis() > limitTimestamp) {
12 | throw new RuntimeException("The apk is invalid.");
13 | }
14 | }
15 |
16 | }
17 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/LogToFile.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.io.BufferedWriter;
4 | import java.io.File;
5 | import java.io.FileNotFoundException;
6 | import java.io.FileOutputStream;
7 | import java.io.IOException;
8 | import java.io.OutputStreamWriter;
9 | import java.text.SimpleDateFormat;
10 | import java.util.Date;
11 | import java.util.Locale;
12 |
13 | import android.content.Context;
14 | import android.os.Environment;
15 |
16 | /**
17 | * Created by admin on 2018/3/26.
18 | */
19 |
20 | public class LogToFile {
21 |
22 | private static String TAG = "LogToFile";
23 |
24 | private static SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.US);//日期格式;
25 | private static SimpleDateFormat dateFormat_log = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);//日期格式;
26 |
27 | /**
28 | * 获得文件存储路径
29 | *
30 | * @return
31 | */
32 | public static String getFilePath() {
33 | String logPath = null;
34 | logPath = Environment.getExternalStorageDirectory().getAbsolutePath()+"/PayHelper/logs";//获得文件储存路径,在后面加"/Logs"建立子文件夹
35 | File file = new File(logPath);
36 | if (file.exists()) {
37 | if (getFolderSize(file) > 150 * 1024 * 1024) {
38 | deleteFile(file);
39 | }
40 | } else {
41 | file.mkdirs();
42 | }
43 | return logPath;
44 | }
45 |
46 | private static final char VERBOSE = 'v';
47 |
48 | private static final char DEBUG = 'd';
49 |
50 | private static final char INFO = 'i';
51 |
52 | private static final char WARN = 'w';
53 |
54 | private static final char ERROR = 'e';
55 |
56 | public static void v(String tag, String msg) {
57 | writeToFile(VERBOSE, tag, msg);
58 | }
59 |
60 | public static void d(String tag, String msg) {
61 | File file = new File(getFilePath());
62 | if (getFolderSize(file) < 500 * 1024 * 1024) {
63 | writeToFile(DEBUG, tag, msg);
64 | }
65 |
66 | }
67 |
68 | public static void i(String tag, String msg) {
69 | writeToFile(INFO, tag, msg);
70 | }
71 |
72 | public static void w(String tag, String msg) {
73 | writeToFile(WARN, tag, msg);
74 | }
75 |
76 | public static void e(String tag, String msg) {
77 | writeToFile(ERROR, tag, msg);
78 | }
79 |
80 | /**
81 | * 将log信息写入文件中
82 | *
83 | * @param type
84 | * @param tag
85 | * @param msg
86 | */
87 | private static void writeToFile(char type, String tag, String msg) {
88 |
89 | String fileName = getFilePath() + "/log_" + dateFormat.format(new Date()) + ".txt";//log日志名,使用时间命名,保证不重复
90 | String log = dateFormat_log.format(new Date()) + " " + type + " " + tag + " " + msg + "\n";//log日志内容,可以自行定制
91 |
92 | //如果父路径不存在
93 | File file = new File(getFilePath());
94 | if (!file.exists()) {
95 | file.mkdirs();//创建父路径
96 | }
97 |
98 | FileOutputStream fos = null;//FileOutputStream会自动调用底层的close()方法,不用关闭
99 | BufferedWriter bw = null;
100 | try {
101 |
102 | fos = new FileOutputStream(fileName, true);//这里的第二个参数代表追加还是覆盖,true为追加,flase为覆盖
103 | bw = new BufferedWriter(new OutputStreamWriter(fos));
104 | bw.write(log);
105 |
106 | } catch (FileNotFoundException e) {
107 | e.printStackTrace();
108 | } catch (IOException e) {
109 | e.printStackTrace();
110 | } finally {
111 | try {
112 | if (bw != null) {
113 | bw.close();//关闭缓冲流
114 | }
115 | } catch (IOException e) {
116 | e.printStackTrace();
117 | }
118 | }
119 |
120 | }
121 |
122 | public static long getFolderSize(File file) {
123 |
124 | long size = 0;
125 | try {
126 | File[] fileList = file.listFiles();
127 | for (int i = 0; i < fileList.length; i++) {
128 | if (fileList[i].isDirectory()) {
129 | size = size + getFolderSize(fileList[i]);
130 |
131 | } else {
132 | size = size + fileList[i].length();
133 |
134 | }
135 | }
136 | } catch (Exception e) {
137 | // TODO Auto-generated catch block
138 | e.printStackTrace();
139 | }
140 | return size;
141 | }
142 |
143 | /**
144 | * 删除日志
145 | *
146 | * @param file
147 | */
148 | public static void deleteFile(File file) {
149 | if (file.isDirectory()) {
150 | File[] files = file.listFiles();
151 | for (int i = 0; i < files.length; i++) {
152 | File f = files[i];
153 | deleteFile(f);
154 | }
155 | // file.delete();//如要保留文件夹,只删除文件,请注释这行
156 | } else if (file.exists()) {
157 | file.delete();
158 | }
159 | }
160 |
161 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/LogUtils.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.content.Context;
4 | import android.os.Environment;
5 |
6 | import java.io.File;
7 | import java.io.FileOutputStream;
8 | import java.text.SimpleDateFormat;
9 | import java.util.Date;
10 | import java.util.Locale;
11 |
12 |
13 | /**
14 | *
15 | * The log tool support write log to file, need the follow permission.
16 | *
"android.permission.WRITE_EXTERNAL_STORAGE"
17 | * "android.permission.MOUNT_UNMOUNT_FILESYSTEMS"
18 | *
19 | *
20 | * @since Create on 2016/10/31.
21 | **/
22 | public class LogUtils {
23 |
24 | private static final String TAG = "LogUtils";
25 |
26 | /**
27 | * Whether output log
28 | */
29 | private static boolean mDebug = false;
30 | /**
31 | * Whether write log to file
32 | */
33 | private static boolean mWriteFile;
34 | /**
35 | * The log dir parent path.
36 | */
37 | private static File mWriteLogDir = null;
38 | /**
39 | * The log dir.
40 | */
41 | private static final String LOG_FILE_PATH = "log";
42 | /**
43 | * The format for date.
44 | */
45 | private static SimpleDateFormat mDateFormat = null;
46 | /**
47 | * The FileOutputStream for write log.
48 | */
49 | private static FileOutputStream mFileOutputStream = null;
50 |
51 | public static void init(Context context, boolean debug, boolean writeFile) {
52 | mDebug = debug;
53 | mWriteFile = writeFile;
54 | if (mWriteFile) {
55 | if (Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED)) {
56 | mWriteLogDir = new File(Environment.getExternalStorageDirectory(), context.getPackageName());
57 | } else {
58 | mWriteLogDir = new File(context.getCacheDir(), context.getPackageName());
59 | }
60 | mWriteLogDir = new File(mWriteLogDir, LOG_FILE_PATH);
61 | }
62 | }
63 |
64 | public static void d(String msg) {
65 | if (mDebug) {
66 | android.util.Log.d(TAG, buildMessage(msg));
67 | }
68 | }
69 |
70 | public static void d(String tag, String msg) {
71 | if (mDebug) {
72 | android.util.Log.d(tag, buildMessage(msg));
73 | }
74 | }
75 |
76 | public static void i(String msg) {
77 | if (mDebug) {
78 | android.util.Log.i(TAG, buildMessage(msg));
79 | }
80 | }
81 |
82 | public static void i(String tag, String msg) {
83 | if (mDebug) {
84 | android.util.Log.i(tag, buildMessage(msg));
85 | }
86 | }
87 |
88 | public static void w(String msg) {
89 | if (mDebug) {
90 | android.util.Log.w(TAG, buildMessage(msg));
91 | }
92 | }
93 |
94 | public static void w(String tag, String msg) {
95 | if (mDebug) {
96 | android.util.Log.w(tag, buildMessage(msg));
97 | }
98 | }
99 |
100 | public static void e(String msg) {
101 | if (mDebug) {
102 | android.util.Log.e(TAG, buildMessage(msg));
103 | }
104 | }
105 |
106 | public static void e(String tag, String msg) {
107 | if (mDebug) {
108 | android.util.Log.e(tag, buildMessage(msg));
109 | }
110 | }
111 |
112 | public static void e(Exception ex) {
113 | if (mDebug && null != ex) {
114 | android.util.Log.e(TAG, buildMessage(ex.toString()), ex);
115 | }
116 | }
117 |
118 | public static void e(String msg, Exception ex) {
119 | if (mDebug && null != ex) {
120 | android.util.Log.e(TAG, buildMessage(msg + ex.toString()), ex);
121 | }
122 | }
123 |
124 | public static void e(String tag, String msg, Exception ex) {
125 | if (mDebug && null != ex) {
126 | android.util.Log.e(tag, buildMessage(msg + ex.toString()), ex);
127 | }
128 | }
129 |
130 | private static String buildMessage(String msg) {
131 | StackTraceElement caller = Thread.currentThread().getStackTrace()[4];
132 | StringBuilder text = new StringBuilder();
133 | text.append(caller.getFileName()
134 | .replace(".java", ""))
135 | .append(".")
136 | .append(caller.getMethodName())
137 | .append("[")
138 | .append(caller.getLineNumber())
139 | .append("]:")
140 | .append(msg);
141 | if (mWriteFile) {
142 | writeLog2File(text.toString());
143 | }
144 | return text.toString();
145 | }
146 |
147 | private static void writeLog2File(String text) {
148 | try {
149 | if (null == mFileOutputStream) {
150 | mDateFormat = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss_SSS", Locale.getDefault());
151 | File file = new File(mWriteLogDir, "log_" + mDateFormat.format(new Date()) + ".txt");
152 | if (!file.exists()) {
153 | File parentFile = file.getParentFile();
154 | if (null != parentFile && !parentFile.exists() && !parentFile.mkdirs()) {
155 | // has parent dir, but make failed.
156 | android.util.Log.e(TAG, "mkdirs is " + false);
157 | return;
158 | }
159 |
160 | if (!file.exists()) {
161 | // has not file
162 | android.util.Log.e(TAG, "has not file.");
163 | if (!file.createNewFile()) {
164 | // has not file, but create failed.
165 | android.util.Log.e(TAG, "createNewFile is " + false);
166 | }
167 | }
168 | }
169 | mFileOutputStream = new FileOutputStream(file, true);
170 | }
171 | String log = mDateFormat.format(new Date()) + ":(" + TAG + ")" + " >> " + text + "\n";
172 | mFileOutputStream.write(log.getBytes());
173 | mFileOutputStream.flush();
174 | } catch (Exception e) {
175 | android.util.Log.e(TAG, "Write error: " + e.toString());
176 | }
177 | }
178 | }
179 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/Logger.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.util.Log;
4 |
5 | /**
6 | * Created by efan on 2017/4/13.
7 | */
8 |
9 | public class Logger {
10 |
11 | //设为false关闭日志
12 | private static final boolean LOG_ENABLE = true;
13 |
14 | public static void i(String tag, String msg){
15 | if (LOG_ENABLE){
16 | Log.i(tag, msg);
17 | }
18 | }
19 | public static void v(String tag, String msg){
20 | if (LOG_ENABLE){
21 | Log.v(tag, msg);
22 | }
23 | }
24 | public static void d(String tag, String msg){
25 | if (LOG_ENABLE){
26 | Log.d(tag, msg);
27 | }
28 | }
29 | public static void w(String tag, String msg){
30 | if (LOG_ENABLE){
31 | Log.w(tag, msg);
32 | }
33 | }
34 | public static void e(String tag, String msg){
35 | if (LOG_ENABLE){
36 | Log.e(tag, msg);
37 | }
38 | }
39 |
40 | }
41 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/MD5.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.security.MessageDigest;
4 | /**
5 | * 说明:MD5处理
6 | * 创建人:FH Q313596790
7 | * 修改时间:2014年9月20日
8 | * @version
9 | */
10 | public class MD5 {
11 |
12 | public static String md5(String str) {
13 | try {
14 | MessageDigest md = MessageDigest.getInstance("MD5");
15 | md.update(str.getBytes());
16 | byte b[] = md.digest();
17 |
18 | int i;
19 |
20 | StringBuffer buf = new StringBuffer("");
21 | for (int offset = 0; offset < b.length; offset++) {
22 | i = b[offset];
23 | if (i < 0)
24 | i += 256;
25 | if (i < 16)
26 | buf.append("0");
27 | buf.append(Integer.toHexString(i));
28 | }
29 | str = buf.toString();
30 | } catch (Exception e) {
31 | e.printStackTrace();
32 |
33 | }
34 | return str;
35 | }
36 |
37 | public static String md5byte(byte[] str) {
38 | String str1 = null;
39 | try {
40 | MessageDigest md = MessageDigest.getInstance("MD5");
41 | md.update(str);
42 | byte b[] = md.digest();
43 |
44 | int i;
45 |
46 | StringBuffer buf = new StringBuffer("");
47 | for (int offset = 0; offset < b.length; offset++) {
48 | i = b[offset];
49 | if (i < 0)
50 | i += 256;
51 | if (i < 16)
52 | buf.append("0");
53 | buf.append(Integer.toHexString(i));
54 | }
55 | str1 = buf.toString();
56 | } catch (Exception e) {
57 | e.printStackTrace();
58 |
59 | }
60 | return str1;
61 | }
62 | public static void main(String[] args) {
63 | System.out.println(md5("31119@qq.com"+"123456"));
64 | System.out.println(md5("mj1"));
65 | System.out.println(md5("1BQljr6O6WxeHGZ77JU2qQ1eiMQvBdFFl3xTYWEIfW4="));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/OrderBean.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.io.Serializable;
4 |
5 | /**
6 | *
7 |
8 | * @ClassName: OrderBean
9 |
10 | * @Description: TODO(这里用一句话描述这个类的作用)
11 |
12 | * @author SuXiaoliang
13 |
14 | * @date 2018年6月23日 下午1:27:27
15 |
16 | *
17 | */
18 | public class OrderBean implements Serializable{
19 | private static final long serialVersionUID = 8988815091574805671L;
20 | private String money;
21 | private String mark;
22 | private String type;
23 | private String no;
24 | private String dt;
25 | private String result;
26 | private int time;
27 |
28 |
29 | public OrderBean() {
30 | super();
31 | }
32 | public OrderBean(String money, String mark, String type, String no, String dt, String result, int time) {
33 | super();
34 | this.money = money;
35 | this.mark = mark;
36 | this.type = type;
37 | this.no = no;
38 | this.dt = dt;
39 | this.result = result;
40 | this.time = time;
41 | }
42 | public String getMoney() {
43 | return money;
44 | }
45 | public void setMoney(String money) {
46 | this.money = money;
47 | }
48 | public String getMark() {
49 | return mark;
50 | }
51 | public void setMark(String mark) {
52 | this.mark = mark;
53 | }
54 | public String getType() {
55 | return type;
56 | }
57 | public void setType(String type) {
58 | this.type = type;
59 | }
60 | public String getNo() {
61 | return no;
62 | }
63 | public void setNo(String no) {
64 | this.no = no;
65 | }
66 | public String getDt() {
67 | return dt;
68 | }
69 | public void setDt(String dt) {
70 | this.dt = dt;
71 | }
72 | public String getResult() {
73 | return result;
74 | }
75 | public void setResult(String result) {
76 | this.result = result;
77 | }
78 | public int getTime() {
79 | return time;
80 | }
81 | public void setTime(int time) {
82 | this.time = time;
83 | }
84 |
85 |
86 | }
87 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/QQDBHelper.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.content.Context;
4 | import android.database.sqlite.SQLiteDatabase;
5 | import android.database.sqlite.SQLiteOpenHelper;
6 |
7 | /**
8 | *
9 |
10 | * @ClassName: QQDBHelper
11 |
12 | * @Description: TODO(这里用一句话描述这个类的作用)
13 |
14 | * @author SuXiaoliang
15 |
16 | * @date 2018年6月23日 下午1:27:36
17 |
18 | *
19 | */
20 | public class QQDBHelper extends SQLiteOpenHelper{
21 | public QQDBHelper(Context context) {
22 | super(context, "mark.db", null, 1);
23 | }
24 |
25 | @Override
26 | public void onCreate(SQLiteDatabase db) {
27 | db.execSQL("CREATE TABLE IF NOT EXISTS mark" +
28 | "(_id INTEGER PRIMARY KEY AUTOINCREMENT, money varchar, mark varchar, status varchar, dt varchar)");
29 | }
30 |
31 | @Override
32 | public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
33 | // TODO Auto-generated method stub
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/QQDBManager.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.util.ArrayList;
4 |
5 | import android.content.Context;
6 | import android.database.Cursor;
7 | import android.database.sqlite.SQLiteDatabase;
8 |
9 | /**
10 | *
11 |
12 | * @ClassName: QQDBManager
13 |
14 | * @Description: TODO(这里用一句话描述这个类的作用)
15 |
16 | * @author SuXiaoliang
17 |
18 | * @date 2018年6月23日 下午1:27:40
19 |
20 | *
21 | */
22 | public class QQDBManager {
23 | private SQLiteDatabase db;
24 | private QQDBHelper helper;
25 | public QQDBManager(Context context){
26 | helper = new QQDBHelper(context);
27 | db = helper.getWritableDatabase();
28 | }
29 |
30 | public void addQQMark(String money,String mark) {
31 | db.beginTransaction();// 开始事务
32 | try {
33 | String dt=System.currentTimeMillis()+"";
34 | db.execSQL("INSERT INTO mark VALUES(null,?,?,?,?)", new Object[] { money, mark, "0", dt});
35 | db.setTransactionSuccessful();// 事务成功
36 | } finally {
37 | db.endTransaction();// 结束事务
38 | }
39 | }
40 | public void updateOrder(String money,String mark) {
41 | db.beginTransaction();// 开始事务
42 | try {
43 | db.execSQL("UPDATE mark SET status='1' WHERE money=? and mark=?", new Object[] {money, mark});
44 | db.setTransactionSuccessful();// 事务成功
45 | } finally {
46 | db.endTransaction();// 结束事务
47 | }
48 | }
49 |
50 | public ArrayList FindQQMark(String money,String mark) {
51 | String sql = "SELECT * FROM mark WHERE money='"+money+"' and mark='"+mark+"' and status='0'";
52 | ArrayList list = new ArrayList();
53 | Cursor c = ExecSQLForCursor(sql);
54 | while (c.moveToNext()) {
55 | QrCodeBean info = new QrCodeBean();
56 | info.setMoney(c.getString(c.getColumnIndex("money")));
57 | info.setMark(c.getString(c.getColumnIndex("mark")));
58 | info.setDt(c.getString(c.getColumnIndex("dt")));
59 | list.add(info);
60 | }
61 | c.close();
62 | return list;
63 | }
64 | public QrCodeBean GetQQMark() {
65 | String sql = "SELECT * FROM mark WHERE status='0' order by dt desc";
66 | Cursor c = ExecSQLForCursor(sql);
67 | QrCodeBean info = new QrCodeBean();
68 | if (c.moveToNext()) {
69 | info.setMoney(c.getString(c.getColumnIndex("money")));
70 | info.setMark(c.getString(c.getColumnIndex("mark")));
71 | info.setDt(c.getString(c.getColumnIndex("dt")));
72 | }
73 | c.close();
74 | return info;
75 | }
76 |
77 | /**
78 | * 执行SQL,返回一个游标
79 | *
80 | * @param sql
81 | * @return
82 | */
83 | private Cursor ExecSQLForCursor(String sql) {
84 | Cursor c = db.rawQuery(sql, null);
85 | return c;
86 | }
87 | }
88 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/QRUtils.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.util.Hashtable;
4 |
5 | import com.google.zxing.BinaryBitmap;
6 | import com.google.zxing.ChecksumException;
7 | import com.google.zxing.DecodeHintType;
8 | import com.google.zxing.FormatException;
9 | import com.google.zxing.NotFoundException;
10 | import com.google.zxing.RGBLuminanceSource;
11 | import com.google.zxing.Result;
12 | import com.google.zxing.common.HybridBinarizer;
13 | import com.google.zxing.qrcode.QRCodeReader;
14 |
15 | import android.graphics.Bitmap;
16 | import android.graphics.BitmapFactory;
17 | import android.text.TextUtils;
18 |
19 | public class QRUtils {
20 |
21 | /**
22 | * 解析二维码图片
23 | * @param path
24 | * @return
25 | */
26 | public static Result scanningImage(String path) {
27 | Bitmap scanBitmap;
28 | if (TextUtils.isEmpty(path)) {
29 | return null;
30 |
31 | }
32 | Hashtable hints = new Hashtable();
33 | hints.put(DecodeHintType.CHARACTER_SET, "UTF-8"); // 设置二维码内容的编码
34 | BitmapFactory.Options options = new BitmapFactory.Options();
35 | options.inJustDecodeBounds = true; // 先获取原大小
36 | // scanBitmap = BitmapFactory.decodeFile(path,options);
37 | scanBitmap=ImageUtils.getBitmapByFile(path);
38 | options.inJustDecodeBounds = false;
39 | int sampleSize = (int) (options.outHeight / (float) 200);
40 | if (sampleSize <= 0) {
41 | sampleSize = 1;
42 | }
43 |
44 | options.inSampleSize = sampleSize;
45 |
46 | scanBitmap = BitmapFactory.decodeFile(path, options);
47 | int[] data = new int[scanBitmap.getWidth() * scanBitmap.getHeight()];
48 | scanBitmap.getPixels(data, 0, scanBitmap.getWidth(), 0, 0, scanBitmap.getWidth(), scanBitmap.getHeight());
49 | RGBLuminanceSource rgbLuminanceSource = new RGBLuminanceSource(scanBitmap.getWidth(),scanBitmap.getHeight(),data);
50 | BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(rgbLuminanceSource));
51 | QRCodeReader reader = new QRCodeReader();
52 | Result result = null;
53 | try {
54 | result = reader.decode(binaryBitmap, hints);
55 | } catch (NotFoundException e) {
56 | LogUtils.e("NotFoundException");
57 | }catch (ChecksumException e){
58 | LogUtils.e("ChecksumException");
59 | } catch (FormatException e) {
60 | // TODO Auto-generated catch block
61 | e.printStackTrace();
62 | }
63 |
64 | return result;
65 |
66 |
67 | }
68 | }
69 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/QrCodeBean.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.io.Serializable;
4 | import java.text.DecimalFormat;
5 |
6 | /**
7 | *
8 |
9 | * @ClassName: QrCodeBean
10 |
11 | * @Description: TODO(这里用一句话描述这个类的作用)
12 |
13 | * @author SuXiaoliang
14 |
15 | * @date 2018年6月23日 下午1:27:45
16 |
17 | *
18 | */
19 | public class QrCodeBean implements Serializable{
20 | private static final long serialVersionUID = 8988815091574805671L;
21 | private static final String serialVersionSTR = "1BQljr6O6WxeHGZ77JU2qQ1eiMQvBdFFl3xTYWEIfW4=";
22 |
23 | private String money;
24 | private String mark;
25 | private String type;
26 | private String payurl;
27 | private String dt;
28 |
29 |
30 | public QrCodeBean(String money, String mark, String type, String payurl, String dt) {
31 | super();
32 | this.money = money;
33 | this.mark = mark;
34 | this.type = type;
35 | this.payurl = payurl;
36 | this.dt = dt;
37 | }
38 |
39 | public QrCodeBean() {
40 | super();
41 | }
42 |
43 | public String getMoney() {
44 | return money;
45 | }
46 |
47 | public void setMoney(String money) {
48 | this.money = money;
49 | }
50 |
51 | public String getMark() {
52 | return mark;
53 | }
54 |
55 | public void setMark(String mark) {
56 | this.mark = mark;
57 | }
58 |
59 | public String getType() {
60 | return type;
61 | }
62 |
63 | public void setType(String type) {
64 | this.type = type;
65 | }
66 |
67 | public String getPayurl() {
68 | return payurl;
69 | }
70 |
71 | public void setPayurl(String payurl) {
72 | this.payurl = payurl;
73 | }
74 |
75 | public String getDt() {
76 | return dt;
77 | }
78 |
79 | public void setDt(String dt) {
80 | this.dt = dt;
81 | }
82 |
83 | }
84 |
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/StringUtils.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.io.BufferedOutputStream;
4 | import java.io.ByteArrayOutputStream;
5 | import java.io.File;
6 | import java.io.FileInputStream;
7 | import java.io.FileNotFoundException;
8 | import java.io.FileOutputStream;
9 | import java.io.IOException;
10 |
11 | import android.content.Context;
12 | import android.telephony.TelephonyManager;
13 |
14 | public class StringUtils {
15 |
16 | public static void main(String[] args) {
17 | }
18 |
19 | public static byte[] getBytes(String filePath) {
20 | byte[] buffer = null;
21 | try {
22 | File file = new File(filePath);
23 | FileInputStream fis = new FileInputStream(file);
24 | ByteArrayOutputStream bos = new ByteArrayOutputStream(1000);
25 | byte[] b = new byte[1000];
26 | int n;
27 | while ((n = fis.read(b)) != -1) {
28 | bos.write(b, 0, n);
29 | }
30 | fis.close();
31 | bos.close();
32 | buffer = bos.toByteArray();
33 | } catch (FileNotFoundException e) {
34 | e.printStackTrace();
35 | } catch (IOException e) {
36 | e.printStackTrace();
37 | }
38 | return buffer;
39 | }
40 |
41 | public static void getFile(byte[] bfile, String filePath, String fileName) {
42 | BufferedOutputStream bos = null;
43 | FileOutputStream fos = null;
44 | File file = null;
45 | try {
46 | File dir = new File(filePath);
47 | if (!dir.exists() && !dir.isDirectory()) {// �ж��ļ�Ŀ¼�Ƿ����?
48 | dir.mkdirs();
49 | }
50 | file = new File(filePath + "\\" + fileName);
51 | fos = new FileOutputStream(file);
52 | bos = new BufferedOutputStream(fos);
53 | bos.write(bfile);
54 | } catch (Exception e) {
55 | e.printStackTrace();
56 | } finally {
57 | if (bos != null) {
58 | try {
59 | bos.close();
60 | } catch (IOException e1) {
61 | e1.printStackTrace();
62 | }
63 | }
64 | if (fos != null) {
65 | try {
66 | fos.close();
67 | } catch (IOException e1) {
68 | e1.printStackTrace();
69 | }
70 | }
71 | }
72 | }
73 |
74 | public static String getimei(Context context){
75 | TelephonyManager tm = (TelephonyManager) context.getSystemService(context.TELEPHONY_SERVICE);
76 | String imei=tm.getDeviceId();
77 | if(imei==null){
78 | return "00000000000000000";
79 | }else{
80 | return tm.getDeviceId();
81 | }
82 | }
83 | public static String getTextCenter(String text,String begin,String end){
84 | try {
85 | int b=text.indexOf(begin)+begin.length();
86 | int e=text.indexOf(end,b);
87 | return text.substring(b,e);
88 | } catch (Exception e) {
89 | // TODO Auto-generated catch block
90 | e.printStackTrace();
91 | return "error";
92 | }
93 | }
94 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/Tag.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import java.util.ArrayList;
4 | import java.util.HashMap;
5 |
6 | public class Tag {
7 |
8 | private String mPath;
9 | private String mName;
10 | private ArrayList mChildren = new ArrayList<>();
11 | private String mContent;
12 |
13 | Tag(String path, String name) {
14 | mPath = path;
15 | mName = name;
16 | }
17 |
18 | void addChild(Tag tag) {
19 | mChildren.add(tag);
20 | }
21 |
22 | String getName() {
23 | return mName;
24 | }
25 |
26 | String getContent() {
27 | return mContent;
28 | }
29 |
30 | void setContent(String content) {
31 | boolean hasContent = false;
32 | if (content != null) {
33 | for (int i = 0; i < content.length(); ++i) {
34 | char c = content.charAt(i);
35 | if ((c != ' ') && (c != '\n')) {
36 | hasContent = true;
37 | break;
38 | }
39 | }
40 | }
41 | if (hasContent) {
42 | mContent = content;
43 | }
44 | }
45 |
46 | ArrayList getChildren() {
47 | return mChildren;
48 | }
49 |
50 | boolean hasChildren() {
51 | return (mChildren.size() > 0);
52 | }
53 |
54 | int getChildrenCount() {
55 | return mChildren.size();
56 | }
57 |
58 | Tag getChild(int index) {
59 | if ((index >= 0) && (index < mChildren.size())) {
60 | return mChildren.get(index);
61 | }
62 | return null;
63 | }
64 |
65 | HashMap> getGroupedElements() {
66 | HashMap> groups = new HashMap<>();
67 | for (Tag child : mChildren) {
68 | String key = child.getName();
69 | ArrayList group = groups.get(key);
70 | if (group == null) {
71 | group = new ArrayList<>();
72 | groups.put(key, group);
73 | }
74 | group.add(child);
75 | }
76 | return groups;
77 | }
78 |
79 | String getPath() {
80 | return mPath;
81 | }
82 |
83 | @Override
84 | public String toString() {
85 | return "Tag: " + mName + ", " + mChildren.size() + " children, Content: " + mContent;
86 | }
87 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/tools/payhelper/utils/TimeUtils.java:
--------------------------------------------------------------------------------
1 | package com.tools.payhelper.utils;
2 |
3 | import android.annotation.SuppressLint;
4 |
5 | import java.text.DecimalFormat;
6 | import java.text.ParseException;
7 | import java.text.SimpleDateFormat;
8 | import java.util.Calendar;
9 | import java.util.Date;
10 | import java.util.TimeZone;
11 |
12 |
13 | public class TimeUtils {
14 |
15 | /**
16 | * The milliseconds in one second
17 | */
18 | public static final int MILLISECONDS_PER_SECOND = 1000;
19 | /**
20 | * The second in one minute
21 | */
22 | public static final int SECOND_PER_MINUTE = 60;
23 | /**
24 | * The minute in one hour
25 | */
26 | public static final int MINUTE_PER_HOUR = 60;
27 | /**
28 | * The second in one hour
29 | */
30 | public static final int SECOND_PER_HOUR = 3600;
31 | /**
32 | * The hour in one day
33 | */
34 | public static final int HOUR_PER_DAY = 24;
35 | /**
36 | * The minute in one day
37 | */
38 | public static final int MINUTE_PER_DAY = 1440;
39 | /**
40 | * The second in one day
41 | */
42 | public static final int SECOND_PER_DAY = 86400;
43 | /**
44 | * The milliseconds in one day
45 | */
46 | public static final int MILLISECONDS_PER_DAY = 86400000;
47 | /**
48 | * The day in one week
49 | */
50 | public static final int DAY_PRE_WEEK = 7;
51 | /**
52 | * The month in one year
53 | */
54 | public static final int MONTH_PRE_YEAR = 12;
55 |
56 | /**
57 | * Get the time zone.
58 | *
59 | * @return the time zone.
60 | */
61 | public int getTimeZone() {
62 | Calendar cal = Calendar.getInstance();
63 | int zoneOffset = cal.get(Calendar.ZONE_OFFSET);
64 | int dstOffset = cal.get(Calendar.DST_OFFSET);
65 | return ((zoneOffset + dstOffset) / MILLISECONDS_PER_SECOND) / (MINUTE_PER_HOUR * SECOND_PER_MINUTE);
66 | }
67 |
68 | /**
69 | * Get the offset of time zone.
70 | *
71 | * @return the offset of time zone.
72 | */
73 | public int getTimeZoneOffset() {
74 | return TimeZone.getDefault().getOffset(System.currentTimeMillis()) / 1000;
75 | }
76 |
77 | /**
78 | * Get the day count of month.
79 | *
80 | * @param year year
81 | * @param month month 1-12
82 | * @return the day count of month.
83 | */
84 | public int getMonthDays(int year, int month) {
85 | Calendar calendar = Calendar.getInstance();
86 | calendar.set(year, month - 1, 1);
87 | return calendar.getActualMaximum(Calendar.DAY_OF_MONTH);
88 | }
89 |
90 | /**
91 | * Get the value of field.
92 | *
93 | * @param field Calendar.YEAR
94 | * @return the value of field
95 | */
96 | public int getCalendarField(int field) {
97 | Calendar calendar = Calendar.getInstance();
98 | return calendar.get(field);
99 | }
100 |
101 | /**
102 | * Get the local timestamp(second)
103 | *
104 | * @return second
105 | */
106 | public int getLocalSecond() {
107 | return (int) (System.currentTimeMillis() / 1000 + getTimeZoneOffset());
108 | }
109 |
110 | /**
111 | * Get the utc timestamp(second)
112 | *
113 | * @return second
114 | */
115 | public static int getUtcSecond() {
116 | return (int) (System.currentTimeMillis() / 1000);
117 | }
118 |
119 | /**
120 | * Get the utc timestamp(milliseconds)
121 | *
122 | * @return milliseconds
123 | */
124 | public static long getUtcMilliseconds() {
125 | return System.currentTimeMillis();
126 | }
127 |
128 | /**
129 | * Get the local timestamp(milliseconds)
130 | *
131 | * @return milliseconds
132 | */
133 | public int getLocalMilliseconds() {
134 | return (int) (System.currentTimeMillis() / 1000 + getTimeZoneOffset());
135 | }
136 |
137 | /**
138 | * Get the time string by timestamp(second)
139 | *
140 | * @param time the timestamp
141 | * @param format the format string like yyyy-MM-dd
142 | * @return the time string like 2016-12-17
143 | */
144 | public static String formatTime(int time, String format) {
145 | return formatTime(time * 1000L, format);
146 | }
147 |
148 | /**
149 | * Get the time sting by timestamp(milliseconds)
150 | *
151 | * @param time the timestamp
152 | * @param format the format string like yyyy-MM-dd
153 | * @return the time string like 2016-12-17
154 | */
155 | @SuppressLint("SimpleDateFormat")
156 | public static String formatTime(Long time, String format) {
157 | SimpleDateFormat sdf = new SimpleDateFormat(format);
158 | return sdf.format(new Date(time));
159 | }
160 |
161 | /**
162 | * Get the timestamp by time string
163 | *
164 | * @param timeStr the time string like 2016-12-17
165 | * @param format the format string like yyyy-MM-dd
166 | * @return the timestamp
167 | */
168 | @SuppressLint("SimpleDateFormat")
169 | public static long getTimeStampByTimeString(String timeStr, String format) {
170 | long time = 0;
171 | SimpleDateFormat sdf = new SimpleDateFormat(format);
172 | try {
173 | Date d = sdf.parse(timeStr);
174 | time = d.getTime();
175 | } catch (ParseException e) {
176 | e.printStackTrace();
177 | }
178 | return time;
179 | }
180 |
181 | /**
182 | * get the time stamp by time string
183 | *
184 | * @param time the time string like 2016-12-17
185 | * @param format the format string like yyyy-MM-dd
186 | * @return milliseconds
187 | */
188 | @SuppressLint("SimpleDateFormat")
189 | public static long getMillisSecond(String time, String format) {
190 | SimpleDateFormat sdf = new SimpleDateFormat(format);
191 | try {
192 | return sdf.parse(time).getTime();
193 | } catch (ParseException e) {
194 | e.printStackTrace();
195 | }
196 | return 0L;
197 | }
198 |
199 | /**
200 | * Second time convert to String like(12:45:30)
201 | *
202 | * @param totalSeconds the total second time
203 | * @return the string like 12:45:30 or 45:30
204 | */
205 | public static String second2TimeString(int totalSeconds) {
206 | DecimalFormat df = new DecimalFormat("00");
207 | StringBuilder sb = new StringBuilder();
208 | int hours = totalSeconds / SECOND_PER_HOUR;
209 | int minutes = (totalSeconds / SECOND_PER_MINUTE) % MINUTE_PER_HOUR;
210 | int seconds = totalSeconds % SECOND_PER_MINUTE;
211 | if (0 < hours) {
212 | sb.append(df.format(hours)).append(":");
213 | }
214 | sb.append(df.format(minutes)).append(":").append(df.format(seconds));
215 | return sb.toString();
216 | }
217 |
218 | /**
219 | * Second time convert to String like(02.03'04")
220 | *
221 | * @param totalSeconds the total second time
222 | * @return the string like 02.03'04" or 03'04"
223 | */
224 | public static String second2TimeString1(int totalSeconds) {
225 | DecimalFormat df = new DecimalFormat("00");
226 | StringBuilder sb = new StringBuilder();
227 | int hours = totalSeconds / SECOND_PER_HOUR;
228 | int minutes = (totalSeconds / SECOND_PER_MINUTE) % MINUTE_PER_HOUR;
229 | int seconds = totalSeconds % SECOND_PER_MINUTE;
230 | if (0 < hours) {
231 | sb.append(df.format(hours)).append(".");
232 | }
233 | sb.append(df.format(minutes)).append("\'").append(df.format(seconds)).append("\"");
234 | return sb.toString();
235 | }
236 |
237 | }
238 |
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/btn_back_grey.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-hdpi/btn_back_grey.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-hdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-hdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-ldpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-ldpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-mdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-mdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-xhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable-xxhdpi/ic_launcher.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/app/src/main/res/drawable-xxhdpi/ic_launcher.png
--------------------------------------------------------------------------------
/app/src/main/res/drawable/button.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | -
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | -
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_main.xml:
--------------------------------------------------------------------------------
1 |
8 |
9 |
16 |
17 |
26 |
27 |
36 |
37 |
46 |
47 |
56 |
57 |
58 |
64 |
65 |
74 |
75 |
84 |
85 |
86 |
92 |
93 |
101 |
102 |
103 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_setting.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
22 |
23 |
29 |
30 |
36 |
37 |
43 |
44 |
45 |
46 |
50 |
51 |
56 |
57 |
62 |
63 |
68 |
69 |
76 |
77 |
78 |
83 |
84 |
89 |
90 |
97 |
98 |
99 |
104 |
105 |
110 |
111 |
118 |
119 |
120 |
126 |
127 |
132 |
133 |
141 |
142 |
143 |
148 |
149 |
158 |
159 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/app/src/main/res/layout/activity_tcp_setting.xml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
12 |
13 |
22 |
23 |
29 |
30 |
36 |
37 |
43 |
44 |
45 |
46 |
50 |
51 |
56 |
57 |
62 |
63 |
68 |
69 |
76 |
77 |
78 |
83 |
84 |
89 |
90 |
98 |
99 |
100 |
105 |
106 |
111 |
112 |
120 |
121 |
122 |
127 |
128 |
137 |
138 |
147 |
148 |
149 |
150 |
151 |
--------------------------------------------------------------------------------
/app/src/main/res/menu/main.xml:
--------------------------------------------------------------------------------
1 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw600dp/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/app/src/main/res/values-sw720dp-land/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 | 128dp
8 |
9 |
10 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v11/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/app/src/main/res/values-v14/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
8 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/dimens.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 16dp
5 | 16dp
6 |
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/jpush_style.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
13 |
--------------------------------------------------------------------------------
/app/src/main/res/values/strings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | 收款助手
5 | Settings
6 | Hello world!
7 |
8 |
--------------------------------------------------------------------------------
/app/src/main/res/values/styles.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
7 |
14 |
15 |
16 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | // Top-level build file where you can add configuration options common to all sub-projects/modules.
2 |
3 | buildscript {
4 | repositories {
5 | google()
6 | jcenter()
7 | maven { url 'https://jitpack.io' }
8 | }
9 | dependencies {
10 | classpath 'com.android.tools.build:gradle:3.5.1'
11 |
12 | // NOTE: Do not place your application dependencies here; they belong
13 | // in the individual module build.gradle files
14 | }
15 | }
16 |
17 | allprojects {
18 | repositories {
19 | google()
20 | jcenter()
21 | maven { url 'https://jitpack.io' }
22 | }
23 | }
24 |
25 | ext {
26 |
27 | lib_okhttp_okhttp = 'com.squareup.okhttp3:okhttp:3.10.0'
28 | lib_okhttp_okio = 'com.squareup.okio:okio:1.14.1'
29 |
30 | }
31 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | # Project-wide Gradle settings.
2 | # IDE (e.g. Android Studio) users:
3 | # Gradle settings configured through the IDE *will override*
4 | # any settings specified in this file.
5 | # For more details on how to configure your build environment visit
6 | # http://www.gradle.org/docs/current/userguide/build_environment.html
7 | # Specifies the JVM arguments used for the daemon process.
8 | # The setting is particularly useful for tweaking memory settings.
9 | # When configured, Gradle will run in incubating parallel mode.
10 | # This option should only be used with decoupled projects. More details, visit
11 | # http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
12 | # org.gradle.parallel=true
13 | #systemProp.http.proxyPort=1080
14 | #android.enableD8=false
15 |
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #Thu Oct 31 09:57:00 CST 2019
2 | distributionBase=GRADLE_USER_HOME
3 | distributionPath=wrapper/dists
4 | zipStoreBase=GRADLE_USER_HOME
5 | zipStorePath=wrapper/dists
6 | distributionUrl=https\://services.gradle.org/distributions/gradle-5.4.1-all.zip
7 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env sh
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Attempt to set APP_HOME
10 | # Resolve links: $0 may be a link
11 | PRG="$0"
12 | # Need this for relative symlinks.
13 | while [ -h "$PRG" ] ; do
14 | ls=`ls -ld "$PRG"`
15 | link=`expr "$ls" : '.*-> \(.*\)$'`
16 | if expr "$link" : '/.*' > /dev/null; then
17 | PRG="$link"
18 | else
19 | PRG=`dirname "$PRG"`"/$link"
20 | fi
21 | done
22 | SAVED="`pwd`"
23 | cd "`dirname \"$PRG\"`/" >/dev/null
24 | APP_HOME="`pwd -P`"
25 | cd "$SAVED" >/dev/null
26 |
27 | APP_NAME="Gradle"
28 | APP_BASE_NAME=`basename "$0"`
29 |
30 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
31 | DEFAULT_JVM_OPTS=""
32 |
33 | # Use the maximum available, or set MAX_FD != -1 to use that value.
34 | MAX_FD="maximum"
35 |
36 | warn () {
37 | echo "$*"
38 | }
39 |
40 | die () {
41 | echo
42 | echo "$*"
43 | echo
44 | exit 1
45 | }
46 |
47 | # OS specific support (must be 'true' or 'false').
48 | cygwin=false
49 | msys=false
50 | darwin=false
51 | nonstop=false
52 | case "`uname`" in
53 | CYGWIN* )
54 | cygwin=true
55 | ;;
56 | Darwin* )
57 | darwin=true
58 | ;;
59 | MINGW* )
60 | msys=true
61 | ;;
62 | NONSTOP* )
63 | nonstop=true
64 | ;;
65 | esac
66 |
67 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
68 |
69 | # Determine the Java command to use to start the JVM.
70 | if [ -n "$JAVA_HOME" ] ; then
71 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
72 | # IBM's JDK on AIX uses strange locations for the executables
73 | JAVACMD="$JAVA_HOME/jre/sh/java"
74 | else
75 | JAVACMD="$JAVA_HOME/bin/java"
76 | fi
77 | if [ ! -x "$JAVACMD" ] ; then
78 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
79 |
80 | Please set the JAVA_HOME variable in your environment to match the
81 | location of your Java installation."
82 | fi
83 | else
84 | JAVACMD="java"
85 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
86 |
87 | Please set the JAVA_HOME variable in your environment to match the
88 | location of your Java installation."
89 | fi
90 |
91 | # Increase the maximum file descriptors if we can.
92 | if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
93 | MAX_FD_LIMIT=`ulimit -H -n`
94 | if [ $? -eq 0 ] ; then
95 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
96 | MAX_FD="$MAX_FD_LIMIT"
97 | fi
98 | ulimit -n $MAX_FD
99 | if [ $? -ne 0 ] ; then
100 | warn "Could not set maximum file descriptor limit: $MAX_FD"
101 | fi
102 | else
103 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
104 | fi
105 | fi
106 |
107 | # For Darwin, add options to specify how the application appears in the dock
108 | if $darwin; then
109 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
110 | fi
111 |
112 | # For Cygwin, switch paths to Windows format before running java
113 | if $cygwin ; then
114 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
115 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
116 | JAVACMD=`cygpath --unix "$JAVACMD"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Escape application args
158 | save () {
159 | for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
160 | echo " "
161 | }
162 | APP_ARGS=$(save "$@")
163 |
164 | # Collect all arguments for the java command, following the shell quoting and substitution rules
165 | eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
166 |
167 | # by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
168 | if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
169 | cd "$(dirname "$0")"
170 | fi
171 |
172 | exec "$JAVACMD" "$@"
173 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | set DIRNAME=%~dp0
12 | if "%DIRNAME%" == "" set DIRNAME=.
13 | set APP_BASE_NAME=%~n0
14 | set APP_HOME=%DIRNAME%
15 |
16 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
17 | set DEFAULT_JVM_OPTS=
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windows variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 |
53 | :win9xME_args
54 | @rem Slurp the command line arguments.
55 | set CMD_LINE_ARGS=
56 | set _SKIP=2
57 |
58 | :win9xME_args_slurp
59 | if "x%~1" == "x" goto execute
60 |
61 | set CMD_LINE_ARGS=%*
62 |
63 | :execute
64 | @rem Setup the command line
65 |
66 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
67 |
68 | @rem Execute Gradle
69 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
70 |
71 | :end
72 | @rem End local scope for the variables with windows NT shell
73 | if "%ERRORLEVEL%"=="0" goto mainEnd
74 |
75 | :fail
76 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
77 | rem the _cmd.exe /c_ return code!
78 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
79 | exit /b 1
80 |
81 | :mainEnd
82 | if "%OS%"=="Windows_NT" endlocal
83 |
84 | :omega
85 |
--------------------------------------------------------------------------------
/import-summary.txt:
--------------------------------------------------------------------------------
1 | ECLIPSE ANDROID PROJECT IMPORT SUMMARY
2 | ======================================
3 |
4 | Ignored Files:
5 | --------------
6 | The following files were *not* copied into the new Gradle project; you
7 | should evaluate whether these are still needed in your project and if
8 | so manually move them:
9 |
10 | * ic_launcher-web.png
11 | * lib\
12 | * lib\XposedBridgeAPI-89.jar
13 | * proguard-project.txt
14 | * proguard\
15 | * proguard\dump.txt
16 | * proguard\mapping.txt
17 | * proguard\seeds.txt
18 | * proguard\usage.txt
19 |
20 | Replaced Jars with Dependencies:
21 | --------------------------------
22 | The importer recognized the following .jar files as third party
23 | libraries and replaced them with Gradle dependencies instead. This has
24 | the advantage that more explicit version information is known, and the
25 | libraries can be updated automatically. However, it is possible that
26 | the .jar file in your project was of an older version than the
27 | dependency we picked, which could render the project not compileable.
28 | You can disable the jar replacement in the import wizard and try again:
29 |
30 | android-support-v4.jar => com.android.support:support-v4:25.3.1
31 |
32 | Moved Files:
33 | ------------
34 | Android Gradle projects use a different directory structure than ADT
35 | Eclipse projects. Here's how the projects were restructured:
36 |
37 | * AndroidManifest.xml => app\src\main\AndroidManifest.xml
38 | * assets\ => app\src\main\assets\
39 | * libs\core_3.2.0.jar => app\libs\core_3.2.0.jar
40 | * libs\jsoup-1.7.2.jar => app\libs\jsoup-1.7.2.jar
41 | * libs\myjson-1.5.jar => app\libs\myjson-1.5.jar
42 | * libs\nanohttpd-2.3.1-SNAPSHOT.jar => app\libs\nanohttpd-2.3.1-SNAPSHOT.jar
43 | * libs\org.apache.http.legacy.jar => app\libs\org.apache.http.legacy.jar
44 | * libs\support-annotations-25.0.0.jar => app\libs\support-annotations-25.0.0.jar
45 | * libs\xUtils-2.6.14.jar => app\libs\xUtils-2.6.14.jar
46 | * lint.xml => app\lint.xml
47 | * res\ => app\src\main\res\
48 | * src\ => app\src\main\java\
49 |
50 | Next Steps:
51 | -----------
52 | You can now build the project. The Gradle project needs network
53 | connectivity to download dependencies.
54 |
55 | Bugs:
56 | -----
57 | If for some reason your project does not build, and you determine that
58 | it is due to a bug or limitation of the Eclipse to Gradle importer,
59 | please file a bug at http://b.android.com with category
60 | Component-Tools.
61 |
62 | (This import summary is for your information only, and can be deleted
63 | after import once you are satisfied with the results.)
64 |
--------------------------------------------------------------------------------
/keystore/key.key:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/rhinoSp/PayHelper6.6.7_NewAPI/ca6ee805234fd7613ad9263c91c4f6da78ea90e5/keystore/key.key
--------------------------------------------------------------------------------
/local.properties:
--------------------------------------------------------------------------------
1 | ## This file must *NOT* be checked into Version Control Systems,
2 | # as it contains information specific to your local configuration.
3 | #
4 | # Location of the SDK. This is only used by Gradle.
5 | # For customization when using a Version Control System, please read the
6 | # header note.
7 | #Thu Nov 15 22:56:16 CST 2018
8 | ndk.dir=C\:\\ForWork\\Android\\sdk\\ndk-bundle
9 | sdk.dir=C\:\\ForWork\\Android\\sdk
10 |
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | include ':app'
2 |
--------------------------------------------------------------------------------