@ -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> |
@ -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> |
@ -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> |
After Width: | Height: | Size: 3.0 KiB |
After Width: | Height: | Size: 4.9 KiB |
After Width: | Height: | Size: 2.0 KiB |
After Width: | Height: | Size: 2.8 KiB |
After Width: | Height: | Size: 4.5 KiB |
After Width: | Height: | Size: 6.9 KiB |
After Width: | Height: | Size: 6.3 KiB |
After Width: | Height: | Size: 10 KiB |
After Width: | Height: | Size: 9.0 KiB |
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 |
@ -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 |
@ -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 "$@" |
@ -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' |
@ -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') |
||||
} |
@ -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> |
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,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; |
||||
} |
||||
|
||||
} |