[
  {
    "path": ".gitignore",
    "content": ".gradle\n/local.properties\n/.idea/workspace.xml\n/.idea/libraries\n.DS_Store\n/build\n/captures\n"
  },
  {
    "path": ".idea/.name",
    "content": "KAndroid"
  },
  {
    "path": ".idea/compiler.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"CompilerConfiguration\">\n    <resourceExtensions />\n    <wildcardResourcePatterns>\n      <entry name=\"!?*.java\" />\n      <entry name=\"!?*.form\" />\n      <entry name=\"!?*.class\" />\n      <entry name=\"!?*.groovy\" />\n      <entry name=\"!?*.scala\" />\n      <entry name=\"!?*.flex\" />\n      <entry name=\"!?*.kt\" />\n      <entry name=\"!?*.clj\" />\n    </wildcardResourcePatterns>\n    <annotationProcessing>\n      <profile default=\"true\" name=\"Default\" enabled=\"false\">\n        <processorPath useClasspath=\"true\" />\n      </profile>\n    </annotationProcessing>\n  </component>\n</project>"
  },
  {
    "path": ".idea/copyright/Copyright_Header.xml",
    "content": "<component name=\"CopyrightManager\">\n  <copyright>\n    <option name=\"myName\" value=\"Copyright Header\" />\n    <option name=\"notice\" value=\"Copyright (C) &amp;#36;today.year. Keegan小钢（http://keeganlee.me）&#10; &#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10; &#10;    http://www.apache.org/licenses/LICENSE-2.0&#10; &#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License. \" />\n  </copyright>\n</component>"
  },
  {
    "path": ".idea/copyright/profiles_settings.xml",
    "content": "<component name=\"CopyrightManager\">\n  <settings default=\"Copyright Header\">\n    <module2copyright>\n      <element module=\"All\" copyright=\"Copyright Header\" />\n    </module2copyright>\n  </settings>\n</component>"
  },
  {
    "path": ".idea/dictionaries/keegan.xml",
    "content": "<component name=\"ProjectDictionaryState\">\n  <dictionary name=\"keegan\" />\n</component>"
  },
  {
    "path": ".idea/gradle.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"GradleSettings\">\n    <option name=\"linkedExternalProjectsSettings\">\n      <GradleProjectSettings>\n        <option name=\"distributionType\" value=\"LOCAL\" />\n        <option name=\"externalProjectPath\" value=\"$PROJECT_DIR$\" />\n        <option name=\"gradleHome\" value=\"$APPLICATION_HOME_DIR$/gradle/gradle-2.4\" />\n        <option name=\"gradleJvm\" value=\"1.7\" />\n        <option name=\"modules\">\n          <set>\n            <option value=\"$PROJECT_DIR$\" />\n            <option value=\"$PROJECT_DIR$/api\" />\n            <option value=\"$PROJECT_DIR$/app\" />\n            <option value=\"$PROJECT_DIR$/core\" />\n            <option value=\"$PROJECT_DIR$/model\" />\n          </set>\n        </option>\n      </GradleProjectSettings>\n    </option>\n  </component>\n</project>"
  },
  {
    "path": ".idea/inspectionProfiles/Project_Default.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <profile version=\"1.0\">\n    <option name=\"myName\" value=\"Project Default\" />\n    <option name=\"myLocal\" value=\"true\" />\n    <inspection_tool class=\"LoggerInitializedWithForeignClass\" enabled=\"false\" level=\"WARNING\" enabled_by_default=\"false\">\n      <option name=\"loggerClassName\" value=\"org.apache.log4j.Logger,org.slf4j.LoggerFactory,org.apache.commons.logging.LogFactory,java.util.logging.Logger\" />\n      <option name=\"loggerFactoryMethodName\" value=\"getLogger,getLogger,getLog,getLogger\" />\n    </inspection_tool>\n  </profile>\n</component>"
  },
  {
    "path": ".idea/inspectionProfiles/profiles_settings.xml",
    "content": "<component name=\"InspectionProjectProfileManager\">\n  <settings>\n    <option name=\"PROJECT_PROFILE\" value=\"Project Default\" />\n    <option name=\"USE_PROJECT_PROFILE\" value=\"true\" />\n    <version value=\"1.0\" />\n  </settings>\n</component>"
  },
  {
    "path": ".idea/misc.xml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<project version=\"4\">\n  <component name=\"EntryPointsManager\">\n    <entry_points version=\"2.0\" />\n  </component>\n  <component name=\"NullableNotNullManager\">\n    <option name=\"myDefaultNullable\" value=\"android.support.annotation.Nullable\" />\n    <option name=\"myDefaultNotNull\" value=\"android.support.annotation.NonNull\" />\n    <option name=\"myNullables\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.Nullable\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nullable\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.Nullable\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.Nullable\" />\n        </list>\n      </value>\n    </option>\n    <option name=\"myNotNulls\">\n      <value>\n        <list size=\"4\">\n          <item index=\"0\" class=\"java.lang.String\" itemvalue=\"org.jetbrains.annotations.NotNull\" />\n          <item index=\"1\" class=\"java.lang.String\" itemvalue=\"javax.annotation.Nonnull\" />\n          <item index=\"2\" class=\"java.lang.String\" itemvalue=\"edu.umd.cs.findbugs.annotations.NonNull\" />\n          <item index=\"3\" class=\"java.lang.String\" itemvalue=\"android.support.annotation.NonNull\" />\n        </list>\n      </value>\n    </option>\n  </component>\n  <component name=\"ProjectInspectionProfilesVisibleTreeState\">\n    <entry key=\"Project Default\">\n      <profile-state>\n        <expanded-state>\n          <State>\n            <id />\n          </State>\n          <State>\n            <id>Java</id>\n          </State>\n          <State>\n            <id>Security issuesJava</id>\n          </State>\n          <State>\n            <id>Serialization issuesJava</id>\n          </State>\n        </expanded-state>\n        <selected-state>\n          <State>\n            <id>SerializableHasSerialVersionUIDField</id>\n          </State>\n        </selected-state>\n      </profile-state>\n    </entry>\n  </component>\n  <component name=\"ProjectLevelVcsManager\" settingsEditedManually=\"false\">\n    <OptionsSetting value=\"true\" id=\"Add\" />\n    <OptionsSetting value=\"true\" id=\"Remove\" />\n    <OptionsSetting value=\"true\" id=\"Checkout\" />\n    <OptionsSetting value=\"true\" id=\"Update\" />\n    <OptionsSetting value=\"true\" id=\"Status\" />\n    <OptionsSetting value=\"true\" id=\"Edit\" />\n    <ConfirmationsSetting value=\"0\" id=\"Add\" />\n    <ConfirmationsSetting value=\"0\" id=\"Remove\" />\n  </component>\n  <component name=\"ProjectRootManager\" version=\"2\" languageLevel=\"JDK_1_7\" assert-keyword=\"true\" jdk-15=\"true\" project-jdk-name=\"1.7\" 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$/KAndroid.iml\" filepath=\"$PROJECT_DIR$/KAndroid.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/api/api.iml\" filepath=\"$PROJECT_DIR$/api/api.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/app/app.iml\" filepath=\"$PROJECT_DIR$/app/app.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/core/core.iml\" filepath=\"$PROJECT_DIR$/core/core.iml\" />\n      <module fileurl=\"file://$PROJECT_DIR$/model/model.iml\" filepath=\"$PROJECT_DIR$/model/model.iml\" />\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=\"\" />\n    <mapping directory=\"$PROJECT_DIR$\" vcs=\"Git\" />\n  </component>\n</project>"
  },
  {
    "path": "KAndroid.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\"KAndroid\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$\" external.system.id=\"GRADLE\" external.system.module.group=\"\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"java-gradle\" name=\"Java-Gradle\">\n      <configuration>\n        <option name=\"BUILD_FOLDER_PATH\" value=\"$MODULE_DIR$/build\" />\n        <option name=\"BUILDABLE\" value=\"false\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_7\" inherit-compiler-output=\"true\">\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <excludeFolder url=\"file://$MODULE_DIR$/.gradle\" />\n    </content>\n    <orderEntry type=\"inheritedJdk\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n  </component>\n</module>"
  },
  {
    "path": "README.md",
    "content": "# kandroid\nKAndroid是一个Android的简单的架构搭建的学习项目。架构上分为了四个层级：模型层、接口层、核心层和应用层。\n四个层级对应的module为：model、api、core和app。\n\n详细的内容可查看博客文章：\n\n[Android项目重构之路:架构篇](http://keeganlee.me/post/android/20150605)\n\n[Android项目重构之路:界面篇](http://keeganlee.me/post/android/20150619)\n\n[Android项目重构之路:实现篇](http://keeganlee.me/post/android/20150629)\n\n"
  },
  {
    "path": "api/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "api/api.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":api\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$/..\" external.system.id=\"GRADLE\" external.system.module.group=\"KAndroid\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"GRADLE_PROJECT_PATH\" value=\":api\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"SELECTED_TEST_ARTIFACT\" value=\"_android_test_\" />\n        <option name=\"ASSEMBLE_TASK_NAME\" value=\"assembleDebug\" />\n        <option name=\"COMPILE_JAVA_TASK_NAME\" value=\"compileDebugSources\" />\n        <option name=\"ASSEMBLE_TEST_TASK_NAME\" value=\"assembleDebugAndroidTest\" />\n        <option name=\"COMPILE_JAVA_TEST_TASK_NAME\" value=\"compileDebugAndroidTestSources\" />\n        <afterSyncTasks>\n          <task>generateDebugAndroidTestSources</task>\n          <task>generateDebugSources</task>\n        </afterSyncTasks>\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/src/main/res\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n        <option name=\"LIBRARY_PROJECT\" value=\"true\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_7\" inherit-compiler-output=\"false\">\n    <output url=\"file://$MODULE_DIR$/build/intermediates/classes/debug\" />\n    <output-test url=\"file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/jni\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/rs\" isTestSource=\"true\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/assets\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/bundles\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dependency-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/incremental\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/jacoco\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/javaResources\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/libs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/lint\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/manifests\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/ndk\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/pre-dexed\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/proguard\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/res\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/rs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/symbols\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/outputs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/tmp\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 22 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-v4-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-annotations-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"appcompat-v7-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"gson-2.3\" level=\"project\" />\n    <orderEntry type=\"module\" module-name=\"model\" exported=\"\" />\n  </component>\n</module>"
  },
  {
    "path": "api/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 22\n    buildToolsVersion \"22.0.0\"\n\n    defaultConfig {\n        minSdkVersion 11\n        targetSdkVersion 22\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:22.0.0'\n    compile 'com.google.code.gson:gson:2.3'\n    compile project(':model')\n}\n"
  },
  {
    "path": "api/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/keegan/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "api/src/androidTest/java/me/keeganlee/kandroid/api/ApplicationTest.java",
    "content": "package me.keeganlee.kandroid.api;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "api/src/main/AndroidManifest.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.keeganlee.kandroid.api\">\n\n    <application android:allowBackup=\"true\" android:label=\"@string/app_name\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "api/src/main/java/me/keeganlee/kandroid/api/Api.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.api;\n\nimport me.keeganlee.kandroid.model.CouponBO;\n\nimport java.util.List;\n\n/**\n * Api接口\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic interface Api {\n    // 发送验证码\n    public final static String SEND_SMS_CODE = \"service.sendSmsCode4Register\";\n    // 注册\n    public final static String REGISTER = \"customer.registerByPhone\";\n    // 登录\n    public final static String LOGIN = \"customer.loginByApp\";\n    // 券列表\n    public final static String LIST_COUPON = \"issue.listNewCoupon\";\n\n    /**\n     * 发送验证码\n     *\n     * @param phoneNum 手机号码\n     * @return 成功时返回：{ \"code\": 0, \"msg\":\"success\" }\n     */\n    public ApiResponse<Void> sendSmsCode4Register(String phoneNum);\n\n    /**\n     * 注册\n     *\n     * @param phoneNum 手机号码\n     * @param code     验证码\n     * @param password MD5加密的密码\n     * @return 成功时返回：{ \"code\": 0, \"msg\":\"success\" }\n     */\n    public ApiResponse<Void> registerByPhone(String phoneNum, String code, String password);\n\n    /**\n     * 登录\n     *\n     * @param loginName 登录名（手机号）\n     * @param password  MD5加密的密码\n     * @param imei      手机IMEI串号\n     * @param loginOS   Android为1\n     * @return 成功时返回：{ \"code\": 0, \"msg\":\"success\" }\n     */\n    public ApiResponse<Void> loginByApp(String loginName, String password, String imei, int loginOS);\n\n    /**\n     * 券列表\n     *\n     * @param currentPage 当前页数\n     * @param pageSize    每页显示数量\n     * @return 成功时返回：{ \"code\": 0, \"msg\":\"success\", \"objList\":[...] }\n     */\n    public ApiResponse<List<CouponBO>> listNewCoupon(int currentPage, int pageSize);\n}\n"
  },
  {
    "path": "api/src/main/java/me/keeganlee/kandroid/api/ApiImpl.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.api;\n\nimport com.google.gson.reflect.TypeToken;\nimport me.keeganlee.kandroid.api.net.HttpEngine;\nimport me.keeganlee.kandroid.api.utils.EncryptUtil;\nimport me.keeganlee.kandroid.model.CouponBO;\n\nimport java.io.IOException;\nimport java.lang.reflect.Type;\nimport java.util.HashMap;\nimport java.util.List;\nimport java.util.Map;\n\n/**\n * Api实现类\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic class ApiImpl implements Api {\n    private final static String APP_KEY = \"ANDROID_KCOUPON\";\n    private final static String TIME_OUT_EVENT = \"CONNECT_TIME_OUT\";\n    private final static String TIME_OUT_EVENT_MSG = \"连接服务器失败\";\n\n    private HttpEngine httpEngine;\n\n    public ApiImpl() {\n        httpEngine = HttpEngine.getInstance();\n    }\n\n    @Override\n    public ApiResponse<Void> sendSmsCode4Register(String phoneNum) {\n        Map<String, String> paramMap = new HashMap<String, String>();\n        paramMap.put(\"appKey\", APP_KEY);\n        paramMap.put(\"method\", SEND_SMS_CODE);\n        paramMap.put(\"phoneNum\", phoneNum);\n\n        Type type = new TypeToken<ApiResponse<Void>>(){}.getType();\n        try {\n            return httpEngine.postHandle(paramMap, type);\n        } catch (IOException e) {\n            return new ApiResponse(TIME_OUT_EVENT, TIME_OUT_EVENT_MSG);\n        }\n    }\n\n    @Override\n    public ApiResponse<Void> registerByPhone(String phoneNum, String code, String password) {\n        Map<String, String> paramMap = new HashMap<String, String>();\n        paramMap.put(\"appKey\", APP_KEY);\n        paramMap.put(\"method\", REGISTER);\n        paramMap.put(\"phoneNum\", phoneNum);\n        paramMap.put(\"code\", code);\n        paramMap.put(\"password\", EncryptUtil.makeMD5(password));\n\n        Type type = new TypeToken<ApiResponse<List<CouponBO>>>(){}.getType();\n        try {\n            return httpEngine.postHandle(paramMap, type);\n        } catch (IOException e) {\n            return new ApiResponse(TIME_OUT_EVENT, TIME_OUT_EVENT_MSG);\n        }\n    }\n\n    @Override\n    public ApiResponse<Void> loginByApp(String loginName, String password, String imei, int loginOS) {\n        Map<String, String> paramMap = new HashMap<String, String>();\n        paramMap.put(\"appKey\", APP_KEY);\n        paramMap.put(\"method\", LOGIN);\n        paramMap.put(\"loginName\", loginName);\n        paramMap.put(\"password\", EncryptUtil.makeMD5(password));\n        paramMap.put(\"imei\", imei);\n        paramMap.put(\"loginOS\", String.valueOf(loginOS));\n\n        Type type = new TypeToken<ApiResponse<List<CouponBO>>>(){}.getType();\n        try {\n            return httpEngine.postHandle(paramMap, type);\n        } catch (IOException e) {\n            return new ApiResponse(TIME_OUT_EVENT, TIME_OUT_EVENT_MSG);\n        }\n    }\n\n    @Override\n    public ApiResponse<List<CouponBO>> listNewCoupon(int currentPage, int pageSize) {\n        Map<String, String> paramMap = new HashMap<String, String>();\n        paramMap.put(\"appKey\", APP_KEY);\n        paramMap.put(\"method\", LIST_COUPON);\n        paramMap.put(\"currentPage\", String.valueOf(currentPage));\n        paramMap.put(\"pageSize\", String.valueOf(pageSize));\n\n        Type type = new TypeToken<ApiResponse<List<CouponBO>>>(){}.getType();\n        try {\n            return httpEngine.postHandle(paramMap, type);\n        } catch (IOException e) {\n            return new ApiResponse(TIME_OUT_EVENT, TIME_OUT_EVENT_MSG);\n        }\n    }\n\n}\n"
  },
  {
    "path": "api/src/main/java/me/keeganlee/kandroid/api/ApiResponse.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.api;\n\n/**\n * Api响应结果的封装类.\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic class ApiResponse<T> {\n    private String event;    // 返回码，0为成功\n    private String msg;      // 返回信息\n    private T obj;           // 单个对象\n    private T objList;       // 数组对象\n    private int currentPage; // 当前页数\n    private int pageSize;    // 每页显示数量\n    private int maxCount;    // 总条数\n    private int maxPage;     // 总页数\n\n    public ApiResponse(String event, String msg) {\n        this.event = event;\n        this.msg = msg;\n    }\n\n    public boolean isSuccess() {\n        return event.equals(\"0\");\n    }\n\n    public String getEvent() {\n        return event;\n    }\n\n    public void setEvent(String event) {\n        this.event = event;\n    }\n\n    public String getMsg() {\n        return msg;\n    }\n\n    public void setMsg(String msg) {\n        this.msg = msg;\n    }\n\n    public T getObj() {\n        return obj;\n    }\n\n    public void setObj(T obj) {\n        this.obj = obj;\n    }\n\n    public T getObjList() {\n        return objList;\n    }\n\n    public void setObjList(T objList) {\n        this.objList = objList;\n    }\n\n    public int getCurrentPage() {\n        return currentPage;\n    }\n\n    public void setCurrentPage(int currentPage) {\n        this.currentPage = currentPage;\n    }\n\n    public int getPageSize() {\n        return pageSize;\n    }\n\n    public void setPageSize(int pageSize) {\n        this.pageSize = pageSize;\n    }\n\n    public int getMaxCount() {\n        return maxCount;\n    }\n\n    public void setMaxCount(int maxCount) {\n        this.maxCount = maxCount;\n    }\n\n    public int getMaxPage() {\n        return maxPage;\n    }\n\n    public void setMaxPage(int maxPage) {\n        this.maxPage = maxPage;\n    }\n}\n"
  },
  {
    "path": "api/src/main/java/me/keeganlee/kandroid/api/net/HttpEngine.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.api.net;\n\nimport android.util.Log;\n\nimport com.google.gson.Gson;\n\nimport java.io.ByteArrayOutputStream;\nimport java.io.IOException;\nimport java.io.InputStream;\nimport java.io.OutputStream;\nimport java.io.UnsupportedEncodingException;\nimport java.lang.reflect.Type;\nimport java.net.HttpURLConnection;\nimport java.net.URL;\nimport java.net.URLEncoder;\nimport java.util.Map;\n\n/**\n * Http引擎处理类\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic class HttpEngine {\n    private final static String TAG = \"HttpEngine\";\n    private final static String SERVER_URL = \"http://domain.com/platform/api\";\n    private final static String REQUEST_MOTHOD = \"POST\";\n    private final static String ENCODE_TYPE = \"UTF-8\";\n    private final static int TIME_OUT = 20000;\n\n    private static HttpEngine instance = null;\n\n    private HttpEngine() {\n\n    }\n\n    public static HttpEngine getInstance() {\n        if (instance == null) {\n            instance = new HttpEngine();\n        }\n        return instance;\n    }\n\n    public <T> T postHandle(Map<String, String> paramsMap, Type typeOfT) throws IOException {\n        String data = joinParams(paramsMap);\n        // 打印出请求\n        Log.i(TAG, \"request: \" + data);\n        HttpURLConnection connection = getConnection();\n        connection.setRequestProperty(\"Content-Length\", String.valueOf(data.getBytes().length));\n        connection.connect();\n        OutputStream os = connection.getOutputStream();\n        os.write(data.getBytes());\n        os.flush();\n        if (connection.getResponseCode() == 200) {\n            // 获取响应的输入流对象\n            InputStream is = connection.getInputStream();\n            // 创建字节输出流对象\n            ByteArrayOutputStream baos = new ByteArrayOutputStream();\n            // 定义读取的长度\n            int len = 0;\n            // 定义缓冲区\n            byte buffer[] = new byte[1024];\n            // 按照缓冲区的大小，循环读取\n            while ((len = is.read(buffer)) != -1) {\n                // 根据读取的长度写入到os对象中\n                baos.write(buffer, 0, len);\n            }\n            // 释放资源\n            is.close();\n            baos.close();\n            connection.disconnect();\n            // 返回字符串\n            final String result = new String(baos.toByteArray());\n            // 打印出结果\n            Log.i(TAG, \"response: \" + result);\n            Gson gson = new Gson();\n            return gson.fromJson(result, typeOfT);\n        } else {\n            connection.disconnect();\n            return null;\n        }\n    }\n\n    // 获取connection\n    private HttpURLConnection getConnection() {\n        HttpURLConnection connection = null;\n        // 初始化connection\n        try {\n            // 根据地址创建URL对象\n            URL url = new URL(SERVER_URL);\n            // 根据URL对象打开链接\n            connection = (HttpURLConnection) url.openConnection();\n            // 设置请求的方式\n            connection.setRequestMethod(REQUEST_MOTHOD);\n            // 发送POST请求必须设置允许输入，默认为true\n            connection.setDoInput(true);\n            // 发送POST请求必须设置允许输出\n            connection.setDoOutput(true);\n            // 设置不使用缓存\n            connection.setUseCaches(false);\n            // 设置请求的超时时间\n            connection.setReadTimeout(TIME_OUT);\n            connection.setConnectTimeout(TIME_OUT);\n            connection.setRequestProperty(\"Content-Type\", \"application/x-www-form-urlencoded\");\n            connection.setRequestProperty(\"Connection\", \"keep-alive\");\n            connection.setRequestProperty(\"Response-Type\", \"json\");\n            connection.setChunkedStreamingMode(0);\n        } catch (IOException e) {\n            e.printStackTrace();\n        }\n        return connection;\n    }\n\n    // 拼接参数列表\n    private String joinParams(Map<String, String> paramsMap) {\n        StringBuilder stringBuilder = new StringBuilder();\n        for (String key : paramsMap.keySet()) {\n            stringBuilder.append(key);\n            stringBuilder.append(\"=\");\n            try {\n                stringBuilder.append(URLEncoder.encode(paramsMap.get(key), ENCODE_TYPE));\n            } catch (UnsupportedEncodingException e) {\n                e.printStackTrace();\n            }\n            stringBuilder.append(\"&\");\n        }\n        return stringBuilder.substring(0, stringBuilder.length() - 1);\n    }\n}\n"
  },
  {
    "path": "api/src/main/java/me/keeganlee/kandroid/api/utils/EncryptUtil.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.api.utils;\n\nimport java.math.BigInteger;\nimport java.security.MessageDigest;\n\n/**\n * 加密工具类\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic class EncryptUtil {\n    // MD5加密\n    public static String makeMD5(String password) {\n        try {\n            // 生成一个MD5加密计算摘要\n            MessageDigest md = MessageDigest.getInstance(\"MD5\");\n            // 计算md5函数\n            md.update(password.getBytes());\n            // digest()最后确定返回md5 hash值，返回值为8为字符串。因为md5 hash值是16位的hex值，实际上就是8位的字符\n            // BigInteger函数则将8位的字符串转换成16位hex值，用字符串来表示；得到字符串形式的hash值\n            return new BigInteger(1, md.digest()).toString(16);\n        } catch (Exception e) {\n            e.printStackTrace();\n        }\n        return password;\n    }\n}\n"
  },
  {
    "path": "api/src/main/res/values/strings.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <string name=\"app_name\">api</string>\n</resources>\n"
  },
  {
    "path": "app/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "app/app.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":app\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$/..\" external.system.id=\"GRADLE\" external.system.module.group=\"KAndroid\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"GRADLE_PROJECT_PATH\" value=\":app\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"SELECTED_TEST_ARTIFACT\" value=\"_android_test_\" />\n        <option name=\"ASSEMBLE_TASK_NAME\" value=\"assembleDebug\" />\n        <option name=\"COMPILE_JAVA_TASK_NAME\" value=\"compileDebugSources\" />\n        <option name=\"ASSEMBLE_TEST_TASK_NAME\" value=\"assembleDebugAndroidTest\" />\n        <option name=\"COMPILE_JAVA_TEST_TASK_NAME\" value=\"compileDebugAndroidTestSources\" />\n        <afterSyncTasks>\n          <task>generateDebugAndroidTestSources</task>\n          <task>generateDebugSources</task>\n        </afterSyncTasks>\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/src/main/res\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_7\" inherit-compiler-output=\"false\">\n    <output url=\"file://$MODULE_DIR$/build/intermediates/classes/debug\" />\n    <output-test url=\"file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/jni\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/rs\" isTestSource=\"true\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/assets\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/bundles\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dependency-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/22.0.0/jars\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/22.0.0/jars\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/exploded-aar/com.google.android.gms/play-services/6.1.71/jars\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/incremental\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/jacoco\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/javaResources\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/libs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/lint\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/manifests\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/ndk\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/pre-dexed\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/proguard\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/res\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/rs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/symbols\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/outputs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/tmp\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 22 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-v4-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-annotations-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"appcompat-v7-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"gson-2.3\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"play-services-6.1.71\" level=\"project\" />\n    <orderEntry type=\"module\" module-name=\"core\" exported=\"\" />\n    <orderEntry type=\"module\" module-name=\"model\" exported=\"\" />\n  </component>\n</module>"
  },
  {
    "path": "app/build.gradle",
    "content": "apply plugin: 'com.android.application'\n\nandroid {\n    compileSdkVersion 22\n    buildToolsVersion \"22.0.0\"\n\n    defaultConfig {\n        applicationId \"me.keeganlee.kandroid\"\n        minSdkVersion 14\n        targetSdkVersion 22\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile project(':model')\n    compile project(':core')\n    compile 'com.android.support:appcompat-v7:22.0.0'\n    compile 'com.google.android.gms:play-services:6.1.71'\n}\n"
  },
  {
    "path": "app/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/keegan/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "app/src/androidTest/java/me/keeganlee/kandroid/ApplicationTest.java",
    "content": "package me.keeganlee.kandroid;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "app/src/main/AndroidManifest.xml",
    "content": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.keeganlee.kandroid\" >\n\n    <uses-permission android:name=\"android.permission.INTERNET\" />\n    <uses-permission android:name=\"android.permission.READ_PHONE_STATE\" />\n\n    <application\n        android:name=\".KApplication\"\n        android:allowBackup=\"true\"\n        android:icon=\"@mipmap/ic_launcher\"\n        android:label=\"@string/app_name\"\n        android:theme=\"@style/AppTheme\" >\n        <activity\n            android:name=\".activity.LoginActivity\"\n            android:label=\"@string/app_name\" >\n            <intent-filter>\n                <action android:name=\"android.intent.action.MAIN\" />\n                <category android:name=\"android.intent.category.LAUNCHER\" />\n            </intent-filter>\n        </activity>\n        <activity\n            android:name=\".activity.RegisterActivity\"\n            android:label=\"@string/title_activity_register\" >\n        </activity>\n        <activity\n            android:name=\".activity.CouponListActivity\"\n            android:label=\"@string/title_activity_coupon_list\" >\n        </activity>\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/KApplication.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid;\n\nimport android.app.Application;\n\nimport me.keeganlee.kandroid.core.AppAction;\nimport me.keeganlee.kandroid.core.AppActionImpl;\n\n/**\n * Application类，应用级别的操作都放这里\n *\n * @version 1.0 创建时间：15/6/25\n */\npublic class KApplication extends Application {\n\n    private AppAction appAction;\n\n    @Override\n    public void onCreate() {\n        super.onCreate();\n        appAction = new AppActionImpl(this);\n    }\n\n    public AppAction getAppAction() {\n        return appAction;\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/activity/CouponListActivity.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.activity;\n\nimport android.os.Bundle;\nimport android.support.v4.widget.SwipeRefreshLayout;\nimport android.widget.ListView;\nimport android.widget.Toast;\n\nimport me.keeganlee.kandroid.R;\nimport me.keeganlee.kandroid.adapter.CouponListAdapter;\nimport me.keeganlee.kandroid.core.ActionCallbackListener;\nimport me.keeganlee.kandroid.model.CouponBO;\n\nimport java.util.List;\n\n/**\n * 券列表\n *\n * @version 1.0 创建时间：15/6/28\n */\npublic class CouponListActivity extends KBaseActivity implements SwipeRefreshLayout.OnRefreshListener {\n    private SwipeRefreshLayout swipeRefreshLayout;\n    private ListView listView;\n    private CouponListAdapter listAdapter;\n    private int currentPage = 1;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_coupon_list);\n\n        initViews();\n        getData();\n\n        // TODO 添加上拉加载更多的功能\n    }\n\n    private void initViews() {\n        swipeRefreshLayout = (SwipeRefreshLayout) findViewById(R.id.swipe_refresh_layout);\n        swipeRefreshLayout.setOnRefreshListener(this);\n        listView = (ListView) findViewById(R.id.list_view);\n        listAdapter = new CouponListAdapter(this);\n        listView.setAdapter(listAdapter);\n    }\n\n    private void getData() {\n        this.appAction.listCoupon(currentPage, new ActionCallbackListener<List<CouponBO>>() {\n            @Override\n            public void onSuccess(List<CouponBO> data) {\n                if (!data.isEmpty()) {\n                    if (currentPage == 1) { // 第一页\n                        listAdapter.setItems(data);\n                    } else { // 分页数据\n                        listAdapter.addItems(data);\n                    }\n                }\n                swipeRefreshLayout.setRefreshing(false);\n            }\n\n            @Override\n            public void onFailure(String errorEvent, String message) {\n                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();\n                swipeRefreshLayout.setRefreshing(false);\n            }\n        });\n    }\n\n    @Override\n    public void onRefresh() {\n        // 需要重置当前页为第一页，并且清掉数据\n        currentPage = 1;\n        listAdapter.clearItems();\n        getData();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/activity/KBaseActivity.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.activity;\n\nimport android.content.Context;\nimport android.os.Bundle;\nimport android.support.v4.app.FragmentActivity;\n\nimport me.keeganlee.kandroid.KApplication;\nimport me.keeganlee.kandroid.core.AppAction;\n\n/**\n * Activity抽象基类\n *\n * @version 1.0 创建时间：15/6/26\n */\npublic abstract class KBaseActivity extends FragmentActivity {\n    // 上下文实例\n    public Context context;\n    // 应用全局的实例\n    public KApplication application;\n    // 核心层的Action实例\n    public AppAction appAction;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        context = getApplicationContext();\n        application = (KApplication) this.getApplication();\n        appAction = application.getAppAction();\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/activity/LoginActivity.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.Toast;\n\nimport me.keeganlee.kandroid.R;\nimport me.keeganlee.kandroid.core.ActionCallbackListener;\n\n/**\n * 登录\n *\n * @version 1.0 创建时间：15/6/26\n */\npublic class LoginActivity extends KBaseActivity {\n\n    private EditText phoneEdit;\n    private EditText passwordEdit;\n    private Button loginBtn;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_login);\n        // 初始化View\n        initViews();\n    }\n\n    // 初始化View\n    private void initViews() {\n        phoneEdit = (EditText) findViewById(R.id.edit_phone);\n        passwordEdit = (EditText) findViewById(R.id.edit_password);\n        loginBtn = (Button) findViewById(R.id.btn_login);\n    }\n\n    // 准备登录\n    public void toLogin(View view) {\n        String loginName = phoneEdit.getText().toString();\n        String password = passwordEdit.getText().toString();\n        loginBtn.setEnabled(false);\n        this.appAction.login(loginName, password, new ActionCallbackListener<Void>() {\n            @Override\n            public void onSuccess(Void data) {\n                Toast.makeText(context, R.string.toast_login_success, Toast.LENGTH_SHORT).show();\n                Intent intent = new Intent(context, CouponListActivity.class);\n                startActivity(intent);\n                finish();\n            }\n\n            @Override\n            public void onFailure(String errorEvent, String message) {\n                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();\n                loginBtn.setEnabled(true);\n            }\n        });\n    }\n\n    // 进入注册页\n    public void toRegister(View view) {\n        Intent intent = new Intent(this, RegisterActivity.class);\n        startActivity(intent);\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/activity/RegisterActivity.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.activity;\n\nimport android.content.Intent;\nimport android.os.Bundle;\nimport android.view.MenuItem;\nimport android.view.View;\nimport android.widget.Button;\nimport android.widget.EditText;\nimport android.widget.Toast;\n\nimport me.keeganlee.kandroid.R;\nimport me.keeganlee.kandroid.core.ActionCallbackListener;\n\n/**\n * 注册\n *\n * @version 1.0 创建时间：15/6/26\n */\npublic class RegisterActivity extends KBaseActivity {\n\n    private EditText phoneEdit;\n    private EditText codeEdit;\n    private EditText passwordEdit;\n    private Button sendCodeBtn;\n    private Button registerBtn;\n\n    @Override\n    protected void onCreate(Bundle savedInstanceState) {\n        super.onCreate(savedInstanceState);\n        setContentView(R.layout.activity_register);\n        getActionBar().setDisplayHomeAsUpEnabled(true);\n\n        initViews();\n    }\n\n    @Override\n    public boolean onOptionsItemSelected(MenuItem item) {\n        // Handle action bar item clicks here. The action bar will\n        // automatically handle clicks on the Home/Up button, so long\n        // as you specify a parent activity in AndroidManifest.xml.\n        int id = item.getItemId();\n\n        //noinspection SimplifiableIfStatement\n        if (id == android.R.id.home) {\n            finish();\n        }\n\n        return super.onOptionsItemSelected(item);\n    }\n\n    private void initViews() {\n        phoneEdit = (EditText) findViewById(R.id.edit_phone);\n        codeEdit = (EditText) findViewById(R.id.edit_code);\n        passwordEdit = (EditText) findViewById(R.id.edit_password);\n        sendCodeBtn = (Button) findViewById(R.id.btn_send_code);\n        registerBtn = (Button) findViewById(R.id.btn_register);\n    }\n\n    // 准备发送验证码\n    public void toSendCode(View view) {\n        String phoneNum = phoneEdit.getText().toString();\n        sendCodeBtn.setEnabled(false);\n        this.appAction.sendSmsCode(phoneNum, new ActionCallbackListener<Void>() {\n            @Override\n            public void onSuccess(Void data) {\n                Toast.makeText(context, R.string.toast_code_has_sent, Toast.LENGTH_SHORT).show();\n                sendCodeBtn.setEnabled(true);\n            }\n\n            @Override\n            public void onFailure(String errorEvent, String message) {\n                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();\n                sendCodeBtn.setEnabled(true);\n            }\n        });\n    }\n\n    // 准备注册\n    public void toRegister(View view) {\n        String phoneNum = phoneEdit.getText().toString();\n        String code = codeEdit.getText().toString();\n        String password = passwordEdit.getText().toString();\n        registerBtn.setEnabled(false);\n        this.appAction.register(phoneNum, code, password, new ActionCallbackListener<Void>() {\n            @Override\n            public void onSuccess(Void data) {\n                Toast.makeText(context, R.string.toast_register_success, Toast.LENGTH_SHORT).show();\n                Intent intent = new Intent(context, CouponListActivity.class);\n                startActivity(intent);\n                finish();\n            }\n\n            @Override\n            public void onFailure(String errorEvent, String message) {\n                Toast.makeText(context, message, Toast.LENGTH_SHORT).show();\n                registerBtn.setEnabled(true);\n            }\n        });\n    }\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/adapter/CouponListAdapter.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.adapter;\n\nimport android.content.Context;\nimport android.text.SpannableString;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.TextView;\n\nimport me.keeganlee.kandroid.R;\nimport me.keeganlee.kandroid.model.CouponBO;\nimport me.keeganlee.kandroid.util.CouponPriceUtil;\n\n/**\n * 券列表的Adapter\n *\n * @version 1.0 创建时间：15/6/28\n */\npublic class CouponListAdapter extends KBaseAdapter<CouponBO> {\n\n    public CouponListAdapter(Context context) {\n        super(context);\n    }\n\n    @Override\n    public View getView(int i, View view, ViewGroup viewGroup) {\n        ViewHolder holder;\n        if (view == null) {\n            view = inflater.inflate(R.layout.item_list_coupon, viewGroup, false);\n            holder = new ViewHolder();\n            holder.titleText = (TextView) view.findViewById(R.id.text_item_title);\n            holder.infoText = (TextView) view.findViewById(R.id.text_item_info);\n            holder.priceText = (TextView) view.findViewById(R.id.text_item_price);\n            view.setTag(holder);\n        } else {\n            holder = (ViewHolder) view.getTag();\n        }\n\n        CouponBO coupon = itemList.get(i);\n        holder.titleText.setText(coupon.getName());\n        holder.infoText.setText(coupon.getIntroduce());\n        SpannableString priceString;\n        // 根据不同的券类型展示不同的价格显示方式\n        switch (coupon.getModelType()) {\n            default:\n            case CouponBO.TYPE_CASH:\n                priceString = CouponPriceUtil.getCashPrice(context, coupon.getFaceValue(), coupon.getEstimateAmount());\n                break;\n            case CouponBO.TYPE_DEBIT:\n                priceString = CouponPriceUtil.getVoucherPrice(context, coupon.getDebitAmount(), coupon.getMiniAmount());\n                break;\n            case CouponBO.TYPE_DISCOUNT:\n                priceString = CouponPriceUtil.getDiscountPrice(context, coupon.getDiscount(), coupon.getMiniAmount());\n                break;\n        }\n        holder.priceText.setText(priceString);\n\n        return view;\n    }\n\n    static class ViewHolder {\n        TextView titleText;\n        TextView infoText;\n        TextView priceText;\n    }\n\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/adapter/KBaseAdapter.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.adapter;\n\nimport android.content.Context;\nimport android.view.LayoutInflater;\nimport android.view.View;\nimport android.view.ViewGroup;\nimport android.widget.BaseAdapter;\n\nimport java.util.ArrayList;\nimport java.util.List;\n\n/**\n * Adapter抽象基类\n *\n * @version 1.0 创建时间：15/6/28\n */\npublic abstract class KBaseAdapter<T> extends BaseAdapter {\n\n    protected Context context;\n    protected LayoutInflater inflater;\n    protected List<T> itemList = new ArrayList<T>();\n\n    public KBaseAdapter(Context context) {\n        this.context = context;\n        inflater = LayoutInflater.from(context);\n    }\n\n    /**\n     * 判断数据是否为空\n     *\n     * @return 为空返回true，不为空返回false\n     */\n    public boolean isEmpty() {\n        return itemList.isEmpty();\n    }\n\n    /**\n     * 在原有的数据上添加新数据\n     *\n     * @param itemList\n     */\n    public void addItems(List<T> itemList) {\n        this.itemList.addAll(itemList);\n        notifyDataSetChanged();\n    }\n\n    /**\n     * 设置为新的数据，旧数据会被清空\n     *\n     * @param itemList\n     */\n    public void setItems(List<T> itemList) {\n        this.itemList.clear();\n        this.itemList = itemList;\n        notifyDataSetChanged();\n    }\n\n    /**\n     * 清空数据\n     */\n    public void clearItems() {\n        itemList.clear();\n        notifyDataSetChanged();\n    }\n\n    @Override\n    public int getCount() {\n        return itemList.size();\n    }\n\n    @Override\n    public Object getItem(int i) {\n        return itemList.get(i);\n    }\n\n    @Override\n    public long getItemId(int i) {\n        return i;\n    }\n\n    @Override\n    abstract public View getView(int i, View view, ViewGroup viewGroup);\n}\n"
  },
  {
    "path": "app/src/main/java/me/keeganlee/kandroid/util/CouponPriceUtil.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.util;\n\nimport android.content.Context;\nimport android.text.Spannable;\nimport android.text.SpannableString;\nimport android.text.Spanned;\nimport android.text.style.AbsoluteSizeSpan;\nimport android.text.style.ForegroundColorSpan;\nimport android.text.style.StrikethroughSpan;\n\nimport java.text.DecimalFormat;\n\n/**\n * 处理券价格的拼接\n *\n * @version 1.0 创建时间：15/6/28\n */\npublic class CouponPriceUtil {\n    /**\n     * 自动处理double数据,保留非0的2位小数\n     */\n    public static String handleDouble(double price) {\n        DecimalFormat decimalFormat = new DecimalFormat(\"##.##\");\n        return decimalFormat.format(price);\n    }\n\n    /**\n     * sp 转 px\n     */\n    public static int sp2px(Context context, float spValue) {\n        final float fontScale = context.getResources().getDisplayMetrics().scaledDensity;\n        return (int) (spValue * fontScale + 0.5f);\n    }\n\n    /**\n     * 现金券显示价格样式\n     */\n    public static SpannableString getCashPrice(Context context, double oldPrice, double newPrice) {\n        StringBuilder builder = new StringBuilder();\n        builder.append(handleDouble(newPrice)).append(\"元\").append(\" \").append(handleDouble(oldPrice)).append(\"元\");\n        int start = 0;\n        int middle = builder.indexOf(\" \") + 1;\n        int end = builder.length();\n        SpannableString string = new SpannableString(builder);\n        /*改变文字的大小*/\n        string.setSpan(new AbsoluteSizeSpan(sp2px(context, 20)), start, middle, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        string.setSpan(new AbsoluteSizeSpan(sp2px(context, 14)), middle, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        /*给文字设置删除线*/\n        string.setSpan(new StrikethroughSpan(), middle, end, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);\n        /*改变文字的颜色*/\n        int textOrange = context.getResources().getColor(android.R.color.holo_red_light);\n        int textGray = context.getResources().getColor(android.R.color.darker_gray);\n        string.setSpan(new ForegroundColorSpan(textOrange), start, middle, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        string.setSpan(new ForegroundColorSpan(textGray), middle, end, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        return string;\n    }\n\n    /**\n     * 抵用券显示样式\n     */\n    public static SpannableString getVoucherPrice(Context context, double voucher, double miniAmount) {\n        StringBuilder builder = new StringBuilder();\n        int textOrange = context.getResources().getColor(android.R.color.holo_red_light);\n        int textGray = context.getResources().getColor(android.R.color.darker_gray);\n        SpannableString string;\n        if (miniAmount > 0) {\n            builder.append(\"满\").append(handleDouble(miniAmount)).append(\"元减\").append(handleDouble(voucher)).append(\"元\");\n            int index = builder.indexOf(\"元\") + 1;\n            string = new SpannableString(builder);\n            /*改变文字的颜色*/\n            int size = string.length();\n            string.setSpan(new ForegroundColorSpan(textGray), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textOrange), 1, index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textGray), index, index + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textOrange), index + 1, size, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        } else {\n            builder.append(\"立减\").append(handleDouble(voucher)).append(\"元\");\n            string = new SpannableString(builder);\n            /*改变文字的颜色*/\n            int size = string.length();\n            string.setSpan(new ForegroundColorSpan(textGray), 0, 2, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textOrange), 2, size, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n        return string;\n    }\n\n    /**\n     * 折扣券显示样式\n     */\n    public static SpannableString getDiscountPrice(Context context, double discount, double miniAmount) {\n        discount = discount * 0.1;\n        StringBuilder builder = new StringBuilder();\n        int textOrange = context.getResources().getColor(android.R.color.holo_red_light);\n        int textGray = context.getResources().getColor(android.R.color.darker_gray);\n        SpannableString string;\n        if (miniAmount > 0) {\n            builder.append(\"满\").append(handleDouble(miniAmount)).append(\"元享\").append(handleDouble(discount)).append(\"折\");\n            int index = builder.indexOf(\"元\") + 1;\n            string = new SpannableString(builder);\n            /*改变文字的颜色*/\n            int size = string.length();\n            string.setSpan(new ForegroundColorSpan(textGray), 0, 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textOrange), 1, index, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textGray), index, index + 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textOrange), index + 1, size - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textGray), size - 1, size, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        } else {\n            builder.append(handleDouble(discount)).append(\"折\");\n            string = new SpannableString(builder);\n            /*改变文字的颜色*/\n            int size = string.length();\n            string.setSpan(new ForegroundColorSpan(textOrange), 0, size - 1, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n            string.setSpan(new ForegroundColorSpan(textGray), size - 1, size, Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);\n        }\n        return string;\n    }\n}\n"
  },
  {
    "path": "app/src/main/res/layout/activity_coupon_list.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<FrameLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    tools:context=\"me.keeganlee.kandroid.activity.CouponListActivity\">\n    <android.support.v4.widget.SwipeRefreshLayout\n        android:id=\"@+id/swipe_refresh_layout\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\">\n        <ListView\n            android:id=\"@+id/list_view\"\n            android:layout_width=\"match_parent\"\n            android:layout_height=\"wrap_content\" />\n    </android.support.v4.widget.SwipeRefreshLayout>\n</FrameLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_login.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    tools:context=\"me.keeganlee.kandroid.activity.LoginActivity\">\n\n    <EditText\n        android:id=\"@+id/edit_phone\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/edit_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/edit_vertical_margin\"\n        android:hint=\"@string/hint_phone\"\n        android:inputType=\"phone\"\n        android:singleLine=\"true\" />\n\n    <EditText\n        android:id=\"@+id/edit_password\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/edit_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/edit_vertical_margin\"\n        android:hint=\"@string/hint_password\"\n        android:inputType=\"textPassword\"\n        android:singleLine=\"true\" />\n\n    <Button\n        android:id=\"@+id/btn_login\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/btn_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/btn_vertical_margin\"\n        android:onClick=\"toLogin\"\n        android:text=\"@string/btn_login\" />\n\n    <Button\n        android:id=\"@+id/btn_goto_register\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginBottom=\"@dimen/btn_vertical_margin\"\n        android:onClick=\"toRegister\"\n        android:text=\"@string/btn_goto_register\" />\n\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/activity_register.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    xmlns:tools=\"http://schemas.android.com/tools\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:orientation=\"vertical\"\n    android:paddingBottom=\"@dimen/activity_vertical_margin\"\n    android:paddingLeft=\"@dimen/activity_horizontal_margin\"\n    android:paddingRight=\"@dimen/activity_horizontal_margin\"\n    android:paddingTop=\"@dimen/activity_vertical_margin\"\n    tools:context=\"me.keeganlee.kandroid.activity.RegisterActivity\">\n\n    <LinearLayout\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:orientation=\"horizontal\">\n        <EditText\n            android:id=\"@+id/edit_phone\"\n            android:layout_width=\"0dp\"\n            android:layout_height=\"wrap_content\"\n            android:layout_weight=\"1\"\n            android:layout_marginTop=\"@dimen/edit_vertical_margin\"\n            android:layout_marginBottom=\"@dimen/edit_vertical_margin\"\n            android:hint=\"@string/hint_phone\"\n            android:inputType=\"phone\"\n            android:singleLine=\"true\" />\n        <Button\n            android:id=\"@+id/btn_send_code\"\n            android:layout_width=\"wrap_content\"\n            android:layout_height=\"wrap_content\"\n            android:onClick=\"toSendCode\"\n            android:text=\"@string/btn_send_code\"/>\n    </LinearLayout>\n\n    <EditText\n        android:id=\"@+id/edit_code\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/edit_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/edit_vertical_margin\"\n        android:hint=\"@string/hint_code\"\n        android:inputType=\"text\"\n        android:singleLine=\"true\" />\n\n    <EditText\n        android:id=\"@+id/edit_password\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/edit_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/edit_vertical_margin\"\n        android:hint=\"@string/hint_password\"\n        android:inputType=\"textPassword\"\n        android:singleLine=\"true\" />\n\n    <Button\n        android:id=\"@+id/btn_register\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:layout_marginTop=\"@dimen/btn_vertical_margin\"\n        android:layout_marginBottom=\"@dimen/btn_vertical_margin\"\n        android:onClick=\"toRegister\"\n        android:text=\"@string/btn_register\" />\n</LinearLayout>\n"
  },
  {
    "path": "app/src/main/res/layout/item_list_coupon.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    android:layout_width=\"match_parent\"\n    android:layout_height=\"match_parent\"\n    android:paddingTop=\"@dimen/item_list_vertical_padding\"\n    android:paddingBottom=\"@dimen/item_list_vertical_padding\"\n    android:paddingLeft=\"@dimen/item_list_horizontal_padding\"\n    android:paddingRight=\"@dimen/item_list_horizontal_padding\"\n    android:orientation=\"vertical\">\n    <TextView\n        android:id=\"@+id/text_item_title\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"@dimen/item_list_title_text_size\"\n        android:textColor=\"@android:color/black\"/>\n    <TextView\n        android:id=\"@+id/text_item_info\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"@dimen/item_list_info_text_size\"\n        android:textColor=\"@android:color/darker_gray\"/>\n    <TextView\n        android:id=\"@+id/text_item_price\"\n        android:layout_width=\"match_parent\"\n        android:layout_height=\"wrap_content\"\n        android:textSize=\"@dimen/item_list_info_text_size\"\n        android:textColor=\"@android:color/holo_red_light\"/>\n</LinearLayout>"
  },
  {
    "path": "app/src/main/res/values/dimens.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <!-- Default screen margins, per the Android Design guidelines. -->\n    <dimen name=\"activity_horizontal_margin\">16dp</dimen>\n    <dimen name=\"activity_vertical_margin\">16dp</dimen>\n\n    <dimen name=\"item_list_horizontal_padding\">16dp</dimen>\n    <dimen name=\"item_list_vertical_padding\">16dp</dimen>\n    <dimen name=\"item_list_title_text_size\">18sp</dimen>\n    <dimen name=\"item_list_info_text_size\">16sp</dimen>\n\n    <dimen name=\"edit_vertical_margin\">5dp</dimen>\n\n    <dimen name=\"btn_vertical_margin\">20dp</dimen>\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/strings.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <string name=\"app_name\">KAndroid</string>\n\n    <!-- 页面标题 -->\n    <string name=\"title_activity_login\">登录</string>\n    <string name=\"title_activity_register\">注册</string>\n    <string name=\"title_activity_coupon_list\">最新券</string>\n\n    <!-- ActionBar -->\n    <string name=\"action_register\">注册</string>\n\n    <!-- 按钮文字 -->\n    <string name=\"btn_login\">登录</string>\n    <string name=\"btn_register\">注册</string>\n    <string name=\"btn_goto_register\">注册</string>\n    <string name=\"btn_send_code\">发送验证码</string>\n\n    <!-- EditText hint -->\n    <string name=\"hint_phone\">手机号码</string>\n    <string name=\"hint_password\">密码</string>\n    <string name=\"hint_code\">验证码</string>\n\n    <!-- Toast信息 -->\n    <string name=\"toast_login_success\">登录成功</string>\n    <string name=\"toast_code_has_sent\">验证码已发送到手机</string>\n    <string name=\"toast_register_success\">注册成功</string>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values/styles.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n\n    <!-- Base application theme. -->\n    <style name=\"AppTheme\" parent=\"@android:style/Theme.Holo.Light.DarkActionBar\">\n        <!-- Customize your theme here. -->\n    </style>\n\n</resources>\n"
  },
  {
    "path": "app/src/main/res/values-w820dp/dimens.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\n         (such as screen margins) for screens with more than 820dp of available width. This\n         would include 7\" and 10\" devices in landscape (~960dp and ~1280dp respectively). -->\n    <dimen name=\"activity_horizontal_margin\">64dp</dimen>\n</resources>\n"
  },
  {
    "path": "build.gradle",
    "content": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\n\nbuildscript {\n    repositories {\n        jcenter()\n    }\n    dependencies {\n        classpath 'com.android.tools.build:gradle:1.2.3'\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        jcenter()\n    }\n}\n"
  },
  {
    "path": "core/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "core/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 22\n    buildToolsVersion \"22.0.0\"\n\n    defaultConfig {\n        minSdkVersion 11\n        targetSdkVersion 22\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:22.0.0'\n    compile project(':model')\n    compile project(':api')\n}\n"
  },
  {
    "path": "core/core.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":core\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$/..\" external.system.id=\"GRADLE\" external.system.module.group=\"KAndroid\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"GRADLE_PROJECT_PATH\" value=\":core\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"SELECTED_TEST_ARTIFACT\" value=\"_android_test_\" />\n        <option name=\"ASSEMBLE_TASK_NAME\" value=\"assembleDebug\" />\n        <option name=\"COMPILE_JAVA_TASK_NAME\" value=\"compileDebugSources\" />\n        <option name=\"ASSEMBLE_TEST_TASK_NAME\" value=\"assembleDebugAndroidTest\" />\n        <option name=\"COMPILE_JAVA_TEST_TASK_NAME\" value=\"compileDebugAndroidTestSources\" />\n        <afterSyncTasks>\n          <task>generateDebugAndroidTestSources</task>\n          <task>generateDebugSources</task>\n        </afterSyncTasks>\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/src/main/res\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n        <option name=\"LIBRARY_PROJECT\" value=\"true\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_7\" inherit-compiler-output=\"false\">\n    <output url=\"file://$MODULE_DIR$/build/intermediates/classes/debug\" />\n    <output-test url=\"file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/jni\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/rs\" isTestSource=\"true\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/assets\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/bundles\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dependency-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/incremental\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/jacoco\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/javaResources\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/libs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/lint\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/manifests\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/ndk\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/pre-dexed\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/proguard\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/res\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/rs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/symbols\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/outputs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/tmp\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 22 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-v4-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-annotations-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"appcompat-v7-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"gson-2.3\" level=\"project\" />\n    <orderEntry type=\"module\" module-name=\"api\" exported=\"\" />\n    <orderEntry type=\"module\" module-name=\"model\" exported=\"\" />\n  </component>\n</module>"
  },
  {
    "path": "core/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/keegan/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "core/src/androidTest/java/me/keeganlee/kandroid/core/ApplicationTest.java",
    "content": "package me.keeganlee.kandroid.core;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "core/src/main/AndroidManifest.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.keeganlee.kandroid.core\">\n\n    <application android:allowBackup=\"true\" android:label=\"@string/app_name\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "core/src/main/java/me/keeganlee/kandroid/core/ActionCallbackListener.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.core;\n\n/**\n * Action的处理结果回调监听器\n *\n * @author Keegan小钢\n * @date 15/6/25\n * @version 1.0\n */\npublic interface ActionCallbackListener<T> {\n    /**\n     * 成功时调用\n     *\n     * @param data 返回的数据\n     */\n    public void onSuccess(T data);\n\n    /**\n     * 失败时调用\n     *\n     * @param errorEvent 错误码\n     * @param message    错误信息\n     */\n    public void onFailure(String errorEvent, String message);\n}\n"
  },
  {
    "path": "core/src/main/java/me/keeganlee/kandroid/core/AppAction.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.core;\n\nimport me.keeganlee.kandroid.model.CouponBO;\n\nimport java.util.List;\n\n/**\n * 接收app层的各种Action\n *\n * @author Keegan小钢\n * @date 15/6/25\n * @version 1.0\n */\npublic interface AppAction {\n    /**\n     * 发送验证码\n     *\n     * @param phoneNum 手机号\n     * @param listener 回调监听器\n     */\n    public void sendSmsCode(String phoneNum, ActionCallbackListener<Void> listener);\n\n    /**\n     * 注册\n     *\n     * @param phoneNum 手机号\n     * @param code     验证码\n     * @param password 密码\n     * @param listener 回调监听器\n     */\n    public void register(String phoneNum, String code, String password, ActionCallbackListener<Void> listener);\n\n    /**\n     * 登录\n     *\n     * @param loginName 登录名\n     * @param password  密码\n     * @param listener  回调监听器\n     */\n    public void login(String loginName, String password, ActionCallbackListener<Void> listener);\n\n    /**\n     * 券列表\n     *\n     * @param currentPage 当前页数\n     * @param listener    回调监听器\n     */\n    public void listCoupon(int currentPage, ActionCallbackListener<List<CouponBO>> listener);\n}\n"
  },
  {
    "path": "core/src/main/java/me/keeganlee/kandroid/core/AppActionImpl.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.core;\n\nimport android.content.Context;\nimport android.os.AsyncTask;\nimport android.telephony.TelephonyManager;\nimport android.text.TextUtils;\n\nimport me.keeganlee.kandroid.api.Api;\nimport me.keeganlee.kandroid.api.ApiImpl;\nimport me.keeganlee.kandroid.api.ApiResponse;\nimport me.keeganlee.kandroid.model.CouponBO;\n\nimport java.util.List;\nimport java.util.regex.Matcher;\nimport java.util.regex.Pattern;\n\n/**\n * AppAction接口的实现类\n *\n * @author Keegan小钢\n * @date 15/6/25\n * @version 1.0\n */\npublic class AppActionImpl implements AppAction {\n\n    private final static int LOGIN_OS = 1; // 表示Android\n    private final static int PAGE_SIZE = 20; // 默认每页20条\n\n    private Context context;\n    private Api api;\n\n    public AppActionImpl(Context context) {\n        this.context = context;\n        this.api = new ApiImpl();\n    }\n\n    @Override\n    public void sendSmsCode(final String phoneNum, final ActionCallbackListener<Void> listener) {\n        // 参数检查\n        if (TextUtils.isEmpty(phoneNum)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"手机号为空\");\n            }\n            return;\n        }\n        Pattern pattern = Pattern.compile(\"1\\\\d{10}\");\n        Matcher matcher = pattern.matcher(phoneNum);\n        if (!matcher.matches()) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, \"手机号不正确\");\n            }\n            return;\n        }\n\n        // 请求Api\n        new AsyncTask<Void, Void, ApiResponse<Void>>() {\n            @Override\n            protected ApiResponse<Void> doInBackground(Void... voids) {\n                return api.sendSmsCode4Register(phoneNum);\n            }\n\n            @Override\n            protected void onPostExecute(ApiResponse<Void> response) {\n                if (listener != null && response != null) {\n                    if (response.isSuccess()) {\n                        listener.onSuccess(null);\n                    } else {\n                        listener.onFailure(response.getEvent(), response.getMsg());\n                    }\n                }\n            }\n        }.execute();\n    }\n\n    @Override\n    public void register(final String phoneNum, final String code, final String password, final ActionCallbackListener<Void> listener) {\n        // 参数检查\n        if (TextUtils.isEmpty(phoneNum)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"手机号为空\");\n            }\n            return;\n        }\n        if (TextUtils.isEmpty(code)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"验证码为空\");\n            }\n            return;\n        }\n        if (TextUtils.isEmpty(password)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"密码为空\");\n            }\n            return;\n        }\n        Pattern pattern = Pattern.compile(\"1\\\\d{10}\");\n        Matcher matcher = pattern.matcher(phoneNum);\n        if (!matcher.matches()) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, \"手机号不正确\");\n            }\n            return;\n        }\n\n        // 请求Api\n        new AsyncTask<Void, Void, ApiResponse<Void>>() {\n            @Override\n            protected ApiResponse<Void> doInBackground(Void... voids) {\n                return api.registerByPhone(phoneNum, code, password);\n            }\n\n            @Override\n            protected void onPostExecute(ApiResponse<Void> response) {\n                if (listener != null && response != null) {\n                    if (response.isSuccess()) {\n                        listener.onSuccess(null);\n                    } else {\n                        listener.onFailure(response.getEvent(), response.getMsg());\n                    }\n                }\n            }\n        }.execute();\n    }\n\n    @Override\n    public void login(final String loginName, final String password, final ActionCallbackListener<Void> listener) {\n        // 参数检查\n        if (TextUtils.isEmpty(loginName)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"登录名为空\");\n            }\n            return;\n        }\n        if (TextUtils.isEmpty(password)) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_NULL, \"密码为空\");\n            }\n            return;\n        }\n\n        // 请求Api\n        new AsyncTask<Void, Void, ApiResponse<Void>>() {\n            @Override\n            protected ApiResponse<Void> doInBackground(Void... voids) {\n                TelephonyManager telephonyManager = (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);\n                String imei = telephonyManager.getDeviceId();\n                return api.loginByApp(loginName, password, imei, LOGIN_OS);\n            }\n\n            @Override\n            protected void onPostExecute(ApiResponse<Void> response) {\n                if (listener != null && response != null) {\n                    if (response.isSuccess()) {\n                        listener.onSuccess(null);\n                    } else {\n                        listener.onFailure(response.getEvent(), response.getMsg());\n                    }\n                }\n            }\n        }.execute();\n    }\n\n    @Override\n    public void listCoupon(final int currentPage, final ActionCallbackListener<List<CouponBO>> listener) {\n        // 参数检查\n        if (currentPage < 0) {\n            if (listener != null) {\n                listener.onFailure(ErrorEvent.PARAM_ILLEGAL, \"当前页数小于零\");\n            }\n        }\n\n        // 请求Api\n        new AsyncTask<Void, Void, ApiResponse<List<CouponBO>>>() {\n            @Override\n            protected ApiResponse<List<CouponBO>> doInBackground(Void... voids) {\n                return api.listNewCoupon(currentPage, PAGE_SIZE);\n            }\n\n            @Override\n            protected void onPostExecute(ApiResponse<List<CouponBO>> response) {\n                if (listener != null && response != null) {\n                    if (response.isSuccess()) {\n                        listener.onSuccess(response.getObjList());\n                    } else {\n                        listener.onFailure(response.getEvent(), response.getMsg());\n                    }\n                }\n            }\n        }.execute();\n    }\n\n}\n"
  },
  {
    "path": "core/src/main/java/me/keeganlee/kandroid/core/ErrorEvent.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.core;\n\n/**\n * 错误码\n *\n * @author Keegan小钢\n * @date 15/6/25\n * @version 1.0\n */\npublic class ErrorEvent {\n    static final public String PARAM_NULL = \"PARAM_NULL\"; // 参数为空\n    static final public String PARAM_ILLEGAL = \"PARAM_ILLEGAL\"; // 参数不合法\n}\n"
  },
  {
    "path": "core/src/main/res/values/strings.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <string name=\"app_name\">core</string>\n</resources>\n"
  },
  {
    "path": "gradle/wrapper/gradle-wrapper.properties",
    "content": "#Wed Apr 10 15:27:10 PDT 2013\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_HOME\nzipStorePath=wrapper/dists\ndistributionUrl=https\\://services.gradle.org/distributions/gradle-2.2.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.\n# Default value: -Xmx10248m -XX:MaxPermSize=256m\n# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\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"
  },
  {
    "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# For Cygwin, ensure paths are in UNIX format before anything is touched.\nif $cygwin ; then\n    [ -n \"$JAVA_HOME\" ] && JAVA_HOME=`cygpath --unix \"$JAVA_HOME\"`\nfi\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\\\"`/\" >&-\nAPP_HOME=\"`pwd -P`\"\ncd \"$SAVED\" >&-\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\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\r\n@rem ##########################################################################\r\n@rem\r\n@rem  Gradle startup script for Windows\r\n@rem\r\n@rem ##########################################################################\r\n\r\n@rem Set local scope for the variables with windows NT shell\r\nif \"%OS%\"==\"Windows_NT\" setlocal\r\n\r\n@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r\nset DEFAULT_JVM_OPTS=\r\n\r\nset DIRNAME=%~dp0\r\nif \"%DIRNAME%\" == \"\" set DIRNAME=.\r\nset APP_BASE_NAME=%~n0\r\nset APP_HOME=%DIRNAME%\r\n\r\n@rem Find java.exe\r\nif defined JAVA_HOME goto findJavaFromJavaHome\r\n\r\nset JAVA_EXE=java.exe\r\n%JAVA_EXE% -version >NUL 2>&1\r\nif \"%ERRORLEVEL%\" == \"0\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:findJavaFromJavaHome\r\nset JAVA_HOME=%JAVA_HOME:\"=%\r\nset JAVA_EXE=%JAVA_HOME%/bin/java.exe\r\n\r\nif exist \"%JAVA_EXE%\" goto init\r\n\r\necho.\r\necho ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r\necho.\r\necho Please set the JAVA_HOME variable in your environment to match the\r\necho location of your Java installation.\r\n\r\ngoto fail\r\n\r\n:init\r\n@rem Get command-line arguments, handling Windowz variants\r\n\r\nif not \"%OS%\" == \"Windows_NT\" goto win9xME_args\r\nif \"%@eval[2+2]\" == \"4\" goto 4NT_args\r\n\r\n:win9xME_args\r\n@rem Slurp the command line arguments.\r\nset CMD_LINE_ARGS=\r\nset _SKIP=2\r\n\r\n:win9xME_args_slurp\r\nif \"x%~1\" == \"x\" goto execute\r\n\r\nset CMD_LINE_ARGS=%*\r\ngoto execute\r\n\r\n:4NT_args\r\n@rem Get arguments from the 4NT Shell from JP Software\r\nset CMD_LINE_ARGS=%$\r\n\r\n:execute\r\n@rem Setup the command line\r\n\r\nset CLASSPATH=%APP_HOME%\\gradle\\wrapper\\gradle-wrapper.jar\r\n\r\n@rem Execute Gradle\r\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%\r\n\r\n:end\r\n@rem End local scope for the variables with windows NT shell\r\nif \"%ERRORLEVEL%\"==\"0\" goto mainEnd\r\n\r\n:fail\r\nrem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r\nrem the _cmd.exe /c_ return code!\r\nif  not \"\" == \"%GRADLE_EXIT_CONSOLE%\" exit 1\r\nexit /b 1\r\n\r\n:mainEnd\r\nif \"%OS%\"==\"Windows_NT\" endlocal\r\n\r\n:omega\r\n"
  },
  {
    "path": "model/.gitignore",
    "content": "/build\n"
  },
  {
    "path": "model/build.gradle",
    "content": "apply plugin: 'com.android.library'\n\nandroid {\n    compileSdkVersion 22\n    buildToolsVersion \"22.0.0\"\n\n    defaultConfig {\n        minSdkVersion 11\n        targetSdkVersion 22\n        versionCode 1\n        versionName \"1.0\"\n    }\n    buildTypes {\n        release {\n            minifyEnabled false\n            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\n        }\n    }\n}\n\ndependencies {\n    compile fileTree(dir: 'libs', include: ['*.jar'])\n    compile 'com.android.support:appcompat-v7:22.0.0'\n}\n"
  },
  {
    "path": "model/model.iml",
    "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<module external.linked.project.id=\":model\" external.linked.project.path=\"$MODULE_DIR$\" external.root.project.path=\"$MODULE_DIR$/..\" external.system.id=\"GRADLE\" external.system.module.group=\"KAndroid\" external.system.module.version=\"unspecified\" type=\"JAVA_MODULE\" version=\"4\">\n  <component name=\"FacetManager\">\n    <facet type=\"android-gradle\" name=\"Android-Gradle\">\n      <configuration>\n        <option name=\"GRADLE_PROJECT_PATH\" value=\":model\" />\n      </configuration>\n    </facet>\n    <facet type=\"android\" name=\"Android\">\n      <configuration>\n        <option name=\"SELECTED_BUILD_VARIANT\" value=\"debug\" />\n        <option name=\"SELECTED_TEST_ARTIFACT\" value=\"_android_test_\" />\n        <option name=\"ASSEMBLE_TASK_NAME\" value=\"assembleDebug\" />\n        <option name=\"COMPILE_JAVA_TASK_NAME\" value=\"compileDebugSources\" />\n        <option name=\"ASSEMBLE_TEST_TASK_NAME\" value=\"assembleDebugAndroidTest\" />\n        <option name=\"COMPILE_JAVA_TEST_TASK_NAME\" value=\"compileDebugAndroidTestSources\" />\n        <afterSyncTasks>\n          <task>generateDebugAndroidTestSources</task>\n          <task>generateDebugSources</task>\n        </afterSyncTasks>\n        <option name=\"ALLOW_USER_CONFIGURATION\" value=\"false\" />\n        <option name=\"MANIFEST_FILE_RELATIVE_PATH\" value=\"/src/main/AndroidManifest.xml\" />\n        <option name=\"RES_FOLDER_RELATIVE_PATH\" value=\"/src/main/res\" />\n        <option name=\"RES_FOLDERS_RELATIVE_PATH\" value=\"file://$MODULE_DIR$/src/main/res\" />\n        <option name=\"ASSETS_FOLDER_RELATIVE_PATH\" value=\"/src/main/assets\" />\n        <option name=\"LIBRARY_PROJECT\" value=\"true\" />\n      </configuration>\n    </facet>\n  </component>\n  <component name=\"NewModuleRootManager\" LANGUAGE_LEVEL=\"JDK_1_7\" inherit-compiler-output=\"false\">\n    <output url=\"file://$MODULE_DIR$/build/intermediates/classes/debug\" />\n    <output-test url=\"file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug\" />\n    <exclude-output />\n    <content url=\"file://$MODULE_DIR$\">\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/debug\" isTestSource=\"false\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/debug\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/r/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug\" isTestSource=\"true\" generated=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/build/generated/res/generated/androidTest/debug\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/debug/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/res\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/resources\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/assets\" type=\"java-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/aidl\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/java\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/jni\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/main/rs\" isTestSource=\"false\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/res\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/resources\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/assets\" type=\"java-test-resource\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/aidl\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/java\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/jni\" isTestSource=\"true\" />\n      <sourceFolder url=\"file://$MODULE_DIR$/src/androidTest/rs\" isTestSource=\"true\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/assets\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/bundles\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/coverage-instrumented-classes\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dependency-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/dex-cache\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/incremental\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/jacoco\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/javaResources\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/libs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/lint\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/manifests\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/ndk\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/pre-dexed\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/proguard\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/res\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/rs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/intermediates/symbols\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/outputs\" />\n      <excludeFolder url=\"file://$MODULE_DIR$/build/tmp\" />\n    </content>\n    <orderEntry type=\"jdk\" jdkName=\"Android API 22 Platform\" jdkType=\"Android SDK\" />\n    <orderEntry type=\"sourceFolder\" forTests=\"false\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-v4-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"support-annotations-22.0.0\" level=\"project\" />\n    <orderEntry type=\"library\" exported=\"\" name=\"appcompat-v7-22.0.0\" level=\"project\" />\n  </component>\n</module>"
  },
  {
    "path": "model/proguard-rules.pro",
    "content": "# Add project specific ProGuard rules here.\n# By default, the flags in this file are appended to flags specified\n# in /Users/keegan/adt-bundle-mac-x86_64-20140702/sdk/tools/proguard/proguard-android.txt\n# You can edit the include path and order by changing the proguardFiles\n# directive in build.gradle.\n#\n# For more details, see\n#   http://developer.android.com/guide/developing/tools/proguard.html\n\n# Add any project specific keep options here:\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"
  },
  {
    "path": "model/src/androidTest/java/me/keeganlee/kandroid/model/ApplicationTest.java",
    "content": "package me.keeganlee.kandroid.model;\n\nimport android.app.Application;\nimport android.test.ApplicationTestCase;\n\n/**\n * <a href=\"http://d.android.com/tools/testing/testing_android.html\">Testing Fundamentals</a>\n */\npublic class ApplicationTest extends ApplicationTestCase<Application> {\n    public ApplicationTest() {\n        super(Application.class);\n    }\n}"
  },
  {
    "path": "model/src/main/AndroidManifest.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n    package=\"me.keeganlee.kandroid.model\">\n\n    <application android:allowBackup=\"true\" android:label=\"@string/app_name\">\n\n    </application>\n\n</manifest>\n"
  },
  {
    "path": "model/src/main/java/me/keeganlee/kandroid/model/CouponBO.java",
    "content": "/**\n * Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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 */\npackage me.keeganlee.kandroid.model;\n\nimport java.io.Serializable;\n\n/**\n * 券的业务模型类，封装了券的基本信息。\n * 券分为了三种类型：现金券、抵扣券、折扣券。\n * 现金券是拥有固定面值的券，有固定的售价；\n * 抵扣券是满足一定金额后可以抵扣的券，比如满100减10元；\n * 折扣券是可以打折的券。\n *\n * @author Keegan小钢\n * @date 15/6/21\n * @version 1.0\n */\npublic class CouponBO implements Serializable {\n    private static final long serialVersionUID = -8022957276104379230L;\n\n    public static final int TYPE_CASH = 1; // 现金券\n    public static final int TYPE_DEBIT = 2; // 抵扣券\n    public static final int TYPE_DISCOUNT = 3; // 折扣券\n\n    private int id;                // 券id\n    private String name;           // 券名称\n    private String introduce;      // 券简介\n    private int modelType;         // 券类型，1为现金券，2为抵扣券，3为折扣券\n    private double faceValue;      // 现金券的面值\n    private double estimateAmount; // 现金券的售价\n    private double debitAmount;    // 抵扣券的抵扣金额\n    private double discount;       // 折扣券的折扣率（0-100）\n    private double miniAmount;     // 抵扣券和折扣券的最小使用金额\n\n    public int getId() {\n        return id;\n    }\n\n    public void setId(int id) {\n        this.id = id;\n    }\n\n    public String getName() {\n        return name;\n    }\n\n    public void setName(String name) {\n        this.name = name;\n    }\n\n    public String getIntroduce() {\n        return introduce;\n    }\n\n    public void setIntroduce(String introduce) {\n        this.introduce = introduce;\n    }\n\n    public int getModelType() {\n        return modelType;\n    }\n\n    public void setModelType(int modelType) {\n        this.modelType = modelType;\n    }\n\n    public double getFaceValue() {\n        return faceValue;\n    }\n\n    public void setFaceValue(double faceValue) {\n        this.faceValue = faceValue;\n    }\n\n    public double getEstimateAmount() {\n        return estimateAmount;\n    }\n\n    public void setEstimateAmount(double estimateAmount) {\n        this.estimateAmount = estimateAmount;\n    }\n\n    public double getDebitAmount() {\n        return debitAmount;\n    }\n\n    public void setDebitAmount(double debitAmount) {\n        this.debitAmount = debitAmount;\n    }\n\n    public double getDiscount() {\n        return discount;\n    }\n\n    public void setDiscount(double discount) {\n        this.discount = discount;\n    }\n\n    public double getMiniAmount() {\n        return miniAmount;\n    }\n\n    public void setMiniAmount(double miniAmount) {\n        this.miniAmount = miniAmount;\n    }\n}\n"
  },
  {
    "path": "model/src/main/res/values/strings.xml",
    "content": "<!--\n Copyright (C) 2015. Keegan小钢（http://keeganlee.me）\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-->\n<resources>\n    <string name=\"app_name\">model</string>\n</resources>\n"
  },
  {
    "path": "settings.gradle",
    "content": "include ':app', ':model', ':api', ':core'\n"
  }
]