[
  {
    "path": ".gitattributes",
    "content": "app/build.gradle merge=ours\n"
  },
  {
    "path": ".github/FUNDING.yml",
    "content": "custom: ['https://weihuagu.github.io/donate/']\n"
  },
  {
    "path": ".github/file_to_push_get_new_build",
    "content": "2023/01/28\n"
  },
  {
    "path": ".github/workflows/android.yml",
    "content": "name: Android CI\n\non:\n  push:\n    branches: [ master ]\n  pull_request:\n    branches: [ master ]\n\njobs:\n  build:\n\n    runs-on: ubuntu-latest\n\n    steps:\n    - uses: actions/checkout@v2\n    - name: set up JDK 1.8\n      uses: actions/setup-java@v1\n      with:\n        java-version: 1.8\n    - name: Build with Gradle\n      run: ./gradlew assembleDebug\n    - name: Upload debug APK\n      uses: actions/upload-artifact@v1\n      with:\n        name: app\n        path: app/build/outputs/apk/debug/app-debug.apk\n"
  },
  {
    "path": ".gitignore",
    "content": "*.iml\n.*.swp\n.gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n.externalNativeBuild\n/app/key.properties\n\n"
  },
  {
    "path": ".idea/codeStyles/Project.xml",
    "content": "<component name=\"ProjectCodeStyleConfiguration\">\n  <code_scheme name=\"Project\" version=\"173\">\n    <codeStyleSettings language=\"XML\">\n      <indentOptions>\n        <option name=\"CONTINUATION_INDENT_SIZE\" value=\"4\" />\n      </indentOptions>\n      <arrangement>\n        <rules>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:android</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>xmlns:.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:id</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*:name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>name</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>style</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>^$</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>http://schemas.android.com/apk/res/android</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>ANDROID_ATTRIBUTE_ORDER</order>\n            </rule>\n          </section>\n          <section>\n            <rule>\n              <match>\n                <AND>\n                  <NAME>.*</NAME>\n                  <XML_ATTRIBUTE />\n                  <XML_NAMESPACE>.*</XML_NAMESPACE>\n                </AND>\n              </match>\n              <order>BY_NAME</order>\n            </rule>\n          </section>\n        </rules>\n      </arrangement>\n    </codeStyleSettings>\n  </code_scheme>\n</component>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleMigrationSettings\" migrationVersion=\"1\" />\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"testRunner\" value=\"PLATFORM\" />\n        <option name=\"distributionType\" value=\"DEFAULT_WRAPPED\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n          </set>\n        </option>\n        <option name=\"resolveModulePerSourceSet\" value=\"false\" />\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" project-jdk-name=\"JDK\" project-jdk-type=\"JavaSDK\">\n    <output url=\"file://$PROJECT_DIR$/build/classes\" />\n  </component>\n  <component name=\"ProjectType\">\n    <option name=\"id\" value=\"Android\" />\n  </component>\n</project>"
  },
  {
    "path": ".idea/modules.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"ProjectModuleManager\">\n    <modules>\n      <module fileurl=\"file://$PROJECT_DIR$/app/app.iml\" filepath=\"$PROJECT_DIR$/app/app.iml\" group=\"receiptnotice/app\" />\n      <module fileurl=\"file://$PROJECT_DIR$/receiptnotice.iml\" filepath=\"$PROJECT_DIR$/receiptnotice.iml\" group=\"receiptnotice\" />\n    </modules>\n  </component>\n</project>"
  },
  {
    "path": ".idea/runConfigurations.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"RunConfigurationProducerService\">\n    <option name=\"ignoredProducers\">\n      <set>\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer\" />\n        <option value=\"org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer\" />\n      </set>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/vcs.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"VcsDirectoryMappings\">\n    <mapping directory=\"\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "LICENSE",
    "content": "Copyright (c) 2019-2030 \n\nmodified part\n\n内容\n1.每个人都可以逐字复制并且分发此协议,但不允许更改任何内容.\n2.此部分所叙述之内容高于以下部分，如果和之下的原基本参考协议有所冲突，采用本部分，即modified part部分\n3.禁止将本项目用于任何商业行为,任何盈利活动都属于商业用途\n4.使用，分发，修改该项目，即等同同意该协议\n\n免责声明\n1.由于使用造成的损失,原项目不负法律责任\n2.由于使用本项目而造成的外部损失，原项目不负担责任\n\n\n    \n    \n    \n    \n    \n    \nApache License part\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright [yyyy] [name of copyright owner]\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "README-zh.md",
    "content": "### 提示\n- `很感谢你的使用`\n- `本软件是开源不盈利软件，没有所谓的定制版，不存在任何的收费QQ群，望周知`\n\n\n\n#### 软件规范及适用范围\n\n- 该软件的适用范围只限于帮助个人用户获取、收集自己的收款信息，它等效于您手工的获取过程。\n- 如您没有上述手工获取的权限，您将无法使用该软件。\n- 不能将本项目用于商业用途。\n\n\n\n#### 应用工作原理\n\n- 手机安装一个app,然后这个服务监听手机收到的通知，如果是想要获取的通知，就把信息推送到指定的url去。\n\n#### 本软件使用方法\n\n- 安装后先将软件加入系统白名单，各个安卓系统的方法各有不同\n\n- 打开软件自动跳转到获取通知权限页面，允许本应用监控通知\n\n- 返回到软件主页，填写你要接受收款信息通知的url,软件在接到收款通知后，会用post的方法，发送json信息.\n\n- 详细使用方法，参考[wiki](https://github.com/WeihuaGu/receiptnotice/wiki)\n\n#### 这个可搭配服务端项目\n\n|getreceipt-server |\n|:-|\n|[getreceipt-server](https://github.com/WeihuaGu/getreceipt-server)|\n\n##### 捐助\n[![](https://img.shields.io/badge/%E6%8D%90%E5%8A%A9-%E6%94%AF%E4%BB%98%E5%AE%9D%7C%E5%BE%AE%E4%BF%A1%7CPayPal-green.svg)](https://donate.indiv.dynv6.net/)\n\n##### 引用项目\n| ||\n|-|-|\n|本软件从NLservice修改而来| [NLservice](https://github.com/WHD597312/NLservice)|\n|实时logcat | [Lynx](https://github.com/pedrovgs/Lynx) |\n\n##### 开源许可\n本项目的代码，wiki等资源基于一个修改版的apache2.0 license协议发布，这意味着你可以拷贝、再发行本项目的内容, 但是你将必须：\n\n不能将本项目用于商业用途，任何盈利活动都属于商业用途。\n在延伸的代码中（修改和有源代码衍生的代码中）需要带有原来代码中的协议，商标，专利声明和其他原来作者规定需要包含的说明。\n\n\n"
  },
  {
    "path": "README.md",
    "content": "# receiptnotice\n\n*This software is open source and not profitable software. There is no so-called customized version.There are no paid QQ groups, hope you know\n*\n\n\n\n#### Application range and specifications\n- The scope of the software is limited to helping individual users to obtain and collect their own collection information, which is equivalent to your manual acquisition process.\n- If you do not have the above-mentioned manual permission, you will not be able to use the software.\n- This project cannot be used for commercial purposes.\n\n#### How the software works\n\n- Install an app on the phone, and then this service listens to the notifications received by the phone. If it receives a notification of receipt, it pushes the information to the specified URL.\n\n#### How to use this software\n\n- Add the software to the system whitelist after installation, each Android method is different\n\n- Open the software to automatically jump to the Get notification permission page, allowing the app to monitor notifications\n\n- Return to the software homepage, fill in the url you want to accept the payment information notification. After receiving the payment notification, the software will use the post method to send json information.\n\n- For detailed usage, refer to [wiki](https://github.com/WeihuaGu/receiptnotice/wiki)\n\n#### This works with server projects\n\n| getreceipt-server |\n|:-|\n| [getreceipt-server](https://github.com/WeihuaGu/getreceipt-server) |\n\n#### Donate\n[![](https://img.shields.io/badge/donate-alipay%7Cwechatpay%7CPayPal-green.svg)](https://donate.indiv.dynv6.net/)\n\n\n##### Reference project\n| ||\n|-|-|\n| This software is modified from NLservice | [NLservice](https://github.com/WHD597312/NLservice) |\n| Real-time logcat | [Lynx](https://github.com/pedrovgs/Lynx) |\n\n##### Open source license\nThe code, wiki and other resources of this project are released under a modified version of the apache2.0 license agreement, which means that you can copy and redistribute the content of this project, but you will have to:\n\n*This project cannot be used for commercial purposes. Any profit-making activities are commercial purposes.*\n\n*In the extended code (modified and source code-derived code), the agreement, trademarks, patent notices, and other original author specifications need to be included in the original code.*\n\n##### [Chinese README](https://github.com/WeihuaGu/receiptnotice/blob/master/README-zh.md)\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\nandroid {\n        compileSdkVersion 28\n                defaultConfig {\n                        applicationId \"com.weihuagu.receiptnotice\"\n                                minSdkVersion 19\n                                targetSdkVersion 28\n                                versionCode 16\n                                versionName \"1.5\"\n                                testInstrumentationRunner \"androidx.test.runner.AndroidJUnitRunner\"\n                }\n\n\n        signingConfigs{\n                debug {\n\n                }\n                release {\n                }\n        }\n\n        buildTypes {\n                debug {\n\n                }\n                release {\n                }\n        }\n        lintOptions {\n                abortOnError false\n        }\n}\ndependencies {\n                implementation fileTree(dir: 'libs', include: ['*.jar'])\n                implementation 'androidx.appcompat:appcompat:1.0.0'\n                implementation 'com.google.android.material:material:1.0.0'\n                implementation 'androidx.cardview:cardview:1.0.0'\n                implementation 'androidx.recyclerview:recyclerview:1.0.0'\n                implementation 'androidx.constraintlayout:constraintlayout:1.1.3'\n                implementation \"androidx.viewpager2:viewpager2:1.0.0-beta04\"\n                implementation 'com.squareup.okhttp3:okhttp:3.12.1'\n                implementation 'com.github.wangjintao:TLog:v1.0.1'\n                implementation 'com.github.pedrovgs:lynx:1.1.0'\n                implementation 'io.socket:socket.io-client:1.0.0'\n                implementation 'com.google.code.gson:gson:2.8.5'\n                implementation 'com.jeremyliao:live-event-bus-x:1.5.7'\n                testImplementation 'junit:junit:4.12'\n                testImplementation \"org.mockito:mockito-core:3.+\"\n                androidTestImplementation 'androidx.test.ext:junit:1.1.1'\n                androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.0'\n                androidTestImplementation 'org.mockito:mockito-android:+'\n}\n\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# You can control the set of applied configuration files using the\n# proguardFiles setting in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# If your project uses WebView with JS, uncomment the following\n# and specify the fully qualified class name to the JavaScript interface\n# class:\n#-keepclassmembers class fqcn.of.javascript.interface.for.webview {\n#   public *;\n#}\n\n# Uncomment this to preserve the line number information for\n# debugging stack traces.\n#-keepattributes SourceFile,LineNumberTable\n\n# If you keep the line number information, uncomment this to\n# hide the original source file name.\n#-renamesourcefileattribute SourceFile\n"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"com.weihuagu.receiptnotice\">\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WRITE_EXTERNAL_STORAGE\" />\n    <uses-permission android:name=\"android.permission.WAKE_LOCK\" />\n    <uses-permission android:name=\"android.permission.DISABLE_KEYGUARD\" />\n\n    <application\n        android:name=\".MainApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:networkSecurityConfig=\"@xml/network_security_config\"\n        android:roundIcon=\"@mipmap/ic_launcher_round\"\n        android:supportsRtl=\"true\"\n        android:theme=\"@style/Theme.AppCompat.Light.NoActionBar\">\n        <meta-data\n            android:name=\"com.google.android.actions\"\n            android:resource=\"@xml/receiptnoticeaccessibilityservice_config\" />\n\n        <activity android:name=\".view.MainActivity\">\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <action android:name=\"android.intent.action.VIEW\" />\n\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".view.FileLogActivity\"\n            android:label=\"@string/filelog_title\">\n            <intent-filter>\n                <action android:name=\"com.weihuagu.receiptnotice.showfilelog\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".view.IllustrateDecryptActivity\"\n            android:label=\"@string/illustratedecrypt_title\">\n            <intent-filter>\n                <action android:name=\"com.weihuagu.receiptnotice.illustratedecryptmethod\" />\n\n                <category android:name=\"android.intent.category.DEFAULT\" />\n            </intent-filter>\n        </activity>\n        <activity android:name=\"com.github.pedrovgs.lynx.LynxActivity\" />\n        <activity android:name=\".view.PreferenceActivity\" />\n        <activity android:name=\".view.UserAgreementActiviy\" />\n        <activity android:name=\".view.FollowThirdAppActivity\">\n        <intent-filter>\n            <action android:name=\"com.weihuagu.receiptnotice.followthirdapp\" />\n        </intent-filter>\n        </activity>\n\n        <service\n            android:name=\".NLService\"\n            android:permission=\"android.permission.BIND_NOTIFICATION_LISTENER_SERVICE\">\n            <intent-filter>\n                <action android:name=\"android.service.notification.NotificationListenerService\" />\n            </intent-filter>\n        </service>\n        <service\n            android:label=\"@string/accessibilityservicename\"\n            android:name=\".ReceiptnoticeAccessibilityService\"\n            android:permission=\"android.permission.BIND_ACCESSIBILITY_SERVICE\">\n            <intent-filter>\n                <action android:name=\"android.accessibilityservice.AccessibilityService\" />\n            </intent-filter>\n\n            <meta-data\n                android:name=\"android.accessibilityservice\"\n                android:resource=\"@xml/receiptnoticeaccessibilityservice_config\" />\n        </service>\n        <service android:name=\".NotificationCollectorMonitorService\" />\n\n        <uses-library\n            android:name=\"org.apache.http.legacy\"\n            android:required=\"false\" />\n    </application>\n\n</manifest>"
  },
  {
    "path": "app/src/main/assets/web/useragreement.html",
    "content": "<html>\n<head>\n    <title>用户协议</title>\n</head>\n<body>\n<h4>软件规范及适用范围</h4>\n<p>\n    - 该软件的适用范围只限于帮助个人用户获取、收集自己的收款信息，它等效于您手工的获取过程。\n</p>\n<p>\n    - 如您没有上述手工获取的权限，您将无法使用该软件。\n</p>\n<p>\n    - 不能将本项目用于商业用途。\n</p>\n</body>\n</html>"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/DatabaseHelper.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport android.content.Context;\nimport android.database.sqlite.SQLiteDatabase;\nimport android.database.sqlite.SQLiteOpenHelper;\n\nimport androidx.annotation.Nullable;\n\npublic class DatabaseHelper extends SQLiteOpenHelper {\n    //数据库版本号\n    private static Integer Version = 1;\n\n    public DatabaseHelper(@Nullable Context context, @Nullable String name, @Nullable SQLiteDatabase.CursorFactory factory, int version) {\n        super(context, name, factory, version);\n    }\n\n    @Override\n    public void onCreate(SQLiteDatabase db) {\n        String plat = \"create table plat(id integer primary key autoincrement,name varchar(64),address varchar(64))\";\n        String pushrecord = \"create table pushrecord(id integer primary key autoincrement,type varchar(64),time varchar(64),title varchar(64),money varchar(64),content varchar(64))\";\n\n        db.execSQL(plat);\n        db.execSQL(pushrecord);\n\n    }\n\n    @Override\n    public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/ForTest.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport android.app.Application;\nimport android.app.Notification;\nimport android.content.Intent;\nimport android.content.Context.*;\nimport android.app.PendingIntent;\nimport android.app.Notification.Builder;\nimport android.app.NotificationManager;\nimport android.widget.Toast;\n\n\nimport com.weihuagu.receiptnotice.action.HandlePost;\nimport com.weihuagu.receiptnotice.view.MainActivity;\n\npublic class ForTest {\n    public void makeAPostTest(String pkg, Notification notification){\n        //接受推送处理\n        NotificationHandle notihandle =new NotificationHandleFactory().getNotificationHandle(pkg,notification,new HandlePost());\n        if(notihandle!=null){\n            notihandle.printNotify();\n            notihandle.handleNotification();\n            notihandle.removeNotification();\n            return;\n        }\n    }\n    private void GenerateNotification() {\n        Intent intent = new Intent(MainApplication.getAppContext(), MainActivity.class);\n        PendingIntent pintent = PendingIntent.getActivity(MainApplication.getAppContext(), 0, intent, 0);\n        Builder builder = new Builder(MainApplication.getAppContext());\n        builder.setSmallIcon(R.drawable.ic_launcher);\n        builder.setTicker(\"这是手记状态栏提示\");\n        builder.setWhen(System.currentTimeMillis());\n        builder.setContentTitle(\"woshi biaoti\");\n        builder.setContentText(\"标题内容我是\");\n        builder.setContentIntent(pintent);\n        builder.setDefaults(Notification.DEFAULT_SOUND);\n        builder.setDefaults(Notification.DEFAULT_LIGHTS);\n        // builder.getNotification();//4.0以及以下版本用这个获取notification\n        Notification notification = builder.build();// 4.1以及以上版本用这个\n        Toast.makeText(MainApplication.getAppContext(), \"生成通知\", 50).show();\n        NotificationManager manager = (NotificationManager) MainApplication.getAppContext()\n                .getSystemService(android.content.Context.NOTIFICATION_SERVICE);\n        manager.notify(23, notification);// 发出通知\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/MainApplication.java",
    "content": "package com.weihuagu.receiptnotice;\nimport android.app.Application;\nimport android.content.Intent;\nimport android.content.Context;\nimport android.content.IntentFilter;\nimport android.content.BroadcastReceiver;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.tao.admin.loglib.TLogApplication;\nimport com.tao.admin.loglib.IConfig;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\n\npublic class MainApplication extends Application {\n        public static Context mContext;\n        private BroadcastReceiver timereceiver;\n\n        @Override\n        public void onCreate() {\n                super.onCreate();\n                startNotificationService();\n                initLogConfig();\n                setSomeGlobal();\n                setMessageBus();\n                setSomeThingWaitMessage();\n\n        }\n\n        private void initLogConfig(){\n                TLogApplication.initialize(this);\n                IConfig.getInstance().isShowLog(false)//是否在logcat中打印log,默认不打印\n                        .isWriteLog(true)//是否在文件中记录，默认不记录\n                        .tag(\"GoFileService\");//logcat 日志过滤tag\n        }\n        private void startNotificationService(){\n                startService(new Intent(this, NotificationCollectorMonitorService.class));\n        }\n        private void setSomeGlobal(){\n                mContext = getApplicationContext();\n        }\n        public void setMessageBus(){\n                LiveEventBus\n                        .config()\n                        .supportBroadcast(this)\n                        .lifecycleObserverAlwaysActive(true);\n        }\n        public static Context getAppContext(){\n                return mContext;\n        }\n        public void timeInterval(){\n            IntentFilter filter=new IntentFilter();\n            filter.addAction(Intent.ACTION_TIME_TICK);\n            registerReceiver(timereceiver,filter);\n        }\n\n        public void setSomeThingWaitMessage(){\n            timeInterval();\n            timereceiver = new BroadcastReceiver() {\n                @Override\n                public void onReceive(Context context, Intent intent) {\n                    String action = intent.getAction();\n                    if (action.equals(Intent.ACTION_TIME_TICK)) {\n                        LogUtil.debugLog(\"接受到一分钟广播action_time_tick事件\");\n                        MessageSendBus.postBaseTimeInterval();\n                    }\n                }\n            };\n        }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/NLService.java",
    "content": "package com.weihuagu.receiptnotice;\nimport android.content.Intent;\nimport android.service.notification.NotificationListenerService;\nimport android.app.Notification;\nimport android.service.notification.StatusBarNotification;\n\nimport androidx.annotation.Nullable;\nimport androidx.lifecycle.Observer;\nimport androidx.localbroadcastmanager.content.LocalBroadcastManager;\n\n\nimport android.os.Bundle;\nimport android.content.SharedPreferences;\nimport android.content.Context;\nimport android.os.Build;\nimport android.widget.Toast;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.action.ActionStatusBarNotification;\nimport com.weihuagu.receiptnotice.action.HandlePost;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.NotificationUtil;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.util.message.MessageConsumer;\n\n\n\npublic class NLService extends NotificationListenerService implements  ActionStatusBarNotification, MessageConsumer {\n        private String TAG=\"NLService\";\n        private String posturl=null;\n        private Context context=null;\n        private String getPostUrl(){\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                return preference.getPostUrl();\n        }\n\n\n        @Override\n        public void onNotificationPosted(StatusBarNotification sbn) {\n                //        super.onNotificationPosted(sbn);\n                //这里只是获取了包名和通知提示信息，其他数据可根据需求取，注意空指针就行\n\n                if(getPostUrl()==null)\n                        return;\n\n                Notification notification = sbn.getNotification();\n                String pkg = sbn.getPackageName();\n                if (notification == null) {\n                        return;\n                }\n\n                Bundle extras = notification.extras;\n                if(extras==null)\n                        return;\n\n                //接受推送处理\n                NotificationHandle notihandle =new NotificationHandleFactory().getNotificationHandle(pkg,notification,new HandlePost());\n                if(notihandle!=null){\n                        notihandle.setStatusBarNotification(sbn);\n                        notihandle.setActionStatusbar(this);\n                        notihandle.printNotify();\n                        notihandle.handleNotification();\n                        notihandle.removeNotification();\n                        return;\n                }\n                LogUtil.debugLog(\"-----------------\");\n                LogUtil.debugLog(\"接受到通知消息\");\n                LogUtil.debugLog(\"这是检测之外的其它通知\");\n                LogUtil.debugLog(\"包名是\"+pkg);\n                NotificationUtil.printNotify(notification);\n\n                LogUtil.debugLog(\"**********************\");\n\n\n        }\n\n        @Override\n        public void onNotificationRemoved(StatusBarNotification sbn) {\n                if (Build.VERSION.SDK_INT >19)\n                        super.onNotificationRemoved(sbn);\n        }\n\n        public void removeNotification(StatusBarNotification sbn){\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                if(preference.isRemoveNotification()){\n                        if (Build.VERSION.SDK_INT >=21)\n                                cancelNotification(sbn.getKey());\n                        else\n                                cancelNotification(sbn.getPackageName(), sbn.getTag(), sbn.getId());\n                        sendToast(\"receiptnotice移除了包名为\"+sbn.getPackageName()+\"的通知\");\n                }\n        }\n\n        private void sendBroadcast(String msg) {\n               Intent intent = new Intent(getPackageName());\n                intent.putExtra(\"text\", msg);\n              LocalBroadcastManager.getInstance(this).sendBroadcast(intent);\n        }\n\n        private void sendToast(String msg){\n                Toast.makeText(getApplicationContext(),msg,Toast.LENGTH_LONG).show();\n        }\n\n\n        //因为通知监听服务会长期一直运行，借助它进行一些消息的监听\n        public void subMessage() {\n                LiveEventBus\n                    .get(\"get_alipay_transfer_money\", TestBeanWithPostFullInformationMap.class)\n                    .observeForever( new Observer<TestBeanWithPostFullInformationMap>() {\n                        @Override\n                        public void onChanged(@Nullable TestBeanWithPostFullInformationMap testpostbean) {\n\n                        }\n                    });\n                LiveEventBus\n                        .get(\"message_finished_one_post\",String[].class)\n                        .observeForever(new Observer<String[]>() {\n                                @Override\n                                public void onChanged(@Nullable String[] testpostbean) {\n                                        PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                                        preference.setNumOfPush(\"add\");\n                                }\n                        });\n\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/NotificationCollectorMonitorService.java",
    "content": "package com.weihuagu.receiptnotice;;\n\nimport android.app.ActivityManager;\nimport android.app.Service;\nimport android.content.ComponentName;\nimport android.content.Context;\nimport android.content.Intent;\nimport android.content.pm.PackageManager;\nimport android.os.IBinder;\nimport android.os.Process;\nimport android.os.Build;\nimport android.util.Log;\nimport android.os.PowerManager.WakeLock;\nimport android.os.PowerManager;\nimport io.socket.client.IO;\nimport io.socket.client.Socket;\n\nimport java.lang.reflect.Field;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Date;\nimport java.util.ArrayList;\nimport java.util.Map;\nimport java.util.Random;\nimport java.lang.System;\nimport java.lang.Thread;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.net.URISyntaxException;\nimport java.text.SimpleDateFormat;\nimport java.security.KeyManagementException;\nimport java.security.NoSuchAlgorithmException;\nimport javax.net.ssl.SSLSocketFactory;\nimport com.google.gson.Gson;\nimport com.weihuagu.receiptnotice.util.DeviceInfoUtil;\nimport com.weihuagu.receiptnotice.util.ExternalInfoUtil;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.util.SSLSocketFactoryCompat;\n\nimport io.socket.emitter.Emitter;\n\nimport java.util.Timer;\nimport java.util.TimerTask;\n\nimport okhttp3.OkHttpClient;\nimport okhttp3.TlsVersion;\nimport okhttp3.ConnectionSpec;\n\n\n/**\n * Created by xinghui on 9/20/16.\n * <p>\n * calling this in your Application's onCreate\n * startService(new Intent(this, NotificationCollectorMonitorService.class));\n * <p>\n * BY THE WAY Don't Forget to Add the Service to the AndroidManifest.xml File.\n * <service android:name=\".NotificationCollectorMonitorService\"/>\n */\npublic class NotificationCollectorMonitorService extends Service {\n\n        /**\n         * {@link Log#isLoggable(String, int)}\n         * <p>\n         * IllegalArgumentException is thrown if the tag.length() > 23.\n         */\n        private static final String TAG = \"NotifiCollectorMonitor\";\n        private Timer timer=null;\n        private String echointerval=null;\n        private TimerTask echotimertask =null;\n        private WakeLock wl=null;\n        private void setWakelock() {\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                if(preference.isWakelock())\n                        obtainWakelock();\n        }\n\n        private void  obtainWakelock() {\n                PowerManager pm = (PowerManager)getSystemService(\n                                Context.POWER_SERVICE);\n                wl = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK,\n                                \"receiptnotice:NotificationCollectorMonitorServicewakelock\");\n                wl.acquire();\n\n        }\n        private void releaseWakelock() {\n                if(wl!=null)\n                        wl.release();\n                else\n                        return;\n        }\n\n\n\n        @Override\n        public void onCreate() {\n                super.onCreate();\n                ensureCollectorRunning();\n                startEchoTimer();\n                setWakelock();\n        }\n\n        @Override\n        public int onStartCommand(Intent intent, int flags, int startId) {\n                return START_STICKY;\n        }\n        private boolean echoServerBySocketio(String echourl,String echojson){\n                Socket mSocket= EchoSocket.getInstance(echourl);\n                mSocket.connect();\n                mSocket.emit(\"echo\",echojson);\n                mSocket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() {\n                        @Override\n                        public void call(Object... args) {\n                                LogUtil.infoLog(\"socket disconnected,try start echo in 5 secend\");\n                                try{\n                                        Thread.sleep(5000);\n                                }catch(InterruptedException e){\n                                        e.printStackTrace();\n                                }\n                                echoServer();\n                        }\n                });\n                return true;\n        }\n        private String getDefaultEchoInterval(){\n                if (Build.VERSION.SDK_INT >= 22 )\n                        return  \"300\";\n                else\n                        return  \"100\";\n        }\n        private void startEchoTimer(){\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                String interval=preference.getEchoInterval();\n                this.echointerval=(!interval.equals(\"\") ?  interval:getDefaultEchoInterval());\n                this.echotimertask=returnEchoTimerTask();\n                this.timer=new Timer();\n                int intervalmilliseconds = Integer.parseInt(this.echointerval)*1000;\n                LogUtil.infoLog(\"now socketio timer milliseconds:\"+intervalmilliseconds);\n                timer.schedule(echotimertask,5*1000,intervalmilliseconds);\n        }\n        private TimerTask returnEchoTimerTask(){\n                return new TimerTask() {\n                        @Override\n                        public void run() {\n                                if(!isIntervalMatchPreference()){\n                                        restartEchoTimer();\n                                        return;\n                                }\n                                LogUtil.debugLog(\"once socketio timer task run\");\n                                boolean flag= echoServer();\n                                if(!flag)\n                                        LogUtil.debugLog(\"socketio timer task not have a server\");\n                        }\n                };\n        }\n        private void restartEchoTimer(){\n                if (this.timer != null) {\n                        this.timer.cancel();\n                        this.timer = null;\n                }\n                if (echotimertask != null) {\n                        echotimertask.cancel();\n                        echotimertask = null;\n                }\n                LogUtil.debugLog(\"restart echo timer task\");\n                startEchoTimer();\n        }\n        private boolean isIntervalMatchPreference(){\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                String interval=preference.getEchoInterval();\n                if(interval.equals(\"\"))\n                        return true;\n                if(interval.equals(this.echointerval))\n                        return true;\n                return false;\n        }\n        private boolean echoServer(){\n                PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n                Gson gson = new Gson();\n                if(preference. isEcho()&&(preference.getEchoServer()!=null)){\n\n                                Date date = new Date(System.currentTimeMillis());\n                                SimpleDateFormat format = new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n                                String time = format.format(date);\n                                DeviceBean device = new DeviceBean();\n                                String deviceid = preference.getDeviceid();\n                                deviceid = (!deviceid.equals(\"\") ? deviceid : DeviceInfoUtil.getUniquePsuedoID());\n                                device.setDeviceid(deviceid);\n                                device.setTime(time);\n                                LogUtil.debugLog(\"start connect socketio\");\n                                //////////////\n\n                                Map devicemap = DeviceBeanReflect(device);\n                                if(devicemap==null)\n                                    return false;\n                                if (preference.getEchoCustomOption().equals(\"\") == false) {\n                                        Map custompostoption = ExternalInfoUtil.getCustomOption(preference.getEchoCustomOption());\n                                        if (custompostoption != null) {\n\n                                            LogUtil.debugLogWithJava(\"echo custom option map\"+custompostoption.toString());\n                                            if(custompostoption.size()>0)\n                                                devicemap.putAll(custompostoption);\n                                        }\n                                }\n                                echoServerBySocketio(preference.getEchoServer(), gson.toJson(devicemap));\n                                LogUtil.debugLog(gson.toJson(devicemap));\n                                return true;\n\n                }\n                else\n                        return false;\n\n        }\n        private void ensureCollectorRunning() {\n                ComponentName collectorComponent = new ComponentName(this, /*NotificationListenerService Inheritance*/ NLService.class);\n                Log.v(TAG, \"ensureCollectorRunning collectorComponent: \" + collectorComponent);\n                ActivityManager manager = (ActivityManager) getSystemService(Context.ACTIVITY_SERVICE);\n                boolean collectorRunning = false;\n                List<ActivityManager.RunningServiceInfo> runningServices = manager.getRunningServices(Integer.MAX_VALUE);\n                if (runningServices == null ) {\n                        Log.w(TAG, \"ensureCollectorRunning() runningServices is NULL\");\n                        return;\n                }\n                for (ActivityManager.RunningServiceInfo service : runningServices) {\n                        if (service.service.equals(collectorComponent)) {\n                                Log.w(TAG, \"ensureCollectorRunning service - pid: \" + service.pid + \", currentPID: \" + Process.myPid() + \", clientPackage: \" + service.clientPackage + \", clientCount: \" + service.clientCount\n                                                + \", clientLabel: \" + ((service.clientLabel == 0) ? \"0\" : \"(\" + getResources().getString(service.clientLabel) + \")\"));\n                                if (service.pid == Process.myPid() /*&& service.clientCount > 0 && !TextUtils.isEmpty(service.clientPackage)*/) {\n                                        collectorRunning = true;\n                                }\n                        }\n                }\n                if (collectorRunning) {\n                        Log.d(TAG, \"ensureCollectorRunning: collector is running\");\n                        return;\n                }\n                Log.d(TAG, \"ensureCollectorRunning: collector not running, reviving...\");\n                toggleNotificationListenerService();\n        }\n\n        private void toggleNotificationListenerService() {\n                Log.d(TAG, \"toggleNotificationListenerService() called\");\n                ComponentName thisComponent = new ComponentName(this, /*getClass()*/ NLService.class);\n                PackageManager pm = getPackageManager();\n                pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_DISABLED, PackageManager.DONT_KILL_APP);\n                pm.setComponentEnabledSetting(thisComponent, PackageManager.COMPONENT_ENABLED_STATE_ENABLED, PackageManager.DONT_KILL_APP);\n\n        }\n\n        @Override\n        public IBinder onBind(Intent intent) {\n                return null;\n        }\n\n        public class DeviceBean{\n                public String deviceid;\n                public String connectedtime;\n                public void setDeviceid(String deviceid){\n                        this.deviceid=deviceid;\n                }\n                public void setTime(String time){\n                        this.connectedtime=time;\n                }\n\n        }\n        public Map DeviceBeanReflect(DeviceBean e){\n                Class cls = e.getClass();\n                Field[] fields = cls.getDeclaredFields();\n                Map<String, String> devicebeanmap = new HashMap<String, String>();\n                for(int i=0; i<fields.length; i++){\n                        Field f = fields[i];\n                        f.setAccessible(true);\n                        try {\n                                devicebeanmap.put((String) f.getName(), (String) f.get(e));\n                                //System.out.println(\"属性名:\" + f.getName() + \" 属性值:\" + f.get(e));\n                        }catch (Exception ee){\n                                //LogUtil.debugLogWithJava(ee.getStackTrace().toString());\n                                return devicebeanmap;\n                        }\n                }\n                return devicebeanmap;\n        }\n\n        public static class EchoSocket{\n                private static Socket instance1=null;\n                private static Socket instance2=null;\n                private static Socket instance3=null;\n                private static final int maxCount = 3;\n                private EchoSocket(){\n                }\n                public static Socket getThisInstance(int i){\n                        if(i==1)\n                                return EchoSocket.instance1;\n                        if(i==2)\n                                return EchoSocket.instance2;\n                        if(i==3)\n                                return EchoSocket.instance3;\n                        else\n                                return null;\n                }\n\n                public static Socket getInstance(String socketserverurl){\n                        Random random = new Random();\n                        int current = random.nextInt(maxCount)+1;\n                        if(getThisInstance(current)==null){\n                                synchronized(EchoSocket.class){\n                                        if(current==1)\n                                                instance1=getIOSocket(socketserverurl);\n                                        if(current==2)\n                                                instance2=getIOSocket(socketserverurl);\n\n                                        if(current==3)\n                                                instance3=getIOSocket(socketserverurl);\n\n                                }\n                        }\n                        return getThisInstance(current);\n                }\n\n                public static Socket getIOSocket(String socketserverurl){\n                        try{\n                                if (Build.VERSION.SDK_INT >= 22 ){\n                                        return IO.socket(socketserverurl);\n                                }\n                                else{\n                                        SSLSocketFactory factory = new SSLSocketFactoryCompat();\n                                        ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\n                                                .tlsVersions(TlsVersion.TLS_1_2)\n                                                .build();\n                                        List<ConnectionSpec> specs = new ArrayList<>();\n                                        specs.add(cs);\n                                        specs.add(ConnectionSpec.COMPATIBLE_TLS);\n                                        specs.add(ConnectionSpec.CLEARTEXT);\n                                        OkHttpClient client = new OkHttpClient.Builder()\n                                                .sslSocketFactory(factory)\n                                                .connectionSpecs(specs)\n                                                .build();\n                                        IO.setDefaultOkHttpWebSocketFactory(client);\n                                        IO.setDefaultOkHttpCallFactory(client);\n                                        // set as an option\n                                        IO.Options opts = new IO.Options();\n                                        opts.callFactory = client;\n                                        opts.webSocketFactory = client;\n                                        return IO.socket(socketserverurl, opts);\n                                }\n                        }catch(URISyntaxException e) {\n                                StringWriter sw = new StringWriter();\n                                PrintWriter pw = new PrintWriter(sw);\n                                e.printStackTrace(pw);\n                                LogUtil.debugLog(sw.toString());\n                                return null;\n                        }catch (KeyManagementException e) {\n                                e.printStackTrace();\n                                return null;\n                        } catch (NoSuchAlgorithmException e) {\n                                e.printStackTrace();\n                                return null;\n                        }\n\n\n                }\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/NotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport android.app.Notification;\nimport android.app.PendingIntent;\nimport android.os.Bundle;\nimport android.service.notification.StatusBarNotification;\n\nimport com.weihuagu.receiptnotice.action.ActionStatusBarNotification;\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.NotificationUtil;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\n\npublic abstract class NotificationHandle {\n        protected String pkgtype;\n        protected Notification notification;\n        protected Bundle extras;\n        protected String title;\n        protected String content;\n        protected String notitime;\n        protected IDoPost postpush;\n        protected ActionStatusBarNotification actionstatusbar;\n        public StatusBarNotification sbn;\n        public NotificationHandle(String rawpkgtype, Notification rawnotification, IDoPost rawpostpush){\n                pkgtype=rawpkgtype;\n                notification=rawnotification;\n                postpush=rawpostpush;\n\n                extras=notification.extras;\n                // 获取通知标题\n                title = extras.getString(Notification.EXTRA_TITLE, \"\");\n                // 获取通知内容\n                content = extras.getString(Notification.EXTRA_TEXT, \"\");\n                long when=notification.when;\n                Date date=new Date(when);\n                SimpleDateFormat format=new SimpleDateFormat(\"yyyy-MM-dd HH:mm:ss\");\n                notitime=format.format(date);\n\n\n        }\n\n        public void setStatusBarNotification(StatusBarNotification sbn){\n                this.sbn=sbn;\n        }\n        public void setActionStatusbar(ActionStatusBarNotification actionstatusbar){\n                this.actionstatusbar=actionstatusbar;\n        }\n        public  abstract void handleNotification();\n\n\n\n        protected void removeNotification(){\n                if(actionstatusbar==null|sbn==null)\n                        return ;\n                actionstatusbar.removeNotification(sbn);\n        }\n\n        protected void printNotify(){\n                LogUtil.debugLog(\"-----------------\");\n                LogUtil.debugLog(\"接受到app消息\");\n                LogUtil.debugLog(\"包名是\"+this.pkgtype);\n                NotificationUtil.printNotify(notification);\n                LogUtil.debugLog(\"**********************\");\n\n\n        }\n\n        protected void openNotify(){\n                PendingIntent pendingIntent = notification.contentIntent;\n                try{\n                        pendingIntent.send();\n                }catch(PendingIntent.CanceledException e){\n\n                }\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/NotificationHandleFactory.java",
    "content": "package com.weihuagu.receiptnotice;\nimport android.app.Notification;\nimport android.provider.Telephony.Sms;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.AlipayPmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.BanksProxy;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.CashbarPmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.IcbcelifePmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.MipushPmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.UnionpayPmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.WechatPmentayNotificationHandle;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.XposedmodulePmentayNotificationHandle;\n\npublic  class NotificationHandleFactory{\n    public PmentayNotificationHandle getNotificationHandle(String pkg, Notification notification, IDoPost postpush){\n                //mipush\n                if(\"com.xiaomi.xmsf\".equals(pkg)){\n                        return  new MipushPmentayNotificationHandle(\"com.xiaomi.xmsf\",notification,postpush);\n                }\n                //支付宝\n                if(\"com.eg.android.AlipayGphone\".equals(pkg)){\n                        return new AlipayPmentayNotificationHandle(\"com.eg.android.AlipayGphone\",notification,postpush);\n                }\n\n                //应用管理GCM代收\n                if(\"android\".equals(pkg)){\n                        return new XposedmodulePmentayNotificationHandle(\"github.tornaco.xposedmoduletest\",notification,postpush);\n                }\n                //微信\n                if(\"com.tencent.mm\".equals(pkg)){\n                        return new WechatPmentayNotificationHandle(\"com.tencent.mm\",notification,postpush);\n                }\n                //收钱吧\n                if(\"com.wosai.cashbar\".equals(pkg)){\n                        return new CashbarPmentayNotificationHandle(\"com.wosai.cashbar\",notification,postpush);\n                }\n                //云闪付\n                if(\"com.unionpay\".equals(pkg)){\n                        return new UnionpayPmentayNotificationHandle(\"com.unionpay\",notification,postpush);\n                }\n                //工银商户之家\n                if(\"com.icbc.biz.elife\".equals(pkg)){\n                        return new IcbcelifePmentayNotificationHandle(\"com.icbc.biz.elife\",notification,postpush);\n                }\n                //接到短信\n                if(getMessageAppPkg().equals(pkg)){\n                        return new BanksProxy(getMessageAppPkg(),notification,postpush);\n                }\n\n\n\n                return null;\n\n        }\n        private String getMessageAppPkg(){\n                return Sms.getDefaultSmsPackage(MainApplication.getAppContext());\n\n        }\n\n}\n\n\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/OnlyWriteToDateBase.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport java.util.Map;\nimport com.weihuagu.receiptnotice.util.DataBaseHolder;\nimport com.google.gson.Gson;\n\npublic class OnlyWriteToDateBase {\n    DataBaseHolder database = DataBaseHolder.getInstance();\n    public void onePostWriteToDateBase(String postjson){\n        Gson gson=new Gson();\n        Map<String,String> postmap=gson.fromJson(postjson,Map.class);\n        String type=postmap.get(\"type\");\n        String time=postmap.get(\"time\");\n        String title=postmap.get(\"title\");\n        String money=postmap.get(\"money\");\n        String content=postmap.get(\"content\");\n        checkHavePlatName(type);\n\n    }\n\n\n    public boolean checkHavePlatName(String plattype){\n        database.sqliteDatabase.query(\"plat\",new String[]{\"name\"},plattype,null,null,null,null);\n        return false;\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/PmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport android.app.Notification;\nimport android.service.notification.StatusBarNotification;\n\nimport com.weihuagu.receiptnotice.action.ActionStatusBarNotification;\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.NotificationUtil;\n\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\npublic abstract class PmentayNotificationHandle extends NotificationHandle{\n        protected ActionStatusBarNotification actionstatusbar;\n        public StatusBarNotification sbn;\n        public PmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype, notification, postpush);\n\n        }\n\n        public void setStatusBarNotification(StatusBarNotification sbn){\n                this.sbn=sbn;\n        }\n        public void setActionStatusbar(ActionStatusBarNotification actionstatusbar){\n                this.actionstatusbar=actionstatusbar;\n        }\n\n        protected  String extractMoney(String content){\n                Pattern pattern = Pattern.compile(\"(收款|收款￥|向你付款|向您付款|入账|到帐)(([1-9]{1}\\\\d*)|([0]{1}))(\\\\.(\\\\d){0,2})?元\");\n                Matcher matcher = pattern.matcher(content);\n                List<String> list = new ArrayList<>();\n                while(matcher.find()){\n                        list.add(matcher.group());\n                }\n                if(list.size()>0){\n                        String tmp=list.get(list.size()-1);\n                        System.out.println(tmp);\n                        Pattern patternnum = Pattern.compile(\"(([1-9]{1}\\\\d*)|([0]{1}))(\\\\.(\\\\d){0,2})?\");\n                        Matcher matchernum = patternnum.matcher(tmp);\n                        if(matchernum.find())\n                                return matchernum.group();\n                        return null;\n                }else\n                        return null;\n\n\n        }\n        protected boolean predictIsPost(String content){\n                Pattern pattern = Pattern.compile(\"(收到|收款|向你付款|向您付款|入账)(([1-9]{1}\\\\d*)|([0]{1}))(\\\\.(\\\\d){0,2})?元\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find())\n                        return true;\n                else\n                        return false;\n\n        }\n\n        protected void removeNotification(){\n                if(actionstatusbar==null|sbn==null)\n                        return ;\n                if(predictIsPost(content))\n                        actionstatusbar.removeNotification(sbn);\n        }\n        protected void printNotify(){\n                LogUtil.debugLog(\"-----------------\");\n                LogUtil.debugLog(\"接受到支付类app消息\");\n                LogUtil.debugLog(\"包名是\"+this.pkgtype);\n                NotificationUtil.printNotify(this.notification);\n                LogUtil.debugLog(\"**********************\");\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/ReceiptnoticeAccessibilityService.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport android.accessibilityservice.AccessibilityService;\nimport android.accessibilityservice.GestureDescription;\nimport android.app.KeyguardManager;\nimport android.content.Context;\nimport android.graphics.Path;\nimport android.os.Build;\nimport android.os.PowerManager;\nimport android.util.DisplayMetrics;\nimport android.util.Log;\nimport android.view.WindowManager;\nimport android.view.accessibility.AccessibilityEvent;\nimport android.view.accessibility.AccessibilityNodeInfo;\nimport android.view.accessibility.AccessibilityWindowInfo;\n\nimport androidx.annotation.Nullable;\nimport androidx.lifecycle.Observer;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.filteringmiddleware.AlipayTransferBean;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.message.MessageConsumer;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\n\nimport java.util.LinkedList;\nimport java.util.List;\nimport java.util.Queue;\n\npublic class ReceiptnoticeAccessibilityService extends AccessibilityService implements MessageConsumer {\n    PowerManager pm=null;\n    String TAG=\"onAccessibilityEvent\";\n    private PowerManager.WakeLock mWakeLock = null;\n    private KeyguardManager mKeyguardManager;\n    private KeyguardManager.KeyguardLock kl;\n    private String lastpoststr = \"\";\n    private String lastnotistr = \"\";\n    private Queue<String> poststrqueue = new LinkedList<String>();\n    private void setLastPostStr(String str){\n        lastpoststr=str;\n    }\n\n    private void setLastNotiStr(String str){\n        lastnotistr=str;\n    }\n    @Override\n    public void onServiceConnected(){\n        debugLogWithDeveloper(\"accessibility service connected\");\n        subMessage();\n        pm = (PowerManager) getSystemService(Context.POWER_SERVICE);\n        mKeyguardManager = (KeyguardManager) getSystemService(Context.KEYGUARD_SERVICE);\n        kl = mKeyguardManager.newKeyguardLock(\"myapp:kllock\");\n\n\n\n    }\n    @Override\n    public void onAccessibilityEvent(AccessibilityEvent event) {\n\n        debugLogWithDeveloper( event.toString());\n        final int eventType = event.getEventType();\n        //根据事件回调类型进行处理\n        switch (eventType) {\n            //当通知栏发生改变时\n            case AccessibilityEvent.TYPE_NOTIFICATION_STATE_CHANGED:\n\n                break;\n            //当窗口的状态发生改变时\n            case AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED:\n                String className = event.getClassName().toString();\n                getAlipayTransferInfo(className);\n                break;\n        }\n\n\n    }\n\n    @Override\n    public void onInterrupt() {\n        debugLogWithDeveloper(  \"oninterrupt\");\n    }\n\n    private void mockSwipe(){\n        if(Build.VERSION.SDK_INT >= 24) {\n            //获取屏幕中心点坐标\n            WindowManager wm = (WindowManager) MainApplication.getAppContext()\n                    .getSystemService(Context.WINDOW_SERVICE);\n            DisplayMetrics dm = new DisplayMetrics();\n            wm.getDefaultDisplay().getMetrics(dm);\n            int width = dm.widthPixels;\n            int height = dm.heightPixels;\n            int cx = width/2;\n            int cy = height / 2;\n            final Path path = new Path();\n\n            path.moveTo(cx, cy); //滑动的起始位置，例如屏幕的中心点X、Y\n            path.lineTo(cx, 0); //需要滑动的位置，如从中心点滑到屏幕的顶部\n            GestureDescription.Builder builder = new GestureDescription.Builder();\n            GestureDescription gestureDescription = builder.addStroke(\n                    new GestureDescription.StrokeDescription(path, 100, 400)\n            ).build(); //移动到中心点，100ms后开始滑动，滑动的时间持续400ms，可以调整\n            dispatchGesture(gestureDescription, new GestureResultCallback() {\n                @Override\n                //如果滑动成功，会回调如下函数，可以在下面记录是否滑动成功，滑动成功或失败都要关闭该路径笔画\n                public void onCompleted(GestureDescription gestureDescription) {\n                    super.onCompleted(gestureDescription);\n                    Log.d(TAG, \"swipe  success.\");\n                    path.close();\n                }\n\n                @Override\n                public void onCancelled(GestureDescription gestureDescription) {\n                    super.onCancelled(gestureDescription);\n                    Log.d(TAG, \" swipe  fail.\");\n                    path.close();\n                }\n            },null);\n        }\n    }\n\n\n    public void subMessage(){\n        LiveEventBus\n                .get(\"action_request_return\", String.class)\n                .observeForever( new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String s) {\n                        LogUtil.debugLog(\"收到订阅消息:action_request_return \" + s);\n                        if(s.equals(\"return\")){\n                            performGlobalAction(GLOBAL_ACTION_BACK);\n\n                        }\n                    }\n                });\n        LiveEventBus\n                .get(\"action_request_home\", String.class)\n                .observeForever( new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String s) {\n                        LogUtil.debugLog(\"收到订阅消息:action_request_home \" + s);\n                        if(s.equals(\"home\")){\n                            performGlobalAction(GLOBAL_ACTION_HOME);\n\n                        }\n                    }\n                });\n        LiveEventBus\n                .get(\"message_noti_alipay_transfer_arrive\", String.class)\n                .observeForever( new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String s) {\n                        LogUtil.debugLog(\"收到订阅消息:message_noti_alipay_transfer_arrive \" + s);\n                        wakeAndUnlock(true);\n                        setLastNotiStr(s);\n\n                    }\n                });\n\n        LiveEventBus\n                .get(\"update_laststr\", String.class)\n                .observeForever( new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String s) {\n                        LogUtil.debugLog(\"收到订阅消息:update_laststr \" + s);\n                        poststrqueue.offer(s);\n                        setLastPostStr(s);\n                    }\n                });\n\n    }\n\n    public void getAlipayTransferInfo(String classname){\n\n        String transnumid=\"com.alipay.mobile.chatapp:id/biz_desc\";\n        String transremarkid=\"com.alipay.mobile.chatapp:id/biz_title\";\n        debugLogWithDeveloper( \":窗口状态改变,类名为\"+classname);\n        if(classname.equals(\"com.alipay.mobile.chatapp.ui.PersonalChatMsgActivity_\")){\n            mockSwipe();\n            AccessibilityNodeInfo nodepersonalchat=null;\n            AccessibilityWindowInfo windowInfopersonalchat=null;\n            if(pm.isScreenOn()) {\n                 nodepersonalchat= getRootInActiveWindow();\n            }else {\n                if(Build.VERSION.SDK_INT >= 21) {\n                    windowInfopersonalchat = getWindows().get(1);\n                    nodepersonalchat=windowInfopersonalchat.getRoot();\n                }\n            }\n            if (nodepersonalchat== null) {\n                return;\n            }\n            // 找到领取红包的点击事件\n            try {\n                List<AccessibilityNodeInfo> list = nodepersonalchat.findAccessibilityNodeInfosByViewId(transnumid);\n                AccessibilityNodeInfo thelastnode= list.get(list.size() - 1);\n                String transnum = thelastnode.getText().toString();\n                List<AccessibilityNodeInfo> remarklist=thelastnode.getParent().findAccessibilityNodeInfosByViewId(transremarkid);\n                String transremark=remarklist.get(remarklist.size()-1).getText().toString();\n                debugLogWithDeveloper(\":金额为\" + transnum);\n                debugLogWithDeveloper(\":备注为\" + transremark);\n                AlipayTransferBean transferbean=new AlipayTransferBean();\n                transferbean.setNum(transnum);\n                transferbean.setRemark(transremark);\n                if(!poststrqueue.poll().equals(lastnotistr))\n                MessageSendBus.postMessageWithget_alipay_transfer_money(transferbean);\n            }catch (ArrayIndexOutOfBoundsException e){\n\n            }\n        }\n\n    }\n\n    public void debugLogWithDeveloper(String info){\n        Log.d(TAG,info);\n    }\n\n    /**\n     * 唤醒屏幕和解锁\n     * @param unLock 是否点亮屏幕\n     */\n    private void wakeAndUnlock(boolean unLock)\n    {\n        if(unLock)\n        {\n            //若为黑屏状态则唤醒屏幕\n            if(!pm.isScreenOn()) {\n                //获取电源管理器对象，ACQUIRE_CAUSES_WAKEUP这个参数能从黑屏唤醒屏幕\n                mWakeLock = pm.newWakeLock(PowerManager.SCREEN_BRIGHT_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP, \"myapp:bright\");\n                //点亮屏幕\n                mWakeLock.acquire();\n                kl.disableKeyguard();\n                Log.i(\"QHB\", \"亮屏\");\n            }\n        }\n        else\n        {\n            //若之前唤醒过屏幕则释放使屏幕不保持常亮\n            if(mWakeLock != null) {\n                mWakeLock.release();\n                mWakeLock = null;\n                Log.i(\"QHB\", \"锁屏\");\n            }\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/TestBeanWithPostFullInformationMap.java",
    "content": "package com.weihuagu.receiptnotice;\n\nimport java.util.Map;\n\npublic class TestBeanWithPostFullInformationMap {\n    private String posturl;\n    private Map<String,String> infomap;\n    private String pkg;\n\n    public String getPosturl() {\n        return posturl;\n    }\n\n    public void setPosturl(String posturl) {\n        this.posturl = posturl;\n    }\n\n    public Map<String, String> getInfomap() {\n        return infomap;\n    }\n\n    public void setInfomap(Map<String, String> infomap) {\n        this.infomap = infomap;\n    }\n\n    public String getPkg() {\n        return pkg;\n    }\n\n    public void setPkg(String pkg) {\n        this.pkg = pkg;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/action/ActionStatusBarNotification.java",
    "content": "package com.weihuagu.receiptnotice.action;\nimport android.service.notification.StatusBarNotification;\n\npublic interface ActionStatusBarNotification{\n        public void removeNotification(StatusBarNotification sbn);\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/action/AsyncResponse.java",
    "content": "package com.weihuagu.receiptnotice.action;\n\nimport java.util.List;\nimport java.util.Map;\n\npublic interface AsyncResponse {\n\tpublic void onDataReceivedSuccess(String[] returnstr);\n    public void onDataReceivedFailed(String[] returnstr,Map<String ,String> postedmap);\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/action/HandlePost.java",
    "content": "package com.weihuagu.receiptnotice.action;\n\nimport android.content.SharedPreferences;\n\n\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.OnlyWriteToDateBase;\nimport com.weihuagu.receiptnotice.filteringmiddleware.PostMapFilter;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.util.RandomUtil;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\n\nimport java.util.Map;\n\n\npublic class HandlePost implements IDoPost, AsyncResponse {\n    protected String posturl=null;\n\n    public HandlePost() {\n        getPostUrl();\n    }\n\n    protected String getPostUrl(){\n        PreferenceUtil preference=new PreferenceUtil(MainApplication.getAppContext());\n        posturl=preference.getPostUrl();\n        return posturl;\n    }\n    @Override\n    public void doPost(Map<String, String> params) {\n        if(this.posturl==null|params==null)\n            return;\n        LogUtil.debugLog(\"开始准备进行post\");\n        if(params.get(\"repeatnum\")!=null){\n            doPostTask(params,null);\n            return;\n        }\n\n        PreferenceUtil preference=new PreferenceUtil(MainApplication.getAppContext());\n        PostMapFilter mapfilter=new PostMapFilter(preference,params,this.posturl);\n        Map<String, String> recordmap=mapfilter.getLogMap();\n        Map<String, String> postmap=mapfilter.getPostMap();\n\n        doPostTask(postmap,recordmap);\n\n    }\n\n    protected void doPostTask(Map<String, String> postmap,Map<String, String> recordmap){\n        PostTask mtask = new PostTask();\n        String tasknum= RandomUtil.getRandomTaskNum();\n        mtask.setRandomTaskNum(tasknum);\n        mtask.setOnAsyncResponse(this);\n        if(recordmap!=null)\n            LogUtil.postRecordLog(tasknum,recordmap.toString());\n        else\n            LogUtil.postRecordLog(tasknum,postmap.toString());\n\n        mtask.execute(postmap);\n\n\n    }\n\n\n    @Override\n    public void onDataReceivedSuccess(String[] returnstr) {\n        LogUtil.debugLog(\"Post Receive-returned post string\");\n        LogUtil.debugLog(returnstr[2]);\n        LogUtil.postResultLog(returnstr[0],returnstr[1],returnstr[2]);\n        MessageSendBus.postMessageWithFinishedonePost(returnstr);\n        new OnlyWriteToDateBase().onePostWriteToDateBase(returnstr[2]);\n\n    }\n\n    @Override\n    public void onDataReceivedFailed(String[] returnstr, Map<String, String> postedmap) {\n        // TODO Auto-generated method stub\n        LogUtil.debugLog(\"Post Receive-post error\");\n        LogUtil.postResultLog(returnstr[0],returnstr[1],returnstr[2]);\n        PreferenceUtil preference=new PreferenceUtil(MainApplication.getAppContext());\n        if(preference.isPostRepeat()){\n            String repeatlimit=preference.getPostRepeatNum();\n            int limitnum=Integer.parseInt(repeatlimit);\n            String repeatnumstr=postedmap.get(\"repeatnum\");\n            int repeatnum=Integer.parseInt(repeatnumstr);\n            if(repeatnum<=limitnum)\n                doPost(postedmap);\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/action/IDoPost.java",
    "content": "package com.weihuagu.receiptnotice.action;\nimport java.util.Map;\n\npublic interface IDoPost{\n        public  void doPost(Map<String, String> params);\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/action/PostTask.java",
    "content": "package com.weihuagu.receiptnotice.action;\n\nimport android.os.AsyncTask;\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.io.IOException;\nimport okhttp3.MediaType;\nimport okhttp3.OkHttpClient;\nimport java.util.Iterator;\nimport android.util.Log;\n\nimport com.weihuagu.receiptnotice.util.NetUtil;\nimport com.weihuagu.receiptnotice.util.UrlUtil;\n\npublic class PostTask extends AsyncTask<Map<String, String>, Void, String[]> {\n\n        public AsyncResponse asyncResponse;\n        public static final MediaType JSON = MediaType.get(\"application/json; charset=utf-8\");\n        public String TAG=\"NLService\";\n        public String randomtasknum;\n        public Map<String ,String> recordpostmap;\n        private NetUtil netutil=new NetUtil();\n        public void setRandomTaskNum(String num){\n                this.randomtasknum=num;\n        }\n        OkHttpClient client = new OkHttpClient();\n        //fuck 竟然不导包找不到个好的map转json的\n        public String map2Json(Map<String,String> map){\n                String mapjson=\"\";\n                Iterator<Map.Entry<String, String>> entries = map.entrySet().iterator();\n                while (entries.hasNext()) {\n                        Map.Entry<String, String> entry = entries.next();\n                        mapjson=mapjson+'\"'+entry.getKey()+'\"' + \":\"+'\"'+entry.getValue()+'\"'+\",\";\n                }\n                int strlength=(int)mapjson.length();\n                mapjson=mapjson.substring(0,(strlength-1));\n                mapjson=\"{\"+mapjson+\"}\";\n                return mapjson;\n        }\n        public void setOnAsyncResponse(AsyncResponse asyncResponse)\n        {\n                this.asyncResponse = asyncResponse;\n        }\n\n        @Override\n        protected String[] doInBackground(Map<String,String> ... key) {\n                recordpostmap=key[0];\n                Map<String ,String> postmap=new HashMap<String,String>();\n                postmap.putAll(key[0]);\n                if(postmap==null)\n                        return null;\n                String url = postmap.get(\"url\");\n\n                if(url==null)\n                        return null;\n\n                String[] resultstr=new String[3];\n                resultstr[0]=this.randomtasknum;\n                postmap.remove(\"url\");\n                String protocol= UrlUtil.httpOrHttps(url);\n                String postjson=map2Json(postmap);\n                if(\"http\".equals(protocol)){\n                        try{\n                                Log.d(TAG,\"post task  url:\"+url);\n                                Log.d(TAG,\"post task postjson:\"+postjson);\n                                String returnstr=netutil.httppost(url,postjson);\n                                resultstr[1]=\"true\";\n                                resultstr[2]=returnstr;\n                                return resultstr;\n                        }catch(IOException e){}\n                }\n                if(\"https\".equals(protocol)){\n                        try{\n                                Log.d(TAG,\"post task  url:\"+url);\n                                Log.d(TAG,\"post task postjson:\"+postjson);\n                                String returnstr=netutil.httpspost(url,postjson);\n                                resultstr[1]=\"true\";\n                                resultstr[2]=returnstr;\n                                return resultstr;\n                        }catch(IOException e){}\n\n                }\n                return null;\n        }\n\n        @Override\n        protected void onPostExecute(String[] resultstr) {\n                super.onPostExecute(resultstr);\n                if (resultstr != null)\n                {\n                        asyncResponse.onDataReceivedSuccess(resultstr);//将结果传给回调接口中的函数\n                }\n                else {\n                        String [] errstr=new String[3];\n                        errstr[0]=this.randomtasknum;\n                        errstr[1]=\"false\";\n                        errstr[2]=\"\";\n                        if(recordpostmap.get(\"repeatnum\")!=null){\n                             String repeatnumstr=recordpostmap.get(\"repeatnum\");\n                             int num=Integer.parseInt(repeatnumstr)+1;\n                             recordpostmap.put(\"repeatnum\",String.valueOf(num));\n                            //key 存在\n                        }\n                        else\n                            recordpostmap.put(\"repeatnum\",\"1\");\n                        asyncResponse.onDataReceivedFailed(errstr,recordpostmap);\n                }\n\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/audiorecognize/AudioHub.java",
    "content": "package com.weihuagu.receiptnotice.audiorecognize;\nimport java.io.File;\nimport java.io.IOException;\nimport java.util.Collection;\nimport java.util.HashSet;\n\nimport android.media.AudioFormat;\nimport android.media.AudioRecord;\nimport android.media.MediaRecorder.AudioSource;\n\npublic class AudioHub {\n    private boolean isRecord = false;\n    private final static int sampleRate = 8000;\n    private static int channelConfig = AudioFormat.CHANNEL_IN_STEREO;\n    private int bufferSize = 0;\n    private int bufferSizeInBytes =AudioRecord.getMinBufferSize(sampleRate,\n            channelConfig, AudioFormat.ENCODING_PCM_16BIT);\n\n    private final AudioRecord recorder;\n\n    public AudioHub() throws IOException{\n        bufferSize=bufferSizeInBytes;\n        recorder = new AudioRecord(\n                AudioSource.VOICE_RECOGNITION, sampleRate,\n                AudioFormat.CHANNEL_IN_MONO,\n                AudioFormat.ENCODING_PCM_16BIT, bufferSizeInBytes);\n        if (recorder.getState() == AudioRecord.STATE_UNINITIALIZED) {\n            recorder.release();\n            throw new IOException(\n                    \"Failed to initialize recorder. Microphone might be already in use.\");\n        }\n    }\n\n    private void startRecord() {\n        recorder.startRecording();\n        // 让录制状态为true\n        isRecord = true;\n        // 开启音频文件写入线程\n        new Thread(new AudioRecordThread()).start();\n    }\n    private void stopRecord() {\n        close();\n    }\n\n    private void close() {\n        if (recorder != null) {\n            System.out.println(\"stopRecord\");\n            isRecord = false;\n            recorder.stop();\n            recorder.release();//释放资源\n        }\n    }\n\n    private void getRecordData(){\n        short[] buffer = new short[bufferSize];\n        recorder.read(buffer, 0, buffer.length); // Skip the first buffer, usually zeroes\n\n    }\n\n    class AudioRecordThread implements Runnable {\n        @Override\n        public void run() {\n            getRecordData();//往文件中写入裸数据\n\n        }\n    }\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/audiorecognize/RecordService.java",
    "content": "package com.weihuagu.receiptnotice.audiorecognize;\n\nimport android.app.Service;\nimport android.content.Intent;\nimport android.os.IBinder;;import androidx.annotation.Nullable;\n\npublic class RecordService extends Service {\n    @Nullable\n    @Override\n    public IBinder onBind(Intent intent) {\n        return null;\n    }\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        try {\n            AudioHub hub=new AudioHub();\n        }catch (Exception e){\n\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/filteringmiddleware/AlipayTransferBean.java",
    "content": "package com.weihuagu.receiptnotice.filteringmiddleware;\n\npublic class  AlipayTransferBean {\n    public String getNum() {\n        return num;\n    }\n\n    public void setNum(String num) {\n        this.num = num;\n    }\n\n    public String getRemark() {\n        return remark;\n    }\n\n    public void setRemark(String remark) {\n        this.remark = remark;\n    }\n\n    private String num;\n    private String remark;\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/filteringmiddleware/PostMapFilter.java",
    "content": "package com.weihuagu.receiptnotice.filteringmiddleware;\n\nimport com.weihuagu.receiptnotice.util.DeviceInfoUtil;\nimport com.weihuagu.receiptnotice.util.ExternalInfoUtil;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.util.encrypt.EncryptFactory;\nimport com.weihuagu.receiptnotice.util.encrypt.Encrypter;\nimport com.weihuagu.receiptnotice.util.encrypt.MD5;\n\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class PostMapFilter {\n    private Map<String, String> unmodifiedmap;\n    private PreferenceUtil preference;\n    private String posturl;\n\n    public PostMapFilter(PreferenceUtil preference, Map<String, String> unmodifiedmap, String posturl) {\n        this.preference = preference;\n        this.unmodifiedmap = unmodifiedmap;\n        this.posturl = posturl;\n    }\n\n    public String getDeviceid() {\n        String deviceid = preference.getDeviceid();\n        if (deviceid.equals(\"\"))\n            deviceid = DeviceInfoUtil.getUniquePsuedoID();\n        else if (preference.isAppendDeviceiduuid())\n            deviceid = deviceid + '-' + DeviceInfoUtil.getUniquePsuedoID();\n        else\n            deviceid = deviceid;\n        return deviceid;\n    }\n\n\n    public Map getPostMap() {\n        Map<String, String> postmap = new HashMap<String, String>();\n        postmap.putAll(getLogMap());\n        postmap.put(\"sign\",new MD5().getSignMd5(postmap.get(\"type\"),postmap.get(\"money\")));\n        if (preference.isEncrypt()) {\n            String encrypt_type = preference.getEncryptMethod();\n            if (encrypt_type != null) {\n                String key = preference.getPasswd();\n                EncryptFactory encryptfactory = new EncryptFactory(key);\n                LogUtil.debugLog(\"加密方法\" + encrypt_type);\n                LogUtil.debugLog(\"加密秘钥\" + key);\n                Encrypter encrypter = encryptfactory.getEncrypter(encrypt_type);\n                if (encrypter != null && key != null) {\n\n                    postmap = encrypter.transferMapValue(postmap);\n                    postmap.put(\"url\", this.posturl);\n                    if (preference.isSkipEncryptDeviceid())\n                        postmap.put(\"deviceid\", getDeviceid());\n                }\n\n            }\n        } else\n            postmap.put(\"encrypt\", \"0\");\n        return postmap;\n    }\n\n    public Map getLogMap() {\n        Map<String, String> recordmap = new HashMap<String, String>();\n        recordmap.putAll(this.unmodifiedmap);\n        recordmap.put(\"url\", this.posturl);\n        recordmap.put(\"deviceid\", getDeviceid());\n        if (preference.getCustomOption().equals(\"\") == false) {\n            Map custompostoption = ExternalInfoUtil.getCustomPostOption(preference.getCustomOption());\n            if (custompostoption != null)\n                recordmap.putAll(custompostoption);\n        }\n        return recordmap;\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/AlipayPmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\nimport androidx.annotation.Nullable;\nimport androidx.lifecycle.Observer;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.filteringmiddleware.AlipayTransferBean;\nimport com.weihuagu.receiptnotice.util.AuthorityUtil;\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.util.message.MessageConsumer;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\n\npublic class AlipayPmentayNotificationHandle extends PmentayNotificationHandle implements MessageConsumer {\n        Map<String,String> tmppostmap=new HashMap<String,String>();\n        public AlipayPmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n\n        }\n        public void handleNotification(){\n                if(title.contains(\"支付宝\") | title.contains(\"收钱码\") | title.contains(\"收款通知\")){\n                        //不可将转账判断延后放，以防止通过昵称虚构金额\n                        if(content.contains(\"向你转了1笔钱\")){\n                                transfercodePush();\n\t\t\t\treturn ;\n                        }\n\n                        if(content.contains(\"成功收款\") | content.contains(\"向你付款\")){\n                                collectioncodePush(true);\n                                return ;\n                        }\n                }\n\t\tif(isInfoHideInTitle()){\n\t\t\tcollectioncodePush(false);\n\t\t\treturn ;\n\t\t}\n\t\t\t\n\n\n\n        }\n\n\tprivate void transfercodePush(){\n\t\t                        Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"alipay-transfer\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"转账\");\n                                postmap.put(\"money\",\"-0.00\");\n                                postmap.put(\"content\",content);\n                                postmap.put(\"transferor\",whoTransferred(content));\n\n                                //use acceesbility service to get info\n                                if (AuthorityUtil.isAccessibilitySettingsOn(MainApplication.getAppContext())) {\n                                        tmppostmap.putAll(postmap);\n                                        subMessage();\n                                        //open notify\n                                        MessageSendBus.postMessageWithReceiptAlipayTransfer(tmppostmap.get(\"time\")+tmppostmap.get(\"content\"));\n                                        this.openNotify();\n                                        return ;\n                                }\n\n                                postpush.doPost(postmap);\n                                return ;\n\t\t\n\t}\n\t\n\tprivate void collectioncodePush(boolean isinfoincontent){\n\t\t  Map<String,String> postmap=new HashMap<String,String>();\n                  postmap.put(\"type\",\"alipay\");\n                  postmap.put(\"time\",notitime);\n                  postmap.put(\"title\",\"支付宝支付\");\n\t\t  if(isinfoincontent){\n                  \tpostmap.put(\"money\",extractMoney(content));\n                  \tpostmap.put(\"content\",content);\n\t\t  }else\n\t\t  {\n\t\t\tpostmap.put(\"money\",extractMoney(title));\n                  \tpostmap.put(\"content\",title);  \n\t\t  }\n\n                  postpush.doPost(postmap);\n                  return ;\n\t}\n\t\n\tprivate boolean isInfoHideInTitle(){\n\t\tif(title.contains(\"成功收款\")&&content.contains(\"立即查看\"))\n\t\t\treturn true;\n\t\treturn false;\n\t\t\t\n\t}\n        private String whoTransferred(String content){\n                Pattern pattern = Pattern.compile(\"(.*)(已成功向你转了)\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                    String tmp=matcher.group(1);\n\t\t\t\t\treturn tmp;\n                \n                }\n                else\n                    return \"\";  \n        \n        }\n\n        public void subMessage() {\n                LiveEventBus\n                        .get(\"get_alipay_transfer_money\", AlipayTransferBean.class)\n                        .observeForever( new Observer<AlipayTransferBean>() {\n                                @Override\n                                public void onChanged(@Nullable AlipayTransferBean transfer) {\n                                        if(tmppostmap.size()==0)\n                                                return;\n                                        LogUtil.debugLog(\"收到订阅消息:get_alipay_transfer_money \" + \"money\"+transfer.getNum()+\"备注\"+transfer.getRemark());\n                                        MessageSendBus.postActionRequestWithReturn();\n                                        MessageSendBus.postActionRequestWithHome();\n                                        tmppostmap.put(\"money\",transfer.getNum());\n                                        tmppostmap.put(\"remark\",transfer.getRemark());\n                                        MessageSendBus.postMessageWithUpdateTheLastPostString(tmppostmap.get(\"time\")+tmppostmap.get(\"content\"));\n                                        postpush.doPost(tmppostmap);\n                                        tmppostmap=new HashMap<String,String>();\n                                        return;\n                                }\n                        });\n        }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/BankDistinguisher.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\n\nimport com.weihuagu.receiptnotice.util.ExternalInfoUtil;\n\nimport java.util.Map;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\nimport java.util.Stack;\nimport java.util.Calendar;\nimport java.text.SimpleDateFormat;\nimport java.text.ParseException;\nimport java.util.Date;\n\n\n\n\npublic class BankDistinguisher{\n        public BankDistinguisher(){\n        }\n        public String distinguishByNum(String num){\n                Map <String, String> map= ExternalInfoUtil.getBanksMessageNum();\n                String whatsback=map.get(num);\n                if(whatsback!=null)\n                        return whatsback;\n                else\n                        return \"\";\n\n        }\n\n        public String distinguishByMessageContent(String content){\n                if(content.contains(\"银行\")&&ExternalInfoUtil.containsBankmessageFeature(content))\n                {\n                        Stack<String> alternativebank = new Stack<String>();\n                        Map <String,String> map=ExternalInfoUtil.getAllBanksNameMap();\n                        for (String key : map.keySet()) {\n                                if(content.contains(key))\n                                        alternativebank.push(key);\n                        }\n                        if(alternativebank.isEmpty())\n                                return \"\";\n                        else\n                                return map.get(alternativebank.peek());\n                }\n                else\n                        return null;\n\n\n\n        }\n\n        public  String extractMoney(String content){\n                Pattern pattern = Pattern.compile(\"(收入|存入|转入|入账)(\\\\(.*\\\\))?(\\\\d{1,3}(,\\\\d{2,3})*(\\\\.\\\\d{0,2})?)元?\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                        String tmp=matcher.group();\n                        Pattern patternnum = Pattern.compile(\"((\\\\d{1,3}(,\\\\d{2,3})*(\\\\.\\\\d{0,2})?))\");\n                        Matcher matchernum = patternnum.matcher(tmp);\n                        if(matchernum.find())\n                                return matchernum.group();\n                        return null;\n                }else\n                        return null;\n\n\n        }\n\n        public String extractCardNum(String content){\n                String pattern = \"(尾号\\\\d{4}的?(卡|账号|账户))\";\n                Pattern r = Pattern.compile(pattern);\n                Matcher m = r.matcher(content);\n                if(m.find())\n                        return m.group();\n                else\n                        return \"\";\n\n\n        }\n\n        public String extractTime(String content,String time){\n\n                Pattern pattern = Pattern.compile(\"([0-9]|0[0-9]|1[0-9]|2[0-3]):([0-5][0-9])\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                        try {\n                                SimpleDateFormat df = new SimpleDateFormat(\"yyyy-MM-dd hh:mm\");\n                                Date date = df.parse(time);\n                                Calendar calendar = Calendar.getInstance();\n                                calendar.setTime(date);\n                                calendar.set(Calendar.HOUR_OF_DAY,Integer.parseInt(matcher.group(1)));\n                                calendar.set(Calendar.MINUTE,Integer.parseInt(matcher.group(2)));\n                                return df.format(calendar.getTime());\n                        } catch (ParseException e) {\n                                return time;\n                        }\n\n                }else\n                        return time;\n\n\n\n\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/BanksProxy.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class BanksProxy extends PmentayNotificationHandle {\n        private BankDistinguisher onedistinguisher=new BankDistinguisher();\n\n        public BanksProxy(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        private String getBankType(){\n                return onedistinguisher.distinguishByMessageContent(content);\n        }\n\n\n        public void handleNotification(){\n                String banktype=getBankType();\n                if(banktype==null)\n                        return;\n\n                String type=null;\n                if(banktype==\"\")\n                        type=\"message-bank\";\n                else\n                        type=\"message-bank-\"+banktype;\n\n                Map<String,String> postmap=new HashMap<String,String>();\n                postmap.put(\"type\",type);\n                postmap.put(\"time\",onedistinguisher.extractTime(content,notitime));\n                postmap.put(\"title\",\"短信银行卡入账\");\n                postmap.put(\"phonenum\",title);\n                postmap.put(\"money\",onedistinguisher.extractMoney(content));\n                postmap.put(\"cardnum\",onedistinguisher.extractCardNum(content));\n                postmap.put(\"content\",content);\n\n                postpush.doPost(postmap);\n                                return ;\n\n\n\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/CashbarPmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\npublic class CashbarPmentayNotificationHandle extends PmentayNotificationHandle {\n        public CashbarPmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(title.contains(\"收钱吧\")){\n                        if(content.contains(\"成功收款\") | content.contains(\"向你付款\")){\n                                Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",getCashbarType(content));\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"支付宝支付\");\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n\n                                postpush.doPost(postmap);\n                                return ;\n                        }\n                }\n\n\n\n        }\n\n\n        private String getCashbarType(String content){\n                Pattern pattern = Pattern.compile(\"(来自)(微信|支付宝|.*)\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                        String tmp=matcher.group(2);\n                        \n                        return \"cashbar-\"+transType(tmp);\n                }else\n                        return \"\";\n\n        }\n\n        private String transType(String chinesetype){\n                if(chinesetype.equals(\"微信\"))\n                        return \"wechat\";\n                if(chinesetype.equals(\"支付宝\"))\n                        return \"alipay\";\n                else return chinesetype;\n        }\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/IcbcelifePmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\n\npublic class IcbcelifePmentayNotificationHandle extends PmentayNotificationHandle {\n        public IcbcelifePmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(title.contains(\"工银商户\")){\n                        if(content.contains(\"已收到\")&&content.contains(\"元\")){\n                                Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"icbcelife\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"工银商户之家\");\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n\n                                postpush.doPost(postmap);\n                                return ;\n                        }\n                }\n\n\n\n        }\n\n        \n\t\t@Override\n        protected  String extractMoney(String content){\n                Pattern pattern = Pattern.compile(\"(收到|收款|向你付款)(([1-9]{1}\\\\d*)|([0]{1}))(\\\\.(\\\\d){0,2})?元\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                        String tmp=matcher.group();\n                        Pattern patternnum = Pattern.compile(\"(([1-9]{1}\\\\d*)|([0]{1}))(\\\\.(\\\\d){0,2})?\");\n                        Matcher matchernum = patternnum.matcher(tmp);\n                        if(matchernum.find())\n                                return matchernum.group();\n                        return null;\n                }else\n                        return null;\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/MipushPmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n\n\npublic class MipushPmentayNotificationHandle extends PmentayNotificationHandle {\n        public MipushPmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(title.contains(\"支付宝\")){\n                        if(content.contains(\"成功收款\")){\n                                Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"alipay\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"支付宝支付\");\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n                                postpush.doPost(postmap);\n                                return ;\n                        }\n                        if(content.contains(\"向你转了1笔钱\")){\n                                Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"alipay-transfer\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"转账\");\n                                postmap.put(\"money\",\"-0.00\");\n                                postmap.put(\"content\",content);\n                                postmap.put(\"transferor\",whoTransferred(content));\n\n                                postpush.doPost(postmap);\n                                return ;\n                        }\n                }\n                if(title.contains(\"动账通知\")){\n                        if(content.contains(\"入账\")&&content.contains(\"尾号为\")){\n                                Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"unionpay\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"云闪付扫码收款\");\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n                                //postmap.put(\"payer\",getPayer(content));\n                                postpush.doPost(postmap);\n                                return ;\n                        }\n                }\n\n\n\n\n        }\n\n\n        \n        private String getPayer(String content){\n                Pattern pattern = Pattern.compile(\"(.*)(通过扫码向您付款)\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                        String tmp=matcher.group(2);\n                        return tmp;\n                }else\n                        return \"\";\n\n        }\n\n        private String whoTransferred(String content){\n                Pattern pattern = Pattern.compile(\"(.*)(已成功向你转了)\");\n                Matcher matcher = pattern.matcher(content);\n                if(matcher.find()){\n                    String tmp=matcher.group(1);\n\t\t\t\t\treturn tmp;\n                \n                }\n                else\n                    return \"\";  \n        \n        }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/UnionpayPmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class UnionpayPmentayNotificationHandle extends PmentayNotificationHandle {\n        public UnionpayPmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(title.contains(\"消息推送\")&&content.contains(\"云闪付收款\")){\n                        Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"unionpay\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",title);\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n                                postpush.doPost(postmap);\n                                return ;\n                }\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/WechatPmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class WechatPmentayNotificationHandle extends PmentayNotificationHandle {\n        public WechatPmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(title.contains(\"微信支付\")|title.contains(\"微信收款\")){\n                        if(content.contains(\"收款\")){\n                                Map<String, String> postmap = new HashMap<String, String>();\n                                postmap.put(\"type\", \"wechat\");\n                                postmap.put(\"time\", notitime);\n                                postmap.put(\"title\", title);\n                                postmap.put(\"money\", extractMoney(content));\n                                postmap.put(\"content\", content);\n                                postpush.doPost(postmap);\n                                return;\n                        }\n                        if(content.contains(\"二维码赞赏\")){\n                                Map<String, String> postmap = new HashMap<String, String>();\n                                postmap.put(\"type\", \"wechat-sponsor\");\n                                postmap.put(\"time\", notitime);\n                                postmap.put(\"title\", title);\n                                postmap.put(\"money\", extractMoney(content));\n                                postmap.put(\"content\", content);\n                                postpush.doPost(postmap);\n                                return;\n                        }\n                }\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/pushclassification/pmentay/XposedmodulePmentayNotificationHandle.java",
    "content": "package com.weihuagu.receiptnotice.pushclassification.pmentay;\nimport android.app.Notification;\n\nimport com.weihuagu.receiptnotice.action.IDoPost;\nimport com.weihuagu.receiptnotice.PmentayNotificationHandle;\n\nimport java.util.Map;\nimport java.util.HashMap;\n\n\npublic class XposedmodulePmentayNotificationHandle extends PmentayNotificationHandle {\n        public XposedmodulePmentayNotificationHandle(String pkgtype, Notification notification, IDoPost postpush){\n                super(pkgtype,notification,postpush);\n        }\n\n        public void handleNotification(){\n                if(content.contains(\"微信支付\")&&content.contains(\"收款\")){\n                        Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"type\",\"wechat\");\n                                postmap.put(\"time\",notitime);\n                                postmap.put(\"title\",\"微信支付\");\n                                postmap.put(\"money\",extractMoney(content));\n                                postmap.put(\"content\",content);\n                                postpush.doPost(postmap);\n                                return ;\n                }\n\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/AuthorityUtil.java",
    "content": "package com.weihuagu.receiptnotice.util;\n\nimport android.content.Context;\nimport android.provider.Settings;\nimport android.text.TextUtils;\n\npublic class AuthorityUtil {\n    public static boolean isAccessibilitySettingsOn(Context mContext) {\n        int accessibilityEnabled = 0;\n        final String service = \"com.weihuagu.receiptnotice/com.weihuagu.receiptnotice.ReceiptnoticeAccessibilityService\";\n        boolean accessibilityFound = false;\n        try {\n            accessibilityEnabled = Settings.Secure.getInt(\n                    mContext.getApplicationContext().getContentResolver(),\n                    android.provider.Settings.Secure.ACCESSIBILITY_ENABLED);\n        } catch (Settings.SettingNotFoundException e) {\n\n        }\n        TextUtils.SimpleStringSplitter mStringColonSplitter = new TextUtils.SimpleStringSplitter(':');\n\n        if (accessibilityEnabled == 1) {\n            LogUtil.debugLog(\"***ACCESSIBILIY IS ENABLED*** -----------------\");\n            String settingValue = Settings.Secure.getString(\n                    mContext.getApplicationContext().getContentResolver(),\n                    Settings.Secure.ENABLED_ACCESSIBILITY_SERVICES);\n            if (settingValue != null) {\n                TextUtils.SimpleStringSplitter splitter = mStringColonSplitter;\n                splitter.setString(settingValue);\n                while (splitter.hasNext()) {\n                    String accessabilityService = splitter.next();\n\n                    LogUtil.debugLog(\"绑定的accessabilityService :: \" + accessabilityService);\n                    if (accessabilityService.equalsIgnoreCase(service)) {\n                        return true;\n                    }\n                }\n            }\n        } else {\n            LogUtil.debugLog(\"***ACCESSIBILIY IS DISABLED***\");\n        }\n\n        return accessibilityFound;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/ByteUtil.java",
    "content": "/*\n *下面两个自己字节的函数源自GcsSloop\n *GitHub: https://github.com/GcsSloop\n */\npackage com.weihuagu.receiptnotice.util;\npublic class ByteUtil {\n        /**\n         * 二进位组转十六进制字符串\n         *\n         * @param buf 二进位组\n         * @return 十六进制字符串\n         */\n        public static String parseByte2HexStr(byte buf[]) {\n                StringBuilder sb = new StringBuilder();\n                for (byte b : buf) {\n                        String hex = Integer.toHexString(b & 0xFF);\n                        if (hex.length() == 1) {\n                                hex = '0' + hex;\n                        }\n                        sb.append(hex.toUpperCase());\n                }\n                return sb.toString();\n        }\n\n        /**\n         * 十六进制字符串转二进位组\n         *\n         * @param hexStr 十六进制字符串\n         * @return 二进位组\n         */\n        public static byte[] parseHexStr2Byte(String hexStr) {\n                if (hexStr.length() < 1) return null;\n                byte[] result = new byte[hexStr.length() / 2];\n\n                for (int i = 0; i < hexStr.length() / 2; i++) {\n                        int high = Integer.parseInt(hexStr.substring(i * 2, i * 2 + 1), 16);\n                        int low = Integer.parseInt(hexStr.substring(i * 2 + 1, i * 2 + 2), 16);\n                        result[i] = (byte) (high * 16 + low);\n                }\n                return result;\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/Constants.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\n\npublic class Constants {\n    /**\n     * Actions.\n     */\n    public static final String ACTION_BROWSER_CONTEXT_MENU = \"ACTION_BROWSER_OPEN\";\n\n    /**\n     * Extras.\n     */\n    public static final String EXTRA_ID = \"EXTRA_ID\";\n    public static final String EXTRA_ACTION_ID = \"EXTRA_ACTION_ID\";\n    public static final String EXTRA_NEW_TAB = \"EXTRA_NEW_TAB\";\n    public static final String EXTRA_LABEL = \"EXTRA_LABEL\";\n    public static final String EXTRA_URL = \"EXTRA_URL\";\n    public static final String EXTRA_FOLDER_ID = \"EXTRA_FOLDER_ID\";\n    public static final String EXTRA_HIT_TEST_RESULT = \"EXTRA_HIT_TEST_RESULT\";\n    public static final String EXTRA_INCOGNITO = \"EXTRA_INCOGNITO\";\n\n    /**\n     * Specials urls.\n     */\n    public static final String URL_ABOUT_BLANK = \"about:blank\";\n    public static final String URL_ABOUT_START = \"about:start\";\n    public static final String URL_ABOUT_TUTORIAL = \"about:tutorial\";\n\n    /**\n     * User agents\n     */\n    public static final String USER_AGENT_ANDROID = \"\";\n    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\";\n\n    /**\n     * Preferences.\n     */\n    public static final String PREFERENCE_HOME_PAGE = \"PREFERENCE_HOME_PAGE\";\n    public static final String PREFERENCE_SEARCH_URL = \"PREFERENCE_SEARCH_URL\";\n    public static final String PREFERENCE_START_PAGE_LIMIT = \"PREFERENCE_START_PAGE_LIMIT\";\n    public static final String PREFERENCE_BUBBLE_POSITION = \"PREFERENCE_BUBBLE_POSITION\";\n    public static final String PREFERENCE_TOOLBARS_AUTOHIDE_DURATION = \"PREFERENCE_TOOLBARS_AUTOHIDE_DURATION\";\n    public static final String PREFERENCES_SWITCH_TABS_METHOD = \"PREFERENCES_SWITCH_TABS_METHOD\";\n\n    public static final String PREFERENCE_ENABLE_JAVASCRIPT = \"PREFERENCE_ENABLE_JAVASCRIPT\";\n    public static final String PREFERENCE_ENABLE_IMAGES = \"PREFERENCE_ENABLE_IMAGES\";\n    public static final String PREFERENCE_USE_WIDE_VIEWPORT = \"PREFERENCE_USE_WIDE_VIEWPORT\";\n    public static final String PREFERENCE_LOAD_WITH_OVERVIEW = \"PREFERENCE_LOAD_WITH_OVERVIEW\";\n    public static final String PREFERENCE_USER_AGENT = \"PREFERENCE_USER_AGENT\";\n    public static final String PREFERENCE_PLUGINS = \"PREFERENCE_PLUGINS\";\n\n    public static final String PREFERENCE_ACCEPT_COOKIES = \"PREFERENCE_ACCEPT_COOKIES\";\n    public static final String PREFERENCE_ENABLE_GEOLOCATION = \"PREFERENCE_ENABLE_GEOLOCATION\";\n    public static final String PREFERENCE_REMEMBER_FORM_DATA = \"PREFERENCE_REMEMBER_FORM_DATA\";\n    public static final String PREFERENCE_REMEMBER_PASSWORDS = \"PREFERENCE_REMEMBER_PASSWORDS\";\n\n    public static final String PREFERENCE_HISTORY_SIZE = \"PREFERENCE_HISTORY_SIZE\";\n    public static final String PREFERENCE_CLEAR_CACHE = \"PREFERENCE_CLEAR_CACHE\";\n    public static final String PREFERENCE_WEBSITES_SETTINGS = \"PREFERENCE_WEBSITES_SETTINGS\";\n    public static final String PREFERENCE_SSL_EXCEPTIONS = \"PREFERENCE_SSL_EXCEPTIONS\";\n    public static final String PREFERENCE_CLEAR_HISTORY = \"PREFERENCE_CLEAR_HISTORY\";\n    public static final String PREFERENCE_CLEAR_COOKIES = \"PREFERENCE_CLEAR_COOKIES\";\n    public static final String PREFERENCE_CLEAR_GEOLOCATION = \"PREFERENCE_CLEAR_GEOLOCATION\";\n    public static final String PREFERENCE_CLEAR_FORM_DATA = \"PREFERENCE_CLEAR_FORM_DATA\";\n    public static final String PREFERENCE_CLEAR_PASSWORDS = \"PREFERENCE_CLEAR_PASSWORDS\";\n    public static final String PREFERENCE_INCOGNITO_BY_DEFAULT = \"PREFERENCE_INCOGNITO_BY_DEFAULT\";\n\n    public static final String PREFERENCE_TEXT_SCALING = \"PREFERENCE_TEXT_SCALING\";\n    public static final String PREFERENCE_MINIMUM_FONT_SIZE = \"PREFERENCE_MINIMUM_FONT_SIZE\";\n    public static final String PREFERENCE_INVERTED_DISPLAY = \"PREFERENCE_INVERTED_DISPLAY\";\n    public static final String PREFERENCE_INVERTED_DISPLAY_CONTRAST = \"PREFERENCE_INVERTED_DISPLAY_CONTRAST\";\n\n    public static final String PREFERENCE_BOOKMARKS_SORT_MODE = \"PREFERENCE_BOOKMARKS_SORT_MODE\";\n\n    public static final String PREFERENCE_FULL_SCREEN = \"PREFERENCE_FULL_SCREEN\";\n\n    public static final String PREFERENCE_RESTORE_TABS = \"PREFERENCE_RESTORE_TABS\";\n\n    public static final String PREFERENCE_UI_TYPE = \"PREFERENCE_UI_TYPE\";\n    public static final String PREFERENCE_CLOSE_PANEL_ON_NEW_TAB = \"PREFERENCE_CLOSE_PANEL_ON_NEW_TAB\";\n\n    public static final String PREFERENCE_JS_LOG_ON_LOGCAT = \"PREFERENCE_JS_LOG_ON_LOGCAT\";\n\n    /**\n     * Technical preferences.\n     */\n    public static final String TECHNICAL_PREFERENCE_LAST_HISTORY_TRUNCATION = \"TECHNICAL_PREFERENCE_LAST_HISTORY_TRUNCATION\";\n    public static final String TECHNICAL_PREFERENCE_FIRST_RUN = \"TECHNICAL_PREFERENCE_FIRST_RUN\";\n    public static final String TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE = \"TECHNICAL_PREFERENCE_LAST_RUN_VERSION_CODE\";\n    public static final String TECHNICAL_PREFERENCE_ADDON_ENABLED = \"TECHNICAL_PREFERENCE_ADDON_ENABLED_\";\n    public static final String TECHNICAL_PREFERENCE_SAVED_TABS = \"TECHNICAL_PREFERENCE_SAVED_TABS\";\n    public static final String TECHNICAL_PREFERENCE_HOMEPAGE_URL_UPDATE_NEEDED = \"TECHNICAL_PREFERENCE_HOMEPAGE_URL_UPDATE_NEEDED\";\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/DataBaseHolder.java",
    "content": "package com.weihuagu.receiptnotice.util;\n\nimport android.database.sqlite.SQLiteDatabase;\n\nimport com.weihuagu.receiptnotice.DatabaseHelper;\nimport com.weihuagu.receiptnotice.MainApplication;\n\npublic class DataBaseHolder {\n    //创建 SingleObject 的一个对象\n    private static DataBaseHolder instance = new DataBaseHolder();\n    public DatabaseHelper dbHelper;\n    public SQLiteDatabase sqliteDatabase;\n\n    //让构造函数为 private，这样该类就不会被实例化\n    private DataBaseHolder(){\n        createDataBase();\n    }\n\n    //获取唯一可用的对象\n    public static DataBaseHolder getInstance(){\n        return instance;\n    }\n\n    private void createDataBase(){\n        dbHelper = new DatabaseHelper(MainApplication.getAppContext(),\"receiptnotice\",null,1);\n        sqliteDatabase = dbHelper.getWritableDatabase();\n    }\n\n    public SQLiteDatabase getDateBase(){\n        return sqliteDatabase;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/DeviceInfoUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport  android.os.Build;\nimport  java.util.UUID;\n\npublic class DeviceInfoUtil {\n        /**\n         * Return pseudo unique ID\n         * @return ID\n         */\n        public static String getUniquePsuedoID() {\n                // If all else fails, if the user does have lower than API 9 (lower\n                // than Gingerbread), has reset their device or 'Secure.ANDROID_ID'\n                // returns 'null', then simply the ID returned will be solely based\n                // off their Android device information. This is where the collisions\n                // can happen.\n                // Thanks http://www.pocketmagic.net/?p=1662!\n                // Try not to use DISPLAY, HOST or ID - these items could change.\n                // If there are collisions, there will be overlapping data\n                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);\n\n                // Thanks to @Roman SL!\n                // http://stackoverflow.com/a/4789483/950427\n                // Only devices with API >= 9 have android.os.Build.SERIAL\n                // http://developer.android.com/reference/android/os/Build.html#SERIAL\n                // If a user upgrades software or roots their device, there will be a duplicate entry\n                String serial = null;\n                try {\n                        serial = android.os.Build.class.getField(\"SERIAL\").get(null).toString();\n\n                        // Go ahead and return the serial for api => 9\n                        return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();\n                } catch (Exception exception) {\n                        // String needs to be initialized\n                        serial = \"serial\"; // some value\n                }\n\n                // Thanks @Joe!\n                // http://stackoverflow.com/a/2853253/950427\n                // Finally, combine the values we have found by using the UUID class to create a unique identifier\n                return new UUID(m_szDevIDShort.hashCode(), serial.hashCode()).toString();\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/ExternalInfoUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport java.util.Map;\nimport java.util.HashMap;\n\npublic class ExternalInfoUtil {\n        /**\n         *\n         * 中国银行:106573095566、777795566；\n\n         招商银行:1065795555、10657559555、1065502010095555；\n\n         建设银行:106573095533、80095533；\n\n         工商银行：95588；62019558；010095588；\n         　　\n         民生银行：10657109095568000、1069088895568；\n\n         农业银行：106366695599、6201395599；\n\n         华夏银行：1065800895577、1069088895577；\n\n         交通银行：106573095559、777795559、555595559000、80095559、\n\n         788895559、797995559\n         *\n         * */\n        public final static Map bankmessagenum = new HashMap() {{\n                put(\"95588\", \"icbc\");\n                put(\"62019558\", \"icbc\");\n                put(\"010095588\", \"icbc\");\n                put(\"106573095566\", \"boc\");\n                put(\"777795566\", \"boc\");\n                put(\"1065795555\", \"cmb\");\n                put(\"10657559555\", \"cmb\");\n                put(\"1065502010095555\", \"cmb\");\n                put(\"106573095533\", \"ccb\");\n                put(\"80095533\", \"ccb\");\n                put(\"10657109095568000\", \"cmbc\");\n                put(\"1069088895568\", \"cmbc\");\n        }};\n\n        public final static Map banksname = new HashMap() {{\n                put(\"工商银行\", \"icbc\");\n                put(\"农业银行\", \"abc\");\n                put(\"中国银行\", \"boc\");\n                put(\"建设银行\", \"ccb\");\n                put(\"邮政储蓄银行\", \"psbc\");\n                put(\"招商银行\", \"cbm\");\n                put(\"浦发银行\", \"spdb\");\n                put(\"兴业银行\", \"cib\");\n                put(\"民生银行\", \"cmbc\");\n                put(\"光大银行\", \"ceb\");\n                put(\"网商银行\", \"my\");\n                put(\"北京银行\", \"bob\");\n        }};\n\n        public final static String [] maybankmessagefeature = new String[]{\n                \"收入\",\n                \"存入\",\n                \"转入\",\n                \"入账\",\n                \"来帐\"\n        };\n\n\n        public static Map getBanksMessageNum(){\n                return bankmessagenum;\n        }\n        public static Map getAllBanksNameMap(){\n                return banksname;\n        }\n        public static String[] getBankmessageFeature(){\n                return maybankmessagefeature;\n        }\n        public static boolean containsBankmessageFeature(String content){\n                for(String x : maybankmessagefeature){\n                        if(content.contains(x))\n                                return true;\n                }\n                return false;\n        }\n        public static Map getCustomPostOption(String custom){\n               return getCustomOption(custom);\n\n        }\n        \n        public static Map getCustomOption(String custom){\n                String s[] = custom.split(\";\");\n                Map customoption = new HashMap();\n                for(String x : s){\n                        String ss[] = getOneitemKeyandValue(x);\n                        if(ss!=null){\n                                customoption.put(ss[0],ss[1]);\n                        }\n                }\n                if(customoption.size()>0)\n                        return customoption;\n                else\n                        return null;\n        }\n\n       public static String[] getOneitemKeyandValue(String item){\n               String s[] = item.split(\":\");\n               if(s.length==2)\n                       return s;\n               else \n                       return null;\n       }\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/FileLogUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport com.tao.admin.loglib.FileUtils;\nimport com.tao.admin.loglib.TLogApplication;\nimport com.tao.admin.loglib.IConfig;\nimport com.weihuagu.receiptnotice.util.OneFileUtil;\n\nimport java.io.File;\nimport java.util.ArrayList;\n\npublic class FileLogUtil extends FileUtils{\n        public static boolean clearLogFile() {\n                try {\n                        File file = new File(TLogApplication.getAPP().getFilesDir(), IConfig.fileName);\n                        if(file.delete())\n                                return true;\n                        else\n                                return false;\n\n                } catch(Exception e) {\n                        e.printStackTrace();\n                        return false;\n                }\n\n\n\n\n        }\n        public static ArrayList getLogList(){\n                        File file = new File(TLogApplication.getAPP().getFilesDir(), IConfig.fileName);\n                        if (!file.exists())\n                                return null;\n\n                        OneFileUtil fileutil = new OneFileUtil(file);\n                        ArrayList filelist=fileutil.getFileList();\n                        String startflag=\"*********************************\";\n                        String endflag=\"------------------------------------------\";\n                        ArrayList filemergelist=fileutil.mergeByFlagline(startflag,endflag,filelist);\n                        return filemergelist;\n\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/LogUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport android.util.Log;\n\nimport com.tao.admin.loglib.Logger;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\n\npublic class LogUtil {\n        public static String TAG=\"NLService\";\n        public static String DEBUGTAG=\"NLDebugService\";\n        public static String EXCEPTIONTAG=\"NLExceptionService\";\n        public static void infoLog(String info){\n                Log.i(TAG,info);\n        }\n\n        public static void debugLog(String info){\n                Log.d(TAG,info);\n        }\n        \n        public static void debugLogWithDeveloper(String info){\n                Log.d(DEBUGTAG,info);\n        }\n\n        public static void debugLogWithJava(String info){\n                System.out.println(DEBUGTAG+\":\"+info);\n        }\n\n        public static void postRecordLog(String tasknum,String post){\n                Logger.i(\"*********************************\");\n                Logger.i(\"开始推送\", \"随机序列号:\"+tasknum);\n                Logger.i(post);\n        }\n\n        public static void postResultLog(String tasknum,String result,String returnstr){\n\n                Logger.i(\"推送结果\",\"随机序列号:\"+tasknum);\n                Logger.i(\"推送结果\",result);\n                Logger.i(\"返回内容\",returnstr);\n                Logger.i(\"------------------------------------------\");\n\n                MessageSendBus.postInterfaceMessageWithUpdateTheRecordlist();\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/NetUtil.java",
    "content": "package com.weihuagu.receiptnotice.util;\n\nimport android.os.Build;\n\nimport com.weihuagu.receiptnotice.MainApplication;\n\nimport java.io.IOException;\nimport java.io.PrintWriter;\nimport java.io.StringWriter;\nimport java.security.KeyManagementException;\nimport java.security.NoSuchAlgorithmException;\nimport java.util.ArrayList;\nimport java.util.List;\nimport java.util.concurrent.TimeUnit;\n\nimport javax.net.ssl.HostnameVerifier;\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSession;\nimport javax.net.ssl.SSLSocketFactory;\nimport javax.net.ssl.TrustManager;\nimport javax.net.ssl.X509TrustManager;\n\nimport okhttp3.ConnectionSpec;\nimport okhttp3.MediaType;\nimport okhttp3.OkHttpClient;\nimport okhttp3.Request;\nimport okhttp3.RequestBody;\nimport okhttp3.Response;\nimport okhttp3.TlsVersion;\n\npublic class NetUtil {\n    public static final MediaType JSON = MediaType.get(\"application/json; charset=utf-8\");\n    OkHttpClient client = new OkHttpClient();\n    PreferenceUtil preferceutil = new PreferenceUtil(MainApplication.getAppContext());\n\n    public String httppost(String url, String json) throws IOException {\n        RequestBody body = RequestBody.create(JSON, json);\n        OkHttpClient client = new OkHttpClient.Builder()\n                .connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间\n                .readTimeout(20, TimeUnit.SECONDS)//设置读取超时时间\n                .build();\n        Request.Builder request = new Request.Builder()\n                .url(url)\n                .post(body);\n        try (Response response = client.newCall(request.build()).execute()) {\n            return response.body().string();\n        }\n    }\n\n    public String httpspost(String url, String json) throws IOException {\n        if (Build.VERSION.SDK_INT >= 21) {\n            if (!preferceutil.isTrustAllCertificates())\n                return httppost(url, json);\n            else {\n                RequestBody body = RequestBody.create(JSON, json);\n                OkHttpClient clientwithtrustallcertificates = getHttpsClientWithTrustAllCertificates();\n                Request.Builder request = new Request.Builder()\n                        .url(url)\n                        .post(body);\n                try (Response response = clientwithtrustallcertificates.newCall(request.build()).execute()) {\n                    return response.body().string();\n                }\n            }\n\n        } else\n            return doHttpsWithApi19(url, json);\n\n\n    }\n\n    public String doHttpsWithApi19(String url, String json) {\n        try {\n            RequestBody body = RequestBody.create(JSON, json);\n            SSLSocketFactory factory = new SSLSocketFactoryCompat();\n            ConnectionSpec cs = new ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)\n                    .tlsVersions(TlsVersion.TLS_1_2)\n                    .build();\n\n            List<ConnectionSpec> specs = new ArrayList<>();\n            specs.add(cs);\n            specs.add(ConnectionSpec.COMPATIBLE_TLS);\n            specs.add(ConnectionSpec.CLEARTEXT);\n\n\n            OkHttpClient client = new OkHttpClient.Builder()\n                    .connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间\n                    .readTimeout(20, TimeUnit.SECONDS)//设置读取超时时间\n                    .sslSocketFactory(factory)\n                    .connectionSpecs(specs)\n                    .build();\n\n            Request.Builder request = new Request.Builder()\n                    .url(url)\n                    .post(body);\n            Response response = client.newCall(request.build()).execute();\n            return response.body().string();\n        } catch (IOException e) {\n            StringWriter sw = new StringWriter();\n            PrintWriter pw = new PrintWriter(sw);\n            e.printStackTrace(pw);\n            LogUtil.debugLog(sw.toString());\n            return null;\n        } catch (KeyManagementException e) {\n            e.printStackTrace();\n            return null;\n        } catch (NoSuchAlgorithmException e) {\n            e.printStackTrace();\n            return null;\n        }\n    }\n\n    private OkHttpClient getHttpsClientWithTrustAllCertificates() {\n        OkHttpClient.Builder okhttpClient = new OkHttpClient().newBuilder();\n        //信任所有服务器地址\n        okhttpClient. connectTimeout(10, TimeUnit.SECONDS)//设置连接超时时间\n                .readTimeout(20, TimeUnit.SECONDS);//设置读取超时时间\n        okhttpClient.hostnameVerifier(new HostnameVerifier() {\n            @Override\n            public boolean verify(String s, SSLSession sslSession) {\n                //设置为true\n                return true;\n            }\n        });\n        //创建管理器\n        TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {\n            @Override\n            public void checkClientTrusted(\n                    java.security.cert.X509Certificate[] x509Certificates,\n                    String s) throws java.security.cert.CertificateException {\n            }\n\n            @Override\n            public void checkServerTrusted(\n                    java.security.cert.X509Certificate[] x509Certificates,\n                    String s) throws java.security.cert.CertificateException {\n            }\n\n            @Override\n            public java.security.cert.X509Certificate[] getAcceptedIssuers() {\n                return new java.security.cert.X509Certificate[]{};\n            }\n        }};\n        try {\n            SSLContext sslContext = SSLContext.getInstance(\"TLS\");\n            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());\n\n            //为OkHttpClient设置sslSocketFactory\n            okhttpClient.sslSocketFactory(sslContext.getSocketFactory());\n\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n\n        return okhttpClient.build();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/NotificationUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport android.app.Notification;\nimport android.os.Bundle;\n\nimport com.weihuagu.receiptnotice.util.LogUtil;\n\nimport java.text.SimpleDateFormat;\nimport java.util.Date;\n\n\n\npublic class NotificationUtil {\n        private static String getNotitime(Notification notification){\n\n                long when=notification.when;\n                Date date=new Date(when);\n                SimpleDateFormat format=new SimpleDateFormat(\"yyyy-MM-dd HH:mm\");\n                String notitime=format.format(date);\n                return notitime;\n\n        }\n\n        private static String getNotiTitle(Bundle extras){\n                String title=null;\n                // 获取通知标题\n                title = extras.getString(Notification.EXTRA_TITLE, \"\");\n                return title;\n        }\n\n        private static String getNotiContent(Bundle extras){\n                String content=null;\n                // 获取通知内容\n                content = extras.getString(Notification.EXTRA_TEXT, \"\");\n                return content;\n        }\n\n        public static void printNotify(Notification notification){\n                if(notification==null){\n                        LogUtil.debugLog(\"notificationutil report: notification is null\");\n                        return;\n                }\n\n                LogUtil.debugLog(getNotitime(notification));\n                LogUtil.debugLog(getNotiTitle(notification.extras));\n                LogUtil.debugLog(getNotiContent(notification.extras));\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/OneFileLogItem.java",
    "content": "package com.weihuagu.receiptnotice.util;\n\npublic class OneFileLogItem {\n    public String getPlatName(){\n        return null;\n    }\n    public String getMoney(){\n        return null;\n    }\n    public String getReply(){\n        return null;\n    }\n    public boolean isRandomSequenceNumberMatches(){\n        return true;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/OneFileUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport java.io.File;\nimport java.io.FileReader;\nimport java.io.BufferedReader;\nimport java.io.IOException;\nimport java.util.Iterator;\nimport java.util.ArrayList;\nimport java.util.LinkedList;\nimport java.util.Deque;\n\npublic class OneFileUtil{\n        private File file;\n        public OneFileUtil(File file){\n                this.file=file;\n        }\n        private String clearOnegroup(Deque<String> onegroup){\n                String tmp=\"\";\n                while(onegroup.size()>0){\n                    String first=onegroup.pollFirst();\n                    tmp=tmp+\"\\n\"+first;\n                }\n                return tmp;\n        \n        }\n        public  ArrayList mergeByFlagline(String startflagline,String endflagline,ArrayList filelist){\n                if(filelist.size()==0)\n                    return null;\n                ArrayList<String> merge=new ArrayList<String>();\n                Iterator fileiterator = filelist.iterator();\n                Deque<String> onegroup = new LinkedList<String>();\n                while (fileiterator.hasNext()) {\n                    String o = (String)fileiterator.next();\n                    onegroup.offerLast(o);\n                    if(onegroup.peekFirst().contains(startflagline)&&onegroup.peekLast().contains(endflagline)){\n                        merge.add(clearOnegroup(onegroup));\n                    \n                    }\n                   \n                }\n                return merge;\n        \n        \n        \n        \n        }\n        public  ArrayList getFileList(){\n                ArrayList<String> arrayList = new ArrayList<String>();\n                FileReader fr = null;\n                try{\n                        if (!file.exists())\n                                return null;\n\n                        fr = new FileReader(file);\n                        BufferedReader bf = new BufferedReader(fr);\n                        String str;\n                        while ((str = bf.readLine()) != null) {\n                                //按行处理\n                                arrayList.add(str);\n                        }\n                        if(arrayList.size()==0)\n                            return null;\n                        else\n                            return arrayList;\n\n\n                } catch (Throwable ex) {\n                        ex.printStackTrace();\n                } finally {\n                        try {\n                                if (fr != null)\n                                        fr.close();\n                        } catch (IOException e) {\n                                e.printStackTrace();\n                        }\n                }\n                return null;\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/PreferenceUtil.java",
    "content": "package com.weihuagu.receiptnotice.util;\n\nimport android.content.Context;\nimport android.content.SharedPreferences;\nimport android.preference.PreferenceManager;\nimport android.widget.Toast;\n\npublic class PreferenceUtil {\n    SharedPreferences sharedPref = null;\n    Context context = null;\n\n    public PreferenceUtil(Context context) {\n        this.context = context;\n        init();\n    }\n\n    public void init() {\n        sharedPref = PreferenceManager.getDefaultSharedPreferences(this.context);\n\n    }\n\n    public String getDeviceid() {\n        return this.sharedPref.getString(\"deviceid\", \"\");\n    }\n\n    public boolean isEncrypt() {\n        return this.sharedPref.getBoolean(\"isencrypt\", false);\n    }\n\n    public boolean isEcho() {\n        return this.sharedPref.getBoolean(\"isecho\", false);\n    }\n\n    public boolean isWakelock() {\n        return this.sharedPref.getBoolean(\"iswakelock\", false);\n    }\n\n    public boolean isAppendDeviceiduuid() {\n        return this.sharedPref.getBoolean(\"isappenddeviceiduuid\", false);\n    }\n\n    public boolean isSkipEncryptDeviceid() {\n        return this.sharedPref.getBoolean(\"isskipencryptdeviceid\", false);\n    }\n\n    public boolean isTrustAllCertificates() {\n        return this.sharedPref.getBoolean(\"istrustallcertificates\", false);\n    }\n    public boolean isAccessibilityService() {\n        return this.sharedPref.getBoolean(\"isaccessibilityservice\", false);\n    }\n    public boolean isAgreeUserAgreement(){\n        return this.sharedPref.getBoolean(\"isagreeuseragreement\", false);\n    }\n    public void setAgreeUserAgreement(boolean flag){\n        SharedPreferences.Editor edit = this.sharedPref.edit();\n        //通过editor对象写入数据\n        edit.putBoolean(\"isagreeuseragreement\",flag);\n        //提交数据存入到xml文件中\n        edit.apply();\n    }\n    public void setNumOfPush(String op){\n        SharedPreferences.Editor edit = this.sharedPref.edit();\n        if(op.equals(\"add\")){\n            int currentnum=getNumOfPush();\n            edit.putInt(\"numofpush\",currentnum++);\n            //提交数据存入到xml文件中\n            edit.apply();\n        }\n\n\n    }\n    public void setPostUrl(String url) {\n        SharedPreferences.Editor edit = this.sharedPref.edit();\n        edit.putString(\"posturl\", url);\n        //提交数据存入到xml文件中\n        edit.apply();\n    }\n\n    public  String getPostUrl(){\n        return this.sharedPref.getString(\"posturl\",null);\n    }\n    public int getNumOfPush(){\n        return this.sharedPref.getInt(\"numofpush\",0);\n    }\n    public String getEchoServer() {\n        return this.sharedPref.getString(\"echoserver\", null);\n    }\n\n    public String getEchoInterval() {\n        return this.sharedPref.getString(\"echointerval\", \"\");\n    }\n\n    public String getEncryptMethod() {\n        return this.sharedPref.getString(\"encryptmethod\", null);\n    }\n\n    public String getPasswd() {\n        return this.sharedPref.getString(\"passwd\", null);\n    }\n\n    public boolean isRemoveNotification() {\n        return this.sharedPref.getBoolean(\"isremovenotification\", false);\n    }\n\n    public boolean isPostRepeat() {\n        return this.sharedPref.getBoolean(\"ispostrepeat\", false);\n    }\n\n    public String getPostRepeatNum() {\n        return this.sharedPref.getString(\"postrepeatnum\", \"3\");\n    }\n\n    public String getCustomOption() {\n        return this.sharedPref.getString(\"custom_option\", \"\");\n    }\n    public String getEchoCustomOption() {\n        return this.sharedPref.getString(\"echo_custom_option\", \"\");\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/RandomUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\nimport java.util.Random;\n\npublic class RandomUtil {\n    public static String  getRandomTaskNum(){\n            Random rand = new Random();\n            return String.valueOf(rand.nextInt(9000) + 1000);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/SSLSocketFactoryCompat.java",
    "content": "package com.weihuagu.receiptnotice.util;\nimport android.os.Build;\n\nimport java.io.IOException;\nimport java.net.InetAddress;\nimport java.net.Socket;\nimport java.security.KeyManagementException;\nimport java.security.NoSuchAlgorithmException;\n\nimport javax.net.ssl.SSLContext;\nimport javax.net.ssl.SSLSocket;\nimport javax.net.ssl.SSLSocketFactory;\n\npublic class SSLSocketFactoryCompat extends SSLSocketFactory{\n    private static final String[] TLS_V12_ONLY = {\"TLSv1.2\"};\n\n    private final SSLSocketFactory delegate;\n\n    public SSLSocketFactoryCompat() throws KeyManagementException, NoSuchAlgorithmException {\n        SSLContext sc = SSLContext.getInstance(\"TLS\");\n        sc.init(null, null, null);\n        delegate = sc.getSocketFactory();\n    }\n\n    public SSLSocketFactoryCompat(SSLSocketFactory delegate) {\n        if (delegate == null) {\n            throw new NullPointerException();\n        }\n        this.delegate = delegate;\n    }\n    \n    @Override\n    public String[] getDefaultCipherSuites() {\n        return delegate.getDefaultCipherSuites();\n    }\n\n    @Override\n    public String[] getSupportedCipherSuites() {\n        return delegate.getSupportedCipherSuites();\n    }\n\n    private Socket enableTls12(Socket socket) {\n        if (Build.VERSION.SDK_INT >= 16 && Build.VERSION.SDK_INT < 20) {\n            if (socket instanceof SSLSocket) {\n                ((SSLSocket) socket).setEnabledProtocols(TLS_V12_ONLY);\n            }\n        }\n        return socket;\n    }\n\n    @Override\n    public Socket createSocket(Socket s, String host, int port, boolean autoClose) throws IOException {\n        return enableTls12(delegate.createSocket(s, host, port, autoClose));\n    }\n\n    @Override\n    public Socket createSocket(String host, int port) throws IOException {\n        return enableTls12(delegate.createSocket(host, port));\n    }\n\n    @Override\n    public Socket createSocket(String host, int port, InetAddress localHost, int localPort) throws IOException {\n        return enableTls12(delegate.createSocket(host, port, localHost, localPort));\n    }\n\n    @Override\n    public Socket createSocket(InetAddress host, int port) throws IOException {\n        return enableTls12(delegate.createSocket(host, port));\n    }\n\n    @Override\n    public Socket createSocket(InetAddress address, int port, InetAddress localAddress, int localPort) throws IOException {\n        return enableTls12(delegate.createSocket(address, port, localAddress, localPort));\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/UrlUtil.java",
    "content": "/*\n * Created By WeihuaGu (email:weihuagu_work@163.com)\n * Copyright (c) 2017\n * All right reserved.\n */\n\npackage com.weihuagu.receiptnotice.util;\n\npublic class UrlUtil {\n    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\"};\n    public static String [] getCommonlyUsedUrls(){\n        return commonusedurls;\n    }\n\n    public static boolean isUrl(String url) {\n        return\n                url.contains(\".\") ||\n                        url.equals(Constants.URL_ABOUT_BLANK) ||\n                        url.equals(Constants.URL_ABOUT_START) ||\n                        url.equals(Constants.URL_ABOUT_TUTORIAL);\n    }\n\n\n    public static String getSearchUrl(String searchurl,String serchcontent) {\n        return searchurl.replaceAll(\"\\\\{searchTerms\\\\}\", serchcontent);\n    }\n\n    public static String httpOrHttps(String address){\n\tif(address.startsWith(\"http://\")){\n            return \"http\";\n        }\n        if(address.startsWith(\"https://\"))\n            return \"https\";\n\n        return null;\n\n    }\n    public static String addressMatch(String address){\n\n\n        if(address.startsWith(\"jian://\")){\n            return address;\n        }\n\n        if(address.startsWith(\"alipay://\")){\n            return address;\n        }\n\n        if(address.startsWith(\"wechat://\")){\n            return address;\n        }\n\n\n        if(address.startsWith(\"http://\")){\n            return address;\n        }\n        if(address.startsWith(\"https://\"))\n            return address;\n\n        if(!address.startsWith(\"http://\")|!address.startsWith(\"https://\")) {\n            address = \"http://\" + address;\n        } // 如果不以http://开头，识别不了，所以判断\n\n\n        return address;\n    }\n    public static String addressMatchInHttps(String address){\n        if(address.startsWith(\"https://\")){\n            return address;\n\n        }\n        if(address.startsWith(\"http://\")){\n            return address.replaceAll(\"http\",\"https\");\n        }\n        else{\n            return \"https://\"+address;\n        }\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/AES.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\nimport com.weihuagu.receiptnotice.util.encrypt.Encrypter;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.Iterator;\n\npublic class AES extends Encrypter {\n        public AES(String key){\n                super(key);\n        }\n        public Map<String,String> transferMapValue(Map<String, String> params){\n                Map<String,String> postmap=new HashMap<String,String>();\n                Iterator entries = params.entrySet().iterator();\n                while (entries.hasNext()) {\n\n                        Map.Entry entry = (Map.Entry) entries.next();\n\n                        String paramkey = (String)entry.getKey();\n\n                        String paramvalue = (String)entry.getValue();\n\n                        //String aesStr = AESUtil.aes(paramvalue, key, Cipher.ENCRYPT_MODE);\n                        String aesStr=null;\n                        postmap.put(paramkey,aesStr);\n\n                }\n                postmap.put(\"encrypt\",\"1\");\n                return postmap;\n\n\n\n\n        }\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/DES.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\nimport com.weihuagu.receiptnotice.util.LogUtil;\n\nimport java.util.Map;\nimport java.util.HashMap;\nimport java.util.Iterator;\nimport javax.crypto.Cipher;\n\npublic class DES extends Encrypter{\n public DES(String key){\nsuper(key);\n}\n\n public Map<String,String> transferMapValue(Map<String, String> params){\n Map<String,String> postmap=new HashMap<String,String>();\nIterator entries = params.entrySet().iterator();\nwhile (entries.hasNext()) {\n    Map.Entry entry = (Map.Entry) entries.next();\n    String paramkey = (String)entry.getKey();\n    String paramvalue = (String)entry.getValue();\n    String desStr = DESUtilWithIV.des(paramvalue, key, Cipher.ENCRYPT_MODE);\n    postmap.put(paramkey,desStr);\n \n}\npostmap.put(\"encrypt\",\"1\");\nLogUtil.debugLogWithJava(\"调试，开始加密字符串\");\nLogUtil.debugLogWithJava(\"加密后的map\");\nLogUtil.debugLogWithJava(postmap.toString());\nreturn postmap;\n\n\n\n\n}\n\n\n\n\n\n\n\n\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/DESUtilWithIV.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\nimport android.annotation.SuppressLint;\nimport androidx.annotation.IntDef;\n\nimport com.weihuagu.receiptnotice.util.ByteUtil;\n\nimport java.io.UnsupportedEncodingException;\nimport java.security.InvalidKeyException;\nimport java.security.NoSuchAlgorithmException;\nimport java.security.spec.InvalidKeySpecException;\nimport javax.crypto.Cipher;\nimport javax.crypto.BadPaddingException;\nimport javax.crypto.IllegalBlockSizeException;\nimport javax.crypto.NoSuchPaddingException;\nimport  java.security.InvalidAlgorithmParameterException;\nimport javax.crypto.SecretKeyFactory;\nimport javax.crypto.spec.DESKeySpec;\nimport javax.crypto.spec.IvParameterSpec;\npublic class DESUtilWithIV{\n@IntDef({Cipher.ENCRYPT_MODE, Cipher.DECRYPT_MODE})\n@interface DESType {}\n /**\n     * Des加密/解密\n     *\n     * @param content  字符串内容\n     * @param password 密钥\n     * @param type     加密：{@link Cipher#ENCRYPT_MODE}，解密：{@link Cipher#DECRYPT_MODE}\n     * @return 加密/解密结果\n     */\n  \n    public static String des(String content, String password,  int type) {\n        try {\n            \n            IvParameterSpec iv = new IvParameterSpec(password.getBytes());\n            DESKeySpec desKey = new DESKeySpec(password.getBytes());\n            SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(\"DES\");\n            @SuppressLint(\"GetInstance\") Cipher cipher = Cipher.getInstance(\"DES/CBC/PKCS5Padding\");\n            cipher.init(type, keyFactory.generateSecret(desKey), iv);\n\n            if (type == Cipher.ENCRYPT_MODE) {\n                byte[] byteContent = content.getBytes(\"utf-8\");\n                return ByteUtil.parseByte2HexStr(cipher.doFinal(byteContent));\n            } else {\n                byte[] byteContent = ByteUtil.parseHexStr2Byte(content);\n                return new String(cipher.doFinal(byteContent));\n            }\n        } catch (InvalidAlgorithmParameterException | NoSuchAlgorithmException | BadPaddingException | IllegalBlockSizeException |\n                UnsupportedEncodingException | InvalidKeyException | NoSuchPaddingException |\n                InvalidKeySpecException e) {\n            e.printStackTrace();\n        }\n        return null;\n}\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/EncryptFactory.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\n\nimport com.weihuagu.receiptnotice.util.LogUtil;\n\npublic class EncryptFactory{\n        private String key;\n        public EncryptFactory(String key){\n                this.key=key;\n        }\n        public Encrypter getEncrypter(String encrypt_type){\n                if(encrypt_type.equals(\"des\"))\n                        return new DES(key);\n                if(encrypt_type.equals(\"aes\"))\n                        return new AES(key);\n                if(encrypt_type.equals(\"md5\"))\n                        return new MD5(key);\n                LogUtil.debugLog(\"没有匹配到合适的Encrypter\");\n                return null;\n\n\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/Encrypter.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\n\nimport java.util.Map;\npublic abstract class Encrypter implements IDataTrans {\nprotected String key;\npublic Encrypter(String key){\nthis.key=key;\n}\npublic Encrypter(){}\npublic abstract Map<String,String> transferMapValue(Map<String, String> params);\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/IDataTrans.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\nimport java.util.Map;                                  \npublic interface IDataTrans{\n    public Map<String,String> transferMapValue(Map<String, String> params);\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/encrypt/MD5.java",
    "content": "package com.weihuagu.receiptnotice.util.encrypt;\n\nimport com.weihuagu.receiptnotice.util.ByteUtil;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.encrypt.Encrypter;\n\nimport java.security.MessageDigest;\nimport java.util.HashMap;\nimport java.util.Map;\n\npublic class MD5 extends Encrypter {\n    public MD5(String key) {\n        super(key);\n    }\n    public MD5(){\n\n    }\n\n    public Map<String, String> transferMapValue(Map<String, String> params) {\n        if(params.get(\"type\")!=null&&params.get(\"money\")!=null&&key!=null) {\n            Map<String, String> postmap = new HashMap<String, String>();\n            postmap.putAll(params);\n            postmap.put(\"sign\", getSignMd5WithSecretkey(params.get(\"type\"), params.get(\"money\"), key));\n            LogUtil.debugLogWithJava(\"调试，sign md5\");\n            return postmap;\n        }else\n        return params;\n\n\n    }\n\n\n    public String getMd5String(String str) {\n        try {\n            byte[] bytesOfMessage = str.getBytes(\"UTF-8\");\n            MessageDigest md = MessageDigest.getInstance(\"MD5\");\n            byte[] thedigest = md.digest(bytesOfMessage);\n            return ByteUtil.parseByte2HexStr(thedigest);\n        } catch (java.io.UnsupportedEncodingException exception) {\n            return null;\n\n        } catch (java.security.NoSuchAlgorithmException exception) {\n            return null;\n        }\n\n    }\n\n    public String getSignMd5(String type, String price) {\n        String md5str=getMd5String(getMd5String(type+price));\n        LogUtil.debugLog(\"md5 string: type is\"+type+\" price is \"+ price + \"   md5str:\"+md5str);\n        return md5str;\n    }\n\n    public String getSignMd5WithSecretkey(String type, String price, String secretkey) {\n        String md5str=getMd5String(getMd5String(type+price)+secretkey);\n        return md5str;\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/message/MessageConsumer.java",
    "content": "package com.weihuagu.receiptnotice.util.message;\n\npublic interface MessageConsumer {\n    public void subMessage();\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/util/message/MessageSendBus.java",
    "content": "package com.weihuagu.receiptnotice.util.message;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.filteringmiddleware.AlipayTransferBean;\nimport com.weihuagu.receiptnotice.TestBeanWithPostFullInformationMap;\n\npublic class MessageSendBus {\n    //请求硬件模拟类\n    public static void postActionRequestWithReturn(){\n        LiveEventBus\n                .get(\"action_request_return\")\n                .post(\"return\");\n    }\n\n    public static void postActionRequestWithHome(){\n        LiveEventBus\n                .get(\"action_request_home\")\n                .post(\"home\");\n    }\n    //收到活动改变等检测信息\n    public static void postMessageWithCommonAccessibilityEvent(String event){\n        LiveEventBus.get(\"get_new_accessibilityevent\").post(event);\n    }\n\n    //消息发送类\n    public static void postMessageWithFinishedonePost(String[] returnstr){\n        LiveEventBus\n                .get(\"message_finished_one_post\")\n                .post(returnstr);\n    }\n    public static void postMessageWithReceiptAlipayTransfer(String transferinfo){\n        LiveEventBus\n                .get(\"message_noti_alipay_transfer_arrive\")\n                .post(transferinfo);\n    }\n\n    public static void postMessageWithUpdateTheLastPostString(String str){\n        LiveEventBus.get(\"update_laststr\").post(str);\n    }\n\n    public static void postMessageWithget_alipay_transfer_money(AlipayTransferBean transferbean){\n        LiveEventBus\n                .get(\"get_alipay_transfer_money\")\n                .post(transferbean);\n    }\n\n    //模型改变通知界面类\n    public static void postInterfaceMessageWithUpdateTheRecordlist(){\n        LiveEventBus\n                .get(\"update_recordlist\")\n                .post(\"update\");\n    }\n\n    //用户点击类消息\n    public static void userMessageWithSetPostUrl(String url){\n        LiveEventBus\n                .get(\"user_set_posturl\")\n                .post(url);\n    }\n\n    //测试消息类\n    public static void  postTestMessageWithPostFullInformationMap(TestBeanWithPostFullInformationMap bean){\n        LiveEventBus\n                .get(\"testmessage_post_full_information_map\")\n                .post(bean);\n    }\n\n    //时间心跳类\n\n    //默认以一定时间发送一次的时间间隔消息.时间间隔是一分钟.\n    public static void postBaseTimeInterval(){\n       LiveEventBus\n\t       .get(\"time_interval\")\n\t       .post(\"base_time_interval\");\n    }\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/FileLogActivity.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\nimport android.widget.TextView;\nimport androidx.appcompat.widget.Toolbar;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport android.view.MenuItem;\nimport android.view.Menu;\nimport android.view.MenuInflater;\nimport android.widget.Toast;\n\nimport com.weihuagu.receiptnotice.util.FileLogUtil;\nimport com.weihuagu.receiptnotice.R;\n\npublic class FileLogActivity extends AppCompatActivity {\n        private RecyclerView recyclerView;\n        private LogListAdapter mAdapter;\n        private RecyclerView.LayoutManager layoutManager;\n\n        private TextView mTextView;\n        private Toolbar myToolbar;\n        private boolean loglist_is_a_wholetext=true;\n\n        @Override\n        protected void onCreate(@Nullable Bundle savedInstanceState) {\n                super.onCreate(savedInstanceState);\n                setContentView(R.layout.activity_log);\n                initView();\n                setLogText();\n        }\n\n        private void initView(){\n                myToolbar= (Toolbar) findViewById(R.id.my_toolbar);\n                setSupportActionBar(myToolbar);\n                mTextView = (TextView) findViewById(R.id.tv_log);\n\n        }\n\n        private void initLoglistView(boolean reverseorder){\n                recyclerView = (RecyclerView) findViewById(R.id.my_recycler_view);\n                //recyclerView.setHasFixedSize(true);\n                // use a linear layout manager\n                layoutManager = new LinearLayoutManager(this);\n                recyclerView.setLayoutManager(layoutManager);\n                // specify an adapter (see also next example)\n                mAdapter = new LogListAdapter(getApplicationContext());\n                ArrayList loglist= FileLogUtil.getLogList();\n                //LogUtil.debugLogWithDeveloper(\"打印通过filelogutil获取到的file log list\");\n                if(loglist!=null&&loglist.size()>0){\n                    loglist_is_a_wholetext=false;\n                    if(reverseorder)\n                    Collections.reverse(loglist);\n                }\n                else{\n                        loglist_is_a_wholetext=true;\n                        return;\n                }\n                mAdapter.setLoglist(loglist);\n                recyclerView.setAdapter(mAdapter);\n        }\n\n\n        private void setLogText(){\n                initLoglistView(false);\n                if(loglist_is_a_wholetext){\n                    String log = FileLogUtil.readLogText();\n                    mTextView.setText(log);\n                }\n                \n        }\n\n        private void clearLog(){\n                FileLogUtil.clearLogFile();\n                setLogText();\n                Toast.makeText(getApplicationContext(), \"已经清空日志\",Toast.LENGTH_SHORT).show();\n        }\n        private void showReverse(){\n                initLoglistView(true); \n        }\n        @Override\n        public boolean onCreateOptionsMenu(Menu menu) {\n                // TODO Auto-generated method stub\n                MenuInflater inflater = getMenuInflater();\n                inflater.inflate(R.menu.log, menu);\n                return true;\n        }\n\n        @Override\n        public boolean onOptionsItemSelected(MenuItem item) {\n                switch (item.getItemId()) {\n                        case R.id.action_clearlog:\n                                // User chose the \"Settings\" item, show the app settings UI...\n                                clearLog();\n                                return true;\n                        case R.id.action_reverseshow:\n                                showReverse();\n                                return true;\n                        default:\n                                // If we got here, the user's action was not recognized.\n                                // Invoke the superclass to handle it.\n                                return super.onOptionsItemSelected(item);\n\n                }\n        }\n\n        @Override\n        protected void onResume() {\n                super.onResume();\n                setLogText();\n        }\n\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/FollowThirdAppActivity.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport android.widget.EditText;\nimport android.widget.TextView;\n\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport com.weihuagu.receiptnotice.R;\n\npublic class FollowThirdAppActivity extends AppCompatActivity {\n    private EditText pkg;\n    private EditText keyword;\n    private EditText type;\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_followthirdapp);\n    }\n    private void initView() {\n        pkg=(EditText)findViewById(R.id.pkg);\n        keyword=(EditText)findViewById(R.id.pkg);\n        type=(EditText)findViewById(R.id.pkg);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/HelloFragment.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\nimport android.widget.Toast;\n\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport androidx.lifecycle.Observer;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.R;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\n\npublic class HelloFragment extends Fragment {\n    private TextView numofpush;\n    private TextView posturl;\n    private View rootview;\n    private PreferenceUtil preference;\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        rootview=inflater.inflate(R.layout.fragment_hello,container, false);\n        return rootview;\n    }\n\n    @Override\n    public void onActivityCreated(@Nullable Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n        initView();\n        subMessage();\n    }\n\n    private void initView(){\n        preference=new PreferenceUtil(getContext());\n        numofpush=(TextView)rootview.findViewById(R.id.numofpush);\n        setTextWithNumofpush();\n        posturl=(TextView)rootview.findViewById(R.id.posturl);\n        setTextWithPosturl();\n    }\n    private void setTextWithNumofpush(){\n        numofpush.setText(\"推送次数\"+preference.getNumOfPush());\n    }\n    private void setTextWithPosturl(){\n        if(preference.getPostUrl()!=null)\n            posturl.setText(\"目前的推送地址：\"+preference.getPostUrl());\n\n    }\n    private void resetText(){\n        setTextWithPosturl();\n        setTextWithNumofpush();\n    }\n    private void subMessage(){\n        LiveEventBus\n                .get(\"message_finished_one_post\",String[].class)\n                .observeForever(new Observer<String[]>() {\n                    @Override\n                    public void onChanged(@Nullable String[] testpostbean) {\n                        resetText();\n                    }\n                });\n        LiveEventBus\n                .get(\"user_set_posturl\",String.class)\n                .observeForever(new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String url) {\n                        resetText();\n                    }\n                });\n        LiveEventBus\n                .get(\"time_interval\",String.class)\n                .observeForever(new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String baseinterval) {\n                        Toast.makeText(MainApplication.getAppContext(), \"接受到一分钟间隔事件，更新推送次数\",\n                                Toast.LENGTH_SHORT).show();\n                        LogUtil.debugLog(\"接受到一分钟一次的时间间隔事件\");\n                        resetText();\n                    }\n                });\n\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/HomeFragmentsAdapter.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\n\nimport androidx.annotation.NonNull;\nimport androidx.fragment.app.Fragment;\nimport androidx.fragment.app.FragmentActivity;\nimport androidx.viewpager2.adapter.FragmentStateAdapter;\n\nimport java.util.ArrayList;\n\npublic class HomeFragmentsAdapter extends FragmentStateAdapter {\n\n        private ArrayList<Fragment> fragmentslist = new ArrayList<>();\n        public HomeFragmentsAdapter(@NonNull FragmentActivity fragmentActivity) {\n                super(fragmentActivity);\n                fragmentslist.add(new HelloFragment());\n                fragmentslist.add(new LogListFragment());\n        }\n\n        @NonNull\n        @Override\n        public Fragment createFragment(int position) {\n                return fragmentslist.get(position);\n        }\n\n        @Override\n        public int getItemCount() {\n                return fragmentslist.size();\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/IllustrateDecryptActivity.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\nimport android.widget.TextView;\n\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.R;\n\npublic class IllustrateDecryptActivity extends AppCompatActivity {\n        private TextView text_method;\n        private TextView text_passwd;\n        private TextView text_iv;\n        private PreferenceUtil preference;\n        private void initView() {\n                text_method = (TextView) findViewById(R.id.info_text_method);\n                text_passwd = (TextView) findViewById(R.id.info_text_passwd);\n                text_iv = (TextView) findViewById(R.id.info_text_iv);\n                preference=new PreferenceUtil(getBaseContext());\n\n        }\n        @Override\n        protected void onCreate(@Nullable Bundle savedInstanceState) {\n                super.onCreate(savedInstanceState);\n                setContentView(R.layout.activity_illustratedecrypt);\n                initView();\n                setText();\n        }\n\n        private void setText(){\n                String encrypt_type=preference.getEncryptMethod(); \n                if(encrypt_type==null){\n                        text_method.setText(\"您没有设置加密方法\");\n                        return;\n                }\n                if(encrypt_type.equals(\"des\")){\n                        String method=\"DES/CBC/PKCS5Padding\";\n                        text_method.setText(\"解密的方法为:\"+method);\n                        String key=preference.getPasswd();\n                        if(key!=null){\n                                text_passwd.setText(\"解密秘钥为:\"+key+\"(des秘钥必须为8位,如果你设置的不是8位，请修改)\");\n                                text_iv.setText(\"解密的初始化向量为:\"+key);\n                        }\n                }\n                if(encrypt_type.equals(\"md5\")){\n\n                        text_method.setText(\"解密的方法为:\"+\"md5校验\");\n                        String key=preference.getPasswd();\n                        if(key!=null){\n                                text_passwd.setText(\"md5加密方法为md5(md5(price + type) + secretkey)\");\n\n                        }\n                }\n\n        }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/LogListAdapter.java",
    "content": "package com.weihuagu.receiptnotice.view;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.recyclerview.widget.RecyclerView.Adapter;\nimport android.view.LayoutInflater;\nimport android.widget.TextView;\nimport android.content.Context;\n\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.R;\n\nimport java.util.ArrayList;\npublic class LogListAdapter extends Adapter<LogListAdapter.RecyclerHolder>{\n        private final LayoutInflater mLayoutInflater;\n        private ArrayList loglist;\n       \n        LogListAdapter(Context context){\n            mLayoutInflater = LayoutInflater.from(context);\n        }\n        public void setLoglist(ArrayList loglist){\n            this.loglist=loglist;\n        }\n        @Override\n        public int getItemCount() {\n                return loglist == null ? 0 : loglist.size();\n        }\n\n\n        @Override\n        public void onBindViewHolder(RecyclerHolder holder, int position) {\n                String onerecord=(String)loglist.get(position);\n                if(holder.recordtext==null)\n                    return;\n                if(onerecord!=null)\n                    holder.recordtext.setText(onerecord);\n                else\n                    LogUtil.debugLogWithDeveloper(\"获取到的loglist 的item text为空\");\n                \n        }\n        \n        @Override\n        public RecyclerHolder onCreateViewHolder(ViewGroup parent, int viewType) {\n           return new RecyclerHolder(mLayoutInflater.inflate(R.layout.item_log_text, parent, false));\n\n        }\n\n\n\n\n\n        class RecyclerHolder extends RecyclerView.ViewHolder {\n                private TextView recordtext;\n                RecyclerHolder(View view){\n                        super(view);\n                        recordtext=view.findViewById(R.id.text_view);\n                }\n\n        }\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/LogListFragment.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.Toast;\n\nimport androidx.annotation.Nullable;\nimport androidx.fragment.app.Fragment;\nimport androidx.recyclerview.widget.LinearLayoutManager;\nimport androidx.recyclerview.widget.RecyclerView;\nimport androidx.lifecycle.Observer;\n\nimport com.jeremyliao.liveeventbus.LiveEventBus;\nimport com.weihuagu.receiptnotice.util.FileLogUtil;\nimport com.weihuagu.receiptnotice.util.LogUtil;\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.util.message.MessageConsumer;\nimport com.weihuagu.receiptnotice.R;\n\nimport java.util.ArrayList;\nimport java.util.Collections;\n\npublic class LogListFragment extends Fragment implements MessageConsumer {\n    private RecyclerView recyclerView;\n    private LogListAdapter mAdapter;\n    private ArrayList loglist;\n    private RecyclerView.LayoutManager layoutManager;\n\n    @Override\n    public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {\n        return inflater.inflate(R.layout.fragment_loglist, container, false);\n    }\n\n    @Override\n    public void onActivityCreated(@Nullable Bundle savedInstanceState) {\n        super.onActivityCreated(savedInstanceState);\n        initLoglistView(false);\n        subMessage();\n    }\n\n    private void initLoglistView(boolean reverseorder) {\n        recyclerView = (RecyclerView) getView().findViewById(R.id.my_recycler_view);\n        layoutManager = new LinearLayoutManager(getContext());\n        recyclerView.setLayoutManager(layoutManager);\n        mAdapter = new LogListAdapter(getContext());\n        loglist = FileLogUtil.getLogList();\n        if (loglist == null) {\n            loglist = new ArrayList<String>();\n            loglist.add(\"推送记录为空\");\n        }\n        //LogUtil.debugLogWithDeveloper(\"打印通过filelogutil获取到的file log list\");\n        if(reverseorder)\n            Collections.reverse(loglist);\n        mAdapter.setLoglist(loglist);\n        recyclerView.setAdapter(mAdapter);\n    }\n\n    private void clearLog() {\n        FileLogUtil.clearLogFile();\n        loglist.clear();\n        mAdapter.notifyDataSetChanged();\n        Toast.makeText(MainApplication.getAppContext(), \"已经清空日志\", Toast.LENGTH_SHORT).show();\n    }\n\n    private void showReverse() {\n        initLoglistView(true);\n    }\n\n    private void updateList() {\n        loglist.clear();\n        loglist.addAll(FileLogUtil.getLogList());\n        mAdapter.notifyDataSetChanged();\n        LogUtil.debugLog(\"更新Loglist in Fragment列表:\");\n    }\n\n    public void subMessage() {\n        LiveEventBus\n                .get(\"update_recordlist\", String.class)\n                .observe(this, new Observer<String>() {\n                    @Override\n                    public void onChanged(@Nullable String s) {\n                        LogUtil.debugLog(\"收到订阅消息:update_recordlist \" + s);\n                        updateList();\n                    }\n                });\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/MainActivity.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport androidx.appcompat.app.AlertDialog;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport android.content.Context;\nimport android.content.DialogInterface;\nimport android.view.MenuItem;\nimport android.view.Menu;\nimport android.content.SharedPreferences;\nimport android.widget.Toast;\nimport android.content.Intent;\nimport android.os.Bundle;\n\nimport androidx.core.app.NotificationManagerCompat;\n\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.AutoCompleteTextView;\n\nimport com.google.android.material.floatingactionbutton.FloatingActionButton;\n\nimport androidx.appcompat.widget.Toolbar;\n\nimport android.view.MenuInflater;\nimport android.widget.ArrayAdapter;\n\nimport androidx.viewpager2.widget.ViewPager2;\n\nimport com.github.pedrovgs.lynx.LynxConfig;\nimport com.github.pedrovgs.lynx.LynxActivity;\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.util.PreferenceUtil;\nimport com.weihuagu.receiptnotice.R;\nimport com.weihuagu.receiptnotice.util.message.MessageSendBus;\n\npublic class MainActivity extends AppCompatActivity implements View.OnClickListener {\n\n    private static final String TAG = \"MainActivity\";\n    private Toolbar myToolbar;\n    private ViewPager2 viewpage;\n    private Button btnsetposturl;\n    private FloatingActionButton btnshowlog;\n    private AutoCompleteTextView posturltextview;\n    private SharedPreferences sp;\n    public PreferenceUtil preference ;\n\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_main);\n        initView();\n        posturlSuggestion();\n\n\n    }\n\n    private void initView() {\n\n        preference = new PreferenceUtil(this);\n        sp = getSharedPreferences(\"url\", Context.MODE_PRIVATE);\n        myToolbar = (Toolbar) findViewById(R.id.my_toolbar);\n        setSupportActionBar(myToolbar);\n        ViewPager2 viewpage = findViewById(R.id.viewpager);\n        HomeFragmentsAdapter viewpageadapter = new HomeFragmentsAdapter(this);\n        viewpage.setAdapter(viewpageadapter);\n        btnsetposturl = (Button) findViewById(R.id.btnsetposturl);\n        btnsetposturl.setOnClickListener(this);\n        btnshowlog = (FloatingActionButton) findViewById(R.id.floatingshowlog);\n        btnshowlog.setOnClickListener(this);\n        posturltextview = (AutoCompleteTextView) findViewById(R.id.posturl);\n        if (getPostUrl() != null)\n            posturltextview.setHint(getPostUrl());\n\n\n    }\n\n    private void setListerner() {\n\n    }\n\n    @Override\n    protected void onResume() {\n        super.onResume();\n        boolean isAuthor = isNotificationServiceEnable();\n        if (!preference.isAgreeUserAgreement()) {\n            jumpUserAgreement();\n\n        }\n        if (!isAuthor) {\n            //直接跳转通知授权界面\n            //android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS是API 22才加入到Settings里，这里直接写死\n            startActivity(new Intent(\"android.settings.ACTION_NOTIFICATION_LISTENER_SETTINGS\"));\n        }\n\n\n    }\n\n    @Override\n    protected void onDestroy() {\n        super.onDestroy();\n    }\n\n    /**\n     * 是否已授权\n     *\n     * @return\n     */\n    private boolean isNotificationServiceEnable() {\n        return NotificationManagerCompat.getEnabledListenerPackages(this).contains(getPackageName());\n    }\n\n    @Override\n    public void onClick(View v) {\n        switch (v.getId()) {\n            case R.id.btnsetposturl:\n                posturltextview.setHint(null);\n                setPostUrl();\n                break;\n            case R.id.floatingshowlog:\n                showLog();\n                break;\n        }\n    }\n\n    private void setPostUrl() {\n        PreferenceUtil preference=new PreferenceUtil(getBaseContext());\n        preference.setPostUrl(posturltextview.getText().toString());\n        MessageSendBus.userMessageWithSetPostUrl(posturltextview.getText().toString());\n        Toast.makeText(getApplicationContext(), \"已经设置posturl为：\" + preference.getPostUrl(),\n                Toast.LENGTH_SHORT).show();\n    }\n\n    private String getPostUrl() {\n        PreferenceUtil preference=new PreferenceUtil(MainApplication.getAppContext());\n        return preference.getPostUrl();\n    }\n\n    private void jumpUserAgreement() {\n        showAgreeMentDialog();\n\n    }\n\n\n    private void posturlSuggestion() {\n        String[] str = new String[2];\n        str[0] = \"\";\n        if(getPostUrl()!=null)\n            str[1] = getPostUrl();\n        else str[1] = \"\";\n        posturltextview.setThreshold(0);\n        ArrayAdapter adapter = new ArrayAdapter<String>(getApplicationContext(), android.R.layout.simple_list_item_1, str);\n        posturltextview.setAdapter(adapter);\n        posturltextview.setOnFocusChangeListener(new View.OnFocusChangeListener() {\n            @Override\n            public void onFocusChange(View v, boolean hasFocus) {\n                AutoCompleteTextView view = (AutoCompleteTextView) v;\n                if (hasFocus) {\n                        view.showDropDown();\n\n                }\n            }\n\n        });\n        //Toast.makeText(getApplicationContext(), str[0], Toast.LENGTH_SHORT).show();\n    }\n\n\n    private void showLog() {\n        //startActivity(new Intent(this, LogActivity.class));\n        openLynxActivity();\n    }\n\n    private void openLynxActivity() {\n        LynxConfig lynxConfig = new LynxConfig();\n        lynxConfig.setMaxNumberOfTracesToShow(4000)\n                .setFilter(\"NLService\");\n\n        Intent lynxActivityIntent = LynxActivity.getIntent(this, lynxConfig);\n        startActivity(lynxActivityIntent);\n    }\n\n    private void openSettingActivity() {\n        Intent intent = new Intent(MainActivity.this, PreferenceActivity.class);\n        startActivity(intent);\n    }\n\n    @Override\n    public boolean onCreateOptionsMenu(Menu menu) {\n        // TODO Auto-generated method stub\n        MenuInflater inflater = getMenuInflater();\n        inflater.inflate(R.menu.main, menu);\n        return true;\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        switch (item.getItemId()) {\n            case R.id.action_settings:\n                // User chose the \"Settings\" item, show the app settings UI...\n                openSettingActivity();\n                return true;\n            default:\n                // If we got here, the user's action was not recognized.\n                // Invoke the superclass to handle it.\n                return super.onOptionsItemSelected(item);\n\n        }\n    }\n\n\n    private void showAgreeMentDialog() {\n        AlertDialog.Builder normalDialog =\n                new AlertDialog.Builder(MainActivity.this);\n\n        normalDialog.setTitle(\"用户协议\").setMessage(\"您必须同意该用户协议才能使用该应用。点击下方的按钮以查看完整的用户协议\");\n        normalDialog.setPositiveButton(\"查看用户协议\",\n                new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                        // ...To-do\n                        Intent intent = new Intent(getBaseContext(), UserAgreementActiviy.class);\n                        startActivity(intent);\n                    }\n                });\n        normalDialog.setNeutralButton(\"同意\",\n                new DialogInterface.OnClickListener() {\n                    @Override\n                    public void onClick(DialogInterface dialog, int which) {\n                        // ...To-do\n                        preference.setAgreeUserAgreement(true);\n                    }\n                });\n        normalDialog.setNegativeButton(\"退出\", new DialogInterface.OnClickListener() {\n            @Override\n            public void onClick(DialogInterface dialog, int which) {\n                // ...To-do\n                finish();\n            }\n        });\n        // 创建实例并显示\n        normalDialog.show();\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/PreferenceActivity.java",
    "content": "package com.weihuagu.receiptnotice.view;\nimport android.content.Intent;\nimport android.content.SharedPreferences;\nimport android.os.Bundle;\nimport android.preference.PreferenceFragment;\nimport android.provider.Settings;\n\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport com.weihuagu.receiptnotice.util.AuthorityUtil;\nimport com.weihuagu.receiptnotice.MainApplication;\nimport com.weihuagu.receiptnotice.R;\n\npublic class PreferenceActivity extends AppCompatActivity {\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        getFragmentManager().beginTransaction().replace(android.R.id.content, new GeneralPreferenceFragment()).commit();\n    }\n\n\n    public static class GeneralPreferenceFragment extends PreferenceFragment implements SharedPreferences.OnSharedPreferenceChangeListener {\n        @Override\n        public void onCreate(Bundle savedInstanceState) {\n            super.onCreate(savedInstanceState);\n            addPreferencesFromResource(R.xml.pref_general);\n        }\n\n        @Override\n        public void onSharedPreferenceChanged(SharedPreferences sharedPreferences, String s) {\n            if (s.equals(\"isaccessibilityservice\") && sharedPreferences.getBoolean(s, false) == true) {\n                if (! AuthorityUtil.isAccessibilitySettingsOn(MainApplication.getAppContext()))\n                    startActivity(new Intent(Settings.ACTION_ACCESSIBILITY_SETTINGS));\n\n            }\n        }\n\n        @Override\n        public void onResume() {\n            super.onResume();\n            // Set up a listener whenever a key changes\n            getPreferenceScreen().getSharedPreferences().registerOnSharedPreferenceChangeListener(this);\n        }\n\n        @Override\n        public void onPause() {\n            super.onPause();\n            // Set up a listener whenever a key changes\n            getPreferenceScreen().getSharedPreferences().unregisterOnSharedPreferenceChangeListener(this);\n        }\n\n\n    }\n\n\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/TestActiviy.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport android.webkit.WebView;\nimport android.widget.TextView;\n\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport com.weihuagu.receiptnotice.R;\nimport com.weihuagu.receiptnotice.ForTest;\n\n\nimport org.w3c.dom.Text;\nimport android.widget.Button;\nimport android.view.View;\n\npublic class TestActiviy extends AppCompatActivity implements View.OnClickListener{\n\n    private TextView money;\n    private Button button;\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_test);\n        money = (TextView) findViewById(R.id.money);\n        button = (Button) findViewById(R.id.action_nitification);\n        button.setOnClickListener(this);\n\n    }\n\n    @Override\n    public void onClick(View v) {\n        switch (v.getId()) {\n            case R.id.action_nitification:\n                new ForTest();\n                break;\n\n        }\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/com/weihuagu/receiptnotice/view/UserAgreementActiviy.java",
    "content": "package com.weihuagu.receiptnotice.view;\n\nimport android.os.Bundle;\nimport android.webkit.WebView;\n\nimport androidx.annotation.Nullable;\nimport androidx.appcompat.app.AppCompatActivity;\n\nimport com.weihuagu.receiptnotice.R;\n\npublic class UserAgreementActiviy extends AppCompatActivity {\n    WebView webView =null;\n\n    @Override\n    protected void onCreate(@Nullable Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_useragreement);\n        webView = (WebView) findViewById(R.id.webview);\n        webView.loadUrl(\"file:///android_asset/web/useragreement.html\");\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/drawable/ic_launcher_background.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillColor=\"#26A69A\"\n        android:pathData=\"M0,0h108v108h-108z\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M9,0L9,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,0L19,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,0L29,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,0L39,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,0L49,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,0L59,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,0L69,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,0L79,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M89,0L89,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M99,0L99,108\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,9L108,9\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,19L108,19\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,29L108,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,39L108,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,49L108,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,59L108,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,69L108,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,79L108,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,89L108,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M0,99L108,99\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,29L89,29\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,39L89,39\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,49L89,49\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,59L89,59\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,69L89,69\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M19,79L89,79\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M29,19L29,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M39,19L39,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M49,19L49,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M59,19L59,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M69,19L69,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n    <path\n        android:fillColor=\"#00000000\"\n        android:pathData=\"M79,19L79,89\"\n        android:strokeColor=\"#33FFFFFF\"\n        android:strokeWidth=\"0.8\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/drawable-v24/ic_launcher_foreground.xml",
    "content": "<vector xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:aapt=\"http://schemas.android.com/aapt\"\n    android:width=\"108dp\"\n    android:height=\"108dp\"\n    android:viewportHeight=\"108\"\n    android:viewportWidth=\"108\">\n    <path\n        android:fillType=\"evenOdd\"\n        android:pathData=\"M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\">\n        <aapt:attr name=\"android:fillColor\">\n            <gradient\n                android:endX=\"78.5885\"\n                android:endY=\"90.9159\"\n                android:startX=\"48.7653\"\n                android:startY=\"61.0927\"\n                android:type=\"linear\">\n                <item\n                    android:color=\"#44000000\"\n                    android:offset=\"0.0\" />\n                <item\n                    android:color=\"#00000000\"\n                    android:offset=\"1.0\" />\n            </gradient>\n        </aapt:attr>\n    </path>\n    <path\n        android:fillColor=\"#FFFFFF\"\n        android:fillType=\"nonZero\"\n        android:pathData=\"M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z\"\n        android:strokeColor=\"#00000000\"\n        android:strokeWidth=\"1\" />\n</vector>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_followthirdapp.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.FollowThirdAppActivity\">\n\n    <androidx.appcompat.widget.Toolbar\n        android:id=\"@+id/my_toolbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"?attr/actionBarSize\"\n        android:background=\"?attr/colorPrimary\"\n        android:elevation=\"4dp\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\" />\n\n\n\n        <LinearLayout\n            android:id=\"@+id/inputlinearlayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:focusable=\"true\"\n            android:focusableInTouchMode=\"true\"\n            android:orientation=\"vertical\"\n            app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\">\n\n            <TextView\n                android:id=\"@+id/tip_pkg\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"应用包名\" />\n            <EditText\n                android:id=\"@+id/pkg\"\n                android:layout_height=\"wrap_content\"\n                android:layout_width=\"match_parent\"\n                android:inputType=\"text\"/>\n\n            <TextView\n                android:id=\"@+id/tip_keyword\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"通知中的关键字\" />\n            <EditText\n                android:id=\"@+id/keyword\"\n                android:layout_height=\"wrap_content\"\n                android:layout_width=\"match_parent\"\n                android:inputType=\"text\"\n                app:layout_constraintTop_toBottomOf=\"@id/pkg\"/>\n\n            <TextView\n                android:id=\"@+id/tip_type\"\n                android:layout_width=\"wrap_content\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"平台名称\" />\n            <EditText\n                android:id=\"@+id/type\"\n                android:layout_height=\"wrap_content\"\n                android:layout_width=\"match_parent\"\n                android:inputType=\"text\"/>\n\n\n            <Button\n                android:id=\"@+id/btnsetthirdapp\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"@string/buttontext_setposturl\" />\n        </LinearLayout>\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_illustratedecrypt.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        xmlns:tools=\"http://schemas.android.com/tools\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\"com.weihuagu.receiptnotice.view.MainActivity\">\n        <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/my_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                android:background=\"?attr/colorPrimary\"\n                android:elevation=\"4dp\"\n                android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\"/>\n        <LinearLayout\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\"\n                android:orientation=\"vertical\">\n                <androidx.cardview.widget.CardView\n                        xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n                        android:layout_gravity=\"center\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        card_view:cardCornerRadius=\"10dp\"\n                        card_view:cardPreventCornerOverlap=\"true\"\n                        card_view:cardUseCompatPadding=\"true\"\n                        card_view:contentPadding=\"10dp\">\n                        <TextView\n                                android:id=\"@+id/info_text_method\"\n                                android:layout_width=\"match_parent\"\n                                android:layout_height=\"wrap_content\" />\n                </androidx.cardview.widget.CardView>\n                <androidx.cardview.widget.CardView\n                        xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n                        android:layout_gravity=\"center\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        card_view:cardCornerRadius=\"10dp\"\n                        card_view:cardPreventCornerOverlap=\"true\"\n                        card_view:cardUseCompatPadding=\"true\"\n                        card_view:contentPadding=\"10dp\">\n                        <TextView\n                                android:id=\"@+id/info_text_passwd\"\n                                android:layout_width=\"match_parent\"\n                                android:layout_height=\"wrap_content\" />\n                </androidx.cardview.widget.CardView>\n                <androidx.cardview.widget.CardView\n                        xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n                        android:layout_gravity=\"center\"\n                        android:layout_width=\"match_parent\"\n                        android:layout_height=\"wrap_content\"\n                        card_view:cardCornerRadius=\"10dp\"\n                        card_view:cardPreventCornerOverlap=\"true\"\n                        card_view:cardUseCompatPadding=\"true\"\n                        card_view:contentPadding=\"10dp\">\n                        <TextView\n                                android:id=\"@+id/info_text_iv\"\n                                android:layout_width=\"match_parent\"\n                                android:layout_height=\"wrap_content\" />\n                </androidx.cardview.widget.CardView>\n        </LinearLayout>\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_log.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n        xmlns:android=\"http://schemas.android.com/apk/res/android\"\n        xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n        xmlns:tools=\"http://schemas.android.com/tools\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        tools:context=\"com.weihuagu.receiptnotice.view.FileLogActivity\">\n        <androidx.appcompat.widget.Toolbar\n                android:id=\"@+id/my_toolbar\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"?attr/actionBarSize\"\n                android:background=\"?attr/colorPrimary\"\n                android:elevation=\"4dp\"\n                android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\"\n                app:layout_constraintTop_toTopOf=\"parent\"/>\n        <androidx.recyclerview.widget.RecyclerView\n                android:id=\"@+id/my_recycler_view\"\n                android:scrollbars=\"vertical\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\"/>\n        <ScrollView\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\">\n                <TextView\n                    android:id=\"@+id/tv_log\"\n                    android:layout_width=\"match_parent\"\n                    android:layout_height=\"wrap_content\" />\n        </ScrollView>\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.MainActivity\">\n\n    <androidx.appcompat.widget.Toolbar\n        android:id=\"@+id/my_toolbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"?attr/actionBarSize\"\n        android:background=\"?attr/colorPrimary\"\n        android:elevation=\"4dp\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\" />\n\n\n\n        <LinearLayout\n            android:id=\"@+id/inputlinearlayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:focusable=\"true\"\n            android:focusableInTouchMode=\"true\"\n            android:orientation=\"vertical\"\n            app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\">\n\n            <AutoCompleteTextView\n                android:id=\"@+id/posturl\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"wrap_content\"\n                android:inputType=\"textUri\"\n                android:text=\"\"></AutoCompleteTextView>\n\n            <Button\n                android:id=\"@+id/btnsetposturl\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"@string/buttontext_setposturl\" />\n        </LinearLayout>\n\n\n    <androidx.viewpager2.widget.ViewPager2\n        android:id=\"@+id/viewpager\"\n        layout_constraintBottom_toBottomOf=\"parent\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_margin=\"0dp\"\n        android:orientation=\"horizontal\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/inputlinearlayout\"\n        app:layout_constraintVertical_bias=\"0.0\"\n        tools:layout_editor_absoluteX=\"-40dp\" />\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/floatingshowlog\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"5dp\"\n        android:src=\"@drawable/log_icon\"\n        app:backgroundTint=\"@color/white\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\" />\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_test.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.MainActivity\">\n\n    <androidx.appcompat.widget.Toolbar\n        android:id=\"@+id/my_toolbar\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"?attr/actionBarSize\"\n        android:background=\"?attr/colorPrimary\"\n        android:elevation=\"4dp\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        android:theme=\"@style/ThemeOverlay.AppCompat.ActionBar\" />\n\n\n\n        <LinearLayout\n            android:id=\"@+id/inputlinearlayout\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\"\n            android:focusable=\"true\"\n            android:focusableInTouchMode=\"true\"\n            android:orientation=\"vertical\"\n            app:layout_constraintTop_toBottomOf=\"@id/my_toolbar\">\n\n            <TextView\n                android:id=\"@+id/money\"\n                android:layout_width=\"fill_parent\"\n                android:layout_height=\"wrap_content\"\n                android:inputType=\"text\"\n                android:text=\"\"></TextView>\n\n            <Button\n                android:id=\"@+id/action_nitification\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:text=\"模拟通知\" />\n        </LinearLayout>\n\n\n    <androidx.viewpager2.widget.ViewPager2\n        android:id=\"@+id/viewpager\"\n        layout_constraintBottom_toBottomOf=\"parent\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"0dp\"\n        android:layout_margin=\"0dp\"\n        android:orientation=\"horizontal\"\n        app:layout_constraintBottom_toBottomOf=\"parent\"\n        app:layout_constraintTop_toBottomOf=\"@id/inputlinearlayout\"\n        app:layout_constraintVertical_bias=\"0.0\"\n        tools:layout_editor_absoluteX=\"-40dp\" />\n\n    <com.google.android.material.floatingactionbutton.FloatingActionButton\n        android:id=\"@+id/floatingshowlog\"\n        android:layout_width=\"wrap_content\"\n        android:layout_height=\"wrap_content\"\n        android:layout_gravity=\"bottom|end\"\n        android:layout_margin=\"5dp\"\n        android:src=\"@drawable/log_icon\"\n        app:backgroundTint=\"@color/white\"\n        app:layout_constraintLeft_toLeftOf=\"parent\"\n        app:layout_constraintBottom_toBottomOf=\"parent\" />\n\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_useragreement.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.MainActivity\">\n\n\n    <WebView\n        android:id=\"@+id/webview\"\n        app:layout_constraintTop_toTopOf=\"parent\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"/>\n\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_hello.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.MainActivity\">\n\n    <androidx.cardview.widget.CardView xmlns:app=\"http://schemas.android.com/tools\"\n        xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n        android:id=\"@+id/cv_item\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"match_parent\"\n        android:layout_margin=\"8dp\"\n        card_view:cardCornerRadius=\"4dp\">\n\n        <LinearLayout\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"match_parent\"\n            android:orientation=\"vertical\">\n\n            <TextView\n                android:id=\"@+id/text_view\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:padding=\"15dp\"\n                android:text=\"@string/text_home_fragment_tip\"\n                android:textIsSelectable=\"true\" />\n\n            <TextView\n                android:id=\"@+id/text_view_next_tip\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:padding=\"20dp\"\n                android:text=\"@string/text_home_fragment_nexttip\"\n                android:textIsSelectable=\"true\"\n                android:textStyle=\"bold\"\n                app:layout_constraintAngle=\"170\"\n                app:layout_constraintCircle=\"@+id/text_view\"\n                app:layout_constraintCircleRadius=\"150dp\" />\n\t    <TextView\n                android:id=\"@+id/numofpush\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:padding=\"15dp\"\n                android:text=\"\"/>\n\t    <TextView\n                android:id=\"@+id/posturl\"\n                android:layout_width=\"match_parent\"\n                android:layout_height=\"wrap_content\"\n                android:padding=\"15dp\"\n                android:text=\"\"\n                android:textIsSelectable=\"true\" />\n\n\n        </LinearLayout>\n    </androidx.cardview.widget.CardView>\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/fragment_loglist.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.constraintlayout.widget.ConstraintLayout\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:app=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"com.weihuagu.receiptnotice.view.FileLogActivity\">\n    <androidx.recyclerview.widget.RecyclerView\n        android:id=\"@+id/my_recycler_view\"\n        android:scrollbars=\"vertical\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        app:layout_constraintTop_toTopOf=\"parent\"/>\n</androidx.constraintlayout.widget.ConstraintLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_home_viewpage_fragment.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:layout_margin=\"8dp\"\n    android:id=\"@+id/cv_item\"\n    card_view:cardCornerRadius=\"4dp\">\n\n    <TextView\n        android:id=\"@+id/text_view\"\n        android:padding=\"20dp\"\n\tandroid:textIsSelectable=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n</androidx.cardview.widget.CardView>\n"
  },
  {
    "path": "app/src/main/res/layout/item_log_text.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<androidx.cardview.widget.CardView\n    xmlns:card_view=\"http://schemas.android.com/apk/res-auto\"\n    xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"wrap_content\"\n    android:layout_margin=\"8dp\"\n    android:id=\"@+id/cv_item\"\n    card_view:cardCornerRadius=\"4dp\">\n\n    <TextView\n        android:id=\"@+id/text_view\"\n        android:padding=\"20dp\"\n\tandroid:textIsSelectable=\"true\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"/>\n</androidx.cardview.widget.CardView>\n"
  },
  {
    "path": "app/src/main/res/menu/log.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:id=\"@+id/action_clearlog\"\n    android:title=\"@string/text_clearlog\" />\n    <item android:id=\"@+id/action_reverseshow\"\n    android:title=\"@string/text_reverseshow\" />\n</menu>\n\n\n"
  },
  {
    "path": "app/src/main/res/menu/main.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<menu xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <item android:id=\"@+id/action_settings\"\n            android:title=\"@string/text_setting\" />\n</menu>\n\n\n"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<adaptive-icon xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <background android:drawable=\"@drawable/ic_launcher_background\" />\n    <foreground android:drawable=\"@drawable/ic_launcher_foreground\" />\n</adaptive-icon>"
  },
  {
    "path": "app/src/main/res/values/colors.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n    <color name=\"colorPrimary\">#3F51B5</color>\n    <color name=\"colorPrimaryDark\">#303F9F</color>\n    <color name=\"colorAccent\">#FF4081</color>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<resources>\n        <string name=\"app_name\">receiptnotice</string>\n        <string name=\"text_setting\">Setting</string>\n        <string name=\"text_clearlog\">clear log</string>\n        <string name=\"text_reverseshow\">reverse display</string>\n        <string name=\"text_home_fragment_tip\">earn tip</string>\n        <string name=\"text_home_fragment_nexttip\">swip left to receipt record</string>\n        <string name=\"filelog_title\">post record</string>\n        <string name=\"illustratedecrypt_title\">Illustrate Decrypt</string>\n        <string name=\"buttontext_setposturl\">set the post url</string>\n        <string name=\"accessibilityservicename\">receiptnotice accessibility</string>\n        <string name=\"accessibility_service_description\">receiptnotice find info by this server</string>\n        <string name=\"btnsetthirdapp\" >set the third follow app </string>\n        <string-array name=\"pref_entries_encryptmethod\">\n                <item>des</item>\n                <item>md5</item>\n        </string-array>\n\n        <string-array name=\"pref_entryvalues_encryptmethod\">\n                <item>des</item>\n                <item>md5</item>\n        </string-array>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"Theme.AppCompat.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n        <item name=\"colorPrimary\">@color/colorPrimary</item>\n        <item name=\"colorPrimaryDark\">@color/colorPrimaryDark</item>\n        <item name=\"colorAccent\">@color/colorAccent</item>\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-zh/strings.xml",
    "content": "<resources>\n        <string name=\"app_name\">接收推送</string>\n        <string name=\"filelog_title\">推送记录</string>\n        <string name=\"illustratedecrypt_title\">解密说明</string>\n        <string name=\"buttontext_setposturl\">设置post地址</string>\n        <string name=\"text_setting\">设置</string>\n        <string name=\"text_clearlog\">清空记录</string>\n        <string name=\"text_reverseshow\">逆序显示</string>\n        <string name=\"text_home_fragment_tip\">愿你赚很多钱</string>\n        <string name=\"text_home_fragment_nexttip\">左滑切换到收款记录</string>\n        <string name=\"accessibilityservicename\">receiptnotice 辅助功能</string>\n        <string name=\"accessibility_service_description\">receiptnotice 需要使用此服务来获取必要的信息</string>\n        <string name=\"btnsetthirdapp\" >设置第三方app </string>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/xml/network_security_config.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<network-security-config>\n        <base-config cleartextTrafficPermitted=\"true\" />\n</network-security-config>"
  },
  {
    "path": "app/src/main/res/xml/pref_general.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<PreferenceScreen xmlns:android=\"http://schemas.android.com/apk/res/android\" >\n        <PreferenceCategory\n                android:key=\"settings\"\n                android:summary=\"设置\"\n                android:title=\"设置\">\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"deviceid\"\n                        android:title=\"deviceid\"\n                        android:summary=\"设置deviceid来标识设备,如果不设置使用系统的Serial号码的UUID\"/>\n\t\t<CheckBoxPreference\n                        android:title=\"跳过deviceid的加密\"\n                        android:defaultValue=\"false\"\n                        android:summary=\"开启后,选择加密也不会加密deviceid\"\n                        android:key=\"isskipencryptdeviceid\" />\n                <CheckBoxPreference\n                        android:title=\"deviceid后缀UUID\"\n                        android:defaultValue=\"false\"\n                        android:summary=\"开启后会在设置的deviceid后缀UUID\"\n\t\t\tandroid:key=\"isappenddeviceiduuid\" />\n\n                <CheckBoxPreference\n                        android:title=\"加密\"\n                        android:defaultValue=\"false\"\n                        android:key=\"isencrypt\" />\n                <ListPreference\n                        android:summary=\"加密方法\"\n                        android:key=\"encryptmethod\"\n                        android:title=\"加密方法\"\n                        android:entries=\"@array/pref_entries_encryptmethod\"\n                        android:entryValues=\"@array/pref_entryvalues_encryptmethod\"\n                        >\n                </ListPreference>\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"passwd\"\n                        android:summary=\"密钥\"\n                        android:title=\"密钥\" />\n                <Preference\n                        android:title=\"解密说明\">\n                        <intent\n                                android:action=\"com.weihuagu.receiptnotice.illustratedecryptmethod\"\n                                android:category=\"android.intent.category.DEFAULT\"/>\n                </Preference>\n                <CheckBoxPreference\n                        android:title=\"wakelock\"\n                        android:defaultValue=\"false\"\n                        android:summary=\"开启wakelock能使cpu处于不休眠的状态，开启后重启手机\"\n                        android:key=\"iswakelock\" />\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"custom_option\"\n                        android:summary=\"用冒号区分键和值,多个使用分号\"\n                        android:title=\"要推送的自定义项\" />\n        </PreferenceCategory>\n        <PreferenceCategory\n                android:key=\"keep_alive\"\n                android:summary=\"报告连接\"\n                android:title=\"报告连接\">\n                <CheckBoxPreference\n                        android:title=\"是否使用socket.io echo server\"\n                        android:defaultValue=\"false\"\n                        android:key=\"isecho\" />\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"echoserver\"\n                        android:summary=\"echo socket.io 服务器\"\n                        android:title=\"echo 服务器\" />\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"echointerval\"\n                        android:summary=\"echo 间隔(秒),建议设置为15秒以上，如设置过大（如10分钟以上时），导致server频繁接到disconnect事件可以调小到不会频繁断开为止。\"\n                        android:title=\"echo 间隔\" />\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"echo_custom_option\"\n                        android:summary=\"用冒号区分键和值,多个使用分号\"\n                        android:title=\"echo时要添加的自定义项\" />\n        </PreferenceCategory>\n        <PreferenceCategory\n                android:key=\"action\"\n                android:summary=\"行为\"\n                android:title=\"行为\">\n                <CheckBoxPreference\n                        android:title=\"是否在推送后移除通知\"\n                        android:defaultValue=\"false\"\n                        android:summary=\"如果勾选，会在推送完后，清除掉这条通知栏的通知\"\n                        android:key=\"isremovenotification\" />\n                <CheckBoxPreference\n                        android:title=\"是否推送失败重复推送\"\n                        android:defaultValue=\"false\"\n                        android:key=\"ispostrepeat\" />\n                <EditTextPreference\n                        android:defaultValue=\"\"\n                        android:key=\"postrepeatnum\"\n                        android:title=\"推送失败重复次数\" />\n                <CheckBoxPreference\n                    android:title=\"是否在推送时信任私有证书\"\n                    android:defaultValue=\"false\"\n                    android:summary=\"如果勾选，会信任所有证书\"\n                    android:key=\"istrustallcertificates\" />\n                <CheckBoxPreference\n                    android:title=\"允许使用无障碍服务获取信息\"\n                    android:defaultValue=\"false\"\n                    android:summary=\"允许无障碍服务\"\n                    android:key=\"isaccessibilityservice\" />\n                <Preference\n                    android:title=\"关注自定义app通知\">\n                        <intent\n                            android:action=\"com.weihuagu.receiptnotice.followthirdapp\"\n                            android:targetClass=\"com.weihuagu.receiptnotice.view.FollowThirdAppActivity\"\n                            android:targetPackage=\"com.weihuagu.receiptnotice\"/>\n                </Preference>\n        </PreferenceCategory>\n        <PreferenceCategory\n                android:key=\"record\"\n                android:summary=\"记录\"\n                android:title=\"记录\">\n                <Preference\n                        android:title=\"推送记录\">\n                        <intent\n                                android:action=\"com.weihuagu.receiptnotice.showfilelog\"\n                                android:targetClass=\"com.weihuagu.receiptnotice.view.FileLogActivity\"\n                                android:targetPackage=\"com.weihuagu.receiptnotice\"/>\n                </Preference>\n        </PreferenceCategory>\n        <PreferenceCategory\n                android:key=\"about\"\n                android:summary=\"关于\"\n                android:title=\"关于\">\n                <Preference\n                        android:title=\"github地址\">\n                        <intent\n                                android:action=\"android.intent.action.VIEW\"\n                                android:category=\"android.intent.category.DEFAULT\"\n                                android:data=\"https://github.com/WeihuaGu/receiptnotice\"/>\n                </Preference>\n        </PreferenceCategory>\n\n\n</PreferenceScreen>\n"
  },
  {
    "path": "app/src/main/res/xml/pref_headers.xml",
    "content": "<preference-headers xmlns:android=\"http://schemas.android.com/apk/res/android\">\n    <!--启动指定PreferenceFragment-->\n    <header\n        android:fragment=\"com.weihuagu.receiptnotice.view.PreferenceActivity$GeneralPreferenceFragment\"\n         />\n\n</preference-headers>\n\n"
  },
  {
    "path": "app/src/main/res/xml/receiptnoticeaccessibilityservice_config.xml",
    "content": "<?xml version =\"1.0\" encoding =\"utf-8\"?>\n<accessibility-service xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:accessibilityEventTypes=\"typeNotificationStateChanged|typeWindowStateChanged|typeWindowContentChanged|typeWindowsChanged\"\n    android:accessibilityFeedbackType=\"feedbackGeneric\"\n    android:accessibilityFlags=\"flagDefault\"\n    android:canRetrieveWindowContent=\"true\"\n    android:description=\"@string/accessibility_service_description\"\n    android:notificationTimeout=\"100\"\n    android:packageNames=\"com.eg.android.AlipayGphone,com.tencent.mm\" />\n"
  },
  {
    "path": "app/src/test/java/com/weihuagu/receiptnotice/TestBankDistinguisher.java",
    "content": "package com.weihuagu.receiptnotice;\nimport com.weihuagu.receiptnotice.pushclassification.pmentay.BankDistinguisher;\n\nimport junit.framework.TestCase;\n\nimport org.junit.Test;\n\npublic class TestBankDistinguisher extends TestCase{\n        BankDistinguisher onedistinguisher=null;\n        protected void setUp() throws Exception {\n                        super.setUp();\n                        onedistinguisher = new BankDistinguisher();\n                }\n\n                @Test\n                public void testDistinguishByMessageContent() throws Exception{\n                        String test1= \"您尾号0345卡8月15日23:46工商银行收入(他行汇入)1,000元，余额1,000.00元。【工商银行】\";\n                        String test2= \"您尾号7865卡人民币活期07:45存入10,00.00[银联入账:（特约）京东]，可用余额1000.00。【浦发银行】\";\n                        String test3=\"【网商银行】您尾号8225的账户，于08月22日 09:32通过支付宝账户（183******13）成功转入20,000.00元。\";\n                        String test4=\"不是银行正确的胡乱测试短信\";\n                        String test5=\"【北京银行】您尾号为****的京卡于19年9月16日10:49银联入账收入1.00元。活期余额435.45元。对方账号尾号:7207。对方户名:二维码快速收款码专用\";\n                        System.out.println(\"test1 工商\");\n                        if(onedistinguisher.distinguishByMessageContent(test1)!=null)\n                                System.out.println(onedistinguisher.distinguishByMessageContent(test1));\n                        else\n                                System.out.println(\"非银行短信\");\n                        ////////////////////////////////////////\n                        System.out.println(\"test2 浦发\");\n                        if(onedistinguisher.distinguishByMessageContent(test2)!=null)\n                                System.out.println(onedistinguisher.distinguishByMessageContent(test2));\n                        else\n                                System.out.println(\"非银行短信\");\n                        ////////////////////////////////////////\n                        System.out.println(\"test3 网商\");\n                        if(onedistinguisher.distinguishByMessageContent(test3)!=null)\n                                System.out.println(onedistinguisher.distinguishByMessageContent(test3));\n                        else\n                                System.out.println(\"非银行短信\");\n                        /////////////////////////////////\n                        if(onedistinguisher.distinguishByMessageContent(test4)!=null)\n                                System.out.println(onedistinguisher.distinguishByMessageContent(test4));\n                        else\n                                System.out.println(\"非银行短信\");\n\n                        System.out.println(onedistinguisher.distinguishByMessageContent(test5));\n\n\n\n\n\n\n\n\n                }\n                @Test\n                public void testExtractMoney() throws Exception{\n                        String test1= \"您尾号0345卡8月15日23:46工商银行收入(他行汇入)1,000元，余额1,000.00元。【工商银行】\";\n                        String test2= \"您尾号7865卡人民币活期07:45存入10,00.00[银联入账:（特约）京东]，可用余额1000.00。【浦发银行】\";\n\n                        String test3=\"【网商银行】您尾号8225的账户，于08月22日 09:32通过支付宝账户（183******13）成功转入20,000.00元。\";\n                        String test4=\"不是银行正确的胡乱测试短信\";\n                        System.out.println(onedistinguisher.extractMoney(test1));\n                }\n                \n                @Test\n                public void testExtractCardNum() throws Exception{\n                         String test1= \"您尾号0345卡8月15日23:46工商银行收入(他行汇入)1,000元，余额1,000.00元。【工商银行】\";\n                        String test3=\"【网商银行】您尾号8225的账户，于08月22日 09:32通过支付宝账户（183******13）成功转入20,000.00元。\";\n                        System.out.println(onedistinguisher.extractCardNum(test1));\n                }\n\n                @Test\n                public void testExtractTime() throws Exception{\n                        String test1= \"您尾号0345卡8月15日23:46工商银行收入(他>行汇入)1,000元，余额1,000.00元。【工商银行】\";\n                        String time= \"2019-09-16 22:37:37\";\n                        System.out.println(onedistinguisher.extractTime(test1,time));\n\n\n\n\n\n\n\n\n\n                }\n\n\n\n        }\n"
  },
  {
    "path": "app/src/test/java/com/weihuagu/receiptnotice/TestDES.java",
    "content": "package com.weihuagu.receiptnotice;\nimport com.weihuagu.receiptnotice.util.encrypt.DES;\n\nimport junit.framework.TestCase;\n\nimport org.junit.Test;\n\nimport java.util.Map;\nimport java.util.HashMap;\npublic class TestDES extends TestCase{\n    DES des=null;\n    protected void setUp() throws Exception {\n        super.setUp();\n        des =new DES(\"abcd12345678\");\n    }\n\n    @Test\n    public void testTransferMapValue() throws Exception{\n        Map<String,String> postmap=new HashMap<String,String>();\n                                postmap.put(\"time\",\"2090 12 04\");\n                                postmap.put(\"title\",\"支付宝支付\");\n                                postmap.put(\"money\",\"345.56\");\n                                postmap.put(\"content\",\"测试des伪造的\");\n    \n    des.transferMapValue(postmap);\n\n\n}\n\n\n\n\n}\n"
  },
  {
    "path": "app/src/test/java/com/weihuagu/receiptnotice/TestExternalInfoUtil.java",
    "content": "package com.weihuagu.receiptnotice;\nimport com.weihuagu.receiptnotice.util.ExternalInfoUtil;\n\nimport junit.framework.TestCase;\n\nimport org.junit.Test;\n\nimport java.util.Map;\nimport java.util.HashMap;\n\npublic class TestExternalInfoUtil extends TestCase{\n        protected void setUp() throws Exception {\n                super.setUp();\n        }\n\n        @Test\n        public void testGetCustomPostOption() throws Exception{\n\n                String test=\"test1-test1value;test2:test2vvalue;test3:test3value\";\n                Map map1 = new HashMap();      //定义Map集合对象\n                map1.put(\"apple\", \"新鲜的苹果\");     //向集合中添加对象\n                map1.put(\"computer\", \"配置优良的计算机\");\n                map1.put(\"book\", \"堆积成山的图书\");\n                Map haha= ExternalInfoUtil.getCustomPostOption(test);\n                map1.putAll(haha);\n                System.out.println(map1.toString());\n        }\n\n\n\n}\n"
  },
  {
    "path": "app/src/test/java/com/weihuagu/receiptnotice/TestOneFileUtil.java",
    "content": "package com.weihuagu.receiptnotice;\nimport com.weihuagu.receiptnotice.util.OneFileUtil;\n\nimport junit.framework.TestCase;\n\nimport org.junit.Test;\n\npublic class TestOneFileUtil extends TestCase{\n    OneFileUtil onefile=null;\n    protected void setUp() throws Exception {\n        super.setUp();\n       //File testlog=new File(this.getClass().getResource(\"/testlog\").getFile());\n       //onefile =new OneFileUtil(testlog);\n    }\n\n    @Test\n    public void testGetFileList() throws Exception{\n       // ArrayList filelist=onefile.getFileList();\n       // ArrayList filemergelist=onefile.mergeByFlagline(\"*********************************\",\"------------------------------------------\",filelist);\n       // System.out.println(\"test log file is:\"+this.getClass().getResource(\"/testlog\").toString());\n       // System.out.println(filemergelist.toString());\n\n\n    }\n\n\n\n\n}\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    \n    repositories {\n        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }\n        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }\n        jcenter()\n        google()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:3.5.2'\n        \n\n        // NOTE: Do not place your application dependencies here; they belong\n        // in the individual module build.gradle files\n    }\n}\n\nallprojects {\n    repositories {\n        maven { url 'http://maven.aliyun.com/nexus/content/groups/public/' }\n        maven { url 'http://maven.aliyun.com/nexus/content/repositories/google' }\n        jcenter()\n        maven { url 'https://jitpack.io' }\n        google()\n    }\n}\n\ntask clean(type: Delete) {\n    delete rootProject.buildDir\n}\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Thu Dec 05 09:29:01 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-5.4.1-all.zip\n"
  },
  {
    "path": "gradle.properties",
    "content": "# Project-wide Gradle settings.\n\n# IDE (e.g. Android Studio) users:\n# Gradle settings configured through the IDE *will override*\n# any settings specified in this file.\n\n# For more details on how to configure your build environment visit\n# http://www.gradle.org/docs/current/userguide/build_environment.html\n\n# Specifies the JVM arguments used for the daemon process.\n# The setting is particularly useful for tweaking memory settings.\norg.gradle.jvmargs=-Xmx1536m\n\n# When configured, Gradle will run in incubating parallel mode.\n# This option should only be used with decoupled projects. More details, visit\n# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\n# org.gradle.parallel=true\n\n#如果进行安卓单元测试出现DexArchiveBuilderException\n#android.enableD8=true\nandroid.useAndroidX=true\nandroid.enableJetifier=true"
  },
  {
    "path": "gradlew",
    "content": "#!/usr/bin/env bash\n\n##############################################################################\n##\n##  Gradle start up script for UN*X\n##\n##############################################################################\n\n# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nDEFAULT_JVM_OPTS=\"\"\n\nAPP_NAME=\"Gradle\"\nAPP_BASE_NAME=`basename \"$0\"`\n\n# Use the maximum available, or set MAX_FD != -1 to use that value.\nMAX_FD=\"maximum\"\n\nwarn ( ) {\n    echo \"$*\"\n}\n\ndie ( ) {\n    echo\n    echo \"$*\"\n    echo\n    exit 1\n}\n\n# OS specific support (must be 'true' or 'false').\ncygwin=false\nmsys=false\ndarwin=false\ncase \"`uname`\" in\n  CYGWIN* )\n    cygwin=true\n    ;;\n  Darwin* )\n    darwin=true\n    ;;\n  MINGW* )\n    msys=true\n    ;;\nesac\n\n# Attempt to set APP_HOME\n# Resolve links: $0 may be a link\nPRG=\"$0\"\n# Need this for relative symlinks.\nwhile [ -h \"$PRG\" ] ; do\n    ls=`ls -ld \"$PRG\"`\n    link=`expr \"$ls\" : '.*-> \\(.*\\)$'`\n    if expr \"$link\" : '/.*' > /dev/null; then\n        PRG=\"$link\"\n    else\n        PRG=`dirname \"$PRG\"`\"/$link\"\n    fi\ndone\nSAVED=\"`pwd`\"\ncd \"`dirname \\\"$PRG\\\"`/\" >/dev/null\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >/dev/null\n\nCLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar\n\n# Determine the Java command to use to start the JVM.\nif [ -n \"$JAVA_HOME\" ] ; then\n    if [ -x \"$JAVA_HOME/jre/sh/java\" ] ; then\n        # IBM's JDK on AIX uses strange locations for the executables\n        JAVACMD=\"$JAVA_HOME/jre/sh/java\"\n    else\n        JAVACMD=\"$JAVA_HOME/bin/java\"\n    fi\n    if [ ! -x \"$JAVACMD\" ] ; then\n        die \"ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\n    fi\nelse\n    JAVACMD=\"java\"\n    which java >/dev/null 2>&1 || die \"ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\n\nPlease set the JAVA_HOME variable in your environment to match the\nlocation of your Java installation.\"\nfi\n\n# Increase the maximum file descriptors if we can.\nif [ \"$cygwin\" = \"false\" -a \"$darwin\" = \"false\" ] ; then\n    MAX_FD_LIMIT=`ulimit -H -n`\n    if [ $? -eq 0 ] ; then\n        if [ \"$MAX_FD\" = \"maximum\" -o \"$MAX_FD\" = \"max\" ] ; then\n            MAX_FD=\"$MAX_FD_LIMIT\"\n        fi\n        ulimit -n $MAX_FD\n        if [ $? -ne 0 ] ; then\n            warn \"Could not set maximum file descriptor limit: $MAX_FD\"\n        fi\n    else\n        warn \"Could not query maximum file descriptor limit: $MAX_FD_LIMIT\"\n    fi\nfi\n\n# For Darwin, add options to specify how the application appears in the dock\nif $darwin; then\n    GRADLE_OPTS=\"$GRADLE_OPTS \\\"-Xdock:name=$APP_NAME\\\" \\\"-Xdock:icon=$APP_HOME/media/gradle.icns\\\"\"\nfi\n\n# For Cygwin, switch paths to Windows format before running java\nif $cygwin ; then\n    APP_HOME=`cygpath --path --mixed \"$APP_HOME\"`\n    CLASSPATH=`cygpath --path --mixed \"$CLASSPATH\"`\n    JAVACMD=`cygpath --unix \"$JAVACMD\"`\n\n    # We build the pattern for arguments to be converted via cygpath\n    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`\n    SEP=\"\"\n    for dir in $ROOTDIRSRAW ; do\n        ROOTDIRS=\"$ROOTDIRS$SEP$dir\"\n        SEP=\"|\"\n    done\n    OURCYGPATTERN=\"(^($ROOTDIRS))\"\n    # Add a user-defined pattern to the cygpath arguments\n    if [ \"$GRADLE_CYGPATTERN\" != \"\" ] ; then\n        OURCYGPATTERN=\"$OURCYGPATTERN|($GRADLE_CYGPATTERN)\"\n    fi\n    # Now convert the arguments - kludge to limit ourselves to /bin/sh\n    i=0\n    for arg in \"$@\" ; do\n        CHECK=`echo \"$arg\"|egrep -c \"$OURCYGPATTERN\" -`\n        CHECK2=`echo \"$arg\"|egrep -c \"^-\"`                                 ### Determine if an option\n\n        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition\n            eval `echo args$i`=`cygpath --path --ignore --mixed \"$arg\"`\n        else\n            eval `echo args$i`=\"\\\"$arg\\\"\"\n        fi\n        i=$((i+1))\n    done\n    case $i in\n        (0) set -- ;;\n        (1) set -- \"$args0\" ;;\n        (2) set -- \"$args0\" \"$args1\" ;;\n        (3) set -- \"$args0\" \"$args1\" \"$args2\" ;;\n        (4) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" ;;\n        (5) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" ;;\n        (6) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" ;;\n        (7) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" ;;\n        (8) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" ;;\n        (9) set -- \"$args0\" \"$args1\" \"$args2\" \"$args3\" \"$args4\" \"$args5\" \"$args6\" \"$args7\" \"$args8\" ;;\n    esac\nfi\n\n# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules\nfunction splitJvmOpts() {\n    JVM_OPTS=(\"$@\")\n}\neval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS\nJVM_OPTS[${#JVM_OPTS[*]}]=\"-Dorg.gradle.appname=$APP_BASE_NAME\"\n\nexec \"$JAVACMD\" \"${JVM_OPTS[@]}\" -classpath \"$CLASSPATH\" org.gradle.wrapper.GradleWrapperMain \"$@\"\n"
  },
  {
    "path": "gradlew.bat",
    "content": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem  Gradle startup script for Windows\n@rem\n@rem ##########################################################################\n\n@rem Set local scope for the variables with windows NT shell\nif \"%OS%\"==\"Windows_NT\" setlocal\n\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\nset DEFAULT_JVM_OPTS=\n\nset DIRNAME=%~dp0\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\nset APP_BASE_NAME=%~n0\nset APP_HOME=%DIRNAME%\n\n@rem Find java.exe\nif defined JAVA_HOME goto findJavaFromJavaHome\n\nset JAVA_EXE=java.exe\n%JAVA_EXE% -version >NUL 2>&1\nif \"%ERRORLEVEL%\" == \"0\" goto init\n\necho.\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:findJavaFromJavaHome\nset JAVA_HOME=%JAVA_HOME:\"=%\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\n\nif exist \"%JAVA_EXE%\" goto init\n\necho.\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\necho.\necho Please set the JAVA_HOME variable in your environment to match the\necho location of your Java installation.\n\ngoto fail\n\n:init\n@rem Get command-line arguments, handling Windowz variants\n\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\n\n:win9xME_args\n@rem Slurp the command line arguments.\nset CMD_LINE_ARGS=\nset _SKIP=2\n\n:win9xME_args_slurp\nif \"x%~1\" == \"x\" goto execute\n\nset CMD_LINE_ARGS=%*\ngoto execute\n\n:4NT_args\n@rem Get arguments from the 4NT Shell from JP Software\nset CMD_LINE_ARGS=%$\n\n:execute\n@rem Setup the command line\n\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\n\n@rem Execute Gradle\n\"%JAVA_EXE%\" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% \"-Dorg.gradle.appname=%APP_BASE_NAME%\" -classpath \"%CLASSPATH%\" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\n\n:end\n@rem End local scope for the variables with windows NT shell\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\n\n:fail\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\nrem the _cmd.exe /c_ return code!\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\nexit /b 1\n\n:mainEnd\nif \"%OS%\"==\"Windows_NT\" endlocal\n\n:omega\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app'\n"
  }
]