初始化仓库项目

master
孔德腾 7 years ago
parent f2e99874bf
commit 8183828093
  1. 8
      .idea/file.template.settings.xml
  2. 5
      .idea/fileTemplates/internal/Class.java
  3. 19
      .idea/gradle.xml
  4. 9
      .idea/libraries/__local_aars___D__AppItem_ShareLib_share_libs_open_sdk_r5990_lite_jar_unspecified_jar.xml
  5. 9
      .idea/libraries/__local_aars___D__AppItem_ShareLib_share_libs_weiboSDKCore_3_1_4_jar_unspecified_jar.xml
  6. 14
      .idea/libraries/com_android_support_animated_vector_drawable_25_0_0.xml
  7. 14
      .idea/libraries/com_android_support_appcompat_v7_25_0_0.xml
  8. 13
      .idea/libraries/com_android_support_support_annotations_25_0_0_jar.xml
  9. 15
      .idea/libraries/com_android_support_support_compat_25_0_0.xml
  10. 15
      .idea/libraries/com_android_support_support_core_ui_25_0_0.xml
  11. 15
      .idea/libraries/com_android_support_support_core_utils_25_0_0.xml
  12. 15
      .idea/libraries/com_android_support_support_fragment_25_0_0.xml
  13. 15
      .idea/libraries/com_android_support_support_media_compat_25_0_0.xml
  14. 10
      .idea/libraries/com_android_support_support_v4_25_0_0.xml
  15. 14
      .idea/libraries/com_android_support_support_vector_drawable_25_0_0.xml
  16. 11
      .idea/libraries/com_squareup_okhttp3_okhttp_3_4_2_jar.xml
  17. 11
      .idea/libraries/com_squareup_okio_okio_1_9_0_jar.xml
  18. 11
      .idea/libraries/com_tencent_mm_opensdk_wechat_sdk_android_with_mta_5_1_0_jar.xml
  19. 11
      .idea/libraries/com_tencent_mm_opensdk_wechat_sdk_android_with_mta_5_1_4_jar.xml
  20. 12
      .idea/libraries/io_reactivex_rxandroid_1_2_1.xml
  21. 11
      .idea/libraries/io_reactivex_rxjava_1_2_3_jar.xml
  22. 11
      .idea/libraries/junit_junit_4_12_jar.xml
  23. 11
      .idea/libraries/org_hamcrest_hamcrest_core_1_3_jar.xml
  24. 33
      .idea/misc.xml
  25. 10
      .idea/modules.xml
  26. 12
      .idea/runConfigurations.xml
  27. 3802
      .idea/workspace.xml
  28. 19
      ShareLib.iml
  29. 1
      app/.gitignore
  30. 123
      app/app.iml
  31. 39
      app/build.gradle
  32. 21
      app/proguard-rules.pro
  33. 26
      app/src/androidTest/java/vip/devkit/share/ExampleInstrumentedTest.java
  34. 30
      app/src/main/AndroidManifest.xml
  35. 118
      app/src/main/java/vip/devkit/share/MainActivity.java
  36. 34
      app/src/main/res/drawable-v24/ic_launcher_foreground.xml
  37. 170
      app/src/main/res/drawable/ic_launcher_background.xml
  38. 27
      app/src/main/res/layout/activity_main.xml
  39. 5
      app/src/main/res/mipmap-anydpi-v26/ic_launcher.xml
  40. 5
      app/src/main/res/mipmap-anydpi-v26/ic_launcher_round.xml
  41. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher.png
  42. BIN
      app/src/main/res/mipmap-hdpi/ic_launcher_round.png
  43. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher.png
  44. BIN
      app/src/main/res/mipmap-mdpi/ic_launcher_round.png
  45. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher.png
  46. BIN
      app/src/main/res/mipmap-xhdpi/ic_launcher_round.png
  47. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher.png
  48. BIN
      app/src/main/res/mipmap-xxhdpi/ic_launcher_round.png
  49. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher.png
  50. BIN
      app/src/main/res/mipmap-xxxhdpi/ic_launcher_round.png
  51. 6
      app/src/main/res/values/colors.xml
  52. 3
      app/src/main/res/values/strings.xml
  53. 11
      app/src/main/res/values/styles.xml
  54. 17
      app/src/test/java/vip/devkit/share/ExampleUnitTest.java
  55. 42
      build.gradle
  56. 18
      gradle.properties
  57. BIN
      gradle/wrapper/gradle-wrapper.jar
  58. 6
      gradle/wrapper/gradle-wrapper.properties
  59. 160
      gradlew
  60. 90
      gradlew.bat
  61. 1
      settings.gradle
  62. 1
      share/.gitignore
  63. 47
      share/build.gradle
  64. BIN
      share/libs/open_sdk_r5990_lite.jar
  65. BIN
      share/libs/weiboSDKCore_3.1.4.jar
  66. 21
      share/proguard-rules.pro
  67. 114
      share/share.iml
  68. 55
      share/src/main/AndroidManifest.xml
  69. BIN
      share/src/main/ic_launcher-web.png
  70. 110
      share/src/main/java/vip/devkit/common/share/LoginUtil.java
  71. 105
      share/src/main/java/vip/devkit/common/share/ShareConfig.java
  72. 64
      share/src/main/java/vip/devkit/common/share/ShareLogger.java
  73. 30
      share/src/main/java/vip/devkit/common/share/ShareManager.java
  74. 300
      share/src/main/java/vip/devkit/common/share/ShareUtil.java
  75. 87
      share/src/main/java/vip/devkit/common/share/_ShareActivity.java
  76. 35
      share/src/main/java/vip/devkit/common/share/login/LoginListener.java
  77. 26
      share/src/main/java/vip/devkit/common/share/login/LoginPlatform.java
  78. 49
      share/src/main/java/vip/devkit/common/share/login/LoginResult.java
  79. 26
      share/src/main/java/vip/devkit/common/share/login/instance/LoginInstance.java
  80. 167
      share/src/main/java/vip/devkit/common/share/login/instance/QQLoginInstance.java
  81. 139
      share/src/main/java/vip/devkit/common/share/login/instance/WeiboLoginInstance.java
  82. 199
      share/src/main/java/vip/devkit/common/share/login/instance/WxLoginInstance.java
  83. 25
      share/src/main/java/vip/devkit/common/share/login/result/BaseToken.java
  84. 62
      share/src/main/java/vip/devkit/common/share/login/result/BaseUser.java
  85. 16
      share/src/main/java/vip/devkit/common/share/login/result/QQToken.java
  86. 41
      share/src/main/java/vip/devkit/common/share/login/result/QQUser.java
  87. 39
      share/src/main/java/vip/devkit/common/share/login/result/WeiboToken.java
  88. 120
      share/src/main/java/vip/devkit/common/share/login/result/WeiboUser.java
  89. 26
      share/src/main/java/vip/devkit/common/share/login/result/WxToken.java
  90. 63
      share/src/main/java/vip/devkit/common/share/login/result/WxUser.java
  91. 126
      share/src/main/java/vip/devkit/common/share/share/ImageDecoder.java
  92. 38
      share/src/main/java/vip/devkit/common/share/share/ShareImageObject.java
  93. 55
      share/src/main/java/vip/devkit/common/share/share/ShareListener.java
  94. 25
      share/src/main/java/vip/devkit/common/share/share/SharePlatform.java
  95. 102
      share/src/main/java/vip/devkit/common/share/share/instance/DefaultShareInstance.java
  96. 218
      share/src/main/java/vip/devkit/common/share/share/instance/QQShareInstance.java
  97. 26
      share/src/main/java/vip/devkit/common/share/share/instance/ShareInstance.java
  98. 155
      share/src/main/java/vip/devkit/common/share/share/instance/WeiboShareInstance.java
  99. 200
      share/src/main/java/vip/devkit/common/share/share/instance/WxShareInstance.java
  100. BIN
      share/src/main/jniLibs/arm64-v8a/libweibosdkcore.so
  101. Some files were not shown because too many files have changed in this diff Show More

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExportableFileTemplateSettings">
<internal_templates>
<template name="Class.java" reformat="true" live-template-enabled="true" enabled="true" />
</internal_templates>
</component>
</project>

@ -0,0 +1,5 @@
#parse("File Header.java")
#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("Class Header.java")
public class ${NAME} {
}

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GradleSettings">
<option name="linkedExternalProjectsSettings">
<GradleProjectSettings>
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />
<option value="$PROJECT_DIR$/app" />
<option value="$PROJECT_DIR$/share" />
</set>
</option>
<option name="resolveModulePerSourceSet" value="false" />
</GradleProjectSettings>
</option>
</component>
</project>

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="__local_aars__:D.\AppItem\ShareLib\share\libs\open_sdk_r5990_lite.jar:unspecified@jar">
<CLASSES>
<root url="jar://$PROJECT_DIR$/share/libs/open_sdk_r5990_lite.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,9 @@
<component name="libraryTable">
<library name="__local_aars__:D.\AppItem\ShareLib\share\libs\weiboSDKCore_3.1.4.jar:unspecified@jar">
<CLASSES>
<root url="jar://$PROJECT_DIR$/share/libs/weiboSDKCore_3.1.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="com.android.support:animated-vector-drawable-25.0.0">
<CLASSES>
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/25.0.0/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/25.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/animated-vector-drawable/25.0.0/animated-vector-drawable-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/animated-vector-drawable/25.0.0/animated-vector-drawable-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="com.android.support:appcompat-v7-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/25.0.0/jars/classes.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/appcompat-v7/25.0.0/res" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/appcompat-v7/25.0.0/appcompat-v7-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/appcompat-v7/25.0.0/appcompat-v7-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,13 @@
<component name="libraryTable">
<library name="com.android.support:support-annotations:25.0.0@jar">
<CLASSES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-annotations/25.0.0/support-annotations-25.0.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-annotations/25.0.0/support-annotations-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-annotations/25.0.0/support-annotations-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="com.android.support:support-compat-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-compat/25.0.0/jars/classes.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-compat/25.0.0/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-compat/25.0.0/jars/libs/internal_impl-25.0.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-compat/25.0.0/support-compat-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-compat/25.0.0/support-compat-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="com.android.support:support-core-ui-25.0.0">
<CLASSES>
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-ui/25.0.0/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-ui/25.0.0/jars/classes.jar!/" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-ui/25.0.0/jars/libs/internal_impl-25.0.0.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-core-ui/25.0.0/support-core-ui-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-core-ui/25.0.0/support-core-ui-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="com.android.support:support-core-utils-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-utils/25.0.0/jars/classes.jar!/" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-utils/25.0.0/jars/libs/internal_impl-25.0.0.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-core-utils/25.0.0/res" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-core-utils/25.0.0/support-core-utils-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-core-utils/25.0.0/support-core-utils-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="com.android.support:support-fragment-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-fragment/25.0.0/jars/classes.jar!/" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-fragment/25.0.0/jars/libs/internal_impl-25.0.0.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-fragment/25.0.0/res" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-fragment/25.0.0/support-fragment-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-fragment/25.0.0/support-fragment-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,15 @@
<component name="libraryTable">
<library name="com.android.support:support-media-compat-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-media-compat/25.0.0/jars/libs/internal_impl-25.0.0.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-media-compat/25.0.0/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-media-compat/25.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-media-compat/25.0.0/support-media-compat-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-media-compat/25.0.0/support-media-compat-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,10 @@
<component name="libraryTable">
<library name="com.android.support:support-v4-25.0.0">
<CLASSES>
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/25.0.0/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-v4/25.0.0/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES />
</library>
</component>

@ -0,0 +1,14 @@
<component name="libraryTable">
<library name="com.android.support:support-vector-drawable-25.0.0">
<CLASSES>
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/25.0.0/jars/classes.jar!/" />
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/25.0.0/res" />
</CLASSES>
<JAVADOC>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-vector-drawable/25.0.0/support-vector-drawable-25.0.0-javadoc.jar!/" />
</JAVADOC>
<SOURCES>
<root url="jar://D:/SDK/extras/android/m2repository/com/android/support/support-vector-drawable/25.0.0/support-vector-drawable-25.0.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="com.squareup.okhttp3:okhttp:3.4.2@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/3.4.2/ccde00f7ccc77af5a6d5752e2cb21f6d8998289f/okhttp-3.4.2.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okhttp3/okhttp/3.4.2/27f62476dfeacb8e8d2595988cd67995e65e9a42/okhttp-3.4.2-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="com.squareup.okio:okio:1.9.0@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.9.0/f824591a0016efbaeddb8300bee54832a1398cfa/okio-1.9.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.squareup.okio/okio/1.9.0/3aaaf83694e8c88e8c33c71b609f0ad506007a4a/okio-1.9.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.1.0@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.tencent.mm.opensdk/wechat-sdk-android-with-mta/5.1.0/ef06c11363a4e7efae4c208a34ca4472cd7b9bd9/wechat-sdk-android-with-mta-5.1.0.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.tencent.mm.opensdk/wechat-sdk-android-with-mta/5.1.0/d996e7d3c71ae323d86ebf390d9a03b27b6c1fcd/wechat-sdk-android-with-mta-5.1.0-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.1.4@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.tencent.mm.opensdk/wechat-sdk-android-with-mta/5.1.4/a2166720f73c470341d9cf4b57edd3bbd42f8f8c/wechat-sdk-android-with-mta-5.1.4.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/com.tencent.mm.opensdk/wechat-sdk-android-with-mta/5.1.4/67f3b847f2177ba2a186a8aa929e516c9d4ce4b5/wechat-sdk-android-with-mta-5.1.4-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,12 @@
<component name="libraryTable">
<library name="io.reactivex:rxandroid-1.2.1">
<CLASSES>
<root url="file://$PROJECT_DIR$/app/build/intermediates/exploded-aar/io.reactivex/rxandroid/1.2.1/res" />
<root url="jar://$PROJECT_DIR$/app/build/intermediates/exploded-aar/io.reactivex/rxandroid/1.2.1/jars/classes.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.reactivex/rxandroid/1.2.1/da8e4eadb096aa6264d31760e8f4623cb565e36b/rxandroid-1.2.1-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="io.reactivex:rxjava:1.2.3@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.reactivex/rxjava/1.2.3/7fe1a94c1aeb958acc876fe616922cc191f3222c/rxjava-1.2.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/io.reactivex/rxjava/1.2.3/8f6af8e090929fe0ebc36b6b79b4da7decfd481e/rxjava-1.2.3-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="junit:junit:4.12@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/2973d150c0dc1fefe998f834810d68f278ea58ec/junit-4.12.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/junit/junit/4.12/a6c32b40bf3d76eca54e3c601e5d1470c86fcdfa/junit-4.12-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,11 @@
<component name="libraryTable">
<library name="org.hamcrest:hamcrest-core:1.3@jar">
<CLASSES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/42a25dc3219429f0e5d060061f71acb49bf010a0/hamcrest-core-1.3.jar!/" />
</CLASSES>
<JAVADOC />
<SOURCES>
<root url="jar://$USER_HOME$/.gradle/caches/modules-2/files-2.1/org.hamcrest/hamcrest-core/1.3/1dc37250fbc78e23a65a67fbbaf71d2e9cbc3c0b/hamcrest-core-1.3-sources.jar!/" />
</SOURCES>
</library>
</component>

@ -0,0 +1,33 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="NullableNotNullManager">
<option name="myDefaultNullable" value="android.support.annotation.Nullable" />
<option name="myDefaultNotNull" value="android.support.annotation.NonNull" />
<option name="myNullables">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.Nullable" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nullable" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.Nullable" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.Nullable" />
</list>
</value>
</option>
<option name="myNotNulls">
<value>
<list size="4">
<item index="0" class="java.lang.String" itemvalue="org.jetbrains.annotations.NotNull" />
<item index="1" class="java.lang.String" itemvalue="javax.annotation.Nonnull" />
<item index="2" class="java.lang.String" itemvalue="edu.umd.cs.findbugs.annotations.NonNull" />
<item index="3" class="java.lang.String" itemvalue="android.support.annotation.NonNull" />
</list>
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_7" project-jdk-name="1.8" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
<option name="id" value="Android" />
</component>
</project>

@ -0,0 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/ShareLib.iml" filepath="$PROJECT_DIR$/ShareLib.iml" />
<module fileurl="file://$PROJECT_DIR$/app/app.iml" filepath="$PROJECT_DIR$/app/app.iml" />
<module fileurl="file://$PROJECT_DIR$/share/share.iml" filepath="$PROJECT_DIR$/share/share.iml" />
</modules>
</component>
</project>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="RunConfigurationProducerService">
<option name="ignoredProducers">
<set>
<option value="org.jetbrains.plugins.gradle.execution.test.runner.AllInPackageGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestClassGradleConfigurationProducer" />
<option value="org.jetbrains.plugins.gradle.execution.test.runner.TestMethodGradleConfigurationProducer" />
</set>
</option>
</component>
</project>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id="ShareLib" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="java-gradle" name="Java-Gradle">
<configuration>
<option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
<option name="BUILDABLE" value="false" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
<exclude-output />
<content url="file://$MODULE_DIR$">
<excludeFolder url="file://$MODULE_DIR$/.gradle" />
</content>
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

1
app/.gitignore vendored

@ -0,0 +1 @@
/build

@ -0,0 +1,123 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":app" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-compat/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-ui/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-core-utils/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-fragment/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-media-compat/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-v4/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/25.0.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/io.reactivex/rxandroid/1.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
<excludeFolder url="file://$MODULE_DIR$/build/test-results" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.1.4@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-fragment-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-annotations:25.0.0@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-core-ui-25.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="org.hamcrest:hamcrest-core:1.3@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-core-utils-25.0.0" level="project" />
<orderEntry type="library" exported="" name="io.reactivex:rxjava:1.2.3@jar" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit:junit:4.12@jar" level="project" />
<orderEntry type="library" exported="" name="com.squareup.okhttp3:okhttp:3.4.2@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:appcompat-v7-25.0.0" level="project" />
<orderEntry type="library" exported="" name="io.reactivex:rxandroid-1.2.1" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-media-compat-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-compat-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:animated-vector-drawable-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.squareup.okio:okio:1.9.0@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-vector-drawable-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-v4-25.0.0" level="project" />
<orderEntry type="module" module-name="share" exported="" />
</component>
</module>

@ -0,0 +1,39 @@
apply plugin: 'com.android.application'
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
applicationId "vip.devkit.share"
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
manifestPlaceholders = [
qq_id: "1106535201"
]
ndk {
abiFilters 'armeabi', 'x86', 'armeabi-v7a'//, 'x86_64', 'arm64-v8a'
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
sourceSets {
main.jniLibs.srcDirs = ['libs']
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.0.0'
// compile 'vip.devkit:common.share:1.0.7'
compile project(':share')
}

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,26 @@
package vip.devkit.share;
import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() throws Exception {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getTargetContext();
assertEquals("vip.devkit.share", appContext.getPackageName());
}
}

@ -0,0 +1,30 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vip.devkit.share">
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="vip.devkit.common.share._ShareActivity"/>
<activity-alias
android:name=".wxapi.WXEntryActivity"
android:exported="true"
android:targetActivity="vip.devkit.common.share._ShareActivity"
/>
</application>
</manifest>

@ -0,0 +1,118 @@
package vip.devkit.share;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.Toast;
import vip.devkit.common.share.LoginUtil;
import vip.devkit.common.share.ShareConfig;
import vip.devkit.common.share.ShareManager;
import vip.devkit.common.share.ShareUtil;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.LoginPlatform;
import vip.devkit.common.share.login.LoginResult;
import vip.devkit.common.share.login.result.QQToken;
import vip.devkit.common.share.login.result.QQUser;
import vip.devkit.common.share.share.ShareListener;
import vip.devkit.common.share.share.SharePlatform;
public class MainActivity extends AppCompatActivity {
LoginListener mLoginListener;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化shareUtil
ShareConfig config = ShareConfig.instance()
.qqId("1106535201")
.weiboId("XXXXXX")
.wxId("xXXXXX");
ShareManager.init(config);
findViewById(R.id.btn_qq).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
/* ShareUtil.shareImage(MainActivity.this, SharePlatform.QQ,
"https://www.baidu.com/img/pcdongtai_b60a4b2d8e0d0d6392de47d4cec6fdc3.gif", new ShareListener() {
@Override
public void shareSuccess() {
Log.i("TAG", "分享成功");
}
@Override
public void shareFailure(Exception e) {
Log.i("TAG", "分享失败");
}
@Override
public void shareCancel() {
Log.i("TAG", "分享取消");
}
});*/
LoginUtil.login(MainActivity.this, LoginPlatform.QQ, mLoginListener);
}
});
findViewById(R.id.btn_qzone).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
ShareUtil.shareImage(MainActivity.this, SharePlatform.WEIBO,
"https://www.baidu.com/img/pcdongtai_b60a4b2d8e0d0d6392de47d4cec6fdc3.gif", new ShareListener() {
@Override
public void shareSuccess() {
Log.i("TAG", "分享成功");
}
@Override
public void shareFailure(Exception e) {
Log.i("TAG", "分享失败");
}
@Override
public void shareCancel() {
Log.i("TAG", "分享取消");
}
});
}
});
mLoginListener = new LoginListener() {
@Override
public void loginSuccess(LoginResult result) {
Toast.makeText(MainActivity.this,
result.getUserInfo() != null ? result.getUserInfo().getNickname()
: "" + "登录成功", Toast.LENGTH_SHORT).show();
// 处理result
switch (result.getPlatform()) {
case LoginPlatform.QQ:
QQUser user = (QQUser) result.getUserInfo();
QQToken token = (QQToken) result.getToken();
Log.i("atag",user+"/"+token+"/"+result.getUserInfo());
break;
case LoginPlatform.WEIBO:
// 处理信息
break;
case LoginPlatform.WX:
break;
}
}
@Override
public void loginFailure(Exception e) {
Toast.makeText(MainActivity.this, "登录失败", Toast.LENGTH_SHORT).show();
}
@Override
public void loginCancel() {
Toast.makeText(MainActivity.this, "登录取消", Toast.LENGTH_SHORT).show();
}
};
}
}

@ -0,0 +1,34 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillType="evenOdd"
android:pathData="M32,64C32,64 38.39,52.99 44.13,50.95C51.37,48.37 70.14,49.57 70.14,49.57L108.26,87.69L108,109.01L75.97,107.97L32,64Z"
android:strokeColor="#00000000"
android:strokeWidth="1">
<aapt:attr name="android:fillColor">
<gradient
android:endX="78.5885"
android:endY="90.9159"
android:startX="48.7653"
android:startY="61.0927"
android:type="linear">
<item
android:color="#44000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#FFFFFF"
android:fillType="nonZero"
android:pathData="M66.94,46.02L66.94,46.02C72.44,50.07 76,56.61 76,64L32,64C32,56.61 35.56,50.11 40.98,46.06L36.18,41.19C35.45,40.45 35.45,39.3 36.18,38.56C36.91,37.81 38.05,37.81 38.78,38.56L44.25,44.05C47.18,42.57 50.48,41.71 54,41.71C57.48,41.71 60.78,42.57 63.68,44.05L69.11,38.56C69.84,37.81 70.98,37.81 71.71,38.56C72.44,39.3 72.44,40.45 71.71,41.19L66.94,46.02ZM62.94,56.92C64.08,56.92 65,56.01 65,54.88C65,53.76 64.08,52.85 62.94,52.85C61.8,52.85 60.88,53.76 60.88,54.88C60.88,56.01 61.8,56.92 62.94,56.92ZM45.06,56.92C46.2,56.92 47.13,56.01 47.13,54.88C47.13,53.76 46.2,52.85 45.06,52.85C43.92,52.85 43,53.76 43,54.88C43,56.01 43.92,56.92 45.06,56.92Z"
android:strokeColor="#00000000"
android:strokeWidth="1" />
</vector>

@ -0,0 +1,170 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportHeight="108"
android:viewportWidth="108">
<path
android:fillColor="#26A69A"
android:pathData="M0,0h108v108h-108z" />
<path
android:fillColor="#00000000"
android:pathData="M9,0L9,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,0L19,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,0L29,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,0L39,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,0L49,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,0L59,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,0L69,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,0L79,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M89,0L89,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M99,0L99,108"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,9L108,9"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,19L108,19"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,29L108,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,39L108,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,49L108,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,59L108,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,69L108,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,79L108,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,89L108,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M0,99L108,99"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,29L89,29"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,39L89,39"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,49L89,49"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,59L89,59"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,69L89,69"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M19,79L89,79"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M29,19L29,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M39,19L39,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M49,19L49,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M59,19L59,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M69,19L69,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
<path
android:fillColor="#00000000"
android:pathData="M79,19L79,89"
android:strokeColor="#33FFFFFF"
android:strokeWidth="0.8" />
</vector>

@ -0,0 +1,27 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context="vip.devkit.share.MainActivity">
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!" />
<Button
android:id="@+id/btn_qq"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="QQ" />
<Button
android:id="@+id/btn_qzone"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="QQ" />
</LinearLayout>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background" />
<foreground android:drawable="@drawable/ic_launcher_foreground" />
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

@ -0,0 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="colorPrimary">#3F51B5</color>
<color name="colorPrimaryDark">#303F9F</color>
<color name="colorAccent">#FF4081</color>
</resources>

@ -0,0 +1,3 @@
<resources>
<string name="app_name">ShareLib</string>
</resources>

@ -0,0 +1,11 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.AppCompat.Light.DarkActionBar">
<!-- Customize your theme here. -->
<item name="colorPrimary">@color/colorPrimary</item>
<item name="colorPrimaryDark">@color/colorPrimaryDark</item>
<item name="colorAccent">@color/colorAccent</item>
</style>
</resources>

@ -0,0 +1,17 @@
package vip.devkit.share;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() throws Exception {
assertEquals(4, 2 + 2);
}
}

@ -0,0 +1,42 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.0.0'
classpath 'com.novoda:bintray-release:0.3.4'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
}
}
allprojects {
repositories {
jcenter()
maven { url 'https://dl.bintray.com/yingzi/maven' }
maven { url "https://jitpack.io" }
}
tasks.withType(Javadoc) {
options.addStringOption('Xdoclint:none', '-quiet')
options.addStringOption('encoding', 'UTF-8')
}
}
task clean(type: Delete) {
delete rootProject.buildDir
}
//
ext {
userOrg = 'yingzi' //bintray注册的用户名
groupId = 'vip.devkit' //compile引用时的第1部分groupId
artifactId = 'common.share' //compile引用时的第2部分项目名
publishVersion = '1.0.8' //compile引用时的第3部分版本号
desc = 'This is a common.widget extend library'
website = 'https://github.com/yingzikeji/AndroidUtils'
licences = ['Apache-2.0']
}

@ -0,0 +1,18 @@
# Project-wide Gradle settings.
# IDE (e.g. Android Studio) users:
# Gradle settings configured through the IDE *will override*
# any settings specified in this file.
# For more details on how to configure your build environment visit
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
org.gradle.jvmargs=-Xmx1536m
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. More details, visit
# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
# org.gradle.parallel=true
android.useDeprecatedNdk=true

Binary file not shown.

@ -0,0 +1,6 @@
#Mon Dec 28 10:00:20 PST 2015
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip

160
gradlew vendored

@ -0,0 +1,160 @@
#!/usr/bin/env bash
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS=""
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn ( ) {
echo "$*"
}
die ( ) {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
esac
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=$((i+1))
done
case $i in
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
function splitJvmOpts() {
JVM_OPTS=("$@")
}
eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"

90
gradlew.bat vendored

@ -0,0 +1,90 @@
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS=
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:init
@rem Get command-line arguments, handling Windowz variants
if not "%OS%" == "Windows_NT" goto win9xME_args
if "%@eval[2+2]" == "4" goto 4NT_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
goto execute
:4NT_args
@rem Get arguments from the 4NT Shell from JP Software
set CMD_LINE_ARGS=%$
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega

@ -0,0 +1 @@
include ':app', ':share'

1
share/.gitignore vendored

@ -0,0 +1 @@
/build

@ -0,0 +1,47 @@
apply plugin: 'com.android.library'
apply plugin: 'com.novoda.bintray-release'
publish {
userOrg = 'yingzi' //bintray注册的用户名
groupId = 'vip.devkit' //compile引用时的第1部分groupId
artifactId = 'common.share' //compile引用时的第2部分项目名
publishVersion = '1.0.8' //compile引用时的第3部分版本号
desc = 'This is a androud-utils extend library'
website = 'https://github.com/yingzikeji/AndroidUtils'
/*
*
* gradlew clean build bintrayUpload -PbintrayUser=yingzi -PbintrayKey=ed9a147c9625f44063e1504a6879b344eb7d76fd -PdryRun=false
* */
}
android {
compileSdkVersion 25
buildToolsVersion "25.0.0"
defaultConfig {
minSdkVersion 15
targetSdkVersion 25
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
lintOptions {
abortOnError false
}
}
dependencies {
compile fileTree(include: ['*.jar'], dir: 'libs')
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:25.0.0'
compile 'io.reactivex:rxjava:1.2.3'
compile 'io.reactivex:rxandroid:1.2.1'
compile 'com.squareup.okhttp3:okhttp:3.4.2'
compile 'com.tencent.mm.opensdk:wechat-sdk-android-with-mta:+'
compile files('libs/open_sdk_r5990_lite.jar')
compile files('libs/weiboSDKCore_3.1.4.jar')
}

Binary file not shown.

@ -0,0 +1,21 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile

@ -0,0 +1,114 @@
<?xml version="1.0" encoding="UTF-8"?>
<module external.linked.project.id=":share" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
<component name="FacetManager">
<facet type="android-gradle" name="Android-Gradle">
<configuration>
<option name="GRADLE_PROJECT_PATH" value=":share" />
</configuration>
</facet>
<facet type="android" name="Android">
<configuration>
<option name="SELECTED_BUILD_VARIANT" value="debug" />
<option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
<option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
<afterSyncTasks>
<task>generateDebugSources</task>
</afterSyncTasks>
<option name="ALLOW_USER_CONFIGURATION" value="false" />
<option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
<option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
<option name="RES_FOLDERS_RELATIVE_PATH" value="file://$MODULE_DIR$/src/main/res" />
<option name="ASSETS_FOLDER_RELATIVE_PATH" value="/src/main/assets" />
<option name="PROJECT_TYPE" value="1" />
</configuration>
</facet>
</component>
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7">
<output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
<output-test url="file://$MODULE_DIR$/build/intermediates/classes/test/debug" />
<exclude-output />
<content url="file://$MODULE_DIR$">
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/testDebug/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/main/res" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/assets" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/main/aidl" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/main/rs" isTestSource="false" />
<sourceFolder url="file://$MODULE_DIR$/src/test/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/test/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/test/rs" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/res" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/resources" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/assets" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/aidl" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/java" isTestSource="true" />
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/rs" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/docs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/annotations" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/lint" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/libs" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/publications" />
<excludeFolder url="file://$MODULE_DIR$/build/reports" />
<excludeFolder url="file://$MODULE_DIR$/build/test-results" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 25 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="com.tencent.mm.opensdk:wechat-sdk-android-with-mta:5.1.4@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-fragment-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-annotations:25.0.0@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-core-ui-25.0.0" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="org.hamcrest:hamcrest-core:1.3@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-core-utils-25.0.0" level="project" />
<orderEntry type="library" exported="" name="io.reactivex:rxjava:1.2.3@jar" level="project" />
<orderEntry type="library" exported="" scope="TEST" name="junit:junit:4.12@jar" level="project" />
<orderEntry type="library" exported="" name="com.squareup.okhttp3:okhttp:3.4.2@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:appcompat-v7-25.0.0" level="project" />
<orderEntry type="library" exported="" name="io.reactivex:rxandroid-1.2.1" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-media-compat-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-compat-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:animated-vector-drawable-25.0.0" level="project" />
<orderEntry type="library" exported="" name="__local_aars__:D.\AppItem\ShareLib\share\libs\open_sdk_r5990_lite.jar:unspecified@jar" level="project" />
<orderEntry type="library" exported="" name="__local_aars__:D.\AppItem\ShareLib\share\libs\weiboSDKCore_3.1.4.jar:unspecified@jar" level="project" />
<orderEntry type="library" exported="" name="com.squareup.okio:okio:1.9.0@jar" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-vector-drawable-25.0.0" level="project" />
<orderEntry type="library" exported="" name="com.android.support:support-v4-25.0.0" level="project" />
</component>
</module>

@ -0,0 +1,55 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="vip.devkit.common.share">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<application
android:allowBackup="true"
android:label="@string/app_name"
android:supportsRtl="true"
>
<activity
android:name="com.sina.weibo.sdk.component.WeiboSdkBrowser"
android:configChanges="keyboardHidden|orientation"
android:exported="false"
android:windowSoftInputMode="adjustResize"
>
</activity>
<activity
android:name="com.tencent.connect.common.AssistActivity"
android:configChanges="orientation|keyboardHidden"
android:taskAffinity="me.shaohui.shareutil"
android:screenOrientation="behind"
android:theme="@android:style/Theme.Translucent.NoTitleBar"
>
</activity>
<activity
android:name="com.tencent.tauth.AuthActivity"
android:noHistory="true">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="${qq_id}"/>
</intent-filter>
</activity>
<activity android:name="vip.devkit.common.share._ShareActivity"
android:launchMode="singleTask"
android:taskAffinity="me.shaohui.shareutil"
android:theme="@android:style/Theme.Translucent.NoTitleBar">
<intent-filter>
<action android:name="com.sina.weibo.sdk.action.ACTION_SDK_REQ_ACTIVITY" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<activity-alias
android:name="${applicationId}.wxapi.WXEntryActivity"
android:exported="true"
android:targetActivity="vip.devkit.common.share._ShareActivity"/>
</application>
</manifest>

Binary file not shown.

After

Width:  |  Height:  |  Size: 26 KiB

@ -0,0 +1,110 @@
package vip.devkit.common.share;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.LoginPlatform;
import vip.devkit.common.share.login.LoginResult;
import vip.devkit.common.share.login.instance.LoginInstance;
import vip.devkit.common.share.login.instance.QQLoginInstance;
import vip.devkit.common.share.login.instance.WeiboLoginInstance;
import vip.devkit.common.share.login.instance.WxLoginInstance;
import vip.devkit.common.share.login.result.BaseToken;
public class LoginUtil {
private static LoginInstance mLoginInstance;
private static LoginListener mLoginListener;
private static int mPlatform;
private static boolean isFetchUserInfo;
static final int TYPE = 799;
public static void login(Context context, @LoginPlatform.Platform int platform,
LoginListener listener) {
login(context, platform, listener, true);
}
public static void login(Context context, @LoginPlatform.Platform int platform,
LoginListener listener, boolean fetchUserInfo) {
mPlatform = platform;
mLoginListener = new LoginListenerProxy(listener);
isFetchUserInfo = fetchUserInfo;
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
static void action(Activity activity) {
switch (mPlatform) {
case LoginPlatform.QQ:
mLoginInstance = new QQLoginInstance(activity, mLoginListener, isFetchUserInfo);
break;
case LoginPlatform.WEIBO:
mLoginInstance = new WeiboLoginInstance(activity, mLoginListener, isFetchUserInfo);
break;
case LoginPlatform.WX:
mLoginInstance = new WxLoginInstance(activity, mLoginListener, isFetchUserInfo);
break;
default:
mLoginListener.loginFailure(new Exception(ShareLogger.INFO.UNKNOW_PLATFORM));
activity.finish();
}
mLoginInstance.doLogin(activity, mLoginListener, isFetchUserInfo);
}
static void handleResult(int requestCode, int resultCode, Intent data) {
if (mLoginInstance != null) {
mLoginInstance.handleResult(requestCode, resultCode, data);
}
}
public static void recycle() {
if (mLoginInstance != null) {
mLoginInstance.recycle();
}
mLoginInstance = null;
mLoginListener = null;
mPlatform = 0;
isFetchUserInfo = false;
}
private static class LoginListenerProxy extends LoginListener {
private LoginListener mListener;
LoginListenerProxy(LoginListener listener) {
mListener = listener;
}
@Override
public void loginSuccess(LoginResult result) {
ShareLogger.i(ShareLogger.INFO.LOGIN_SUCCESS);
mListener.loginSuccess(result);
recycle();
}
@Override
public void loginFailure(Exception e) {
ShareLogger.i(ShareLogger.INFO.LOGIN_FAIl);
mListener.loginFailure(e);
recycle();
}
@Override
public void loginCancel() {
ShareLogger.i(ShareLogger.INFO.LOGIN_CANCEL);
mListener.loginCancel();
recycle();
}
@Override
public void beforeFetchUserInfo(BaseToken token) {
ShareLogger.i(ShareLogger.INFO.LOGIN_AUTH_SUCCESS);
mListener.beforeFetchUserInfo(token);
}
}
}

@ -0,0 +1,105 @@
/*
******************************* Copyright (c)*********************************\
**
** (c) Copyright 2017, DevKit.vip, china, qd. sd
** All Rights Reserved
**
** By(K)
********************************End of Head************************************\
*/
package vip.devkit.common.share;
/**
* : ShareConfig
* 功能描述:
* : By k
* :vip@devkit.vip
* :www.devkit.vip
* 创建日期: 2018/1/29
* : V 1.0
* 代码修改:修改人 - 修改时间
* 修改备注
*/
public class ShareConfig {
private String wxId;
private String wxSecret;
private String qqId;
private String weiboId;
private String weiboRedirectUrl = "https://api.weibo.com/oauth2/default.html";
private String weiboScope = "email";
private boolean debug;
public static ShareConfig instance() {
return new ShareConfig();
}
public ShareConfig wxId(String id) {
wxId = id;
return this;
}
public ShareConfig wxSecret(String id) {
wxSecret = id;
return this;
}
public ShareConfig qqId(String id) {
qqId = id;
return this;
}
public ShareConfig weiboId(String id) {
weiboId = id;
return this;
}
public ShareConfig weiboRedirectUrl(String url) {
weiboRedirectUrl = url;
return this;
}
public ShareConfig weiboScope(String scope) {
weiboScope = scope;
return this;
}
public ShareConfig debug(boolean isDebug) {
debug = isDebug;
return this;
}
public String getWxId() {
return wxId;
}
public String getWxSecret() {
return wxSecret;
}
public String getQqId() {
return qqId;
}
public String getWeiboId() {
return weiboId;
}
public String getWeiboRedirectUrl() {
return weiboRedirectUrl;
}
public String getWeiboScope() {
return weiboScope;
}
public boolean isDebug() {
return debug;
}
}

@ -0,0 +1,64 @@
package vip.devkit.common.share;
import android.util.Log;
public class ShareLogger {
private static final String TAG = "share_util_log";
public static void i(String info) {
if (ShareManager.CONFIG.isDebug()) {
Log.i(TAG, info);
}
}
public static void e(String error) {
if (ShareManager.CONFIG.isDebug()) {
Log.e(TAG, error);
}
}
public static class INFO {
public static final String SHARE_SUCCESS = "call share success";
public static final String SHARE_FAILURE = "call share failure";
public static final String SHARE_CANCEL = "call share cancel";
public static final String SHARE_REQUEST = "call share request";
// for share
public static final String HANDLE_DATA_NULL = "Handle the result, but the data is null, please check you app id";
public static final String UNKNOWN_ERROR = "Unknown error";
public static final String NOT_INSTALL = "The application is not install";
public static final String DEFAULT_QQ_SHARE_ERROR = "QQ share failed";
public static final String QQ_NOT_SUPPORT_SHARE_TXT = "QQ not support share text";
public static final String IMAGE_FETCH_ERROR = "Image fetch error";
public static final String SD_CARD_NOT_AVAILABLE = "The sd card is not available";
// for login
public static final String LOGIN_SUCCESS = "call login success";
public static final String LOGIN_FAIl = "call login failed";
public static final String LOGIN_CANCEL = "call login cancel";
public static final String LOGIN_AUTH_SUCCESS = "call before fetch user info";
public static final String ILLEGAL_TOKEN = "Illegal token, please check your config";
public static final String QQ_LOGIN_ERROR = "QQ login error";
public static final String QQ_AUTH_SUCCESS = "QQ auth success";
public static final String WEIBO_AUTH_ERROR = "weibo auth error";
public static final String UNKNOW_PLATFORM = "unknown platform";
public static final String WX_ERR_SENT_FAILED = "Wx sent failed";
public static final String WX_ERR_UNSUPPORT = "Wx UnSupport";
public static final String WX_ERR_AUTH_DENIED = "Wx auth denied";
public static final String WX_ERR_AUTH_ERROR = "Wx auth error";
public static final String AUTH_CANCEL = "auth cancel";
public static final String FETCH_USER_INOF_ERROR = "Fetch user info error";
// for shareActivity
public static final String ACTIVITY_CREATE = "ShareActivity onCreate";
public static final String ACTIVITY_RESUME = "ShareActivity onResume";
public static final String ACTIVITY_RESULT = "ShareActivity onActivityResult";
public static final String ACTIVITY_NEW_INTENT = "ShareActivity onNewIntent";
}
}

@ -0,0 +1,30 @@
/*
******************************* Copyright (c)*********************************\
**
** (c) Copyright 2017, DevKit.vip, china, qd. sd
** All Rights Reserved
**
** By(K)
********************************End of Head************************************\
*/
package vip.devkit.common.share;
/**
* : ShareManager
* 功能描述:
* : By k
* :vip@devkit.vip
* :www.devkit.vip
* 创建日期: 2018/1/29
* : V 1.0
* 代码修改:修改人 - 修改时间
* 修改备注
*/
public class ShareManager {
private static boolean isInit = false;
public static ShareConfig CONFIG;
public static void init(ShareConfig config) {
isInit = true;
CONFIG = config;
}
}

@ -0,0 +1,300 @@
/*
******************************* Copyright (c)*********************************\
**
** (c) Copyright 2017, DevKit.vip, china, qd. sd
** All Rights Reserved
**
** By(K)
********************************End of Head************************************\
*/
package vip.devkit.common.share;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.support.annotation.NonNull;
import android.text.TextUtils;
import com.sina.weibo.sdk.api.share.IWeiboShareAPI;
import com.sina.weibo.sdk.api.share.WeiboShareSDK;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import java.util.List;
import java.util.Locale;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
import vip.devkit.common.share.share.SharePlatform;
import vip.devkit.common.share.share.instance.DefaultShareInstance;
import vip.devkit.common.share.share.instance.QQShareInstance;
import vip.devkit.common.share.share.instance.ShareInstance;
import vip.devkit.common.share.share.instance.WeiboShareInstance;
import vip.devkit.common.share.share.instance.WxShareInstance;
/**
* : ShareUtil
* 功能描述:
* : By k
* :vip@devkit.vip
* :www.devkit.vip
* 创建日期: 2018/1/29
* : V 1.0
* 代码修改:修改人 - 修改时间
* 修改备注
*/
public class ShareUtil {
/**
* 测试case
*
* 1. 本地图片 vs 网络图片
* 2. 图片大小限制
* 3. 文字长度限制
*/
public static final int TYPE = 798;
public static ShareListener mShareListener;
private static ShareInstance mShareInstance;
private final static int TYPE_IMAGE = 1;
private final static int TYPE_TEXT = 2;
private final static int TYPE_MEDIA = 3;
private static int mType;
private static int mPlatform;
private static String mText;
private static ShareImageObject mShareImageObject;
private static String mTitle;
private static String mSummary;
private static String mTargetUrl;
static void action(Activity activity) {
mShareInstance = getShareInstance(mPlatform, activity);
// 防止之后调用 NullPointException
if (mShareListener == null) {
activity.finish();
return;
}
if (!mShareInstance.isInstall(activity)) {
mShareListener.shareFailure(new Exception(ShareLogger.INFO.NOT_INSTALL));
activity.finish();
return;
}
switch (mType) {
case TYPE_TEXT:
mShareInstance.shareText(mPlatform, mText, activity, mShareListener);
break;
case TYPE_IMAGE:
mShareInstance.shareImage(mPlatform, mShareImageObject, activity, mShareListener);
break;
case TYPE_MEDIA:
mShareInstance.shareMedia(mPlatform, mTitle, mTargetUrl, mSummary,
mShareImageObject, activity, mShareListener);
break;
}
}
public static void shareText(Context context, @SharePlatform.Platform int platform, String text,
ShareListener listener) {
mType = TYPE_TEXT;
mText = text;
mPlatform = platform;
mShareListener = buildProxyListener(listener);
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
public static void shareImage(Context context, @SharePlatform.Platform final int platform,
final String urlOrPath, ShareListener listener) {
mType = TYPE_IMAGE;
mPlatform = platform;
mShareImageObject = new ShareImageObject(urlOrPath);
mShareListener = buildProxyListener(listener);
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
public static void shareImage(Context context, @SharePlatform.Platform final int platform,
final Bitmap bitmap, ShareListener listener) {
mType = TYPE_IMAGE;
mPlatform = platform;
mShareImageObject = new ShareImageObject(bitmap);
mShareListener = buildProxyListener(listener);
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
public static void shareMedia(Context context, @SharePlatform.Platform int platform,
String title, String summary, String targetUrl, Bitmap thumb, ShareListener listener) {
mType = TYPE_MEDIA;
mPlatform = platform;
mShareImageObject = new ShareImageObject(thumb);
mSummary = summary;
mTargetUrl = targetUrl;
mTitle = title;
mShareListener = buildProxyListener(listener);
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
public static void shareMedia(Context context, @SharePlatform.Platform int platform,
String title, String summary, String targetUrl, String thumbUrlOrPath,
ShareListener listener) {
mType = TYPE_MEDIA;
mPlatform = platform;
mShareImageObject = new ShareImageObject(thumbUrlOrPath);
mSummary = summary;
mTargetUrl = targetUrl;
mTitle = title;
mShareListener = buildProxyListener(listener);
context.startActivity(_ShareActivity.newInstance(context, TYPE));
}
private static ShareListener buildProxyListener(ShareListener listener) {
return new ShareListenerProxy(listener);
}
public static void handleResult(Intent data) {
// 微博分享会同时回调onActivityResult和onNewIntent, 而且前者返回的intent为null
if (mShareInstance != null && data != null) {
mShareInstance.handleResult(data);
} else if (data == null) {
if (mPlatform != SharePlatform.WEIBO) {
ShareLogger.e(ShareLogger.INFO.HANDLE_DATA_NULL);
}
} else {
ShareLogger.e(ShareLogger.INFO.UNKNOWN_ERROR);
}
}
private static ShareInstance getShareInstance(@SharePlatform.Platform int platform,
Context context) {
switch (platform) {
case SharePlatform.WX:
case SharePlatform.WX_TIMELINE:
return new WxShareInstance(context, ShareManager.CONFIG.getWxId());
case SharePlatform.QQ:
case SharePlatform.QZONE:
return new QQShareInstance(context, ShareManager.CONFIG.getQqId());
case SharePlatform.WEIBO:
return new WeiboShareInstance(context, ShareManager.CONFIG.getWeiboId());
case SharePlatform.DEFAULT:
default:
return new DefaultShareInstance();
}
}
public static void recycle() {
mTitle = null;
mSummary = null;
mShareListener = null;
// bitmap recycle
if (mShareImageObject != null
&& mShareImageObject.getBitmap() != null
&& !mShareImageObject.getBitmap().isRecycled()) {
mShareImageObject.getBitmap().recycle();
}
mShareImageObject = null;
if (mShareInstance != null) {
mShareInstance.recycle();
}
mShareInstance = null;
}
/**
* 检查客户端是否安装
*/
public static boolean isInstalled(@SharePlatform.Platform int platform, Context context) {
switch (platform) {
case SharePlatform.QQ:
case SharePlatform.QZONE:
return isQQInstalled(context);
case SharePlatform.WEIBO:
return isWeiBoInstalled(context);
case SharePlatform.WX:
case SharePlatform.WX_TIMELINE:
return isWeiXinInstalled(context);
case SharePlatform.DEFAULT:
return true;
default:
return false;
}
}
@Deprecated
public static boolean isQQInstalled(@NonNull Context context) {
PackageManager pm = context.getPackageManager();
if (pm == null) {
return false;
}
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
for (PackageInfo info : packageInfos) {
if (TextUtils.equals(info.packageName.toLowerCase(Locale.getDefault()),
"com.tencent.mobileqq")) {
return true;
}
}
return false;
}
@Deprecated
public static boolean isWeiBoInstalled(@NonNull Context context) {
IWeiboShareAPI shareAPI =
WeiboShareSDK.createWeiboAPI(context, ShareManager.CONFIG.getWeiboId());
return shareAPI.isWeiboAppInstalled();
}
@Deprecated
public static boolean isWeiXinInstalled(Context context) {
IWXAPI api = WXAPIFactory.createWXAPI(context, ShareManager.CONFIG.getWxId(), true);
return api.isWXAppInstalled();
}
private static class ShareListenerProxy extends ShareListener {
private final ShareListener mShareListener;
ShareListenerProxy(ShareListener listener) {
mShareListener = listener;
}
@Override
public void shareSuccess() {
ShareLogger.i(ShareLogger.INFO.SHARE_SUCCESS);
ShareUtil.recycle();
mShareListener.shareSuccess();
}
@Override
public void shareFailure(Exception e) {
ShareLogger.i(ShareLogger.INFO.SHARE_FAILURE);
ShareUtil.recycle();
mShareListener.shareFailure(e);
}
@Override
public void shareCancel() {
ShareLogger.i(ShareLogger.INFO.SHARE_CANCEL);
ShareUtil.recycle();
mShareListener.shareCancel();
}
@Override
public void shareRequest() {
ShareLogger.i(ShareLogger.INFO.SHARE_REQUEST);
mShareListener.shareRequest();
}
}
}

@ -0,0 +1,87 @@
package vip.devkit.common.share;
import android.app.Activity;
import android.app.Application;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import android.support.annotation.Nullable;
import vip.devkit.common.share.ShareLogger.INFO;
public class _ShareActivity extends Activity {
private int mType;
private boolean isNew;
private static final String TYPE = "share_activity_type";
public static Intent newInstance(Context context, int type) {
Intent intent = new Intent(context, _ShareActivity.class);
if (context instanceof Application) {
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
}
intent.putExtra(TYPE, type);
return intent;
}
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
ShareLogger.i(INFO.ACTIVITY_CREATE);
isNew = true;
// init data
mType = getIntent().getIntExtra(TYPE, 0);
if (mType == ShareUtil.TYPE) {
// 分享
ShareUtil.action(this);
} else if (mType == LoginUtil.TYPE) {
// 登录
LoginUtil.action(this);
} else {
// handle 微信回调
LoginUtil.handleResult(-1, -1, getIntent());
ShareUtil.handleResult(getIntent());
finish();
}
}
@Override
protected void onResume() {
super.onResume();
ShareLogger.i(INFO.ACTIVITY_RESUME);
if (isNew) {
isNew = false;
} else {
finish();
}
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
ShareLogger.i(INFO.ACTIVITY_NEW_INTENT);
// 处理回调
if (mType == LoginUtil.TYPE) {
LoginUtil.handleResult(0, 0, intent);
} else if (mType == ShareUtil.TYPE) {
ShareUtil.handleResult(intent);
}
finish();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
ShareLogger.i(INFO.ACTIVITY_RESULT);
// 处理回调
if (mType == LoginUtil.TYPE) {
LoginUtil.handleResult(requestCode, resultCode, data);
} else if (mType == ShareUtil.TYPE) {
ShareUtil.handleResult(data);
}
finish();
}
}

@ -0,0 +1,35 @@
/*
******************************* Copyright (c)*********************************\
**
** (c) Copyright 2017, DevKit.vip, china, qd. sd
** All Rights Reserved
**
** By(K)
********************************End of Head************************************\
*/
package vip.devkit.common.share.login;
import vip.devkit.common.share.login.result.BaseToken;
/**
* : LoginListener
* 功能描述:
* : By k
* :vip@devkit.vip
* :www.devkit.vip
* 创建日期: 2018/1/29
* : V 1.0
* 代码修改:修改人 - 修改时间
* 修改备注
*/
public abstract class LoginListener {
public abstract void loginSuccess(LoginResult result);
public void beforeFetchUserInfo(BaseToken token) {
}
public abstract void loginFailure(Exception e);
public abstract void loginCancel();
}

@ -0,0 +1,26 @@
package vip.devkit.common.share.login;
import android.support.annotation.IntDef;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class LoginPlatform {
@Documented
@IntDef({QQ, WX, WEIBO})
@Retention(RetentionPolicy.SOURCE)
@Target(ElementType.PARAMETER)
public @interface Platform {
}
public static final int QQ = 1;
public static final int WX = 3;
public static final int WEIBO = 5;
}

@ -0,0 +1,49 @@
package vip.devkit.common.share.login;
import vip.devkit.common.share.login.result.BaseToken;
import vip.devkit.common.share.login.result.BaseUser;
public class LoginResult {
private BaseToken mToken;
private BaseUser mUserInfo;
private int mPlatform;
public LoginResult(int platform, BaseToken token) {
mPlatform = platform;
mToken = token;
}
public LoginResult(int platform, BaseToken token, BaseUser userInfo) {
mPlatform = platform;
mToken = token;
mUserInfo = userInfo;
}
public int getPlatform() {
return mPlatform;
}
public void setPlatform(int platform) {
this.mPlatform = platform;
}
public BaseToken getToken() {
return mToken;
}
public void setToken(BaseToken token) {
mToken = token;
}
public BaseUser getUserInfo() {
return mUserInfo;
}
public void setUserInfo(BaseUser userInfo) {
mUserInfo = userInfo;
}
}

@ -0,0 +1,26 @@
package vip.devkit.common.share.login.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.result.BaseToken;
public abstract class LoginInstance {
public LoginInstance(Activity activity, LoginListener listener, boolean fetchUserInfo) {
}
public abstract void doLogin(Activity activity, LoginListener listener, boolean fetchUserInfo);
public abstract void fetchUserInfo(BaseToken token);
public abstract void handleResult(int requestCode, int resultCode, Intent data);
public abstract boolean isInstall(Context context);
public abstract void recycle();
}

@ -0,0 +1,167 @@
package vip.devkit.common.share.login.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.text.TextUtils;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.Tencent;
import com.tencent.tauth.UiError;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.IOException;
import java.util.List;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.ShareLogger;
import vip.devkit.common.share.ShareManager;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.LoginPlatform;
import vip.devkit.common.share.login.LoginResult;
import vip.devkit.common.share.login.result.BaseToken;
import vip.devkit.common.share.login.result.QQToken;
import vip.devkit.common.share.login.result.QQUser;
public class QQLoginInstance extends LoginInstance {
private static final String SCOPE = "get_simple_userinfo";
private static final String URL = "https://graph.qq.com/user/get_user_info";
private Tencent mTencent;
private IUiListener mIUiListener;
private LoginListener mLoginListener;
public QQLoginInstance(Activity activity, final LoginListener listener,
final boolean fetchUserInfo) {
super(activity, listener, fetchUserInfo);
mTencent = Tencent.createInstance(ShareManager.CONFIG.getQqId(),
activity.getApplicationContext());
mLoginListener = listener;
mIUiListener = new IUiListener() {
@Override
public void onComplete(Object o) {
ShareLogger.i(ShareLogger.INFO.QQ_AUTH_SUCCESS);
try {
QQToken token = QQToken.parse((JSONObject) o);
if (fetchUserInfo) {
listener.beforeFetchUserInfo(token);
fetchUserInfo(token);
} else {
listener.loginSuccess(new LoginResult(LoginPlatform.QQ, token));
}
} catch (JSONException e) {
ShareLogger.i(ShareLogger.INFO.ILLEGAL_TOKEN);
mLoginListener.loginFailure(e);
}
}
@Override
public void onError(UiError uiError) {
ShareLogger.i(ShareLogger.INFO.QQ_LOGIN_ERROR);
listener.loginFailure(
new Exception("QQError: " + uiError.errorCode + uiError.errorDetail));
}
@Override
public void onCancel() {
ShareLogger.i(ShareLogger.INFO.AUTH_CANCEL);
listener.loginCancel();
}
};
}
@Override
public void doLogin(Activity activity, final LoginListener listener, boolean fetchUserInfo) {
mTencent.login(activity, SCOPE, mIUiListener);
}
@Override
public void fetchUserInfo(final BaseToken token) {
Observable.fromEmitter(new Action1<Emitter<QQUser>>() {
@Override
public void call(Emitter<QQUser> qqUserEmitter) {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(buildUserInfoUrl(token, URL)).build();
try {
Response response = client.newCall(request).execute();
JSONObject jsonObject = new JSONObject(response.body().string());
QQUser user = QQUser.parse(token.getOpenid(), jsonObject);
qqUserEmitter.onNext(user);
} catch (IOException | JSONException e) {
ShareLogger.e(ShareLogger.INFO.FETCH_USER_INOF_ERROR);
qqUserEmitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<QQUser>() {
@Override
public void call(QQUser qqUser) {
mLoginListener.loginSuccess(
new LoginResult(LoginPlatform.QQ, token, qqUser));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mLoginListener.loginFailure(new Exception(throwable));
}
});
}
private String buildUserInfoUrl(BaseToken token, String base) {
return base
+ "?access_token="
+ token.getAccessToken()
+ "&oauth_consumer_key="
+ ShareManager.CONFIG.getQqId()
+ "&openid="
+ token.getOpenid();
}
@Override
public void handleResult(int requestCode, int resultCode, Intent data) {
Tencent.handleResultData(data, mIUiListener);
}
@Override
public boolean isInstall(Context context) {
PackageManager pm = context.getPackageManager();
if (pm == null) {
return false;
}
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
for (PackageInfo info : packageInfos) {
if (TextUtils.equals(info.packageName.toLowerCase(), "com.tencent.mobileqq")) {
return true;
}
}
return false;
}
@Override
public void recycle() {
mTencent.releaseResource();
mIUiListener = null;
mLoginListener = null;
mTencent = null;
}
}

@ -0,0 +1,139 @@
package vip.devkit.common.share.login.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.os.Bundle;
import com.sina.weibo.sdk.api.share.IWeiboShareAPI;
import com.sina.weibo.sdk.api.share.WeiboShareSDK;
import com.sina.weibo.sdk.auth.AuthInfo;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
import com.sina.weibo.sdk.auth.WeiboAuthListener;
import com.sina.weibo.sdk.auth.sso.SsoHandler;
import com.sina.weibo.sdk.exception.WeiboException;
import java.io.IOException;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import org.json.JSONException;
import org.json.JSONObject;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.ShareLogger;
import vip.devkit.common.share.ShareManager;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.LoginPlatform;
import vip.devkit.common.share.login.LoginResult;
import vip.devkit.common.share.login.result.BaseToken;
import vip.devkit.common.share.login.result.WeiboToken;
import vip.devkit.common.share.login.result.WeiboUser;
import static vip.devkit.common.share.ShareLogger.INFO;
public class WeiboLoginInstance extends LoginInstance {
private static final String USER_INFO = "https://api.weibo.com/2/users/show.json";
private SsoHandler mSsoHandler;
private LoginListener mLoginListener;
public WeiboLoginInstance(Activity activity, LoginListener listener, boolean fetchUserInfo) {
super(activity, listener, fetchUserInfo);
AuthInfo authInfo = new AuthInfo(activity, ShareManager.CONFIG.getWeiboId(),
ShareManager.CONFIG.getWeiboRedirectUrl(), ShareManager.CONFIG.getWeiboScope());
mSsoHandler = new SsoHandler(activity, authInfo);
mLoginListener = listener;
}
@Override
public void doLogin(Activity activity, final LoginListener listener,
final boolean fetchUserInfo) {
mSsoHandler.authorize(new WeiboAuthListener() {
@Override
public void onComplete(Bundle bundle) {
Oauth2AccessToken accessToken = Oauth2AccessToken.parseAccessToken(bundle);
WeiboToken weiboToken = WeiboToken.parse(accessToken);
if (fetchUserInfo) {
listener.beforeFetchUserInfo(weiboToken);
fetchUserInfo(weiboToken);
} else {
listener.loginSuccess(new LoginResult(LoginPlatform.WEIBO, weiboToken));
}
}
@Override
public void onWeiboException(WeiboException e) {
ShareLogger.i(INFO.WEIBO_AUTH_ERROR);
listener.loginFailure(e);
}
@Override
public void onCancel() {
ShareLogger.i(INFO.AUTH_CANCEL);
listener.loginCancel();
}
});
}
@Override
public void fetchUserInfo(final BaseToken token) {
Observable.fromEmitter(new Action1<Emitter<WeiboUser>>() {
@Override
public void call(Emitter<WeiboUser> weiboUserEmitter) {
OkHttpClient client = new OkHttpClient();
Request request =
new Request.Builder().url(buildUserInfoUrl(token, USER_INFO)).build();
try {
Response response = client.newCall(request).execute();
JSONObject jsonObject = new JSONObject(response.body().string());
WeiboUser user = WeiboUser.parse(jsonObject);
weiboUserEmitter.onNext(user);
} catch (IOException | JSONException e) {
ShareLogger.e(INFO.FETCH_USER_INOF_ERROR);
weiboUserEmitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<WeiboUser>() {
@Override
public void call(WeiboUser weiboUser) {
mLoginListener.loginSuccess(
new LoginResult(LoginPlatform.WEIBO, token, weiboUser));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mLoginListener.loginFailure(new Exception(throwable));
}
});
}
private String buildUserInfoUrl(BaseToken token, String baseUrl) {
return baseUrl + "?access_token=" + token.getAccessToken() + "&uid=" + token.getOpenid();
}
@Override
public void handleResult(int requestCode, int resultCode, Intent data) {
mSsoHandler.authorizeCallBack(requestCode, resultCode, data);
}
@Override
public boolean isInstall(Context context) {
IWeiboShareAPI shareAPI =
WeiboShareSDK.createWeiboAPI(context, ShareManager.CONFIG.getWeiboId());
return shareAPI.isWeiboAppInstalled();
}
@Override
public void recycle() {
mSsoHandler = null;
mLoginListener = null;
}
}

@ -0,0 +1,199 @@
package vip.devkit.common.share.login.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import java.io.IOException;
import org.json.JSONException;
import org.json.JSONObject;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.ShareLogger;
import vip.devkit.common.share.ShareManager;
import vip.devkit.common.share.login.LoginListener;
import vip.devkit.common.share.login.LoginPlatform;
import vip.devkit.common.share.login.LoginResult;
import vip.devkit.common.share.login.result.BaseToken;
import vip.devkit.common.share.login.result.WxToken;
import vip.devkit.common.share.login.result.WxUser;
import vip.devkit.common.share.ShareLogger.INFO;
public class WxLoginInstance extends LoginInstance {
public static final String SCOPE_USER_INFO = "snsapi_userinfo";
private static final String SCOPE_BASE = "snsapi_base";
private static final String BASE_URL = "https://api.weixin.qq.com/sns/";
private IWXAPI mIWXAPI;
private LoginListener mLoginListener;
private OkHttpClient mClient;
private boolean fetchUserInfo;
public WxLoginInstance(Activity activity, LoginListener listener, boolean fetchUserInfo) {
super(activity, listener, fetchUserInfo);
mLoginListener = listener;
mIWXAPI = WXAPIFactory.createWXAPI(activity, ShareManager.CONFIG.getWxId());
mClient = new OkHttpClient();
this.fetchUserInfo = fetchUserInfo;
}
@Override
public void doLogin(Activity activity, LoginListener listener, boolean fetchUserInfo) {
final SendAuth.Req req = new SendAuth.Req();
req.scope = SCOPE_USER_INFO;
req.state = String.valueOf(System.currentTimeMillis());
mIWXAPI.sendReq(req);
}
private void getToken(final String code) {
Observable.fromEmitter(new Action1<Emitter<WxToken>>() {
@Override
public void call(Emitter<WxToken> wxTokenEmitter) {
Request request = new Request.Builder().url(buildTokenUrl(code)).build();
try {
Response response = mClient.newCall(request).execute();
JSONObject jsonObject = new JSONObject(response.body().string());
WxToken token = WxToken.parse(jsonObject);
wxTokenEmitter.onNext(token);
} catch (IOException | JSONException e) {
wxTokenEmitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<WxToken>() {
@Override
public void call(WxToken wxToken) {
if (fetchUserInfo) {
mLoginListener.beforeFetchUserInfo(wxToken);
fetchUserInfo(wxToken);
} else {
mLoginListener.loginSuccess(new LoginResult(LoginPlatform.WX, wxToken));
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mLoginListener.loginFailure(new Exception(throwable.getMessage()));
}
});
}
@Override
public void fetchUserInfo(final BaseToken token) {
Observable.fromEmitter(new Action1<Emitter<WxUser>>() {
@Override
public void call(Emitter<WxUser> wxUserEmitter) {
Request request = new Request.Builder().url(buildUserInfoUrl(token)).build();
try {
Response response = mClient.newCall(request).execute();
JSONObject jsonObject = new JSONObject(response.body().string());
WxUser user = WxUser.parse(jsonObject);
wxUserEmitter.onNext(user);
} catch (IOException | JSONException e) {
wxUserEmitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Action1<WxUser>() {
@Override
public void call(WxUser wxUser) {
mLoginListener.loginSuccess(
new LoginResult(LoginPlatform.WX, token, wxUser));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
mLoginListener.loginFailure(new Exception(throwable));
}
});
}
@Override
public void handleResult(int requestCode, int resultCode, Intent data) {
mIWXAPI.handleIntent(data, new IWXAPIEventHandler() {
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
if (baseResp instanceof SendAuth.Resp && baseResp.getType() == 1) {
SendAuth.Resp resp = (SendAuth.Resp) baseResp;
switch (resp.errCode) {
case BaseResp.ErrCode.ERR_OK:
getToken(resp.code);
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
mLoginListener.loginCancel();
break;
case BaseResp.ErrCode.ERR_SENT_FAILED:
mLoginListener.loginFailure(new Exception(ShareLogger.INFO.WX_ERR_SENT_FAILED));
break;
case BaseResp.ErrCode.ERR_UNSUPPORT:
mLoginListener.loginFailure(new Exception(ShareLogger.INFO.WX_ERR_UNSUPPORT));
break;
case BaseResp.ErrCode.ERR_AUTH_DENIED:
mLoginListener.loginFailure(new Exception(INFO.WX_ERR_AUTH_DENIED));
break;
default:
mLoginListener.loginFailure(new Exception(INFO.WX_ERR_AUTH_ERROR));
}
}
}
});
}
@Override
public boolean isInstall(Context context) {
return mIWXAPI.isWXAppInstalled();
}
@Override
public void recycle() {
if (mIWXAPI != null) {
mIWXAPI.detach();
}
}
private String buildTokenUrl(String code) {
return BASE_URL
+ "oauth2/access_token?appid="
+ ShareManager.CONFIG.getWxId()
+ "&secret="
+ ShareManager.CONFIG.getWxSecret()
+ "&code="
+ code
+ "&grant_type=authorization_code";
}
private String buildUserInfoUrl(BaseToken token) {
return BASE_URL
+ "userinfo?access_token="
+ token.getAccessToken()
+ "&openid="
+ token.getOpenid();
}
}

@ -0,0 +1,25 @@
package vip.devkit.common.share.login.result;
public class BaseToken {
private String access_token;
private String openid;
public String getAccessToken() {
return access_token;
}
public void setAccessToken(String access_token) {
this.access_token = access_token;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
}

@ -0,0 +1,62 @@
package vip.devkit.common.share.login.result;
public class BaseUser {
/**
* sex
* 0. 未知
* 1.
* 2.
*/
private String openId;
private String nickname;
private int sex;
private String headImageUrl;
private String headImageUrlLarge;
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
public int getSex() {
return sex;
}
public void setSex(int sex) {
this.sex = sex;
}
public String getHeadImageUrl() {
return headImageUrl;
}
public void setHeadImageUrl(String headImageUrl) {
this.headImageUrl = headImageUrl;
}
public String getHeadImageUrlLarge() {
return headImageUrlLarge;
}
public void setHeadImageUrlLarge(String headImageUrlLarge) {
this.headImageUrlLarge = headImageUrlLarge;
}
}

@ -0,0 +1,16 @@
package vip.devkit.common.share.login.result;
import org.json.JSONException;
import org.json.JSONObject;
public class QQToken extends BaseToken {
public static QQToken parse(JSONObject jsonObject) throws JSONException {
QQToken token = new QQToken();
token.setAccessToken(jsonObject.getString("access_token"));
token.setOpenid(jsonObject.getString("openid"));
return token;
}
}

@ -0,0 +1,41 @@
package vip.devkit.common.share.login.result;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
public class QQUser extends BaseUser {
private String qZoneHeadImage;
private String qZoneHeadImageLarge;
public static QQUser parse(String openId, JSONObject jsonObject) throws JSONException {
QQUser user = new QQUser();
user.setNickname(jsonObject.getString("nickname"));
user.setOpenId(openId);
user.setSex(TextUtils.equals("男", jsonObject.getString("gender")) ? 1 : 2);
user.setHeadImageUrl(jsonObject.getString("figureurl_qq_1"));
user.setHeadImageUrlLarge(jsonObject.getString("figureurl_qq_2"));
user.setqZoneHeadImage(jsonObject.getString("figureurl_1"));
user.setqZoneHeadImageLarge(jsonObject.getString("figureurl_2"));
return user;
}
public String getqZoneHeadImage() {
return qZoneHeadImage;
}
public void setqZoneHeadImage(String qZoneHeadImage) {
this.qZoneHeadImage = qZoneHeadImage;
}
public String getqZoneHeadImageLarge() {
return qZoneHeadImageLarge;
}
public void setqZoneHeadImageLarge(String qZoneHeadImageLarge) {
this.qZoneHeadImageLarge = qZoneHeadImageLarge;
}
}

@ -0,0 +1,39 @@
package vip.devkit.common.share.login.result;
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
/**
* Created by shaohui on 2016/12/3.
*/
public class WeiboToken extends BaseToken {
private String refreshToken;
private String phoneNum;
public static WeiboToken parse(Oauth2AccessToken token) {
WeiboToken target = new WeiboToken();
target.setOpenid(token.getUid());
target.setAccessToken(token.getToken());
target.setRefreshToken(token.getRefreshToken());
target.setPhoneNum(token.getPhoneNum());
return target;
}
public String getRefreshToken() {
return refreshToken;
}
public void setRefreshToken(String refreshToken) {
this.refreshToken = refreshToken;
}
public String getPhoneNum() {
return phoneNum;
}
public void setPhoneNum(String phoneNum) {
this.phoneNum = phoneNum;
}
}

@ -0,0 +1,120 @@
package vip.devkit.common.share.login.result;
import android.text.TextUtils;
import org.json.JSONException;
import org.json.JSONObject;
public class WeiboUser extends BaseUser {
private String language;
private String city;
private String province;
private String headimgurl_hd;
/**
* 示例
* {
*     "id": 1404376560,
*     "screen_name": "zaku",
*     "name": "zaku",
*     "province": "11",
*     "city": "5",
*     "location": "北京 朝阳区",
*     "description": "人生五十年,乃如梦如幻;有生斯有死,壮士复何憾。",
*     "url": "http://blog.sina.com.cn/zaku",
*     "profile_image_url": "http://tp1.sinaimg.cn/1404376560/50/0/1",
*     "domain": "zaku",
*     "gender": "m",
*     "followers_count": 1204,
*     "friends_count": 447,
*     "statuses_count": 2908,
*     "favourites_count": 0,
*     "created_at": "Fri Aug 28 00:00:00 +0800 2009",
*     "following": false,
*     "allow_all_act_msg": false,
*     "geo_enabled": true,
*     "verified": false,
*     "status": {
*         "created_at": "Tue May 24 18:04:53 +0800 2011",
*         "id": 11142488790,
*         "text": "我的相机到了。",
*         "favorited": false,
*         "truncated": false,
*         "in_reply_to_status_id": "",
*         "in_reply_to_user_id": "",
*         "in_reply_to_screen_name": "",
*         "geo": null,
*         "mid": "5610221544300749636",
*         "annotations": [],
*         "reposts_count": 5,
*         "comments_count": 8
*     },
*     "allow_all_comment": true,
*     "avatar_large": "http://tp1.sinaimg.cn/1404376560/180/0/1",
*     "verified_reason": "",
*     "follow_me": false,
*     "online_status": 0,
*     "bi_followers_count": 215
* }
*/
public static WeiboUser parse(JSONObject jsonObject) throws JSONException {
WeiboUser user = new WeiboUser();
user.setOpenId(String.valueOf(jsonObject.getInt("id")));
user.setNickname(jsonObject.getString("screen_name"));
// 性别
String gender = jsonObject.getString("gender");
if (TextUtils.equals(gender, "m")) {
user.setSex(1);
} else if (TextUtils.equals(gender, "f")) {
user.setSex(2);
} else {
user.setSex(0);
}
user.setHeadImageUrl(jsonObject.getString("profile_image_url"));
user.setHeadImageUrlLarge(jsonObject.getString("avatar_large"));
user.setHeadimgurl_hd(jsonObject.getString("avatar_hd"));
user.setCity(jsonObject.getString("city"));
user.setProvince(jsonObject.getString("province"));
return user;
}
public String getLanguage() {
return language;
}
public void setLanguage(String language) {
this.language = language;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getHeadimgurl_hd() {
return headimgurl_hd;
}
public void setHeadimgurl_hd(String headimgurl_hd) {
this.headimgurl_hd = headimgurl_hd;
}
}

@ -0,0 +1,26 @@
package vip.devkit.common.share.login.result;
import org.json.JSONException;
import org.json.JSONObject;
public class WxToken extends BaseToken {
private String refresh_token;
public static WxToken parse(JSONObject jsonObject) throws JSONException {
WxToken wxToken = new WxToken();
wxToken.setOpenid(jsonObject.getString("openid"));
wxToken.setAccessToken(jsonObject.getString("access_token"));
wxToken.setRefreshToken(jsonObject.getString("refresh_token"));
return wxToken;
}
public String getRefreshToken() {
return refresh_token;
}
public void setRefreshToken(String refresh_token) {
this.refresh_token = refresh_token;
}
}

@ -0,0 +1,63 @@
package vip.devkit.common.share.login.result;
import org.json.JSONException;
import org.json.JSONObject;
public class WxUser extends BaseUser {
private String city;
private String country;
private String province;
private String unionid;
public static WxUser parse(JSONObject jsonObject) throws JSONException {
WxUser user = new WxUser();
user.setOpenId(jsonObject.getString("openid"));
user.setNickname(jsonObject.getString("nickname"));
user.setSex(jsonObject.getInt("sex"));
user.setHeadImageUrl(jsonObject.getString("headimgurl"));
user.setHeadImageUrlLarge(jsonObject.getString("headimgurl")); // 重复
user.setProvince(jsonObject.getString("province"));
user.setCity(jsonObject.getString("city"));
user.setCountry(jsonObject.getString("country"));
user.setUnionid(jsonObject.getString("unionid"));
return user;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public String getProvince() {
return province;
}
public void setProvince(String province) {
this.province = province;
}
public String getUnionid() {
return unionid;
}
public void setUnionid(String unionid) {
this.unionid = unionid;
}
}

@ -0,0 +1,126 @@
package vip.devkit.common.share.share;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Environment;
import android.text.TextUtils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import okhttp3.HttpUrl;
import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okio.BufferedSink;
import okio.Okio;
import vip.devkit.common.share.ShareLogger;
public class ImageDecoder {
private static final String FILE_NAME = "share_image.jpg";
public static String decode(Context context, ShareImageObject imageObject) throws Exception {
File resultFile = cacheFile(context);
if (!TextUtils.isEmpty(imageObject.getPathOrUrl())) {
return decode(context, imageObject.getPathOrUrl());
} else if (imageObject.getBitmap() != null) {
// save bitmap to file
FileOutputStream outputStream = new FileOutputStream(resultFile);
imageObject.getBitmap().compress(Bitmap.CompressFormat.JPEG, 100, outputStream);
outputStream.close();
return resultFile.getAbsolutePath();
} else {
throw new IllegalArgumentException();
}
}
private static String decode(Context context, String pathOrUrl) throws Exception {
File resultFile = cacheFile(context);
if (new File(pathOrUrl).exists()) {
// copy file
return decodeFile(new File(pathOrUrl), resultFile);
} else if (HttpUrl.parse(pathOrUrl) != null) {
// download image
return downloadImageToUri(pathOrUrl, resultFile);
} else {
throw new IllegalArgumentException("Please input a file path or http url");
}
}
private static String downloadImageToUri(String url, File resultFile) throws IOException {
OkHttpClient client = new OkHttpClient();
Request request = new Request.Builder().url(url).build();
Response response = client.newCall(request).execute();
BufferedSink sink = Okio.buffer(Okio.sink(resultFile));
sink.writeAll(response.body().source());
sink.close();
response.close();
return resultFile.getAbsolutePath();
}
private static File cacheFile(Context context) throws Exception {
String state = Environment.getExternalStorageState();
if (state != null && state.equals(Environment.MEDIA_MOUNTED)) {
return new File(context.getExternalFilesDir(""), FILE_NAME);
} else {
throw new Exception(ShareLogger.INFO.SD_CARD_NOT_AVAILABLE);
}
}
private static void copyFile(InputStream inputStream, OutputStream outputStream)
throws IOException {
byte[] buffer = new byte[4096];
while (-1 != inputStream.read(buffer)) {
outputStream.write(buffer);
}
outputStream.flush();
inputStream.close();
outputStream.close();
}
private static String decodeFile(File origin, File result) throws IOException {
copyFile(new FileInputStream(origin), new FileOutputStream(result, false));
return result.getAbsolutePath();
}
public static byte[] compress2Byte(String imagePath, int size, int length) {
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeFile(imagePath, options);
int outH = options.outHeight;
int outW = options.outWidth;
int inSampleSize = 1;
while (outH / inSampleSize > size || outW / inSampleSize > size) {
inSampleSize *= 2;
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
Bitmap bitmap = BitmapFactory.decodeFile(imagePath, options);
ByteArrayOutputStream result = new ByteArrayOutputStream();
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, result);
if (result.size() > length) {
result.reset();
quality -= 10;
bitmap.compress(Bitmap.CompressFormat.JPEG, quality, result);
}
bitmap.recycle();
return result.toByteArray();
}
}

@ -0,0 +1,38 @@
package vip.devkit.common.share.share;
import android.graphics.Bitmap;
/**
* Created by shaohui on 2016/11/19.
*/
public class ShareImageObject {
private Bitmap mBitmap;
private String mPathOrUrl;
public ShareImageObject(Bitmap bitmap) {
mBitmap = bitmap;
}
public ShareImageObject(String pathOrUrl) {
mPathOrUrl = pathOrUrl;
}
public Bitmap getBitmap() {
return mBitmap;
}
public void setBitmap(Bitmap bitmap) {
mBitmap = bitmap;
}
public String getPathOrUrl() {
return mPathOrUrl;
}
public void setPathOrUrl(String pathOrUrl) {
mPathOrUrl = pathOrUrl;
}
}

@ -0,0 +1,55 @@
package vip.devkit.common.share.share;
import com.sina.weibo.sdk.api.share.BaseResponse;
import com.sina.weibo.sdk.api.share.IWeiboHandler;
import com.sina.weibo.sdk.constant.WBConstants;
import com.tencent.tauth.IUiListener;
import com.tencent.tauth.UiError;
import vip.devkit.common.share.ShareLogger.INFO;
public abstract class ShareListener implements IUiListener, IWeiboHandler.Response {
@Override
public final void onComplete(Object o) {
shareSuccess();
}
@Override
public final void onError(UiError uiError) {
shareFailure(
new Exception(uiError == null ? INFO.DEFAULT_QQ_SHARE_ERROR : uiError.errorDetail));
}
@Override
public final void onCancel() {
shareCancel();
}
@Override
public final void onResponse(BaseResponse baseResponse) {
switch (baseResponse.errCode) {
case WBConstants.ErrorCode.ERR_OK:
shareSuccess();
break;
case WBConstants.ErrorCode.ERR_FAIL:
shareFailure(new Exception(baseResponse.errMsg));
break;
case WBConstants.ErrorCode.ERR_CANCEL:
shareCancel();
break;
default:
shareFailure(new Exception(baseResponse.errMsg));
}
}
public abstract void shareSuccess();
public abstract void shareFailure(Exception e);
public abstract void shareCancel();
// 用于缓解用户焦虑
public void shareRequest() {
}
}

@ -0,0 +1,25 @@
package vip.devkit.common.share.share;
import android.support.annotation.IntDef;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Created by shaohui on 2016/11/18.
*/
public class SharePlatform {
@IntDef({ DEFAULT, QQ, QZONE, WEIBO, WX, WX_TIMELINE })
@Retention(RetentionPolicy.SOURCE)
public @interface Platform{}
public static final int DEFAULT = 0;
public static final int QQ = 1;
public static final int QZONE = 2;
public static final int WX = 3;
public static final int WX_TIMELINE = 4;
public static final int WEIBO = 5;
}

@ -0,0 +1,102 @@
package vip.devkit.common.share.share.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.net.Uri;
import java.io.File;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.R;
import vip.devkit.common.share.share.ImageDecoder;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
public class DefaultShareInstance implements ShareInstance {
@Override
public void shareText(int platform, String text, Activity activity, ShareListener listener) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, text);
sendIntent.setType("text/plain");
activity.startActivity(Intent.createChooser(sendIntent,
activity.getResources().getString(R.string.vista_share_title)));
}
@Override
public void shareMedia(int platform, String title, String targetUrl, String summary,
ShareImageObject shareImageObject, Activity activity, ShareListener listener) {
Intent sendIntent = new Intent();
sendIntent.setAction(Intent.ACTION_SEND);
sendIntent.putExtra(Intent.EXTRA_TEXT, String.format("%s %s", title, targetUrl));
sendIntent.setType("text/plain");
activity.startActivity(Intent.createChooser(sendIntent,
activity.getResources().getString(R.string.vista_share_title)));
}
@Override
public void shareImage(int platform, final ShareImageObject shareImageObject,
final Activity activity, final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<Uri>>() {
@Override
public void call(Emitter<Uri> emitter) {
try {
Uri uri =
Uri.fromFile(new File(ImageDecoder.decode(activity, shareImageObject)));
emitter.onNext(uri);
emitter.onCompleted();
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.BUFFER)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<Uri>() {
@Override
public void call(Uri uri) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
shareIntent.putExtra(Intent.EXTRA_STREAM, uri);
shareIntent.setType("image/jpeg");
activity.startActivity(Intent.createChooser(shareIntent,
activity.getResources().getText(R.string.vista_share_title)));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
listener.shareFailure(new Exception(throwable));
}
});
}
@Override
public void handleResult(Intent data) {
// Default share, do nothing
}
@Override
public boolean isInstall(Context context) {
Intent shareIntent = new Intent();
shareIntent.setAction(Intent.ACTION_SEND);
return context.getPackageManager()
.resolveActivity(shareIntent, PackageManager.MATCH_DEFAULT_ONLY) != null;
}
@Override
public void recycle() {
}
}

@ -0,0 +1,218 @@
package vip.devkit.common.share.share.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.text.TextUtils;
import com.tencent.connect.share.QQShare;
import com.tencent.connect.share.QzonePublish;
import com.tencent.connect.share.QzoneShare;
import com.tencent.tauth.Tencent;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import vip.devkit.common.share.ShareUtil;
import vip.devkit.common.share.share.ImageDecoder;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
import vip.devkit.common.share.share.SharePlatform;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action0;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import static vip.devkit.common.share.ShareLogger.INFO;
public class QQShareInstance implements ShareInstance {
private Tencent mTencent;
public QQShareInstance(Context context, String app_id) {
mTencent = Tencent.createInstance(app_id, context);
}
@Override
public void shareText(int platform, String text, Activity activity, ShareListener listener) {
if (platform == SharePlatform.QZONE) {
shareToQZoneForText(text, activity, listener);
} else {
activity.finish();
listener.shareFailure(new Exception(INFO.QQ_NOT_SUPPORT_SHARE_TXT));
}
}
@Override
public void shareMedia(final int platform, final String title, final String targetUrl,
final String summary, final ShareImageObject shareImageObject, final Activity activity,
final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<String>>() {
@Override
public void call(Emitter<String> emitter) {
try {
emitter.onNext(ImageDecoder.decode(activity, shareImageObject));
emitter.onCompleted();
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String s) {
if (platform == SharePlatform.QZONE) {
shareToQZoneForMedia(title, targetUrl, summary, s, activity,
listener);
} else {
shareToQQForMedia(title, summary, targetUrl, s, activity, listener);
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
activity.finish();
listener.shareFailure(new Exception(throwable));
}
});
}
@Override
public void shareImage(final int platform, final ShareImageObject shareImageObject,
final Activity activity, final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<String>>() {
@Override
public void call(Emitter<String> emitter) {
try {
emitter.onNext(ImageDecoder.decode(activity, shareImageObject));
emitter.onCompleted();
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<String>() {
@Override
public void call(String localPath) {
if (platform == SharePlatform.QZONE) {
shareToQzoneForImage(localPath, activity, listener);
} else {
shareToQQForImage(localPath, activity, listener);
}
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
activity.finish();
listener.shareFailure(new Exception(throwable));
}
});
}
@Override
public void handleResult(Intent data) {
Tencent.handleResultData(data, ShareUtil.mShareListener);
}
@Override
public boolean isInstall(Context context) {
PackageManager pm = context.getPackageManager();
if (pm == null) {
return false;
}
List<PackageInfo> packageInfos = pm.getInstalledPackages(0);
for (PackageInfo info : packageInfos) {
if (TextUtils.equals(info.packageName.toLowerCase(), "com.tencent.mobileqq")) {
return true;
}
}
return false;
}
@Override
public void recycle() {
if (mTencent != null) {
mTencent.releaseResource();
mTencent = null;
}
}
private void shareToQQForMedia(String title, String summary, String targetUrl, String thumbUrl,
Activity activity, ShareListener listener) {
final Bundle params = new Bundle();
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, thumbUrl);
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
params.putString(QQShare.SHARE_TO_QQ_SUMMARY,summary);
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, thumbUrl);
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, 123);
params.putString(QQShare.SHARE_TO_QQ_APP_NAME,null);
mTencent.shareToQQ(activity, params, listener);
}
private void shareToQQForImage(String localUrl, Activity activity, ShareListener listener) {
Bundle params = new Bundle();
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, localUrl);
mTencent.shareToQQ(activity, params, listener);
}
private void shareToQZoneForText(String text, Activity activity, ShareListener listener) {
final Bundle params = new Bundle();
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, text);
mTencent.publishToQzone(activity, params, listener);
}
private void shareToQZoneForMedia(String title, String targetUrl, String summary,
String imageUrl, Activity activity, ShareListener listener) {
final Bundle params = new Bundle();
final ArrayList<String> image = new ArrayList<>();
image.add(imageUrl);
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, summary);
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, image);
mTencent.shareToQzone(activity, params, listener);
}
private void shareToQzoneForImage(String imagePath, Activity activity, ShareListener listener) {
final Bundle params = new Bundle();
final ArrayList<String> image = new ArrayList<>();
image.add(imagePath);
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE,
QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, image);
mTencent.publishToQzone(activity, params, listener);
}
}

@ -0,0 +1,26 @@
package vip.devkit.common.share.share.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
public interface ShareInstance {
void shareText(int platform, String text, Activity activity, ShareListener listener);
void shareMedia(int platform, String title, String targetUrl, String summary,
ShareImageObject shareImageObject, Activity activity, ShareListener listener);
void shareImage(int platform, ShareImageObject shareImageObject, Activity activity,
ShareListener listener);
void handleResult(Intent data);
boolean isInstall(Context context);
void recycle();
}

@ -0,0 +1,155 @@
package vip.devkit.common.share.share.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.media.Image;
import android.text.TextUtils;
import android.util.Pair;
import com.sina.weibo.sdk.api.ImageObject;
import com.sina.weibo.sdk.api.TextObject;
import com.sina.weibo.sdk.api.WeiboMultiMessage;
import com.sina.weibo.sdk.api.share.IWeiboShareAPI;
import com.sina.weibo.sdk.api.share.SendMessageToWeiboResponse;
import com.sina.weibo.sdk.api.share.SendMultiMessageToWeiboRequest;
import com.sina.weibo.sdk.api.share.WeiboShareSDK;
import com.sina.weibo.sdk.constant.WBConstants;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.ShareUtil;
import vip.devkit.common.share.share.ImageDecoder;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
public class WeiboShareInstance implements ShareInstance {
/**
* 微博分享限制thumb image必须小于2097152否则点击分享会没有反应
*/
private IWeiboShareAPI mWeiboShareAPI;
private static final int TARGET_SIZE = 1024;
private static final int TARGET_LENGTH = 2097152;
public WeiboShareInstance(Context context, String appId) {
mWeiboShareAPI = WeiboShareSDK.createWeiboAPI(context, appId);
mWeiboShareAPI.registerApp();
}
@Override
public void shareText(int platform, String text, Activity activity, ShareListener listener) {
TextObject textObject = new TextObject();
textObject.text = text;
WeiboMultiMessage message = new WeiboMultiMessage();
message.textObject = textObject;
sendRequest(activity, message);
}
@Override
public void shareMedia(int platform, final String title, final String targetUrl, String summary,
ShareImageObject shareImageObject, final Activity activity,
final ShareListener listener) {
String content = String.format("%s %s", title, targetUrl);
shareTextOrImage(shareImageObject, content, activity, listener);
}
@Override
public void shareImage(int platform, ShareImageObject shareImageObject, Activity activity,
ShareListener listener) {
shareTextOrImage(shareImageObject, null, activity, listener);
}
@Override
public void handleResult(Intent intent) {
SendMessageToWeiboResponse baseResponse =
new SendMessageToWeiboResponse(intent.getExtras());
switch (baseResponse.errCode) {
case WBConstants.ErrorCode.ERR_OK:
ShareUtil.mShareListener.shareSuccess();
break;
case WBConstants.ErrorCode.ERR_FAIL:
ShareUtil.mShareListener.shareFailure(new Exception(baseResponse.errMsg));
break;
case WBConstants.ErrorCode.ERR_CANCEL:
ShareUtil.mShareListener.shareCancel();
break;
default:
ShareUtil.mShareListener.shareFailure(new Exception(baseResponse.errMsg));
}
}
@Override
public boolean isInstall(Context context) {
return mWeiboShareAPI.isWeiboAppInstalled();
}
@Override
public void recycle() {
mWeiboShareAPI = null;
}
private void shareTextOrImage(final ShareImageObject shareImageObject, final String text,
final Activity activity, final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<Pair<String, byte[]>>>() {
@Override
public void call(Emitter<Pair<String, byte[]>> emitter) {
try {
String path = ImageDecoder.decode(activity, shareImageObject);
emitter.onNext(Pair.create(path,
ImageDecoder.compress2Byte(path, TARGET_SIZE, TARGET_LENGTH)));
emitter.onCompleted();
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<Pair<String, byte[]>>() {
@Override
public void call(Pair<String, byte[]> pair) {
ImageObject imageObject = new ImageObject();
imageObject.imageData = pair.second;
imageObject.imagePath = pair.first;
WeiboMultiMessage message = new WeiboMultiMessage();
message.imageObject = imageObject;
if (!TextUtils.isEmpty(text)) {
TextObject textObject = new TextObject();
textObject.text = text;
message.textObject = textObject;
}
sendRequest(activity, message);
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
activity.finish();
listener.shareFailure(new Exception(throwable));
}
});
}
private void sendRequest(Activity activity, WeiboMultiMessage message) {
SendMultiMessageToWeiboRequest request = new SendMultiMessageToWeiboRequest();
request.transaction = String.valueOf(System.currentTimeMillis());
request.multiMessage = message;
mWeiboShareAPI.sendRequest(activity, request);
}
}

@ -0,0 +1,200 @@
package vip.devkit.common.share.share.instance;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.media.Image;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import com.tencent.mm.opensdk.modelbase.BaseReq;
import com.tencent.mm.opensdk.modelbase.BaseResp;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
import com.tencent.mm.opensdk.modelmsg.WXImageObject;
import com.tencent.mm.opensdk.modelmsg.WXMediaMessage;
import com.tencent.mm.opensdk.modelmsg.WXTextObject;
import com.tencent.mm.opensdk.modelmsg.WXWebpageObject;
import com.tencent.mm.opensdk.openapi.IWXAPI;
import com.tencent.mm.opensdk.openapi.IWXAPIEventHandler;
import com.tencent.mm.opensdk.openapi.WXAPIFactory;
import rx.Emitter;
import rx.Observable;
import rx.android.schedulers.AndroidSchedulers;
import rx.functions.Action1;
import rx.schedulers.Schedulers;
import vip.devkit.common.share.ShareUtil;
import vip.devkit.common.share.share.ImageDecoder;
import vip.devkit.common.share.share.ShareImageObject;
import vip.devkit.common.share.share.ShareListener;
import vip.devkit.common.share.share.SharePlatform;
public class WxShareInstance implements ShareInstance {
/**
* 微信分享限制thumb image必须小于32Kb否则点击分享会没有反应
*/
private IWXAPI mIWXAPI;
private static final int THUMB_SIZE = 32 * 1024 * 8;
private static final int TARGET_SIZE = 200;
public WxShareInstance(Context context, String appId) {
mIWXAPI = WXAPIFactory.createWXAPI(context, appId, true);
mIWXAPI.registerApp(appId);
}
@Override
public void shareText(int platform, String text, Activity activity, ShareListener listener) {
WXTextObject textObject = new WXTextObject();
textObject.text = text;
WXMediaMessage message = new WXMediaMessage();
message.mediaObject = textObject;
message.description = text;
sendMessage(platform, message, buildTransaction("text"));
}
@Override
public void shareMedia(
final int platform, final String title, final String targetUrl, final String summary,
final ShareImageObject shareImageObject, final Activity activity, final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<byte[]>>() {
@Override
public void call(Emitter<byte[]> emitter) {
try {
String imagePath = ImageDecoder.decode(activity, shareImageObject);
emitter.onNext(ImageDecoder.compress2Byte(imagePath, TARGET_SIZE, THUMB_SIZE));
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.DROP)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<byte[]>() {
@Override
public void call(byte[] bytes) {
WXWebpageObject webpageObject = new WXWebpageObject();
webpageObject.webpageUrl = targetUrl;
WXMediaMessage message = new WXMediaMessage(webpageObject);
message.title = title;
message.description = summary;
message.thumbData = bytes;
sendMessage(platform, message, buildTransaction("webPage"));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
activity.finish();
listener.shareFailure(new Exception(throwable));
}
});
}
@Override
public void shareImage(final int platform, final ShareImageObject shareImageObject,
final Activity activity, final ShareListener listener) {
Observable.fromEmitter(new Action1<Emitter<Pair<Bitmap, byte[]>>>() {
@Override
public void call(Emitter<Pair<Bitmap, byte[]>> emitter) {
try {
String imagePath = ImageDecoder.decode(activity, shareImageObject);
emitter.onNext(Pair.create(BitmapFactory.decodeFile(imagePath),
ImageDecoder.compress2Byte(imagePath, TARGET_SIZE, THUMB_SIZE)));
} catch (Exception e) {
emitter.onError(e);
}
}
}, Emitter.BackpressureMode.BUFFER)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doOnRequest(new Action1<Long>() {
@Override
public void call(Long aLong) {
listener.shareRequest();
}
})
.subscribe(new Action1<Pair<Bitmap, byte[]>>() {
@Override
public void call(Pair<Bitmap, byte[]> pair) {
WXImageObject imageObject = new WXImageObject(pair.first);
WXMediaMessage message = new WXMediaMessage();
message.mediaObject = imageObject;
message.thumbData = pair.second;
sendMessage(platform, message, buildTransaction("image"));
}
}, new Action1<Throwable>() {
@Override
public void call(Throwable throwable) {
activity.finish();
listener.shareFailure(new Exception(throwable));
}
});
}
@Override
public void handleResult(Intent data) {
mIWXAPI.handleIntent(data, new IWXAPIEventHandler() {
@Override
public void onReq(BaseReq baseReq) {
}
@Override
public void onResp(BaseResp baseResp) {
switch (baseResp.errCode) {
case BaseResp.ErrCode.ERR_OK:
ShareUtil.mShareListener.shareSuccess();
break;
case BaseResp.ErrCode.ERR_USER_CANCEL:
ShareUtil.mShareListener.shareCancel();
break;
default:
ShareUtil.mShareListener.shareFailure(new Exception(baseResp.errStr));
}
}
});
}
@Override
public boolean isInstall(Context context) {
return mIWXAPI.isWXAppInstalled();
}
@Override
public void recycle() {
mIWXAPI.detach();
}
private void sendMessage(int platform, WXMediaMessage message, String transaction) {
SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = transaction;
req.message = message;
req.scene = platform == SharePlatform.WX_TIMELINE ? SendMessageToWX.Req.WXSceneTimeline
: SendMessageToWX.Req.WXSceneSession;
mIWXAPI.sendReq(req);
}
private String buildTransaction(String type) {
return System.currentTimeMillis() + type;
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save