├── .gitattributes ├── .gitignore ├── README.md ├── app ├── .gitignore ├── build.gradle ├── debug │ ├── app-debug.apk │ ├── output.json │ └── test-app-debug.apk ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── weihuagu │ │ └── receiptnotice │ │ └── TestCashbarNotificationHandle.java │ ├── main │ ├── AndroidManifest.xml │ ├── java │ │ └── com │ │ │ └── weihuagu │ │ │ └── receiptnotice │ │ │ ├── AES.java │ │ │ ├── ActionStatusBarNotification.java │ │ │ ├── AlipayNotificationHandle.java │ │ │ ├── AsyncResponse.java │ │ │ ├── ByteUtil.java │ │ │ ├── CashbarNotificationHandle.java │ │ │ ├── Constants.java │ │ │ ├── DES.java │ │ │ ├── DESUtilWithIV.java │ │ │ ├── DeviceInfoUtil.java │ │ │ ├── EncryptFactory.java │ │ │ ├── Encrypter.java │ │ │ ├── FileLogActivity.java │ │ │ ├── FileLogUtil.java │ │ │ ├── IDataTrans.java │ │ │ ├── IDoPost.java │ │ │ ├── IcbcelifeNotificationHandle.java │ │ │ ├── IllustrateDecryptActivity.java │ │ │ ├── LogListAdapter.java │ │ │ ├── LogUtil.java │ │ │ ├── MainActivity.java │ │ │ ├── MainApplication.java │ │ │ ├── MipushNotificationHandle.java │ │ │ ├── NLService.java │ │ │ ├── NotificationCollectorMonitorService.java │ │ │ ├── NotificationHandle.java │ │ │ ├── NotificationHandleFactory.java │ │ │ ├── OneFileUtil.java │ │ │ ├── PostTask.java │ │ │ ├── PreferenceActivity.java │ │ │ ├── PreferenceUtil.java │ │ │ ├── RandomUtil.java │ │ │ ├── SSLSocketFactoryCompat.java │ │ │ ├── UnionpayNotificationHandle.java │ │ │ ├── UrlUtil.java │ │ │ ├── WechatNotificationHandle.java │ │ │ └── XposedmoduleNotificationHandle.java │ └── res │ │ ├── drawable-v24 │ │ └── ic_launcher_foreground.xml │ │ ├── drawable │ │ ├── ic_launcher.png │ │ ├── ic_launcher_background.xml │ │ └── log_icon.png │ │ ├── layout │ │ ├── activity_illustratedecrypt.xml │ │ ├── activity_log.xml │ │ ├── activity_main.xml │ │ └── item_log_text.xml │ │ ├── menu │ │ ├── log.xml │ │ └── main.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_launcher.xml │ │ └── ic_launcher_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_launcher.png │ │ └── ic_launcher_round.png │ │ ├── values-zh │ │ └── strings.xml │ │ ├── values │ │ ├── colors.xml │ │ ├── strings.xml │ │ └── styles.xml │ │ └── xml │ │ ├── pref_general.xml │ │ └── pref_headers.xml │ └── test │ └── java │ └── com │ └── weihuagu │ └── receiptnotice │ ├── TestDES.java │ └── TestOneFileUtil.java ├── build.gradle ├── gradle.properties ├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── payment-listener ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src │ ├── androidTest │ └── java │ │ └── com │ │ └── lhalcyon │ │ └── pl │ │ └── ExampleInstrumentedTest.java │ ├── main │ ├── AndroidManifest.xml │ ├── ic_notifier-web.png │ ├── java │ │ └── com │ │ │ └── lhalcyon │ │ │ └── pl │ │ │ ├── ActionStatusBarNotification.java │ │ │ ├── AsyncResponse.java │ │ │ ├── PLInitializer.java │ │ │ ├── handler │ │ │ ├── AlipayNotificationHandle.java │ │ │ ├── CashbarNotificationHandle.java │ │ │ ├── IcbcelifeNotificationHandle.java │ │ │ ├── MipushNotificationHandle.java │ │ │ ├── NotificationHandle.java │ │ │ ├── NotificationHandleFactory.java │ │ │ ├── OtherNotificationHandle.java │ │ │ ├── UnionpayNotificationHandle.java │ │ │ ├── WechatNotificationHandle.java │ │ │ └── XposedmoduleNotificationHandle.java │ │ │ ├── service │ │ │ ├── NLService.java │ │ │ ├── NotificationCollectorMonitorService.java │ │ │ └── NotificationForegroundMonitorService.java │ │ │ ├── support │ │ │ ├── ILog.java │ │ │ └── OnNotificationReceivedListener.java │ │ │ └── util │ │ │ ├── DeviceInfoUtil.java │ │ │ ├── LogUtil.java │ │ │ ├── NotificationUtil.java │ │ │ └── PreferenceUtil.java │ └── res │ │ ├── drawable │ │ └── ic_notifier_background.xml │ │ ├── mipmap-anydpi-v26 │ │ ├── ic_notifier.xml │ │ └── ic_notifier_round.xml │ │ ├── mipmap-hdpi │ │ ├── ic_notifier.png │ │ ├── ic_notifier_foreground.png │ │ └── ic_notifier_round.png │ │ ├── mipmap-mdpi │ │ ├── ic_notifier.png │ │ ├── ic_notifier_foreground.png │ │ └── ic_notifier_round.png │ │ ├── mipmap-xhdpi │ │ ├── ic_notifier.png │ │ ├── ic_notifier_foreground.png │ │ └── ic_notifier_round.png │ │ ├── mipmap-xxhdpi │ │ ├── ic_notifier.png │ │ ├── ic_notifier_foreground.png │ │ └── ic_notifier_round.png │ │ ├── mipmap-xxxhdpi │ │ ├── ic_notifier.png │ │ ├── ic_notifier_foreground.png │ │ └── ic_notifier_round.png │ │ └── values │ │ └── strings.xml │ └── test │ └── java │ └── com │ └── lhalcyon │ └── pl │ └── ExampleUnitTest.java ├── settings.gradle └── test-app ├── .gitignore ├── build.gradle ├── proguard-rules.pro └── src ├── androidTest └── java │ └── org │ └── loois │ └── test_app │ └── ExampleInstrumentedTest.java ├── main ├── AndroidManifest.xml ├── java │ └── org │ │ └── loois │ │ └── test_app │ │ └── MainActivity.java └── res │ ├── drawable-v24 │ └── ic_launcher_foreground.xml │ ├── drawable │ └── ic_launcher_background.xml │ ├── layout │ └── activity_main.xml │ ├── mipmap-anydpi-v26 │ ├── ic_launcher.xml │ └── ic_launcher_round.xml │ ├── mipmap-hdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-mdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ ├── mipmap-xxxhdpi │ ├── ic_launcher.png │ └── ic_launcher_round.png │ └── values │ ├── colors.xml │ ├── strings.xml │ └── styles.xml └── test └── java └── org └── loois └── test_app └── ExampleUnitTest.java /.gitattributes: -------------------------------------------------------------------------------- 1 | app/build.gradle merge=ours 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .*.swp 3 | .gradle 4 | /local.properties 5 | /.idea/workspace.xml 6 | /.idea/libraries 7 | .DS_Store 8 | /build 9 | /captures 10 | .externalNativeBuild 11 | /app/key.properties 12 | 13 | .idea 14 | .idea/ -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## payment-monitor 2 | 3 | __payment-monitor__ 是一款Android原生插件,对手机通知栏监听,针对支付类型通知进行回调. 4 | 5 | 目前支持 6 | 7 | - 支付宝 8 | - 收钱吧 9 | - 工商银行 10 | - 云闪付 11 | - 微信 / 微信店员 12 | 13 | ### 0.0.3 14 | 15 | 这里更新了文档为uni的引入方式,历史版本写的是weex引入方法可能有所误导. 16 | 17 | ```javascript 18 | 19 | 66 | 67 | ``` 68 | 69 | 前台服务演示: 70 | 71 | ![](https://i.loli.net/2019/07/31/5d4131497aa0c72064.png) 72 | 73 | 回调中的params字段实例: 74 | 75 | ![](https://i.loli.net/2019/07/24/5d38155eaccad17075.png) 76 | 77 | 78 | 79 | --- 80 | 81 | 82 | 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /app/.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | -------------------------------------------------------------------------------- /app/build.gradle: -------------------------------------------------------------------------------- 1 | apply plugin: 'com.android.application' 2 | android { 3 | compileSdkVersion 27 4 | defaultConfig { 5 | applicationId "com.weihuagu.receiptnotice" 6 | minSdkVersion 19 7 | targetSdkVersion 25 8 | versionCode 11 9 | versionName "1.0" 10 | testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" 11 | } 12 | 13 | 14 | signingConfigs { 15 | debug { 16 | 17 | } 18 | release { 19 | } 20 | } 21 | 22 | buildTypes { 23 | debug { 24 | 25 | } 26 | release { 27 | } 28 | } 29 | compileOptions { 30 | targetCompatibility 1.8 31 | sourceCompatibility 1.8 32 | } 33 | 34 | lintOptions { 35 | abortOnError false 36 | checkReleaseBuilds false 37 | 38 | 39 | } 40 | } 41 | dependencies { 42 | implementation fileTree(dir: 'libs', include: ['*.jar']) 43 | implementation 'com.android.support:appcompat-v7:27.0.2' 44 | implementation 'com.android.support:design:27.0.2' 45 | implementation 'com.android.support:cardview-v7:27.0.2' 46 | implementation 'com.android.support:recyclerview-v7:27.0.2' 47 | implementation 'com.android.support.constraint:constraint-layout:1.0.2' 48 | implementation 'com.squareup.okhttp3:okhttp:3.12.1' 49 | implementation 'com.github.wangjintao:TLog:v1.0.1' 50 | implementation 'com.github.pedrovgs:lynx:1.1.0' 51 | implementation 'io.socket:socket.io-client:1.0.0' 52 | implementation 'com.google.code.gson:gson:2.8.5' 53 | testImplementation 'junit:junit:4.12' 54 | } 55 | 56 | -------------------------------------------------------------------------------- /app/debug/app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lhalcyon/payment-listener/aa7149f425cbf64609348d8725909654aa8fdfc7/app/debug/app-debug.apk -------------------------------------------------------------------------------- /app/debug/output.json: -------------------------------------------------------------------------------- 1 | [{"outputType":{"type":"APK"},"apkInfo":{"type":"MAIN","splits":[],"versionCode":11,"versionName":"1.0","enabled":true,"outputFile":"app-debug.apk","fullName":"debug","baseName":"debug"},"path":"app-debug.apk","properties":{}}] -------------------------------------------------------------------------------- /app/debug/test-app-debug.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lhalcyon/payment-listener/aa7149f425cbf64609348d8725909654aa8fdfc7/app/debug/test-app-debug.apk -------------------------------------------------------------------------------- /app/proguard-rules.pro: -------------------------------------------------------------------------------- 1 | # Add project specific ProGuard rules here. 2 | # You can control the set of applied configuration files using the 3 | # proguardFiles setting in build.gradle. 4 | # 5 | # For more details, see 6 | # http://developer.android.com/guide/developing/tools/proguard.html 7 | 8 | # If your project uses WebView with JS, uncomment the following 9 | # and specify the fully qualified class name to the JavaScript interface 10 | # class: 11 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 12 | # public *; 13 | #} 14 | 15 | # Uncomment this to preserve the line number information for 16 | # debugging stack traces. 17 | #-keepattributes SourceFile,LineNumberTable 18 | 19 | # If you keep the line number information, uncomment this to 20 | # hide the original source file name. 21 | #-renamesourcefileattribute SourceFile 22 | -------------------------------------------------------------------------------- /app/src/androidTest/java/com/weihuagu/receiptnotice/TestCashbarNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | import android.os.Bundle; 4 | import android.support.test.InstrumentationRegistry; 5 | import android.support.test.runner.AndroidJUnit4; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import static org.junit.Assert.*; 9 | import static org.mockito.Mockito.*; 10 | import org.mockito.ArgumentMatchers; 11 | import java.util.Map; 12 | import java.util.HashMap; 13 | 14 | @RunWith(AndroidJUnit4.class) 15 | public class TestCashbarNotificationHandle{ 16 | CashbarNotificationHandle cashbar=null; 17 | protected void setUp() throws Exception { 18 | IDoPost dopost=new IDoPost(){ 19 | public void doPost(Map params){ 20 | if(params!=null) 21 | System.out.println(params.toString()); 22 | } 23 | }; 24 | Notification mocknoti=mock(Notification.class); 25 | Bundle mockextras=mock(Bundle.class); 26 | when(mockextras.getString(Notification.EXTRA_TITLE, "")).thenReturn("收钱吧"); 27 | when(mockextras.getString(Notification.EXTRA_TEXT, "")).thenReturn("成功收款0.12元,来自支付宝"); 28 | when(mocknoti.extras).thenReturn(mockextras); 29 | long whenval = 1346524199000l; 30 | when(mocknoti.when).thenReturn(whenval); 31 | cashbar=new CashbarNotificationHandle ("package name",mocknoti,dopost); 32 | 33 | } 34 | 35 | @Test 36 | public void testGetCashbarType() throws Exception{ 37 | setUp(); 38 | cashbar.handleNotification(); 39 | 40 | } 41 | 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 24 | 25 | 26 | 27 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/AES.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import java.util.Map; 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import javax.crypto.Cipher; 6 | public class AES extends Encrypter{ 7 | public AES(String key){ 8 | super(key); 9 | } 10 | public Map transferMapValue(Map params){ 11 | Map postmap=new HashMap(); 12 | Iterator entries = params.entrySet().iterator(); 13 | while (entries.hasNext()) { 14 | 15 | Map.Entry entry = (Map.Entry) entries.next(); 16 | 17 | String paramkey = (String)entry.getKey(); 18 | 19 | String paramvalue = (String)entry.getValue(); 20 | 21 | //String aesStr = AESUtil.aes(paramvalue, key, Cipher.ENCRYPT_MODE); 22 | String aesStr=null; 23 | postmap.put(paramkey,aesStr); 24 | 25 | } 26 | postmap.put("encrypt","1"); 27 | return postmap; 28 | 29 | 30 | 31 | 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/ActionStatusBarNotification.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.service.notification.StatusBarNotification; 3 | 4 | public interface ActionStatusBarNotification{ 5 | public void removeNotification(StatusBarNotification sbn); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/AlipayNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | 10 | public class AlipayNotificationHandle extends NotificationHandle{ 11 | public AlipayNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 12 | super(pkgtype,notification,postpush); 13 | } 14 | 15 | public void handleNotification(){ 16 | if(title.contains("支付宝")){ 17 | if(content.contains("成功收款") | content.contains("向你付款")){ 18 | Map postmap=new HashMap(); 19 | postmap.put("type","alipay"); 20 | postmap.put("time",notitime); 21 | postmap.put("title","支付宝支付"); 22 | postmap.put("money",extractMoney(content)); 23 | postmap.put("content",content); 24 | 25 | postpush.doPost(postmap); 26 | return ; 27 | } 28 | if(content.contains("向你转了1笔钱")){ 29 | Map postmap=new HashMap(); 30 | postmap.put("type","alipay-transfer"); 31 | postmap.put("time",notitime); 32 | postmap.put("title","转账"); 33 | postmap.put("money","-0.00"); 34 | postmap.put("content",content); 35 | postmap.put("transferor",whoTransferred(content)); 36 | 37 | postpush.doPost(postmap); 38 | return ; 39 | } 40 | } 41 | 42 | 43 | 44 | } 45 | 46 | private String whoTransferred(String content){ 47 | Pattern pattern = Pattern.compile("(.*)(已成功向你转了)"); 48 | Matcher matcher = pattern.matcher(content); 49 | if(matcher.find()){ 50 | String tmp=matcher.group(1); 51 | return tmp; 52 | 53 | } 54 | else 55 | return ""; 56 | 57 | } 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | } 70 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/AsyncResponse.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import java.util.List; 4 | import java.util.Map; 5 | 6 | public interface AsyncResponse { 7 | public void onDataReceivedSuccess(String[] returnstr); 8 | public void onDataReceivedFailed(String[] returnstr,Map postedmap); 9 | } 10 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/ByteUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | *下面两个自己字节的函数源自GcsSloop 3 | *GitHub: https://github.com/GcsSloop 4 | */ 5 | package com.weihuagu.receiptnotice; 6 | public class ByteUtil { 7 | /** 8 | * 二进位组转十六进制字符串 9 | * 10 | * @param buf 二进位组 11 | * @return 十六进制字符串 12 | */ 13 | public static String parseByte2HexStr(byte buf[]) { 14 | StringBuilder sb = new StringBuilder(); 15 | for (byte b : buf) { 16 | String hex = Integer.toHexString(b & 0xFF); 17 | if (hex.length() == 1) { 18 | hex = '0' + hex; 19 | } 20 | sb.append(hex.toUpperCase()); 21 | } 22 | return sb.toString(); 23 | } 24 | 25 | /** 26 | * 十六进制字符串转二进位组 27 | * 28 | * @param hexStr 十六进制字符串 29 | * @return 二进位组 30 | */ 31 | public static byte[] parseHexStr2Byte(String hexStr) { 32 | if (hexStr.length() < 1) return null; 33 | byte[] result = new byte[hexStr.length() / 2]; 34 | 35 | for (int i = 0; i < hexStr.length() / 2; i++) { 36 | int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16); 37 | int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16); 38 | result[i] = (byte) (high * 16 + low); 39 | } 40 | return result; 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/CashbarNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | 10 | public class CashbarNotificationHandle extends NotificationHandle{ 11 | public CashbarNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 12 | super(pkgtype,notification,postpush); 13 | } 14 | 15 | public void handleNotification(){ 16 | if(title.contains("收钱吧")){ 17 | if(content.contains("成功收款") | content.contains("向你付款")){ 18 | Map postmap=new HashMap(); 19 | postmap.put("type",getCashbarType(content)); 20 | postmap.put("time",notitime); 21 | postmap.put("title","支付宝支付"); 22 | postmap.put("money",extractMoney(content)); 23 | postmap.put("content",content); 24 | 25 | postpush.doPost(postmap); 26 | return ; 27 | } 28 | } 29 | 30 | 31 | 32 | } 33 | 34 | 35 | private String getCashbarType(String content){ 36 | Pattern pattern = Pattern.compile("(来自)(微信|支付宝|.*)"); 37 | Matcher matcher = pattern.matcher(content); 38 | if(matcher.find()){ 39 | String tmp=matcher.group(2); 40 | 41 | return "cashbar-"+transType(tmp); 42 | }else 43 | return ""; 44 | 45 | } 46 | 47 | private String transType(String chinesetype){ 48 | if(chinesetype.equals("微信")) 49 | return "wechat"; 50 | if(chinesetype.equals("支付宝")) 51 | return "alipay"; 52 | else return chinesetype; 53 | } 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | } 66 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/Constants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | 9 | public class Constants { 10 | /** 11 | * Actions. 12 | */ 13 | public static final String ACTION_BROWSER_CONTEXT_MENU = "ACTION_BROWSER_OPEN"; 14 | 15 | /** 16 | * Extras. 17 | */ 18 | public static final String EXTRA_ID = "EXTRA_ID"; 19 | public static final String EXTRA_ACTION_ID = "EXTRA_ACTION_ID"; 20 | public static final String EXTRA_NEW_TAB = "EXTRA_NEW_TAB"; 21 | public static final String EXTRA_LABEL = "EXTRA_LABEL"; 22 | public static final String EXTRA_URL = "EXTRA_URL"; 23 | public static final String EXTRA_FOLDER_ID = "EXTRA_FOLDER_ID"; 24 | public static final String EXTRA_HIT_TEST_RESULT = "EXTRA_HIT_TEST_RESULT"; 25 | public static final String EXTRA_INCOGNITO = "EXTRA_INCOGNITO"; 26 | 27 | /** 28 | * Specials urls. 29 | */ 30 | public static final String URL_ABOUT_BLANK = "about:blank"; 31 | public static final String URL_ABOUT_START = "about:start"; 32 | public static final String URL_ABOUT_TUTORIAL = "about:tutorial"; 33 | 34 | /** 35 | * User agents 36 | */ 37 | public static final String USER_AGENT_ANDROID = ""; 38 | public static final String USER_AGENT_DESKTOP = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/534.24 (KHTML, like Gecko) Chrome/11.0.696.34 Safari/534.24"; 39 | 40 | /** 41 | * Preferences. 42 | */ 43 | public static final String PREFERENCE_HOME_PAGE = "PREFERENCE_HOME_PAGE"; 44 | public static final String PREFERENCE_SEARCH_URL = "PREFERENCE_SEARCH_URL"; 45 | public static final String PREFERENCE_START_PAGE_LIMIT = "PREFERENCE_START_PAGE_LIMIT"; 46 | public static final String PREFERENCE_BUBBLE_POSITION = "PREFERENCE_BUBBLE_POSITION"; 47 | public static final String PREFERENCE_TOOLBARS_AUTOHIDE_DURATION = "PREFERENCE_TOOLBARS_AUTOHIDE_DURATION"; 48 | public static final String PREFERENCES_SWITCH_TABS_METHOD = "PREFERENCES_SWITCH_TABS_METHOD"; 49 | 50 | public static final String PREFERENCE_ENABLE_JAVASCRIPT = "PREFERENCE_ENABLE_JAVASCRIPT"; 51 | public static final String PREFERENCE_ENABLE_IMAGES = "PREFERENCE_ENABLE_IMAGES"; 52 | public static final String PREFERENCE_USE_WIDE_VIEWPORT = "PREFERENCE_USE_WIDE_VIEWPORT"; 53 | public static final String PREFERENCE_LOAD_WITH_OVERVIEW = "PREFERENCE_LOAD_WITH_OVERVIEW"; 54 | public static final String PREFERENCE_USER_AGENT = "PREFERENCE_USER_AGENT"; 55 | public static final String PREFERENCE_PLUGINS = "PREFERENCE_PLUGINS"; 56 | 57 | public static final String PREFERENCE_ACCEPT_COOKIES = "PREFERENCE_ACCEPT_COOKIES"; 58 | public static final String PREFERENCE_ENABLE_GEOLOCATION = "PREFERENCE_ENABLE_GEOLOCATION"; 59 | public static final String PREFERENCE_REMEMBER_FORM_DATA = "PREFERENCE_REMEMBER_FORM_DATA"; 60 | public static final String PREFERENCE_REMEMBER_PASSWORDS = "PREFERENCE_REMEMBER_PASSWORDS"; 61 | 62 | public static final String PREFERENCE_HISTORY_SIZE = "PREFERENCE_HISTORY_SIZE"; 63 | public static final String PREFERENCE_CLEAR_CACHE = "PREFERENCE_CLEAR_CACHE"; 64 | public static final String PREFERENCE_WEBSITES_SETTINGS = "PREFERENCE_WEBSITES_SETTINGS"; 65 | public static final String PREFERENCE_SSL_EXCEPTIONS = "PREFERENCE_SSL_EXCEPTIONS"; 66 | public static final String PREFERENCE_CLEAR_HISTORY = "PREFERENCE_CLEAR_HISTORY"; 67 | public static final String PREFERENCE_CLEAR_COOKIES = "PREFERENCE_CLEAR_COOKIES"; 68 | public static final String PREFERENCE_CLEAR_GEOLOCATION = "PREFERENCE_CLEAR_GEOLOCATION"; 69 | public static final String PREFERENCE_CLEAR_FORM_DATA = "PREFERENCE_CLEAR_FORM_DATA"; 70 | public static final String PREFERENCE_CLEAR_PASSWORDS = "PREFERENCE_CLEAR_PASSWORDS"; 71 | public static final String PREFERENCE_INCOGNITO_BY_DEFAULT = "PREFERENCE_INCOGNITO_BY_DEFAULT"; 72 | 73 | public static final String PREFERENCE_TEXT_SCALING = "PREFERENCE_TEXT_SCALING"; 74 | public static final String PREFERENCE_MINIMUM_FONT_SIZE = "PREFERENCE_MINIMUM_FONT_SIZE"; 75 | public static final String PREFERENCE_INVERTED_DISPLAY = "PREFERENCE_INVERTED_DISPLAY"; 76 | public static final String PREFERENCE_INVERTED_DISPLAY_CONTRAST = "PREFERENCE_INVERTED_DISPLAY_CONTRAST"; 77 | 78 | public static final String PREFERENCE_BOOKMARKS_SORT_MODE = "PREFERENCE_BOOKMARKS_SORT_MODE"; 79 | 80 | public static final String PREFERENCE_FULL_SCREEN = "PREFERENCE_FULL_SCREEN"; 81 | 82 | public static final String PREFERENCE_RESTORE_TABS = "PREFERENCE_RESTORE_TABS"; 83 | 84 | public static final String PREFERENCE_UI_TYPE = "PREFERENCE_UI_TYPE"; 85 | public static final String PREFERENCE_CLOSE_PANEL_ON_NEW_TAB = "PREFERENCE_CLOSE_PANEL_ON_NEW_TAB"; 86 | 87 | public static final String PREFERENCE_JS_LOG_ON_LOGCAT = "PREFERENCE_JS_LOG_ON_LOGCAT"; 88 | 89 | /** 90 | * Technical preferences. 91 | */ 92 | public static final String TECHNICAL_PREFERENCE_LAST_HISTORY_TRUNCATION = "TECHNICAL_PREFERENCE_LAST_HISTORY_TRUNCATION"; 93 | public static final String TECHNICAL_PREFERENCE_FIRST_RUN = "TECHNICAL_PREFERENCE_FIRST_RUN"; 94 | public static final String TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE = "TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE"; 95 | public static final String TECHNICAL_PREFERENCE_ADDON_ENABLED = "TECHNICAL_PREFERENCE_ADDON_ENABLED_"; 96 | public static final String TECHNICAL_PREFERENCE_SAVED_TABS = "TECHNICAL_PREFERENCE_SAVED_TABS"; 97 | public static final String TECHNICAL_PREFERENCE_HOMEPAGE_URL_UPDATE_NEEDED = "TECHNICAL_PREFERENCE_HOMEPAGE_URL_UPDATE_NEEDED"; 98 | } 99 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/DES.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import java.util.Map; 3 | import java.util.HashMap; 4 | import java.util.Iterator; 5 | import javax.crypto.Cipher; 6 | 7 | public class DES extends Encrypter{ 8 | public DES(String key){ 9 | super(key); 10 | } 11 | 12 | public Map transferMapValue(Map params){ 13 | Map postmap=new HashMap(); 14 | Iterator entries = params.entrySet().iterator(); 15 | while (entries.hasNext()) { 16 | Map.Entry entry = (Map.Entry) entries.next(); 17 | String paramkey = (String)entry.getKey(); 18 | String paramvalue = (String)entry.getValue(); 19 | String desStr = DESUtilWithIV.des(paramvalue, key, Cipher.ENCRYPT_MODE); 20 | postmap.put(paramkey,desStr); 21 | 22 | } 23 | postmap.put("encrypt","1"); 24 | LogUtil.debugLogWithJava("调试,开始加密字符串"); 25 | LogUtil.debugLogWithJava("加密后的map"); 26 | LogUtil.debugLogWithJava(postmap.toString()); 27 | return postmap; 28 | 29 | 30 | 31 | 32 | } 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/DESUtilWithIV.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.annotation.SuppressLint; 3 | import android.support.annotation.IntDef; 4 | 5 | import java.io.UnsupportedEncodingException; 6 | import java.security.InvalidKeyException; 7 | import java.security.NoSuchAlgorithmException; 8 | import java.security.SecureRandom; 9 | import java.security.spec.InvalidKeySpecException; 10 | import javax.crypto.Cipher; 11 | import javax.crypto.BadPaddingException; 12 | import javax.crypto.Cipher; 13 | import javax.crypto.IllegalBlockSizeException; 14 | import javax.crypto.NoSuchPaddingException; 15 | import java.security.InvalidAlgorithmParameterException; 16 | import javax.crypto.SecretKeyFactory; 17 | import javax.crypto.spec.DESKeySpec; 18 | import javax.crypto.spec.IvParameterSpec; 19 | public class DESUtilWithIV{ 20 | @IntDef({Cipher.ENCRYPT_MODE, Cipher.DECRYPT_MODE}) 21 | @interface DESType {} 22 | /** 23 | * Des加密/解密 24 | * 25 | * @param content 字符串内容 26 | * @param password 密钥 27 | * @param type 加密:{@link Cipher#ENCRYPT_MODE},解密:{@link Cipher#DECRYPT_MODE} 28 | * @return 加密/解密结果 29 | */ 30 | 31 | public static String des(String content, String password, int type) { 32 | try { 33 | 34 | IvParameterSpec iv = new IvParameterSpec(password.getBytes()); 35 | DESKeySpec desKey = new DESKeySpec(password.getBytes()); 36 | SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES"); 37 | @SuppressLint("GetInstance") Cipher cipher = Cipher.getInstance("DES/CBC/PKCS5Padding"); 38 | cipher.init(type, keyFactory.generateSecret(desKey), iv); 39 | 40 | if (type == Cipher.ENCRYPT_MODE) { 41 | byte[] byteContent = content.getBytes("utf-8"); 42 | return ByteUtil.parseByte2HexStr(cipher.doFinal(byteContent)); 43 | } else { 44 | byte[] byteContent = ByteUtil.parseHexStr2Byte(content); 45 | return new String(cipher.doFinal(byteContent)); 46 | } 47 | } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException | 48 | UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException | 49 | InvalidKeySpecException e) { 50 | e.printStackTrace(); 51 | } 52 | return null; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/DeviceInfoUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | */ 4 | 5 | package com.weihuagu.receiptnotice; 6 | import android.os.Build; 7 | import java.util.UUID; 8 | 9 | public class DeviceInfoUtil { 10 | /** 11 | * Return pseudo unique ID 12 | * @return ID 13 | */ 14 | public static String getUniquePsuedoID() { 15 | // If all else fails, if the user does have lower than API 9 (lower 16 | // than Gingerbread), has reset their device or 'Secure.ANDROID_ID' 17 | // returns 'null', then simply the ID returned will be solely based 18 | // off their Android device information. This is where the collisions 19 | // can happen. 20 | // Thanks http://www.pocketmagic.net/?p=1662! 21 | // Try not to use DISPLAY, HOST or ID - these items could change. 22 | // If there are collisions, there will be overlapping data 23 | String m_szDevIDShort = "35" + (Build.BOARD.length() % 10) + (Build.BRAND.length() % 10) + (Build.CPU_ABI.length() % 10) + (Build.DEVICE.length() % 10) + (Build.MANUFACTURER.length() % 10) + (Build.MODEL.length() % 10) + (Build.PRODUCT.length() % 10); 24 | 25 | // Thanks to @Roman SL! 26 | // http://stackoverflow.com/a/4789483/950427 27 | // Only devices with API >= 9 have android.os.Build.SERIAL 28 | // http://developer.android.com/reference/android/os/Build.html#SERIAL 29 | // If a user upgrades software or roots their device, there will be a duplicate entry 30 | String serial = null; 31 | try { 32 | serial = android.os.Build.class.getField("SERIAL").get(null).toString(); 33 | 34 | // Go ahead and return the serial for api => 9 35 | return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); 36 | } catch (Exception exception) { 37 | // String needs to be initialized 38 | serial = "serial"; // some value 39 | } 40 | 41 | // Thanks @Joe! 42 | // http://stackoverflow.com/a/2853253/950427 43 | // Finally, combine the values we have found by using the UUID class to create a unique identifier 44 | return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString(); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/EncryptFactory.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | public class EncryptFactory{ 3 | private String key; 4 | public EncryptFactory(String key){ 5 | this.key=key; 6 | } 7 | public Encrypter getEncrypter(String encrypt_type){ 8 | if(encrypt_type.equals("des")) 9 | return new DES(key); 10 | if(encrypt_type.equals("aes")) 11 | return new AES(key); 12 | LogUtil.debugLog("没有匹配到合适的Encrypter"); 13 | return null; 14 | 15 | 16 | 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/Encrypter.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import java.util.Map; 3 | public abstract class Encrypter implements IDataTrans{ 4 | protected String key; 5 | public Encrypter(String key){ 6 | this.key=key; 7 | } 8 | public abstract Map transferMapValue(Map params); 9 | 10 | 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/FileLogActivity.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import android.os.Bundle; 6 | import android.support.annotation.Nullable; 7 | import android.support.v7.app.AppCompatActivity; 8 | import android.widget.TextView; 9 | import android.support.v7.widget.Toolbar; 10 | import android.support.v7.widget.RecyclerView; 11 | import android.support.v7.widget.LinearLayoutManager; 12 | import android.view.MenuItem; 13 | import android.view.Menu; 14 | import android.view.MenuInflater; 15 | import android.widget.Toast; 16 | import com.tao.admin.loglib.FileUtils; 17 | 18 | public class FileLogActivity extends AppCompatActivity { 19 | private RecyclerView recyclerView; 20 | private LogListAdapter mAdapter; 21 | private RecyclerView.LayoutManager layoutManager; 22 | 23 | private TextView mTextView; 24 | private Toolbar myToolbar; 25 | private boolean loglist_is_a_wholetext=true; 26 | 27 | @Override 28 | protected void onCreate(@Nullable Bundle savedInstanceState) { 29 | super.onCreate(savedInstanceState); 30 | setContentView(R.layout.activity_log); 31 | initView(); 32 | setLogText(); 33 | } 34 | 35 | private void initView(){ 36 | myToolbar= (Toolbar) findViewById(R.id.my_toolbar); 37 | setSupportActionBar(myToolbar); 38 | mTextView = (TextView) findViewById(R.id.tv_log); 39 | 40 | } 41 | 42 | private void initLoglistView(boolean reverseorder){ 43 | recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view); 44 | //recyclerView.setHasFixedSize(true); 45 | // use a linear layout manager 46 | layoutManager = new LinearLayoutManager(this); 47 | recyclerView.setLayoutManager(layoutManager); 48 | // specify an adapter (see also next example) 49 | mAdapter = new LogListAdapter(getApplicationContext()); 50 | ArrayList loglist=FileLogUtil.getLogList(); 51 | //LogUtil.debugLogWithDeveloper("打印通过filelogutil获取到的file log list"); 52 | if(loglist!=null&&loglist.size()>0){ 53 | loglist_is_a_wholetext=false; 54 | if(reverseorder) 55 | Collections.reverse(loglist); 56 | } 57 | else{ 58 | loglist_is_a_wholetext=true; 59 | return; 60 | } 61 | mAdapter.setLoglist(loglist); 62 | recyclerView.setAdapter(mAdapter); 63 | } 64 | 65 | 66 | private void setLogText(){ 67 | initLoglistView(false); 68 | if(loglist_is_a_wholetext){ 69 | String log = FileLogUtil.readLogText(); 70 | mTextView.setText(log); 71 | } 72 | 73 | } 74 | 75 | private void clearLog(){ 76 | FileLogUtil.clearLogFile(); 77 | setLogText(); 78 | Toast.makeText(getApplicationContext(), "已经清空日志",Toast.LENGTH_SHORT).show(); 79 | } 80 | private void showReverse(){ 81 | initLoglistView(true); 82 | } 83 | @Override 84 | public boolean onCreateOptionsMenu(Menu menu) { 85 | // TODO Auto-generated method stub 86 | MenuInflater inflater = getMenuInflater(); 87 | inflater.inflate(R.menu.log, menu); 88 | return true; 89 | } 90 | 91 | @Override 92 | public boolean onOptionsItemSelected(MenuItem item) { 93 | switch (item.getItemId()) { 94 | case R.id.action_clearlog: 95 | // User chose the "Settings" item, show the app settings UI... 96 | clearLog(); 97 | return true; 98 | case R.id.action_reverseshow: 99 | showReverse(); 100 | return true; 101 | default: 102 | // If we got here, the user's action was not recognized. 103 | // Invoke the superclass to handle it. 104 | return super.onOptionsItemSelected(item); 105 | 106 | } 107 | } 108 | 109 | @Override 110 | protected void onResume() { 111 | super.onResume(); 112 | setLogText(); 113 | } 114 | 115 | 116 | 117 | } 118 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/FileLogUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | import com.tao.admin.loglib.FileUtils; 9 | import com.tao.admin.loglib.TLogApplication; 10 | import com.tao.admin.loglib.IConfig; 11 | import java.io.File; 12 | import java.io.FileReader; 13 | import java.util.ArrayList; 14 | import java.io.BufferedReader; 15 | import java.io.IOException; 16 | 17 | public class FileLogUtil extends FileUtils{ 18 | public static boolean clearLogFile() { 19 | try { 20 | File file = new File(TLogApplication.getAPP().getFilesDir(), IConfig.fileName); 21 | if(file.delete()) 22 | return true; 23 | else 24 | return false; 25 | 26 | } catch(Exception e) { 27 | e.printStackTrace(); 28 | return false; 29 | } 30 | 31 | 32 | 33 | 34 | } 35 | public static ArrayList getLogList(){ 36 | File file = new File(TLogApplication.getAPP().getFilesDir(), IConfig.fileName); 37 | if (!file.exists()) 38 | return null; 39 | 40 | OneFileUtil fileutil = new OneFileUtil(file); 41 | ArrayList filelist=fileutil.getFileList(); 42 | String startflag="*********************************"; 43 | String endflag="------------------------------------------"; 44 | ArrayList filemergelist=fileutil.mergeByFlagline(startflag,endflag,filelist); 45 | return filemergelist; 46 | 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/IDataTrans.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import java.util.Map; 3 | public interface IDataTrans{ 4 | public Map transferMapValue(Map params); 5 | 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/IDoPost.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import java.util.Map; 3 | 4 | public interface IDoPost{ 5 | public void doPost(Map params); 6 | } 7 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/IcbcelifeNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | 10 | 11 | public class IcbcelifeNotificationHandle extends NotificationHandle{ 12 | public IcbcelifeNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 13 | super(pkgtype,notification,postpush); 14 | } 15 | 16 | public void handleNotification(){ 17 | if(title.contains("工银商户")){ 18 | if(content.contains("已收到")&&content.contains("元")){ 19 | Map postmap=new HashMap(); 20 | postmap.put("type","icbcelife"); 21 | postmap.put("time",notitime); 22 | postmap.put("title","工银商户之家"); 23 | postmap.put("money",extractMoney(content)); 24 | postmap.put("content",content); 25 | 26 | postpush.doPost(postmap); 27 | return ; 28 | } 29 | } 30 | 31 | 32 | 33 | } 34 | 35 | 36 | @Override 37 | protected String extractMoney(String content){ 38 | Pattern pattern = Pattern.compile("(收到|收款|向你付款)(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?元"); 39 | Matcher matcher = pattern.matcher(content); 40 | if(matcher.find()){ 41 | String tmp=matcher.group(); 42 | Pattern patternnum = Pattern.compile("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?"); 43 | Matcher matchernum = patternnum.matcher(tmp); 44 | if(matchernum.find()) 45 | return matchernum.group(); 46 | return null; 47 | }else 48 | return null; 49 | 50 | 51 | } 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | } 67 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/IllustrateDecryptActivity.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import android.os.Bundle; 4 | import android.support.annotation.Nullable; 5 | import android.support.v7.app.AppCompatActivity; 6 | import android.widget.TextView; 7 | 8 | public class IllustrateDecryptActivity extends AppCompatActivity { 9 | private TextView text_method; 10 | private TextView text_passwd; 11 | private TextView text_iv; 12 | private PreferenceUtil preference; 13 | private void initView() { 14 | text_method = (TextView) findViewById(R.id.info_text_method); 15 | text_passwd = (TextView) findViewById(R.id.info_text_passwd); 16 | text_iv = (TextView) findViewById(R.id.info_text_iv); 17 | preference=new PreferenceUtil(getBaseContext()); 18 | 19 | } 20 | @Override 21 | protected void onCreate(@Nullable Bundle savedInstanceState) { 22 | super.onCreate(savedInstanceState); 23 | setContentView(R.layout.activity_illustratedecrypt); 24 | initView(); 25 | setText(); 26 | } 27 | 28 | private void setText(){ 29 | String encrypt_type=preference.getEncryptMethod(); 30 | if(encrypt_type==null){ 31 | text_method.setText("您没有设置加密方法"); 32 | return; 33 | } 34 | if(encrypt_type.equals("des")){ 35 | String method="DES/CBC/PKCS5Padding"; 36 | text_method.setText("解密的方法为:"+method); 37 | String key=preference.getPasswd(); 38 | if(key!=null){ 39 | text_passwd.setText("解密秘钥为:"+key+"(des秘钥必须为8位,如果你设置的不是8位,请修改)"); 40 | text_iv.setText("解密的初始化向量为:"+key); 41 | } 42 | } 43 | 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/LogListAdapter.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.view.View; 3 | import android.view.ViewGroup; 4 | import android.support.v7.widget.RecyclerView; 5 | import android.support.v7.widget.RecyclerView.Adapter; 6 | import android.view.LayoutInflater; 7 | import android.widget.TextView; 8 | import android.content.Context; 9 | import java.util.ArrayList; 10 | public class LogListAdapter extends Adapter{ 11 | private final LayoutInflater mLayoutInflater; 12 | private ArrayList loglist; 13 | 14 | LogListAdapter(Context context){ 15 | mLayoutInflater = LayoutInflater.from(context); 16 | } 17 | public void setLoglist(ArrayList loglist){ 18 | this.loglist=loglist; 19 | } 20 | @Override 21 | public int getItemCount() { 22 | return loglist == null ? 0 : loglist.size(); 23 | } 24 | 25 | 26 | @Override 27 | public void onBindViewHolder(RecyclerHolder holder, int position) { 28 | String onerecord=(String)loglist.get(position); 29 | if(holder.recordtext==null) 30 | return; 31 | if(onerecord!=null) 32 | holder.recordtext.setText(onerecord); 33 | else 34 | LogUtil.debugLogWithDeveloper("获取到的loglist 的item text为空"); 35 | 36 | } 37 | 38 | @Override 39 | public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) { 40 | return new RecyclerHolder(mLayoutInflater.inflate(R.layout.item_log_text, parent, false)); 41 | 42 | } 43 | 44 | 45 | 46 | 47 | 48 | class RecyclerHolder extends RecyclerView.ViewHolder { 49 | private TextView recordtext; 50 | RecyclerHolder(View view){ 51 | super(view); 52 | recordtext=view.findViewById(R.id.text_view); 53 | } 54 | 55 | } 56 | 57 | } 58 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/LogUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | import android.util.Log; 9 | import com.tao.admin.loglib.Logger; 10 | 11 | public class LogUtil { 12 | public static String TAG="NLService"; 13 | public static String DEBUGTAG="NLDebugService"; 14 | public static String EXCEPTIONTAG="NLExceptionService"; 15 | public static void infoLog(String info){ 16 | Log.i(TAG,info); 17 | } 18 | 19 | public static void debugLog(String info){ 20 | Log.d(TAG,info); 21 | } 22 | 23 | public static void debugLogWithDeveloper(String info){ 24 | Log.d(DEBUGTAG,info); 25 | } 26 | 27 | public static void debugLogWithJava(String info){ 28 | System.out.println(DEBUGTAG+":"+info); 29 | } 30 | 31 | public static void postRecordLog(String tasknum,String post){ 32 | Logger.i("*********************************"); 33 | Logger.i("开始推送", "随机序列号:"+tasknum); 34 | Logger.i(post); 35 | } 36 | 37 | public static void postResultLog(String tasknum,String result,String returnstr){ 38 | 39 | Logger.i("推送结果","随机序列号:"+tasknum); 40 | Logger.i("推送结果",result); 41 | Logger.i("返回内容",returnstr); 42 | Logger.i("------------------------------------------"); 43 | 44 | 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import android.support.v7.app.AppCompatActivity; 4 | import android.app.Notification; 5 | import android.app.NotificationManager; 6 | import android.content.BroadcastReceiver; 7 | import android.content.Context; 8 | import android.view.MenuItem; 9 | import android.view.Menu; 10 | import android.content.SharedPreferences; 11 | import android.widget.Toast; 12 | import android.content.Intent; 13 | import android.content.IntentFilter; 14 | import android.os.Bundle; 15 | import android.support.v4.app.NotificationManagerCompat; 16 | import android.support.v4.content.LocalBroadcastManager; 17 | import android.view.View; 18 | import android.widget.Button; 19 | import android.widget.TextView; 20 | import android.widget.EditText; 21 | import android.support.design.widget.FloatingActionButton; 22 | import android.support.v7.widget.Toolbar; 23 | import android.view.MenuInflater; 24 | 25 | import com.tao.admin.loglib.Logger; 26 | import com.github.pedrovgs.lynx.LynxConfig; 27 | import com.github.pedrovgs.lynx.LynxActivity; 28 | 29 | public class MainActivity extends AppCompatActivity implements View.OnClickListener{ 30 | 31 | private static final String TAG = "MainActivity"; 32 | private Toolbar myToolbar; 33 | private Button btnsetposturl; 34 | private FloatingActionButton btnshowlog; 35 | private EditText posturl; 36 | private SharedPreferences sp ; 37 | 38 | 39 | @Override 40 | protected void onCreate(Bundle savedInstanceState) { 41 | super.onCreate(savedInstanceState); 42 | setContentView(R.layout.activity_main); 43 | initView(); 44 | } 45 | 46 | private void initView() { 47 | 48 | sp = getSharedPreferences("url", Context.MODE_PRIVATE); 49 | myToolbar= (Toolbar) findViewById(R.id.my_toolbar); 50 | setSupportActionBar(myToolbar); 51 | btnsetposturl=(Button) findViewById(R.id.btnsetposturl); 52 | btnsetposturl.setOnClickListener(this); 53 | btnshowlog=(FloatingActionButton) findViewById(R.id.floatingshowlog); 54 | btnshowlog.setOnClickListener(this); 55 | posturl = (EditText) findViewById(R.id.posturl); 56 | if(getPostUrl()!=null) 57 | posturl.setHint(getPostUrl()); 58 | 59 | 60 | 61 | } 62 | 63 | @Override 64 | protected void onResume() { 65 | super.onResume(); 66 | boolean isAuthor=isNotificationServiceEnable(); 67 | if (!isAuthor){ 68 | //直接跳转通知授权界面 69 | //android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS是API 22才加入到Settings里,这里直接写死 70 | startActivity(new Intent("android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS")); 71 | } 72 | } 73 | 74 | @Override 75 | protected void onDestroy() { 76 | super.onDestroy(); 77 | } 78 | 79 | /** 80 | * 是否已授权 81 | * 82 | * @return 83 | */ 84 | private boolean isNotificationServiceEnable() { 85 | return NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName()); 86 | } 87 | 88 | @Override 89 | public void onClick(View v) { 90 | switch (v.getId()) { 91 | case R.id.btnsetposturl: 92 | posturl.setHint(null); 93 | setPostUrl(); 94 | break; 95 | case R.id.floatingshowlog: 96 | showLog(); 97 | break; 98 | } 99 | } 100 | 101 | private void setPostUrl() { 102 | SharedPreferences.Editor edit = sp.edit(); 103 | //通过editor对象写入数据 104 | edit.putString("posturl",posturl.getText().toString()); 105 | //提交数据存入到xml文件中 106 | edit.apply(); 107 | Toast.makeText(getApplicationContext(), "已经设置posturl为:"+posturl.getText().toString(), 108 | Toast.LENGTH_SHORT).show(); 109 | } 110 | 111 | private String getPostUrl(){ 112 | String posturlpath; 113 | posturlpath =sp.getString("posturl", ""); 114 | if (posturlpath==null) 115 | return null; 116 | else 117 | return posturlpath; 118 | } 119 | 120 | 121 | private void showLog() { 122 | //startActivity(new Intent(this, LogActivity.class)); 123 | openLynxActivity(); 124 | } 125 | private void openLynxActivity() { 126 | LynxConfig lynxConfig = new LynxConfig(); 127 | lynxConfig.setMaxNumberOfTracesToShow(4000) 128 | .setFilter("NLService"); 129 | 130 | Intent lynxActivityIntent = LynxActivity.getIntent(this, lynxConfig); 131 | startActivity(lynxActivityIntent); 132 | } 133 | private void openSettingActivity(){ 134 | Intent intent = new Intent(MainActivity.this, PreferenceActivity.class); 135 | startActivity(intent); 136 | } 137 | 138 | @Override 139 | public boolean onCreateOptionsMenu(Menu menu) { 140 | // TODO Auto-generated method stub 141 | MenuInflater inflater = getMenuInflater(); 142 | inflater.inflate(R.menu.main, menu); 143 | return true; 144 | } 145 | 146 | @Override 147 | public boolean onOptionsItemSelected(MenuItem item) { 148 | switch (item.getItemId()) { 149 | case R.id.action_settings: 150 | // User chose the "Settings" item, show the app settings UI... 151 | openSettingActivity(); 152 | return true; 153 | default: 154 | // If we got here, the user's action was not recognized. 155 | // Invoke the superclass to handle it. 156 | return super.onOptionsItemSelected(item); 157 | 158 | } 159 | } 160 | 161 | 162 | 163 | 164 | 165 | } 166 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/MainApplication.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Application; 3 | import android.content.Intent; 4 | 5 | import com.tao.admin.loglib.TLogApplication; 6 | import com.tao.admin.loglib.IConfig; 7 | public class MainApplication extends Application { 8 | 9 | @Override 10 | public void onCreate() { 11 | super.onCreate(); 12 | startNotificationService(); 13 | initLogConfig(); 14 | } 15 | 16 | private void initLogConfig(){ 17 | TLogApplication.initialize(this); 18 | IConfig.getInstance().isShowLog(false)//是否在logcat中打印log,默认不打印 19 | .isWriteLog(true)//是否在文件中记录,默认不记录 20 | .tag("GoFileService");//logcat 日志过滤tag 21 | } 22 | private void startNotificationService(){ 23 | startService(new Intent(this, NotificationCollectorMonitorService.class)); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/MipushNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | 9 | 10 | 11 | public class MipushNotificationHandle extends NotificationHandle{ 12 | public MipushNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 13 | super(pkgtype,notification,postpush); 14 | } 15 | 16 | public void handleNotification(){ 17 | if(title.contains("支付宝")){ 18 | if(content.contains("成功收款")){ 19 | Map postmap=new HashMap(); 20 | postmap.put("type","alipay"); 21 | postmap.put("time",notitime); 22 | postmap.put("title","支付宝支付"); 23 | postmap.put("money",extractMoney(content)); 24 | postmap.put("content",content); 25 | postpush.doPost(postmap); 26 | return ; 27 | } 28 | if(content.contains("向你转了1笔钱")){ 29 | Map postmap=new HashMap(); 30 | postmap.put("type","alipay-transfer"); 31 | postmap.put("time",notitime); 32 | postmap.put("title","转账"); 33 | postmap.put("money","-0.00"); 34 | postmap.put("content",content); 35 | postmap.put("transferor",whoTransferred(content)); 36 | 37 | postpush.doPost(postmap); 38 | return ; 39 | } 40 | } 41 | if(title.contains("动账通知")){ 42 | if(content.contains("入账")&&content.contains("尾号为")){ 43 | Map postmap=new HashMap(); 44 | postmap.put("type","unionpay"); 45 | postmap.put("time",notitime); 46 | postmap.put("title","云闪付扫码收款"); 47 | postmap.put("money",extractMoney(content)); 48 | postmap.put("content",content); 49 | //postmap.put("payer",getPayer(content)); 50 | postpush.doPost(postmap); 51 | return ; 52 | } 53 | } 54 | 55 | 56 | 57 | 58 | } 59 | 60 | 61 | 62 | private String getPayer(String content){ 63 | Pattern pattern = Pattern.compile("(.*)(通过扫码向您付款)"); 64 | Matcher matcher = pattern.matcher(content); 65 | if(matcher.find()){ 66 | String tmp=matcher.group(2); 67 | return tmp; 68 | }else 69 | return ""; 70 | 71 | } 72 | 73 | private String whoTransferred(String content){ 74 | Pattern pattern = Pattern.compile("(.*)(已成功向你转了)"); 75 | Matcher matcher = pattern.matcher(content); 76 | if(matcher.find()){ 77 | String tmp=matcher.group(1); 78 | return tmp; 79 | 80 | } 81 | else 82 | return ""; 83 | 84 | } 85 | 86 | 87 | } 88 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/NotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import android.os.Bundle; 4 | import android.app.Notification; 5 | import android.service.notification.StatusBarNotification; 6 | import java.util.regex.Matcher; 7 | import java.util.regex.Pattern; 8 | import java.text.SimpleDateFormat; 9 | import java.util.Date; 10 | 11 | 12 | public abstract class NotificationHandle{ 13 | protected String pkgtype; 14 | protected Notification notification; 15 | protected Bundle extras; 16 | protected String title; 17 | protected String content; 18 | protected String notitime; 19 | protected IDoPost postpush; 20 | protected ActionStatusBarNotification actionstatusbar; 21 | public StatusBarNotification sbn; 22 | public NotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 23 | this.pkgtype=pkgtype; 24 | this.notification=notification; 25 | this.postpush=postpush; 26 | 27 | this.extras=notification.extras; 28 | // 获取通知标题 29 | title = extras.getString(Notification.EXTRA_TITLE, ""); 30 | // 获取通知内容 31 | content = extras.getString(Notification.EXTRA_TEXT, ""); 32 | long when=notification.when; 33 | Date date=new Date(when); 34 | SimpleDateFormat format=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 35 | notitime=format.format(date); 36 | 37 | 38 | } 39 | 40 | public void setStatusBarNotification(StatusBarNotification sbn){ 41 | this.sbn=sbn; 42 | } 43 | public void setActionStatusbar(ActionStatusBarNotification actionstatusbar){ 44 | this.actionstatusbar=actionstatusbar; 45 | } 46 | public abstract void handleNotification(); 47 | protected String extractMoney(String content){ 48 | Pattern pattern = Pattern.compile("(收款|向你付款|向您付款|入账)(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?元"); 49 | Matcher matcher = pattern.matcher(content); 50 | if(matcher.find()){ 51 | String tmp=matcher.group(); 52 | Pattern patternnum = Pattern.compile("(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?"); 53 | Matcher matchernum = patternnum.matcher(tmp); 54 | if(matchernum.find()) 55 | return matchernum.group(); 56 | return null; 57 | }else 58 | return null; 59 | 60 | 61 | } 62 | protected boolean predictIsPost(String content){ 63 | Pattern pattern = Pattern.compile("(收到|收款|向你付款|向您付款|入账)(([1-9]{1}\\d*)|([0]{1}))(\\.(\\d){0,2})?元"); 64 | Matcher matcher = pattern.matcher(content); 65 | if(matcher.find()) 66 | return true; 67 | else 68 | return false; 69 | 70 | } 71 | 72 | protected void removeNotification(){ 73 | if(actionstatusbar==null|sbn==null) 74 | return ; 75 | if(predictIsPost(content)) 76 | actionstatusbar.removeNotification(sbn); 77 | } 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | } 95 | 96 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/NotificationHandleFactory.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | public class NotificationHandleFactory{ 4 | public NotificationHandle getNotificationHandle(String pkg,Notification notification,IDoPost postpush){ 5 | //mipush 6 | if("com.xiaomi.xmsf".equals(pkg)){ 7 | return new MipushNotificationHandle("com.xiaomi.xmsf",notification,postpush); 8 | } 9 | //支付宝 10 | if("com.eg.android.AlipayGphone".equals(pkg)){ 11 | return new AlipayNotificationHandle("com.eg.android.AlipayGphone",notification,postpush); 12 | } 13 | 14 | //应用管理GCM代收 15 | if("android".equals(pkg)){ 16 | return new XposedmoduleNotificationHandle("github.tornaco.xposedmoduletest",notification,postpush); 17 | } 18 | //微信 19 | if("com.tencent.mm".equals(pkg)){ 20 | return new WechatNotificationHandle("com.tencent.mm",notification,postpush); 21 | } 22 | //收钱吧 23 | if("com.wosai.cashbar".equals(pkg)){ 24 | return new CashbarNotificationHandle("com.wosai.cashbar",notification,postpush); 25 | } 26 | //云闪付 27 | if("com.unionpay".equals(pkg)){ 28 | return new UnionpayNotificationHandle("com.unionpay",notification,postpush); 29 | } 30 | //工银商户之家 31 | if("com.icbc.biz.elife".equals(pkg)){ 32 | return new IcbcelifeNotificationHandle("com.icbc.biz.elife",notification,postpush); 33 | } 34 | 35 | 36 | return null; 37 | 38 | } 39 | 40 | } 41 | 42 | 43 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/OneFileUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | import java.io.File; 9 | import java.io.FileReader; 10 | import java.io.BufferedReader; 11 | import java.io.IOException; 12 | import java.util.Iterator; 13 | import java.util.ArrayList; 14 | import java.util.LinkedList; 15 | import java.util.Deque; 16 | 17 | public class OneFileUtil{ 18 | private File file; 19 | public OneFileUtil(File file){ 20 | this.file=file; 21 | } 22 | private String clearOnegroup(Deque onegroup){ 23 | String tmp=""; 24 | while(onegroup.size()>0){ 25 | String first=onegroup.pollFirst(); 26 | tmp=tmp+"\n"+first; 27 | } 28 | return tmp; 29 | 30 | } 31 | public ArrayList mergeByFlagline(String startflagline,String endflagline,ArrayList filelist){ 32 | if(filelist.size()==0) 33 | return null; 34 | ArrayList merge=new ArrayList(); 35 | Iterator fileiterator = filelist.iterator(); 36 | Deque onegroup = new LinkedList(); 37 | while (fileiterator.hasNext()) { 38 | String o = (String)fileiterator.next(); 39 | onegroup.offerLast(o); 40 | if(onegroup.peekFirst().contains(startflagline)&&onegroup.peekLast().contains(endflagline)){ 41 | merge.add(clearOnegroup(onegroup)); 42 | 43 | } 44 | 45 | } 46 | return merge; 47 | 48 | 49 | 50 | 51 | } 52 | public ArrayList getFileList(){ 53 | ArrayList arrayList = new ArrayList(); 54 | FileReader fr = null; 55 | try{ 56 | if (!file.exists()) 57 | return null; 58 | 59 | fr = new FileReader(file); 60 | BufferedReader bf = new BufferedReader(fr); 61 | String str; 62 | while ((str = bf.readLine()) != null) { 63 | //按行处理 64 | arrayList.add(str); 65 | } 66 | if(arrayList.size()==0) 67 | return null; 68 | else 69 | return arrayList; 70 | 71 | 72 | } catch (Throwable ex) { 73 | ex.printStackTrace(); 74 | } finally { 75 | try { 76 | if (fr != null) 77 | fr.close(); 78 | } catch (IOException e) { 79 | e.printStackTrace(); 80 | } 81 | } 82 | return null; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/PostTask.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | 3 | import java.util.List; 4 | import java.io.PrintWriter; 5 | import java.io.StringWriter; 6 | 7 | import android.os.AsyncTask; 8 | import java.util.Map; 9 | import java.util.HashMap; 10 | import java.util.List; 11 | import java.util.ArrayList; 12 | import java.io.IOException; 13 | import java.security.KeyManagementException; 14 | import java.security.NoSuchAlgorithmException; 15 | import javax.net.ssl.SSLSocketFactory; 16 | import java.util.concurrent.TimeUnit; 17 | import okhttp3.MediaType; 18 | import okhttp3.OkHttpClient; 19 | import okhttp3.Request; 20 | import okhttp3.RequestBody; 21 | import okhttp3.Response; 22 | import okhttp3.TlsVersion; 23 | import okhttp3.ConnectionSpec; 24 | import java.util.Iterator; 25 | import android.util.Log; 26 | import android.os.Build; 27 | 28 | public class PostTask extends AsyncTask, Void, String[]> { 29 | 30 | public AsyncResponse asyncResponse; 31 | public static final MediaType JSON = MediaType.get("application/json; charset=utf-8"); 32 | public String TAG="NLService"; 33 | public String randomtasknum; 34 | public Map recordpostmap; 35 | public void setRandomTaskNum(String num){ 36 | this.randomtasknum=num; 37 | } 38 | OkHttpClient client = new OkHttpClient(); 39 | String httppost(String url, String json) throws IOException { 40 | RequestBody body = RequestBody.create(JSON, json); 41 | OkHttpClient client = new OkHttpClient.Builder() 42 | .connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间 43 | .readTimeout(20, TimeUnit.SECONDS)//设置读取超时时间 44 | .build(); 45 | Request.Builder request = new Request.Builder() 46 | .url(url) 47 | .post(body); 48 | try (Response response = client.newCall(request.build()).execute()) { 49 | return response.body().string(); 50 | } 51 | } 52 | 53 | String httpspost(String url, String json) throws IOException{ 54 | if (Build.VERSION.SDK_INT >= 22 ) 55 | return httppost(url, json); 56 | try { 57 | RequestBody body = RequestBody.create(JSON, json); 58 | SSLSocketFactory factory = new SSLSocketFactoryCompat(); 59 | ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) 60 | .tlsVersions(TlsVersion.TLS_1_2) 61 | .build(); 62 | 63 | List specs = new ArrayList<>(); 64 | specs.add(cs); 65 | specs.add(ConnectionSpec.COMPATIBLE_TLS); 66 | specs.add(ConnectionSpec.CLEARTEXT); 67 | 68 | 69 | OkHttpClient client = new OkHttpClient.Builder() 70 | .connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间 71 | .readTimeout(20, TimeUnit.SECONDS)//设置读取超时时间 72 | .sslSocketFactory(factory) 73 | .connectionSpecs(specs) 74 | .build(); 75 | 76 | Request.Builder request = new Request.Builder() 77 | .url(url) 78 | .post(body); 79 | Response response = client.newCall(request.build()).execute(); 80 | return response.body().string(); 81 | } 82 | catch( IOException e){ 83 | StringWriter sw = new StringWriter(); 84 | PrintWriter pw = new PrintWriter(sw); 85 | e.printStackTrace(pw); 86 | LogUtil.debugLog(sw.toString()); 87 | return null; 88 | } 89 | catch (KeyManagementException e) { 90 | e.printStackTrace(); 91 | return null; 92 | } catch (NoSuchAlgorithmException e) { 93 | e.printStackTrace(); 94 | return null; 95 | } 96 | 97 | } 98 | //fuck 竟然不导包找不到个好的map转json的 99 | public String map2Json(Map map){ 100 | String mapjson=""; 101 | Iterator> entries = map.entrySet().iterator(); 102 | while (entries.hasNext()) { 103 | Map.Entry entry = entries.next(); 104 | mapjson=mapjson+'"'+entry.getKey()+'"' + ":"+'"'+entry.getValue()+'"'+","; 105 | } 106 | int strlength=(int)mapjson.length(); 107 | mapjson=mapjson.substring(0,(strlength-1)); 108 | mapjson="{"+mapjson+"}"; 109 | return mapjson; 110 | } 111 | public void setOnAsyncResponse(AsyncResponse asyncResponse) 112 | { 113 | this.asyncResponse = asyncResponse; 114 | } 115 | 116 | @Override 117 | protected String[] doInBackground(Map ... key) { 118 | recordpostmap=key[0]; 119 | Map postmap=new HashMap(); 120 | postmap.putAll(key[0]); 121 | if(postmap==null) 122 | return null; 123 | String url = postmap.get("url"); 124 | 125 | if(url==null) 126 | return null; 127 | 128 | String[] resultstr=new String[3]; 129 | resultstr[0]=this.randomtasknum; 130 | postmap.remove("url"); 131 | String protocol=UrlUtil.httpOrHttps(url); 132 | String postjson=map2Json(postmap); 133 | if("http".equals(protocol)){ 134 | try{ 135 | Log.d(TAG,"post task url:"+url); 136 | Log.d(TAG,"post task postjson:"+postjson); 137 | String returnstr=httppost(url,postjson); 138 | resultstr[1]="true"; 139 | resultstr[2]=returnstr; 140 | return resultstr; 141 | }catch(IOException e){} 142 | } 143 | if("https".equals(protocol)){ 144 | try{ 145 | Log.d(TAG,"post task url:"+url); 146 | Log.d(TAG,"post task postjson:"+postjson); 147 | String returnstr=httpspost(url,postjson); 148 | resultstr[1]="true"; 149 | resultstr[2]=returnstr; 150 | return resultstr; 151 | }catch(IOException e){} 152 | 153 | } 154 | return null; 155 | } 156 | 157 | @Override 158 | protected void onPostExecute(String[] resultstr) { 159 | super.onPostExecute(resultstr); 160 | if (resultstr != null) 161 | { 162 | asyncResponse.onDataReceivedSuccess(resultstr);//将结果传给回调接口中的函数 163 | } 164 | else { 165 | String [] errstr=new String[3]; 166 | errstr[0]=this.randomtasknum; 167 | errstr[1]="false"; 168 | errstr[2]=""; 169 | if(recordpostmap.get("repeatnum")!=null){ 170 | String repeatnumstr=recordpostmap.get("repeatnum"); 171 | int num=Integer.parseInt(repeatnumstr)+1; 172 | recordpostmap.put("repeatnum",String.valueOf(num)); 173 | //key 存在 174 | } 175 | else 176 | recordpostmap.put("repeatnum","1"); 177 | asyncResponse.onDataReceivedFailed(errstr,recordpostmap); 178 | } 179 | 180 | } 181 | 182 | } 183 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/PreferenceActivity.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.os.Bundle; 3 | import android.os.Build; 4 | import android.preference.PreferenceFragment; 5 | import android.support.v7.app.AppCompatActivity; 6 | public class PreferenceActivity extends AppCompatActivity { 7 | 8 | @Override 9 | protected void onCreate(Bundle savedInstanceState) { 10 | super.onCreate(savedInstanceState); 11 | getFragmentManager().beginTransaction().replace(android.R.id.content, new GeneralPreferenceFragment()).commit(); 12 | } 13 | 14 | 15 | public static class GeneralPreferenceFragment extends PreferenceFragment { 16 | @Override 17 | public void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | addPreferencesFromResource(R.xml.pref_general); 20 | } 21 | } 22 | 23 | } 24 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/PreferenceUtil.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.content.Context; 3 | import android.content.SharedPreferences; 4 | import android.preference.PreferenceManager; 5 | public class PreferenceUtil{ 6 | SharedPreferences sharedPref=null; 7 | Context context=null; 8 | public PreferenceUtil(Context context){ 9 | this.context=context; 10 | init(); 11 | } 12 | public void init(){ 13 | sharedPref=PreferenceManager.getDefaultSharedPreferences(this.context); 14 | 15 | } 16 | public String getDeviceid(){ 17 | return this.sharedPref.getString("deviceid",""); 18 | } 19 | public boolean isEncrypt(){ 20 | return this.sharedPref.getBoolean("isencrypt",false); 21 | } 22 | public boolean isEcho(){ 23 | return this.sharedPref.getBoolean("isecho",false); 24 | } 25 | public String getEchoServer(){ 26 | return this.sharedPref.getString("echoserver",null); 27 | } 28 | public String getEchoInterval(){ 29 | return this.sharedPref.getString("echointerval",""); 30 | } 31 | public String getEncryptMethod(){ 32 | return this.sharedPref.getString("encryptmethod",null); 33 | } 34 | public String getPasswd(){ 35 | return this.sharedPref.getString("passwd",null); 36 | } 37 | public boolean isRemoveNotification(){ 38 | return this.sharedPref.getBoolean("isremovenotification",false); 39 | } 40 | public boolean isPostRepeat(){ 41 | return this.sharedPref.getBoolean("ispostrepeat",false); 42 | } 43 | public String getPostRepeatNum(){ 44 | return this.sharedPref.getString("postrepeatnum","3"); 45 | } 46 | 47 | } 48 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/RandomUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | import java.util.Random; 9 | 10 | public class RandomUtil { 11 | public static String getRandomTaskNum(){ 12 | Random rand = new Random(); 13 | return String.valueOf(rand.nextInt(9000) + 1000); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/SSLSocketFactoryCompat.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.os.Build; 3 | 4 | import java.io.IOException; 5 | import java.net.InetAddress; 6 | import java.net.Socket; 7 | import java.security.KeyManagementException; 8 | import java.security.NoSuchAlgorithmException; 9 | 10 | import javax.net.ssl.SSLContext; 11 | import javax.net.ssl.SSLSocket; 12 | import javax.net.ssl.SSLSocketFactory; 13 | 14 | public class SSLSocketFactoryCompat extends SSLSocketFactory{ 15 | private static final String[] TLS_V12_ONLY = {"TLSv1.2"}; 16 | 17 | private final SSLSocketFactory delegate; 18 | 19 | public SSLSocketFactoryCompat() throws KeyManagementException, NoSuchAlgorithmException { 20 | SSLContext sc = SSLContext.getInstance("TLS"); 21 | sc.init(null, null, null); 22 | delegate = sc.getSocketFactory(); 23 | } 24 | 25 | public SSLSocketFactoryCompat(SSLSocketFactory delegate) { 26 | if (delegate == null) { 27 | throw new NullPointerException(); 28 | } 29 | this.delegate = delegate; 30 | } 31 | 32 | @Override 33 | public String[] getDefaultCipherSuites() { 34 | return delegate.getDefaultCipherSuites(); 35 | } 36 | 37 | @Override 38 | public String[] getSupportedCipherSuites() { 39 | return delegate.getSupportedCipherSuites(); 40 | } 41 | 42 | private Socket enableTls12(Socket socket) { 43 | if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 20) { 44 | if (socket instanceof SSLSocket) { 45 | ((SSLSocket) socket).setEnabledProtocols(TLS_V12_ONLY); 46 | } 47 | } 48 | return socket; 49 | } 50 | 51 | @Override 52 | public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException { 53 | return enableTls12(delegate.createSocket(s, host, port, autoClose)); 54 | } 55 | 56 | @Override 57 | public Socket createSocket(String host, int port) throws IOException { 58 | return enableTls12(delegate.createSocket(host, port)); 59 | } 60 | 61 | @Override 62 | public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException { 63 | return enableTls12(delegate.createSocket(host, port, localHost, localPort)); 64 | } 65 | 66 | @Override 67 | public Socket createSocket(InetAddress host, int port) throws IOException { 68 | return enableTls12(delegate.createSocket(host, port)); 69 | } 70 | 71 | @Override 72 | public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException { 73 | return enableTls12(delegate.createSocket(address, port, localAddress, localPort)); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/UnionpayNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | 7 | 8 | public class UnionpayNotificationHandle extends NotificationHandle{ 9 | public UnionpayNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 10 | super(pkgtype,notification,postpush); 11 | } 12 | 13 | public void handleNotification(){ 14 | if(title.contains("消息推送")&&content.contains("云闪付收款")){ 15 | Map postmap=new HashMap(); 16 | postmap.put("type","unionpay"); 17 | postmap.put("time",notitime); 18 | postmap.put("title",title); 19 | postmap.put("money",extractMoney(content)); 20 | postmap.put("content",content); 21 | postpush.doPost(postmap); 22 | return ; 23 | } 24 | 25 | 26 | 27 | } 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/UrlUtil.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Created By WeihuaGu (email:weihuagu_work@163.com) 3 | * Copyright (c) 2017 4 | * All right reserved. 5 | */ 6 | 7 | package com.weihuagu.receiptnotice; 8 | 9 | public class UrlUtil { 10 | public static String [] commonusedurls={"m.baidu.com","www.baidu.com","cn.bing.com","Jd.com","weibo.com","weibo.cn","sina.cn","www.tmall.com","www.taobao.com","tianya.cn","github.com","news.163.com","mail.163.com","image.baidu.com","wwww.zhihu.com","www.huanqiu.com","www.ifeng.com","www.jianshu.com","www.xueqiu.com"}; 11 | public static String [] getCommonlyUsedUrls(){ 12 | return commonusedurls; 13 | } 14 | 15 | public static boolean isUrl(String url) { 16 | return 17 | url.contains(".") || 18 | url.equals(Constants.URL_ABOUT_BLANK) || 19 | url.equals(Constants.URL_ABOUT_START) || 20 | url.equals(Constants.URL_ABOUT_TUTORIAL); 21 | } 22 | 23 | 24 | public static String getSearchUrl(String searchurl,String serchcontent) { 25 | return searchurl.replaceAll("\\{searchTerms\\}", serchcontent); 26 | } 27 | 28 | public static String httpOrHttps(String address){ 29 | if(address.startsWith("http://")){ 30 | return "http"; 31 | } 32 | if(address.startsWith("https://")) 33 | return "https"; 34 | 35 | return null; 36 | 37 | } 38 | public static String addressMatch(String address){ 39 | 40 | 41 | if(address.startsWith("jian://")){ 42 | return address; 43 | } 44 | 45 | if(address.startsWith("alipay://")){ 46 | return address; 47 | } 48 | 49 | if(address.startsWith("wechat://")){ 50 | return address; 51 | } 52 | 53 | 54 | if(address.startsWith("http://")){ 55 | return address; 56 | } 57 | if(address.startsWith("https://")) 58 | return address; 59 | 60 | if(!address.startsWith("http://")|!address.startsWith("https://")) { 61 | address = "http://" + address; 62 | } // 如果不以http://开头,识别不了,所以判断 63 | 64 | 65 | return address; 66 | } 67 | public static String addressMatchInHttps(String address){ 68 | if(address.startsWith("https://")){ 69 | return address; 70 | 71 | } 72 | if(address.startsWith("http://")){ 73 | return address.replaceAll("http","https"); 74 | } 75 | else{ 76 | return "https://"+address; 77 | } 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/WechatNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | 7 | 8 | public class WechatNotificationHandle extends NotificationHandle{ 9 | public WechatNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 10 | super(pkgtype,notification,postpush); 11 | } 12 | 13 | public void handleNotification(){ 14 | if((title.contains("微信支付")|title.contains("微信收款"))&&content.contains("收款")){ 15 | Map postmap=new HashMap(); 16 | postmap.put("type","wechat"); 17 | postmap.put("time",notitime); 18 | postmap.put("title",title); 19 | postmap.put("money",extractMoney(content)); 20 | postmap.put("content",content); 21 | postpush.doPost(postmap); 22 | return ; 23 | } 24 | 25 | 26 | 27 | } 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | } 42 | -------------------------------------------------------------------------------- /app/src/main/java/com/weihuagu/receiptnotice/XposedmoduleNotificationHandle.java: -------------------------------------------------------------------------------- 1 | package com.weihuagu.receiptnotice; 2 | import android.app.Notification; 3 | 4 | import java.util.Map; 5 | import java.util.HashMap; 6 | 7 | 8 | public class XposedmoduleNotificationHandle extends NotificationHandle{ 9 | public XposedmoduleNotificationHandle(String pkgtype,Notification notification,IDoPost postpush){ 10 | super(pkgtype,notification,postpush); 11 | } 12 | 13 | public void handleNotification(){ 14 | if(content.contains("微信支付")&&content.contains("收款")){ 15 | Map postmap=new HashMap(); 16 | postmap.put("type","wechat"); 17 | postmap.put("time",notitime); 18 | postmap.put("title","微信支付"); 19 | postmap.put("money",extractMoney(content)); 20 | postmap.put("content",content); 21 | postpush.doPost(postmap); 22 | return ; 23 | } 24 | 25 | 26 | 27 | 28 | } 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | } 43 | -------------------------------------------------------------------------------- /app/src/main/res/drawable-v24/ic_launcher_foreground.xml: -------------------------------------------------------------------------------- 1 | 7 | 12 | 13 | 19 | 22 | 25 | 26 | 27 | 28 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lhalcyon/payment-listener/aa7149f425cbf64609348d8725909654aa8fdfc7/app/src/main/res/drawable/ic_launcher.png -------------------------------------------------------------------------------- /app/src/main/res/drawable/ic_launcher_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 10 | 15 | 20 | 25 | 30 | 35 | 40 | 45 | 50 | 55 | 60 | 65 | 70 | 75 | 80 | 85 | 90 | 95 | 100 | 105 | 110 | 115 | 120 | 125 | 130 | 135 | 140 | 145 | 150 | 155 | 160 | 165 | 170 | 171 | -------------------------------------------------------------------------------- /app/src/main/res/drawable/log_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lhalcyon/payment-listener/aa7149f425cbf64609348d8725909654aa8fdfc7/app/src/main/res/drawable/log_icon.png -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_illustratedecrypt.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 21 | 30 | 34 | 35 | 44 | 48 | 49 | 58 | 62 | 63 | 64 | 65 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_log.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 22 | 26 | 27 | 31 | 32 | 33 | 34 | 35 | -------------------------------------------------------------------------------- /app/src/main/res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 2 | 9 | 16 | 17 | 22 | 28 | 29 |