nullsafety
This commit is contained in:
parent
8c505c5a74
commit
db4c1712c2
12
.drone.yml
12
.drone.yml
@ -16,19 +16,9 @@ steps:
|
||||
# - name: pub-cache
|
||||
# path: /opt/flutter/.pub-cache
|
||||
# commands:
|
||||
# - flutter pub run build_runner clean
|
||||
# - flutter pub run build_runner build --delete-conflicting-outputs
|
||||
|
||||
#- name: android-check
|
||||
# image: v7lin/flutter:1.17.3-stable
|
||||
# volumes:
|
||||
# - name: pub-cache
|
||||
# path: /opt/flutter/.pub-cache
|
||||
# - name: gradle
|
||||
# path: /root/.gradle
|
||||
# commands:
|
||||
# - cd example/android/
|
||||
# - ./gradlew :wechat_kit:check
|
||||
|
||||
# docker run --rm -it -v ${PWD}:/src v7lin/clang:5.0.2-r0 sh -c "clang-format -style=file -i src/Classes/*.h src/Classes/*.m"
|
||||
#- name: ios-format
|
||||
# image: v7lin/clang
|
||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -6,6 +6,6 @@
|
||||
|
||||
build/
|
||||
|
||||
# custom
|
||||
.idea/
|
||||
#
|
||||
*.iml
|
||||
.idea/
|
||||
|
@ -1,3 +1,9 @@
|
||||
## 2.0.0
|
||||
|
||||
* nullsafety
|
||||
* 不再支持 Android embedding v1
|
||||
* Weibo 单例
|
||||
|
||||
## 1.1.0
|
||||
|
||||
* 优化
|
||||
|
34
README.md
34
README.md
@ -1,24 +1,24 @@
|
||||
# weibo_kit
|
||||
|
||||
[](https://cloud.drone.io/v7lin/weibo_kit)
|
||||
[](https://codecov.io/gh/v7lin/weibo_kit)
|
||||
[](https://github.com/v7lin/weibo_kit/releases)
|
||||
[](https://cloud.drone.io/rxreader/weibo_kit)
|
||||
[](https://codecov.io/gh/rxreader/weibo_kit)
|
||||
[](https://github.com/rxreader/weibo_kit/releases)
|
||||
[](https://pub.dartlang.org/packages/weibo_kit)
|
||||
[](https://github.com/v7lin/weibo_kit/blob/master/LICENSE)
|
||||
[](https://github.com/rxreader/weibo_kit/blob/master/LICENSE)
|
||||
|
||||
flutter版新浪微博SDK
|
||||
|
||||
## fake 系列 libraries
|
||||
|
||||
* [flutter版微信SDK](https://github.com/v7lin/wechat_kit)
|
||||
* [flutter版腾讯(QQ)SDK](https://github.com/v7lin/tencent_kit)
|
||||
* [flutter版新浪微博SDK](https://github.com/v7lin/weibo_kit)
|
||||
* [flutter版支付宝SDK](https://github.com/v7lin/alipay_kit)
|
||||
* [flutter版walle渠道打包工具](https://github.com/v7lin/walle_kit)
|
||||
* [flutter版微信SDK](https://github.com/rxreader/wechat_kit)
|
||||
* [flutter版腾讯(QQ)SDK](https://github.com/rxreader/tencent_kit)
|
||||
* [flutter版新浪微博SDK](https://github.com/rxreader/weibo_kit)
|
||||
* [flutter版支付宝SDK](https://github.com/rxreader/alipay_kit)
|
||||
* [flutter版walle渠道打包工具](https://github.com/rxreader/walle_kit)
|
||||
|
||||
## dart/flutter 私服
|
||||
|
||||
* [simple_pub_server](https://github.com/v7lin/simple_pub_server)
|
||||
* [simple_pub_server](https://github.com/rxreader/simple_pub_server)
|
||||
|
||||
## docs
|
||||
|
||||
@ -29,6 +29,15 @@ flutter版新浪微博SDK
|
||||
|
||||
## android
|
||||
|
||||
```groovy
|
||||
buildscript {
|
||||
dependencies {
|
||||
// 3.5.4/3.6.4/4.x.x
|
||||
classpath 'com.android.tools.build:gradle:3.5.4'
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
```
|
||||
# 不需要做任何额外接入工作
|
||||
# 混淆已打入 Library,随 Library 引用,自动添加到 apk 打包混淆
|
||||
@ -153,13 +162,16 @@ iOS 9系统策略更新,限制了http协议的访问,此外应用需要在
|
||||
```
|
||||
## flutter
|
||||
|
||||
* break change
|
||||
* 2.0.0: nullsafety & 不再支持 Android embedding v1 & Weibo 单例
|
||||
|
||||
* snapshot
|
||||
|
||||
```
|
||||
dependencies:
|
||||
weibo_kit:
|
||||
git:
|
||||
url: https://github.com/v7lin/weibo_kit.git
|
||||
url: https://github.com/rxreader/weibo_kit.git
|
||||
```
|
||||
|
||||
* release
|
||||
|
59
analysis_options.yaml
Executable file → Normal file
59
analysis_options.yaml
Executable file → Normal file
@ -29,12 +29,15 @@ analyzer:
|
||||
missing_return: warning
|
||||
# allow having TODOs in the code
|
||||
todo: ignore
|
||||
# allow self-reference to deprecated members (we do this because otherwise we have
|
||||
# to annotate every member in every test, assert, etc, when we deprecate something)
|
||||
deprecated_member_use_from_same_package: ignore
|
||||
# Ignore analyzer hints for updating pubspecs when using Future or
|
||||
# Stream and not importing dart:async
|
||||
# Please see https://github.com/flutter/flutter/pull/24528 for details.
|
||||
sdk_version_async_exported_from_core: ignore
|
||||
exclude:
|
||||
- "**/*.g.dart"
|
||||
- "lib/*.g.dart"
|
||||
|
||||
linter:
|
||||
rules:
|
||||
@ -46,6 +49,7 @@ linter:
|
||||
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
|
||||
- always_require_non_null_named_parameters
|
||||
- always_specify_types
|
||||
- always_use_package_imports # we do this commonly
|
||||
- annotate_overrides
|
||||
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
|
||||
# - avoid_as # required for implicit-casts: true
|
||||
@ -55,7 +59,8 @@ linter:
|
||||
- avoid_classes_with_only_static_members
|
||||
# - avoid_double_and_int_checks # only useful when targeting JS runtime
|
||||
- avoid_empty_else
|
||||
# - avoid_equals_and_hash_code_on_mutable_classes # not yet tested
|
||||
- avoid_equals_and_hash_code_on_mutable_classes
|
||||
# - avoid_escaping_inner_quotes # not yet tested
|
||||
- avoid_field_initializers_in_const_classes
|
||||
- avoid_function_literals_in_foreach_calls
|
||||
# - avoid_implementing_value_types # not yet tested
|
||||
@ -74,9 +79,10 @@ linter:
|
||||
- avoid_returning_null_for_void
|
||||
# - avoid_returning_this # there are plenty of valid reasons to return this
|
||||
# - avoid_setters_without_getters # not yet tested
|
||||
# - avoid_shadowing_type_parameters # not yet tested
|
||||
- avoid_shadowing_type_parameters
|
||||
- avoid_single_cascade_in_expression_statements
|
||||
- avoid_slow_async_io
|
||||
# - avoid_type_to_string # we do this commonly
|
||||
- avoid_types_as_parameter_names
|
||||
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
|
||||
# - avoid_unnecessary_containers # not yet tested
|
||||
@ -88,60 +94,66 @@ linter:
|
||||
- camel_case_types
|
||||
- cancel_subscriptions
|
||||
# - cascade_invocations # not yet tested
|
||||
- cast_nullable_to_non_nullable
|
||||
# - close_sinks # not reliable enough
|
||||
# - comment_references # blocked on https://github.com/flutter/flutter/issues/20765
|
||||
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
|
||||
- control_flow_in_finally
|
||||
# - curly_braces_in_flow_control_structures # not yet tested
|
||||
# - curly_braces_in_flow_control_structures # not required by flutter style
|
||||
# - diagnostic_describe_all_properties # not yet tested
|
||||
- directives_ordering
|
||||
# - do_not_use_environment # we do this commonly
|
||||
- empty_catches
|
||||
- empty_constructor_bodies
|
||||
- empty_statements
|
||||
# - file_names # not yet tested
|
||||
- exhaustive_cases
|
||||
- file_names # not yet tested
|
||||
- flutter_style_todos
|
||||
- hash_and_equals
|
||||
- implementation_imports
|
||||
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
||||
- iterable_contains_unrelated_type
|
||||
# - join_return_with_assignment # not yet tested
|
||||
# - join_return_with_assignment # not required by flutter style
|
||||
- leading_newlines_in_multiline_strings
|
||||
- library_names
|
||||
- library_prefixes
|
||||
# - lines_longer_than_80_chars # not yet tested
|
||||
# - lines_longer_than_80_chars # not required by flutter style
|
||||
- list_remove_unrelated_type
|
||||
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
||||
# - missing_whitespace_between_adjacent_strings # not yet tested
|
||||
- no_adjacent_strings_in_list
|
||||
# - no_default_cases # too many false positives
|
||||
- no_duplicate_case_values
|
||||
# - no_logic_in_create_state # not yet tested
|
||||
# - no_runtimeType_toString # not yet tested
|
||||
- no_logic_in_create_state
|
||||
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
|
||||
- non_constant_identifier_names
|
||||
# - null_closures # not yet tested
|
||||
- null_check_on_nullable_type_parameter
|
||||
# - null_closures # not required by flutter style
|
||||
# - omit_local_variable_types # opposite of always_specify_types
|
||||
# - one_member_abstracts # too many false positives
|
||||
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
|
||||
- overridden_fields
|
||||
- package_api_docs
|
||||
- package_names
|
||||
# - package_names # non conforming packages in sdk
|
||||
- package_prefixed_library_names
|
||||
# - parameter_assignments # we do this commonly
|
||||
- prefer_adjacent_string_concatenation
|
||||
- prefer_asserts_in_initializer_lists
|
||||
# - prefer_asserts_with_message # not yet tested
|
||||
# - prefer_asserts_with_message # not required by flutter style
|
||||
- prefer_collection_literals
|
||||
- prefer_conditional_assignment
|
||||
- prefer_const_constructors
|
||||
- prefer_const_constructors_in_immutables
|
||||
- prefer_const_declarations
|
||||
- prefer_const_literals_to_create_immutables
|
||||
# - prefer_constructors_over_static_methods # not yet tested
|
||||
# - prefer_constructors_over_static_methods # far too many false positives
|
||||
- prefer_contains
|
||||
# - prefer_double_quotes # opposite of prefer_single_quotes
|
||||
- prefer_equal_for_default_values
|
||||
# - prefer_expression_function_bodies # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#consider-using--for-short-functions-and-methods
|
||||
# - prefer_final_fields
|
||||
# - prefer_final_in_for_each
|
||||
# - prefer_final_locals
|
||||
- prefer_final_fields
|
||||
- prefer_final_in_for_each
|
||||
- prefer_final_locals
|
||||
- prefer_for_elements_to_map_fromIterable
|
||||
- prefer_foreach
|
||||
# - prefer_function_declarations_over_variables # not yet tested
|
||||
@ -166,16 +178,18 @@ linter:
|
||||
# - provide_deprecation_message # not yet tested
|
||||
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
|
||||
- recursive_getters
|
||||
# - sized_box_for_whitespace # not yet tested
|
||||
- slash_for_doc_comments
|
||||
# - sort_child_properties_last # not yet tested
|
||||
- sort_constructors_first
|
||||
- sort_pub_dependencies
|
||||
# - sort_pub_dependencies # prevents separating pinned transitive dependencies
|
||||
- sort_unnamed_constructors_first
|
||||
- test_types_in_equals
|
||||
- throw_in_finally
|
||||
- tighten_type_of_initializing_formals
|
||||
# - type_annotate_public_apis # subset of always_specify_types
|
||||
- type_init_formals
|
||||
# - unawaited_futures # too many false positives
|
||||
- unawaited_futures # too many false positives
|
||||
# - unnecessary_await_in_return # not yet tested
|
||||
- unnecessary_brace_in_string_interps
|
||||
- unnecessary_const
|
||||
@ -184,20 +198,27 @@ linter:
|
||||
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
|
||||
- unnecessary_new
|
||||
- unnecessary_null_aware_assignments
|
||||
# - unnecessary_null_checks # not yet tested
|
||||
- unnecessary_null_in_if_null_operators
|
||||
- unnecessary_nullable_for_final_variable_declarations
|
||||
- unnecessary_overrides
|
||||
- unnecessary_parenthesis
|
||||
# - unnecessary_raw_strings # not yet tested
|
||||
- unnecessary_statements
|
||||
- unnecessary_string_escapes
|
||||
- unnecessary_string_interpolations
|
||||
- unnecessary_this
|
||||
- unrelated_type_equality_checks
|
||||
# - unsafe_html # not yet tested
|
||||
- use_full_hex_values_for_flutter_colors
|
||||
# - use_function_type_syntax_for_parameters # not yet tested
|
||||
- use_is_even_rather_than_modulo
|
||||
# - use_key_in_widget_constructors # not yet tested
|
||||
- use_late_for_private_fields_and_variables
|
||||
- use_raw_strings
|
||||
- use_rethrow_when_possible
|
||||
# - use_setters_to_change_properties # not yet tested
|
||||
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
|
||||
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
|
||||
- valid_regexps
|
||||
- void_checks
|
||||
- void_checks
|
||||
|
@ -1,5 +1,5 @@
|
||||
group 'io.github.v7lin.weibo_kit'
|
||||
version '1.1.0'
|
||||
version '2.0.0'
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
@ -8,7 +8,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,7 +25,6 @@ rootProject.allprojects {
|
||||
}
|
||||
|
||||
apply plugin: 'com.android.library'
|
||||
apply from: './quality.gradle'
|
||||
|
||||
android {
|
||||
compileSdkVersion 28
|
||||
@ -54,8 +53,6 @@ android {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'androidx.annotation:annotation:1.0.0'
|
||||
|
||||
// v9.12.0
|
||||
vendorImplementation 'androidx.appcompat:appcompat:1.0.0'
|
||||
vendorImplementation 'com.sina.weibo.sdk:core:9.12.0:openDefaultRelease@aar'
|
||||
|
@ -1,135 +0,0 @@
|
||||
<?xml version="1.0"?>
|
||||
<!DOCTYPE module PUBLIC
|
||||
"-//Puppy Crawl//DTD Check Configuration 1.3//EN"
|
||||
"http://checkstyle.sourceforge.net/dtds/configuration_1_3.dtd">
|
||||
|
||||
<module name="Checker">
|
||||
<!--module name="NewlineAtEndOfFile"/-->
|
||||
<module name="FileLength"/>
|
||||
<module name="FileTabCharacter"/>
|
||||
|
||||
<!-- Trailing spaces -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="\s+$"/>
|
||||
<property name="message" value="Line has trailing spaces."/>
|
||||
</module>
|
||||
|
||||
<!-- Space after 'for' and 'if' -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^\s*(for|if)[^ ]\("/>
|
||||
<property name="message" value="Space needed before opening parenthesis."/>
|
||||
</module>
|
||||
|
||||
<!-- For each spacing -->
|
||||
<module name="RegexpSingleline">
|
||||
<property name="format" value="^\s*for \(.*?([^ ]:|:[^ ])"/>
|
||||
<property name="message" value="Space needed around ':' character."/>
|
||||
</module>
|
||||
|
||||
<module name="TreeWalker">
|
||||
<!--<property name="cacheFile" value="${checkstyle.cache.file}"/>-->
|
||||
|
||||
<!-- Checks for Javadoc comments. -->
|
||||
<!-- See http://checkstyle.sf.net/config_javadoc.html -->
|
||||
<!--module name="JavadocMethod"/-->
|
||||
<!--module name="JavadocType"/-->
|
||||
<!--module name="JavadocVariable"/-->
|
||||
<!--module name="JavadocStyle"/-->
|
||||
|
||||
|
||||
<!-- Checks for Naming Conventions. -->
|
||||
<!-- See http://checkstyle.sf.net/config_naming.html -->
|
||||
<!--<module name="ConstantName"/>-->
|
||||
<module name="LocalFinalVariableName"/>
|
||||
<module name="LocalVariableName"/>
|
||||
<module name="MemberName"/>
|
||||
<module name="MethodName">
|
||||
<property name="format" value="^[a-z][a-zA-Z0-9_]*$"/>
|
||||
</module>
|
||||
<module name="PackageName"/>
|
||||
<module name="ParameterName"/>
|
||||
<module name="StaticVariableName"/>
|
||||
<module name="TypeName"/>
|
||||
|
||||
|
||||
<!-- Checks for imports -->
|
||||
<!-- See http://checkstyle.sf.net/config_import.html -->
|
||||
<module name="AvoidStarImport"/>
|
||||
<module name="IllegalImport"/>
|
||||
<module name="RedundantImport"/>
|
||||
<module name="UnusedImports">
|
||||
<property name="processJavadoc" value="true"/>
|
||||
</module>
|
||||
|
||||
|
||||
<!-- Checks for Size Violations. -->
|
||||
<!-- See http://checkstyle.sf.net/config_sizes.html -->
|
||||
<module name="LineLength">
|
||||
<property name="max" value="200"/>
|
||||
</module>
|
||||
<module name="MethodLength"/>
|
||||
<!--module name="ParameterNumber"/-->
|
||||
|
||||
|
||||
<!-- Checks for whitespace -->
|
||||
<!-- See http://checkstyle.sf.net/config_whitespace.html -->
|
||||
<module name="GenericWhitespace"/>
|
||||
<module name="EmptyForIteratorPad"/>
|
||||
<module name="MethodParamPad"/>
|
||||
<!--<module name="NoWhitespaceAfter"/>-->
|
||||
<module name="NoWhitespaceBefore"/>
|
||||
<module name="OperatorWrap"/>
|
||||
<module name="ParenPad"/>
|
||||
<module name="TypecastParenPad"/>
|
||||
<module name="WhitespaceAfter"/>
|
||||
<module name="WhitespaceAround"/>
|
||||
|
||||
|
||||
<!-- Modifier Checks -->
|
||||
<!-- See http://checkstyle.sf.net/config_modifiers.html -->
|
||||
<module name="ModifierOrder"/>
|
||||
<module name="RedundantModifier"/>
|
||||
|
||||
|
||||
<!-- Checks for blocks. You know, those {}'s -->
|
||||
<!-- See http://checkstyle.sf.net/config_blocks.html -->
|
||||
<!--module name="AvoidNestedBlocks"/-->
|
||||
<!--module name="EmptyBlock"/-->
|
||||
<module name="LeftCurly"/>
|
||||
<!--module name="NeedBraces"/-->
|
||||
<module name="RightCurly"/>
|
||||
|
||||
|
||||
<!-- Checks for common coding problems -->
|
||||
<!-- See http://checkstyle.sf.net/config_coding.html -->
|
||||
<!--module name="AvoidInlineConditionals"/-->
|
||||
<module name="CovariantEquals"/>
|
||||
<module name="EmptyStatement"/>
|
||||
<!--<module name="EqualsAvoidNull"/>-->
|
||||
<module name="EqualsHashCode"/>
|
||||
<!--module name="HiddenField"/-->
|
||||
<module name="IllegalInstantiation"/>
|
||||
<!--<module name="InnerAssignment"/>-->
|
||||
<!--module name="MagicNumber"/-->
|
||||
<module name="MissingSwitchDefault"/>
|
||||
<!--<module name="RedundantThrows"/>-->
|
||||
<module name="SimplifyBooleanExpression"/>
|
||||
<module name="SimplifyBooleanReturn"/>
|
||||
|
||||
<!-- Checks for class design -->
|
||||
<!-- See http://checkstyle.sf.net/config_design.html -->
|
||||
<!--module name="DesignForExtension"/-->
|
||||
<!--module name="FinalClass"/-->
|
||||
<!--module name="HideUtilityClassConstructor"/-->
|
||||
<!--module name="InterfaceIsType"/-->
|
||||
<!--module name="VisibilityModifier"/-->
|
||||
|
||||
|
||||
<!-- Miscellaneous other checks. -->
|
||||
<!-- See http://checkstyle.sf.net/config_misc.html -->
|
||||
<!--module name="ArrayTypeStyle"/-->
|
||||
<!--module name="FinalParameters"/-->
|
||||
<!--module name="TodoComment"/-->
|
||||
<module name="UpperEll"/>
|
||||
</module>
|
||||
</module>
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||
|
@ -1,17 +0,0 @@
|
||||
apply plugin: 'checkstyle'
|
||||
|
||||
check.dependsOn 'checkstyle'
|
||||
|
||||
checkstyle {
|
||||
// toolVersion = "6.15"
|
||||
}
|
||||
|
||||
task checkstyle(type: Checkstyle) {
|
||||
configFile project.file('checkstyle.xml')
|
||||
source 'src/main/java'
|
||||
ignoreFailures false
|
||||
showViolations true
|
||||
include '**/*.java'
|
||||
|
||||
classpath = files()
|
||||
}
|
@ -1,274 +0,0 @@
|
||||
package io.github.v7lin.weibo_kit;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.sina.weibo.sdk.api.ImageObject;
|
||||
import com.sina.weibo.sdk.api.TextObject;
|
||||
import com.sina.weibo.sdk.api.WebpageObject;
|
||||
import com.sina.weibo.sdk.api.WeiboMultiMessage;
|
||||
import com.sina.weibo.sdk.auth.AuthInfo;
|
||||
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
|
||||
import com.sina.weibo.sdk.auth.WbAuthListener;
|
||||
import com.sina.weibo.sdk.common.UiError;
|
||||
import com.sina.weibo.sdk.openapi.IWBAPI;
|
||||
import com.sina.weibo.sdk.openapi.WBAPIFactory;
|
||||
import com.sina.weibo.sdk.share.WbShareCallback;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.flutter.plugin.common.BinaryMessenger;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
public class WeiboKit implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener {
|
||||
|
||||
private static class WeiboErrorCode {
|
||||
public static final int SUCCESS = 0;//成功
|
||||
public static final int USERCANCEL = -1;//用户取消发送
|
||||
public static final int SENT_FAIL = -2;//发送失败
|
||||
public static final int AUTH_DENY = -3;//授权失败
|
||||
public static final int USERCANCEL_INSTALL = -4;//用户取消安装微博客户端
|
||||
public static final int PAY_FAIL = -5;//支付失败
|
||||
public static final int SHARE_IN_SDK_FAILED = -8;//分享失败 详情见response UserInfo
|
||||
public static final int UNSUPPORT = -99;//不支持的请求
|
||||
public static final int UNKNOWN = -100;
|
||||
}
|
||||
|
||||
private static final String METHOD_REGISTERAPP = "registerApp";
|
||||
private static final String METHOD_ISINSTALLED = "isInstalled";
|
||||
private static final String METHOD_AUTH = "auth";
|
||||
private static final String METHOD_SHARETEXT = "shareText";
|
||||
private static final String METHOD_SHAREIMAGE = "shareImage";
|
||||
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
|
||||
|
||||
private static final String METHOD_ONAUTHRESP = "onAuthResp";
|
||||
private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp";
|
||||
|
||||
private static final String ARGUMENT_KEY_APPKEY = "appKey";
|
||||
private static final String ARGUMENT_KEY_SCOPE = "scope";
|
||||
private static final String ARGUMENT_KEY_REDIRECTURL = "redirectUrl";
|
||||
private static final String ARGUMENT_KEY_TEXT = "text";
|
||||
private static final String ARGUMENT_KEY_TITLE = "title";
|
||||
private static final String ARGUMENT_KEY_DESCRIPTION = "description";
|
||||
private static final String ARGUMENT_KEY_THUMBDATA = "thumbData";
|
||||
private static final String ARGUMENT_KEY_IMAGEDATA = "imageData";
|
||||
private static final String ARGUMENT_KEY_IMAGEURI = "imageUri";
|
||||
private static final String ARGUMENT_KEY_WEBPAGEURL = "webpageUrl";
|
||||
|
||||
private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode";
|
||||
private static final String ARGUMENT_KEY_RESULT_ERRORMESSAGE = "errorMessage";
|
||||
private static final String ARGUMENT_KEY_RESULT_USERID = "userId";
|
||||
private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken";
|
||||
private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken";
|
||||
private static final String ARGUMENT_KEY_RESULT_EXPIRESIN = "expiresIn";
|
||||
|
||||
//
|
||||
|
||||
private Context applicationContext;
|
||||
private Activity activity;
|
||||
|
||||
private MethodChannel channel;
|
||||
|
||||
private IWBAPI iwbapi;
|
||||
|
||||
public WeiboKit() {
|
||||
super();
|
||||
}
|
||||
|
||||
public WeiboKit(Context applicationContext, Activity activity) {
|
||||
this.applicationContext = applicationContext;
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
public void setApplicationContext(@Nullable Context applicationContext) {
|
||||
this.applicationContext = applicationContext;
|
||||
}
|
||||
|
||||
public void setActivity(@Nullable Activity activity) {
|
||||
this.activity = activity;
|
||||
}
|
||||
|
||||
public void startListening(@NonNull BinaryMessenger messenger) {
|
||||
channel = new MethodChannel(messenger, "v7lin.github.io/weibo_kit");
|
||||
channel.setMethodCallHandler(this);
|
||||
}
|
||||
|
||||
public void stopListening() {
|
||||
channel.setMethodCallHandler(null);
|
||||
channel = null;
|
||||
}
|
||||
|
||||
// --- MethodCallHandler
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
|
||||
if (METHOD_REGISTERAPP.equals(call.method)) {
|
||||
String appKey = call.argument(ARGUMENT_KEY_APPKEY);
|
||||
String scope = call.argument(ARGUMENT_KEY_SCOPE);
|
||||
String redirectUrl = call.argument(ARGUMENT_KEY_REDIRECTURL);
|
||||
|
||||
iwbapi = WBAPIFactory.createWBAPI(activity);
|
||||
iwbapi.registerApp(applicationContext, new AuthInfo(applicationContext, appKey, redirectUrl, scope));
|
||||
result.success(null);
|
||||
} else if (METHOD_ISINSTALLED.equals(call.method)) {
|
||||
result.success(iwbapi.isWBAppInstalled());
|
||||
} else if (METHOD_AUTH.equals(call.method)) {
|
||||
handleAuthCall(call, result);
|
||||
} else if (METHOD_SHARETEXT.equals(call.method)) {
|
||||
handleShareTextCall(call, result);
|
||||
} else if (METHOD_SHAREIMAGE.equals(call.method) ||
|
||||
METHOD_SHAREWEBPAGE.equals(call.method)) {
|
||||
handleShareMediaCall(call, result);
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAuthCall(MethodCall call, MethodChannel.Result result) {
|
||||
if (iwbapi != null) {
|
||||
iwbapi.authorize(new WbAuthListener() {
|
||||
@Override
|
||||
public void onComplete(Oauth2AccessToken token) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (token.isSessionValid()) {
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||
map.put(ARGUMENT_KEY_RESULT_USERID, token.getUid());
|
||||
map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, token.getAccessToken());
|
||||
map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, token.getRefreshToken());
|
||||
long expiresIn = (long) Math.ceil((token.getExpiresTime() - System.currentTimeMillis()) / 1000.0);
|
||||
map.put(ARGUMENT_KEY_RESULT_EXPIRESIN, expiresIn);// 向上取整
|
||||
} else {
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||
}
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
private void handleShareTextCall(MethodCall call, MethodChannel.Result result) {
|
||||
WeiboMultiMessage message = new WeiboMultiMessage();
|
||||
|
||||
TextObject object = new TextObject();
|
||||
object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024
|
||||
|
||||
message.textObject = object;
|
||||
|
||||
if (iwbapi != null) {
|
||||
iwbapi.shareMessage(message, false);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
private void handleShareMediaCall(MethodCall call, MethodChannel.Result result) {
|
||||
WeiboMultiMessage message = new WeiboMultiMessage();
|
||||
|
||||
if (METHOD_SHAREIMAGE.equals(call.method)) {
|
||||
if (call.hasArgument(ARGUMENT_KEY_TEXT)) {
|
||||
TextObject object = new TextObject();
|
||||
object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024
|
||||
|
||||
message.textObject = object;
|
||||
}
|
||||
|
||||
ImageObject object = new ImageObject();
|
||||
if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) {
|
||||
object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA);// 2 * 1024 * 1024
|
||||
} else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) {
|
||||
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
||||
object.imagePath = Uri.parse(imageUri).getPath();// 512 - 10 * 1024 * 1024
|
||||
}
|
||||
|
||||
message.mediaObject = object;
|
||||
} else if (METHOD_SHAREWEBPAGE.equals(call.method)) {
|
||||
WebpageObject object = new WebpageObject();
|
||||
object.identify = UUID.randomUUID().toString();
|
||||
object.title = call.argument(ARGUMENT_KEY_TITLE);// 512
|
||||
object.description = call.argument(ARGUMENT_KEY_DESCRIPTION);// 1024
|
||||
object.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA);// 32 * 1024
|
||||
object.defaultText = call.argument(ARGUMENT_KEY_DESCRIPTION);
|
||||
object.actionUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);// 512
|
||||
|
||||
message.mediaObject = object;
|
||||
}
|
||||
|
||||
if (iwbapi != null) {
|
||||
iwbapi.shareMessage(message, false);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case 32973:
|
||||
if (iwbapi != null) {
|
||||
iwbapi.authorizeCallback(requestCode, resultCode, data);
|
||||
}
|
||||
return true;
|
||||
case 10001:
|
||||
if (iwbapi != null) {
|
||||
iwbapi.doResultIntent(data, new WbShareCallback() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SHARE_IN_SDK_FAILED);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,76 +1,294 @@
|
||||
package io.github.v7lin.weibo_kit;
|
||||
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.net.Uri;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
|
||||
import com.sina.weibo.sdk.api.ImageObject;
|
||||
import com.sina.weibo.sdk.api.TextObject;
|
||||
import com.sina.weibo.sdk.api.WebpageObject;
|
||||
import com.sina.weibo.sdk.api.WeiboMultiMessage;
|
||||
import com.sina.weibo.sdk.auth.AuthInfo;
|
||||
import com.sina.weibo.sdk.auth.Oauth2AccessToken;
|
||||
import com.sina.weibo.sdk.auth.WbAuthListener;
|
||||
import com.sina.weibo.sdk.common.UiError;
|
||||
import com.sina.weibo.sdk.openapi.IWBAPI;
|
||||
import com.sina.weibo.sdk.openapi.WBAPIFactory;
|
||||
import com.sina.weibo.sdk.share.WbShareCallback;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||
import io.flutter.plugin.common.PluginRegistry.Registrar;
|
||||
import io.flutter.plugin.common.MethodCall;
|
||||
import io.flutter.plugin.common.MethodChannel;
|
||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
|
||||
import io.flutter.plugin.common.MethodChannel.Result;
|
||||
import io.flutter.plugin.common.PluginRegistry;
|
||||
|
||||
/** WeiboKitPlugin */
|
||||
public class WeiboKitPlugin implements FlutterPlugin, ActivityAware {
|
||||
// This static function is optional and equivalent to onAttachedToEngine. It supports the old
|
||||
// pre-Flutter-1.12 Android projects. You are encouraged to continue supporting
|
||||
// plugin registration via this function while apps migrate to use the new Android APIs
|
||||
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
|
||||
//
|
||||
// It is encouraged to share logic between onAttachedToEngine and registerWith to keep
|
||||
// them functionally equivalent. Only one of onAttachedToEngine or registerWith will be called
|
||||
// depending on the user's project. onAttachedToEngine or registerWith must both be defined
|
||||
// in the same class.
|
||||
public static void registerWith(Registrar registrar) {
|
||||
WeiboKit weiboKit = new WeiboKit(registrar.context(), registrar.activity());
|
||||
registrar.addActivityResultListener(weiboKit);
|
||||
weiboKit.startListening(registrar.messenger());
|
||||
}
|
||||
/**
|
||||
* WeiboKitPlugin
|
||||
*/
|
||||
public class WeiboKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.ActivityResultListener, MethodCallHandler {
|
||||
|
||||
// --- FlutterPlugin
|
||||
private static class WeiboErrorCode {
|
||||
public static final int SUCCESS = 0;//成功
|
||||
public static final int USERCANCEL = -1;//用户取消发送
|
||||
public static final int SENT_FAIL = -2;//发送失败
|
||||
public static final int AUTH_DENY = -3;//授权失败
|
||||
public static final int USERCANCEL_INSTALL = -4;//用户取消安装微博客户端
|
||||
public static final int PAY_FAIL = -5;//支付失败
|
||||
public static final int SHARE_IN_SDK_FAILED = -8;//分享失败 详情见response UserInfo
|
||||
public static final int UNSUPPORT = -99;//不支持的请求
|
||||
public static final int UNKNOWN = -100;
|
||||
}
|
||||
|
||||
private final WeiboKit weiboKit;
|
||||
private static final String METHOD_REGISTERAPP = "registerApp";
|
||||
private static final String METHOD_ISINSTALLED = "isInstalled";
|
||||
private static final String METHOD_AUTH = "auth";
|
||||
private static final String METHOD_SHARETEXT = "shareText";
|
||||
private static final String METHOD_SHAREIMAGE = "shareImage";
|
||||
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
|
||||
|
||||
private ActivityPluginBinding pluginBinding;
|
||||
private static final String METHOD_ONAUTHRESP = "onAuthResp";
|
||||
private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp";
|
||||
|
||||
public WeiboKitPlugin() {
|
||||
weiboKit = new WeiboKit();
|
||||
}
|
||||
private static final String ARGUMENT_KEY_APPKEY = "appKey";
|
||||
private static final String ARGUMENT_KEY_SCOPE = "scope";
|
||||
private static final String ARGUMENT_KEY_REDIRECTURL = "redirectUrl";
|
||||
private static final String ARGUMENT_KEY_TEXT = "text";
|
||||
private static final String ARGUMENT_KEY_TITLE = "title";
|
||||
private static final String ARGUMENT_KEY_DESCRIPTION = "description";
|
||||
private static final String ARGUMENT_KEY_THUMBDATA = "thumbData";
|
||||
private static final String ARGUMENT_KEY_IMAGEDATA = "imageData";
|
||||
private static final String ARGUMENT_KEY_IMAGEURI = "imageUri";
|
||||
private static final String ARGUMENT_KEY_WEBPAGEURL = "webpageUrl";
|
||||
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||
weiboKit.setApplicationContext(binding.getApplicationContext());
|
||||
weiboKit.setActivity(null);
|
||||
weiboKit.startListening(binding.getBinaryMessenger());
|
||||
}
|
||||
private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode";
|
||||
private static final String ARGUMENT_KEY_RESULT_ERRORMESSAGE = "errorMessage";
|
||||
private static final String ARGUMENT_KEY_RESULT_USERID = "userId";
|
||||
private static final String ARGUMENT_KEY_RESULT_ACCESSTOKEN = "accessToken";
|
||||
private static final String ARGUMENT_KEY_RESULT_REFRESHTOKEN = "refreshToken";
|
||||
private static final String ARGUMENT_KEY_RESULT_EXPIRESIN = "expiresIn";
|
||||
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
weiboKit.stopListening();
|
||||
weiboKit.setActivity(null);
|
||||
weiboKit.setApplicationContext(null);
|
||||
}
|
||||
/// The MethodChannel that will the communication between Flutter and native Android
|
||||
///
|
||||
/// This local reference serves to register the plugin with the Flutter Engine and unregister it
|
||||
/// when the Flutter Engine is detached from the Activity
|
||||
private MethodChannel channel;
|
||||
private Context applicationContext;
|
||||
private ActivityPluginBinding activityPluginBinding;
|
||||
|
||||
// --- ActivityAware
|
||||
private IWBAPI iwbapi;
|
||||
|
||||
@Override
|
||||
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
|
||||
weiboKit.setActivity(binding.getActivity());
|
||||
pluginBinding = binding;
|
||||
pluginBinding.addActivityResultListener(weiboKit);
|
||||
}
|
||||
// --- FlutterPlugin
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivityForConfigChanges() {
|
||||
onDetachedFromActivity();
|
||||
}
|
||||
@Override
|
||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||
channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/weibo_kit");
|
||||
channel.setMethodCallHandler(this);
|
||||
applicationContext = binding.getApplicationContext();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
|
||||
onAttachedToActivity(binding);
|
||||
}
|
||||
@Override
|
||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||
channel.setMethodCallHandler(null);
|
||||
channel = null;
|
||||
applicationContext = null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivity() {
|
||||
weiboKit.setActivity(null);
|
||||
pluginBinding.removeActivityResultListener(weiboKit);
|
||||
pluginBinding = null;
|
||||
}
|
||||
// --- ActivityAware
|
||||
|
||||
@Override
|
||||
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
|
||||
activityPluginBinding = binding;
|
||||
activityPluginBinding.addActivityResultListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivityForConfigChanges() {
|
||||
onDetachedFromActivity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
|
||||
onAttachedToActivity(binding);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDetachedFromActivity() {
|
||||
activityPluginBinding.removeActivityResultListener(this);
|
||||
activityPluginBinding = null;
|
||||
}
|
||||
|
||||
// --- ActivityResultListener
|
||||
|
||||
@Override
|
||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||
switch (requestCode) {
|
||||
case 32973:
|
||||
if (iwbapi != null) {
|
||||
iwbapi.authorizeCallback(requestCode, resultCode, data);
|
||||
}
|
||||
return true;
|
||||
case 10001:
|
||||
if (iwbapi != null) {
|
||||
iwbapi.doResultIntent(data, new WbShareCallback() {
|
||||
@Override
|
||||
public void onComplete() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SHARE_IN_SDK_FAILED);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --- MethodCallHandler
|
||||
|
||||
@Override
|
||||
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
if (METHOD_REGISTERAPP.equals(call.method)) {
|
||||
String appKey = call.argument(ARGUMENT_KEY_APPKEY);
|
||||
String scope = call.argument(ARGUMENT_KEY_SCOPE);
|
||||
String redirectUrl = call.argument(ARGUMENT_KEY_REDIRECTURL);
|
||||
iwbapi = WBAPIFactory.createWBAPI(activityPluginBinding.getActivity());
|
||||
iwbapi.registerApp(applicationContext, new AuthInfo(applicationContext, appKey, redirectUrl, scope));
|
||||
result.success(null);
|
||||
} else if (METHOD_ISINSTALLED.equals(call.method)) {
|
||||
result.success(iwbapi.isWBAppInstalled());
|
||||
} else if (METHOD_AUTH.equals(call.method)) {
|
||||
handleAuthCall(call, result);
|
||||
} else if (METHOD_SHARETEXT.equals(call.method)) {
|
||||
handleShareTextCall(call, result);
|
||||
} else if (METHOD_SHAREIMAGE.equals(call.method) ||
|
||||
METHOD_SHAREWEBPAGE.equals(call.method)) {
|
||||
handleShareMediaCall(call, result);
|
||||
} else {
|
||||
result.notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
private void handleAuthCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
if (iwbapi != null) {
|
||||
iwbapi.authorize(new WbAuthListener() {
|
||||
@Override
|
||||
public void onComplete(Oauth2AccessToken token) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
if (token.isSessionValid()) {
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.SUCCESS);
|
||||
map.put(ARGUMENT_KEY_RESULT_USERID, token.getUid());
|
||||
map.put(ARGUMENT_KEY_RESULT_ACCESSTOKEN, token.getAccessToken());
|
||||
map.put(ARGUMENT_KEY_RESULT_REFRESHTOKEN, token.getRefreshToken());
|
||||
long expiresIn = (long) Math.ceil((token.getExpiresTime() - System.currentTimeMillis()) / 1000.0);
|
||||
map.put(ARGUMENT_KEY_RESULT_EXPIRESIN, expiresIn);// 向上取整
|
||||
} else {
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||
}
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onError(UiError uiError) {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.UNKNOWN);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCancel() {
|
||||
Map<String, Object> map = new HashMap<>();
|
||||
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, WeiboErrorCode.USERCANCEL);
|
||||
if (channel != null) {
|
||||
channel.invokeMethod(METHOD_ONAUTHRESP, map);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
private void handleShareTextCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
WeiboMultiMessage message = new WeiboMultiMessage();
|
||||
|
||||
TextObject object = new TextObject();
|
||||
object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024
|
||||
|
||||
message.textObject = object;
|
||||
|
||||
if (iwbapi != null) {
|
||||
iwbapi.shareMessage(message, false);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
|
||||
private void handleShareMediaCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||
WeiboMultiMessage message = new WeiboMultiMessage();
|
||||
|
||||
if (METHOD_SHAREIMAGE.equals(call.method)) {
|
||||
if (call.hasArgument(ARGUMENT_KEY_TEXT)) {
|
||||
TextObject object = new TextObject();
|
||||
object.text = call.argument(ARGUMENT_KEY_TEXT);// 1024
|
||||
|
||||
message.textObject = object;
|
||||
}
|
||||
|
||||
ImageObject object = new ImageObject();
|
||||
if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) {
|
||||
object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA);// 2 * 1024 * 1024
|
||||
} else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) {
|
||||
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
||||
object.imagePath = Uri.parse(imageUri).getPath();// 512 - 10 * 1024 * 1024
|
||||
}
|
||||
|
||||
message.mediaObject = object;
|
||||
} else if (METHOD_SHAREWEBPAGE.equals(call.method)) {
|
||||
WebpageObject object = new WebpageObject();
|
||||
object.identify = UUID.randomUUID().toString();
|
||||
object.title = call.argument(ARGUMENT_KEY_TITLE);// 512
|
||||
object.description = call.argument(ARGUMENT_KEY_DESCRIPTION);// 1024
|
||||
object.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA);// 32 * 1024
|
||||
object.defaultText = call.argument(ARGUMENT_KEY_DESCRIPTION);
|
||||
object.actionUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);// 512
|
||||
|
||||
message.mediaObject = object;
|
||||
}
|
||||
|
||||
if (iwbapi != null) {
|
||||
iwbapi.shareMessage(message, false);
|
||||
}
|
||||
result.success(null);
|
||||
}
|
||||
}
|
||||
|
5
android/src/vendor/AndroidManifest.xml
vendored
5
android/src/vendor/AndroidManifest.xml
vendored
@ -3,4 +3,9 @@
|
||||
|
||||
<uses-permission android:name="android.permission.INTERNET" />
|
||||
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
|
||||
|
||||
<queries>
|
||||
<!-- targetSdkVersion>=30 -> Android 11 软件包可见性 -->
|
||||
<package android:name="com.sina.weibo" />
|
||||
</queries>
|
||||
</manifest>
|
||||
|
7
example/.gitignore
vendored
7
example/.gitignore
vendored
@ -22,6 +22,7 @@
|
||||
|
||||
# Flutter/Dart/Pub related
|
||||
**/doc/api/
|
||||
**/ios/Flutter/.last_build_id
|
||||
.dart_tool/
|
||||
.flutter-plugins
|
||||
.flutter-plugins-dependencies
|
||||
@ -39,5 +40,7 @@ app.*.symbols
|
||||
# Obfuscation related
|
||||
app.*.map.json
|
||||
|
||||
# Exceptions to above rules.
|
||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
||||
# Android Studio will place build artifacts here
|
||||
/android/app/debug
|
||||
/android/app/profile
|
||||
/android/app/release
|
||||
|
4
example/android/.gitignore
vendored
4
example/android/.gitignore
vendored
@ -5,3 +5,7 @@ gradle-wrapper.jar
|
||||
/gradlew.bat
|
||||
/local.properties
|
||||
GeneratedPluginRegistrant.java
|
||||
|
||||
# Remember to never publicly share your keystore.
|
||||
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
|
||||
key.properties
|
||||
|
@ -5,7 +5,7 @@ buildscript {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath 'com.android.tools.build:gradle:3.5.0'
|
||||
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
|
||||
|
@ -10,75 +10,29 @@ project 'Runner', {
|
||||
'Release' => :release,
|
||||
}
|
||||
|
||||
def parse_KV_file(file, separator='=')
|
||||
file_abs_path = File.expand_path(file)
|
||||
if !File.exists? file_abs_path
|
||||
return [];
|
||||
def flutter_root
|
||||
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
generated_key_values = {}
|
||||
skip_line_start_symbols = ["#", "/"]
|
||||
File.foreach(file_abs_path) do |line|
|
||||
next if skip_line_start_symbols.any? { |symbol| line =~ /^\s*#{symbol}/ }
|
||||
plugin = line.split(pattern=separator)
|
||||
if plugin.length == 2
|
||||
podname = plugin[0].strip()
|
||||
path = plugin[1].strip()
|
||||
podpath = File.expand_path("#{path}", file_abs_path)
|
||||
generated_key_values[podname] = podpath
|
||||
else
|
||||
puts "Invalid plugin specification: #{line}"
|
||||
end
|
||||
|
||||
File.foreach(generated_xcode_build_settings_path) do |line|
|
||||
matches = line.match(/FLUTTER_ROOT\=(.*)/)
|
||||
return matches[1].strip if matches
|
||||
end
|
||||
generated_key_values
|
||||
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
|
||||
end
|
||||
|
||||
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
|
||||
|
||||
flutter_ios_podfile_setup
|
||||
|
||||
target 'Runner' do
|
||||
# Flutter Pod
|
||||
|
||||
copied_flutter_dir = File.join(__dir__, 'Flutter')
|
||||
copied_framework_path = File.join(copied_flutter_dir, 'Flutter.framework')
|
||||
copied_podspec_path = File.join(copied_flutter_dir, 'Flutter.podspec')
|
||||
unless File.exist?(copied_framework_path) && File.exist?(copied_podspec_path)
|
||||
# Copy Flutter.framework and Flutter.podspec to Flutter/ to have something to link against if the xcode backend script has not run yet.
|
||||
# That script will copy the correct debug/profile/release version of the framework based on the currently selected Xcode configuration.
|
||||
# CocoaPods will not embed the framework on pod install (before any build phases can generate) if the dylib does not exist.
|
||||
|
||||
generated_xcode_build_settings_path = File.join(copied_flutter_dir, 'Generated.xcconfig')
|
||||
unless File.exist?(generated_xcode_build_settings_path)
|
||||
raise "Generated.xcconfig must exist. If you're running pod install manually, make sure flutter pub get is executed first"
|
||||
end
|
||||
generated_xcode_build_settings = parse_KV_file(generated_xcode_build_settings_path)
|
||||
cached_framework_dir = generated_xcode_build_settings['FLUTTER_FRAMEWORK_DIR'];
|
||||
|
||||
unless File.exist?(copied_framework_path)
|
||||
FileUtils.cp_r(File.join(cached_framework_dir, 'Flutter.framework'), copied_flutter_dir)
|
||||
end
|
||||
unless File.exist?(copied_podspec_path)
|
||||
FileUtils.cp(File.join(cached_framework_dir, 'Flutter.podspec'), copied_flutter_dir)
|
||||
end
|
||||
end
|
||||
|
||||
# Keep pod path relative so it can be checked into Podfile.lock.
|
||||
pod 'Flutter', :path => 'Flutter'
|
||||
|
||||
# Plugin Pods
|
||||
|
||||
# Prepare symlinks folder. We use symlinks to avoid having Podfile.lock
|
||||
# referring to absolute paths on developers' machines.
|
||||
system('rm -rf .symlinks')
|
||||
system('mkdir -p .symlinks/plugins')
|
||||
plugin_pods = parse_KV_file('../.flutter-plugins')
|
||||
plugin_pods.each do |name, path|
|
||||
symlink = File.join('.symlinks', 'plugins', name)
|
||||
File.symlink(path, symlink)
|
||||
pod name, :path => File.join(symlink, 'ios')
|
||||
end
|
||||
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
|
||||
end
|
||||
|
||||
post_install do |installer|
|
||||
installer.pods_project.targets.each do |target|
|
||||
target.build_configurations.each do |config|
|
||||
config.build_settings['ENABLE_BITCODE'] = 'NO'
|
||||
end
|
||||
flutter_additional_ios_build_settings(target)
|
||||
end
|
||||
end
|
||||
|
@ -1,15 +1,17 @@
|
||||
PODS:
|
||||
- Flutter (1.0.0)
|
||||
- FMDB (2.7.5):
|
||||
- FMDB/standard (= 2.7.5)
|
||||
- FMDB/standard (2.7.5)
|
||||
- path_provider (0.0.1):
|
||||
- Flutter
|
||||
- path_provider_linux (0.0.1):
|
||||
- sqflite (0.0.2):
|
||||
- Flutter
|
||||
- path_provider_macos (0.0.1):
|
||||
- FMDB (>= 2.7.5)
|
||||
- weibo_kit (2.0.0):
|
||||
- Flutter
|
||||
- weibo_kit (1.1.0):
|
||||
- Flutter
|
||||
- weibo_kit/vendor (= 1.1.0)
|
||||
- weibo_kit/vendor (1.1.0):
|
||||
- weibo_kit/vendor (= 2.0.0)
|
||||
- weibo_kit/vendor (2.0.0):
|
||||
- Flutter
|
||||
- Weibo_SDK (~> 3.2.7)
|
||||
- Weibo_SDK (3.2.7)
|
||||
@ -17,12 +19,12 @@ PODS:
|
||||
DEPENDENCIES:
|
||||
- Flutter (from `Flutter`)
|
||||
- path_provider (from `.symlinks/plugins/path_provider/ios`)
|
||||
- path_provider_linux (from `.symlinks/plugins/path_provider_linux/ios`)
|
||||
- path_provider_macos (from `.symlinks/plugins/path_provider_macos/ios`)
|
||||
- sqflite (from `.symlinks/plugins/sqflite/ios`)
|
||||
- weibo_kit (from `.symlinks/plugins/weibo_kit/ios`)
|
||||
|
||||
SPEC REPOS:
|
||||
trunk:
|
||||
- FMDB
|
||||
- Weibo_SDK
|
||||
|
||||
EXTERNAL SOURCES:
|
||||
@ -30,21 +32,19 @@ EXTERNAL SOURCES:
|
||||
:path: Flutter
|
||||
path_provider:
|
||||
:path: ".symlinks/plugins/path_provider/ios"
|
||||
path_provider_linux:
|
||||
:path: ".symlinks/plugins/path_provider_linux/ios"
|
||||
path_provider_macos:
|
||||
:path: ".symlinks/plugins/path_provider_macos/ios"
|
||||
sqflite:
|
||||
:path: ".symlinks/plugins/sqflite/ios"
|
||||
weibo_kit:
|
||||
:path: ".symlinks/plugins/weibo_kit/ios"
|
||||
|
||||
SPEC CHECKSUMS:
|
||||
Flutter: 0e3d915762c693b495b44d77113d4970485de6ec
|
||||
Flutter: 434fef37c0980e73bb6479ef766c45957d4b510c
|
||||
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
|
||||
path_provider: abfe2b5c733d04e238b0d8691db0cfd63a27a93c
|
||||
path_provider_linux: 4d630dc393e1f20364f3e3b4a2ff41d9674a84e4
|
||||
path_provider_macos: f760a3c5b04357c380e2fddb6f9db6f3015897e0
|
||||
weibo_kit: 82a3b5501bbe2ae59528e683a80277079ecc95cb
|
||||
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
|
||||
weibo_kit: 9327afb47ffde6c4fd4b091973f91eae4440a0c4
|
||||
Weibo_SDK: 5a4d08f7e1fedbb635435e4585c8c0439c7da089
|
||||
|
||||
PODFILE CHECKSUM: f32fb4e7c14f8b3ca19a369d7be425dd9241af27
|
||||
PODFILE CHECKSUM: 8e679eca47255a8ca8067c4c67aab20e64cb974d
|
||||
|
||||
COCOAPODS: 1.8.4
|
||||
COCOAPODS: 1.10.0
|
||||
|
@ -149,7 +149,6 @@
|
||||
97C146EC1CF9000F007C117D /* Resources */,
|
||||
9705A1C41CF9048500538489 /* Embed Frameworks */,
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
|
||||
1F77EE1FF4C528197971DB94 /* [CP] Embed Pods Frameworks */,
|
||||
BEFF80007E7E4E2B2694658C /* [CP] Copy Pods Resources */,
|
||||
);
|
||||
buildRules = (
|
||||
@ -208,23 +207,6 @@
|
||||
/* End PBXResourcesBuildPhase section */
|
||||
|
||||
/* Begin PBXShellScriptBuildPhase section */
|
||||
1F77EE1FF4C528197971DB94 /* [CP] Embed Pods Frameworks */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
inputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist",
|
||||
);
|
||||
name = "[CP] Embed Pods Frameworks";
|
||||
outputFileListPaths = (
|
||||
"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist",
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
shellPath = /bin/sh;
|
||||
shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n";
|
||||
showEnvVarsInLog = 0;
|
||||
};
|
||||
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
|
||||
isa = PBXShellScriptBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
|
@ -3,26 +3,22 @@ import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||
import 'package:image/image.dart' as image;
|
||||
import 'package:okhttp_kit/okhttp_kit.dart';
|
||||
import 'package:path/path.dart' as path;
|
||||
import 'package:path_provider/path_provider.dart' as path_provider;
|
||||
import 'package:weibo_kit/weibo_kit.dart';
|
||||
|
||||
void main() {
|
||||
runZoned(() {
|
||||
runApp(MyApp());
|
||||
}, onError: (dynamic error, dynamic stack) {
|
||||
print(error);
|
||||
print(stack);
|
||||
});
|
||||
const String _WEIBO_APP_KEY = 'your weibo app key';
|
||||
const List<String> _WEIBO_SCOPE = <String>[
|
||||
WeiboScope.ALL,
|
||||
];
|
||||
|
||||
if (Platform.isAndroid) {
|
||||
SystemUiOverlayStyle systemUiOverlayStyle =
|
||||
const SystemUiOverlayStyle(statusBarColor: Colors.transparent);
|
||||
SystemChrome.setSystemUIOverlayStyle(systemUiOverlayStyle);
|
||||
}
|
||||
void main() {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
Weibo.instance.registerApp(
|
||||
appKey: _WEIBO_APP_KEY,
|
||||
scope: _WEIBO_SCOPE,
|
||||
);
|
||||
runApp(MyApp());
|
||||
}
|
||||
|
||||
class MyApp extends StatelessWidget {
|
||||
@ -42,48 +38,33 @@ class Home extends StatefulWidget {
|
||||
}
|
||||
|
||||
class _HomeState extends State<Home> {
|
||||
static const String _WEIBO_APP_KEY = 'your weibo app key';
|
||||
static const List<String> _WEIBO_SCOPE = <String>[
|
||||
WeiboScope.ALL,
|
||||
];
|
||||
late final StreamSubscription<WeiboAuthResp> _auth =
|
||||
Weibo.instance.authResp().listen(_listenAuth);
|
||||
late final StreamSubscription<WeiboSdkResp> _share =
|
||||
Weibo.instance.shareMsgResp().listen(_listenShareMsg);
|
||||
|
||||
Weibo _weibo = Weibo()
|
||||
..registerApp(
|
||||
appKey: _WEIBO_APP_KEY,
|
||||
scope: _WEIBO_SCOPE,
|
||||
);
|
||||
|
||||
StreamSubscription<WeiboAuthResp> _auth;
|
||||
StreamSubscription<WeiboSdkResp> _share;
|
||||
|
||||
WeiboAuthResp _authResp;
|
||||
WeiboAuthResp? _authResp;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_auth = _weibo.authResp().listen(_listenAuth);
|
||||
_share = _weibo.shareMsgResp().listen(_listenShareMsg);
|
||||
}
|
||||
|
||||
void _listenAuth(WeiboAuthResp resp) {
|
||||
_authResp = resp;
|
||||
String content = 'auth: ${resp.errorCode}';
|
||||
final String content = 'auth: ${resp.errorCode}';
|
||||
_showTips('登录', content);
|
||||
}
|
||||
|
||||
void _listenShareMsg(WeiboSdkResp resp) {
|
||||
String content = 'share: ${resp.errorCode}';
|
||||
final String content = 'share: ${resp.errorCode}';
|
||||
_showTips('分享', content);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
if (_auth != null) {
|
||||
_auth.cancel();
|
||||
}
|
||||
if (_share != null) {
|
||||
_share.cancel();
|
||||
}
|
||||
_auth.cancel();
|
||||
_share.cancel();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@ -98,14 +79,15 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: const Text('环境检查'),
|
||||
onTap: () async {
|
||||
String content = 'weibo: ${await _weibo.isInstalled()}';
|
||||
final String content =
|
||||
'weibo: ${await Weibo.instance.isInstalled()}';
|
||||
_showTips('环境检查', content);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('登录'),
|
||||
onTap: () {
|
||||
_weibo.auth(
|
||||
Weibo.instance.auth(
|
||||
appKey: _WEIBO_APP_KEY,
|
||||
scope: _WEIBO_SCOPE,
|
||||
);
|
||||
@ -114,15 +96,14 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: const Text('用户信息'),
|
||||
onTap: () async {
|
||||
if (_authResp != null &&
|
||||
_authResp.errorCode == WeiboSdkResp.SUCCESS) {
|
||||
WeiboUserInfoResp userInfoResp = await _weibo.getUserInfo(
|
||||
if (_authResp?.isSuccessful ?? false) {
|
||||
final WeiboUserInfoResp userInfoResp =
|
||||
await Weibo.instance.getUserInfo(
|
||||
appkey: _WEIBO_APP_KEY,
|
||||
userId: _authResp.userId,
|
||||
accessToken: _authResp.accessToken,
|
||||
userId: _authResp!.userId!,
|
||||
accessToken: _authResp!.accessToken!,
|
||||
);
|
||||
if (userInfoResp != null &&
|
||||
userInfoResp.errorCode == WeiboApiResp.ERROR_CODE_SUCCESS) {
|
||||
if (userInfoResp.isSuccessful) {
|
||||
_showTips('用户信息',
|
||||
'${userInfoResp.screenName}\n${userInfoResp.description}\n${userInfoResp.location}\n${userInfoResp.profileImageUrl}');
|
||||
} else {
|
||||
@ -135,7 +116,7 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: const Text('文字分享'),
|
||||
onTap: () {
|
||||
_weibo.shareText(
|
||||
Weibo.instance.shareText(
|
||||
text: 'Share Text',
|
||||
);
|
||||
},
|
||||
@ -143,70 +124,32 @@ class _HomeState extends State<Home> {
|
||||
ListTile(
|
||||
title: const Text('图片分享'),
|
||||
onTap: () async {
|
||||
OkHttpClient client = OkHttpClientBuilder().build();
|
||||
Response resp = await client
|
||||
.newCall(RequestBuilder()
|
||||
.get()
|
||||
.url(HttpUrl.parse(
|
||||
'https://www.baidu.com/img/bd_logo1.png?where=super'))
|
||||
.build())
|
||||
.enqueue();
|
||||
if (resp.isSuccessful()) {
|
||||
Directory saveDir = Platform.isAndroid
|
||||
? await path_provider.getExternalStorageDirectory()
|
||||
: await path_provider.getApplicationDocumentsDirectory();
|
||||
File saveFile = File(path.join(saveDir.path, 'timg.png'));
|
||||
if (!saveFile.existsSync()) {
|
||||
saveFile.createSync(recursive: true);
|
||||
saveFile.writeAsBytesSync(
|
||||
await resp.body().bytes(),
|
||||
flush: true,
|
||||
);
|
||||
}
|
||||
await _weibo.shareImage(
|
||||
text: 'Share Text',
|
||||
imageUri: Uri.file(saveFile.path),
|
||||
);
|
||||
}
|
||||
final File file = await DefaultCacheManager().getSingleFile(
|
||||
'https://www.baidu.com/img/bd_logo1.png?where=super');
|
||||
await Weibo.instance.shareImage(
|
||||
text: 'Share Text',
|
||||
imageUri: Uri.file(file.path),
|
||||
);
|
||||
},
|
||||
),
|
||||
ListTile(
|
||||
title: const Text('网页分享'),
|
||||
onTap: () async {
|
||||
OkHttpClient client = OkHttpClientBuilder().build();
|
||||
Response resp = await client
|
||||
.newCall(RequestBuilder()
|
||||
.get()
|
||||
.url(HttpUrl.parse(
|
||||
'https://www.baidu.com/img/bd_logo1.png?where=super'))
|
||||
.build())
|
||||
.enqueue();
|
||||
if (resp.isSuccessful()) {
|
||||
Directory saveDir = Platform.isAndroid
|
||||
? await path_provider.getExternalStorageDirectory()
|
||||
: await path_provider.getApplicationDocumentsDirectory();
|
||||
File saveFile = File(path.join(saveDir.path, 'timg.png'));
|
||||
if (!saveFile.existsSync()) {
|
||||
saveFile.createSync(recursive: true);
|
||||
saveFile.writeAsBytesSync(
|
||||
await resp.body().bytes(),
|
||||
flush: true,
|
||||
);
|
||||
}
|
||||
image.Image thumbnail =
|
||||
image.decodePng(saveFile.readAsBytesSync());
|
||||
Uint8List thumbData = thumbnail.getBytes();
|
||||
if (thumbData.length > 32 * 1024) {
|
||||
thumbData = Uint8List.fromList(image.encodeJpg(thumbnail,
|
||||
quality: 100 * 32 * 1024 ~/ thumbData.length));
|
||||
}
|
||||
await _weibo.shareWebpage(
|
||||
title: 'title',
|
||||
description: 'share webpage',
|
||||
thumbData: thumbData.buffer.asUint8List(),
|
||||
webpageUrl: 'https://www.baidu.com',
|
||||
);
|
||||
final File file = await DefaultCacheManager().getSingleFile(
|
||||
'https://www.baidu.com/img/bd_logo1.png?where=super');
|
||||
final image.Image thumbnail =
|
||||
image.decodeImage(file.readAsBytesSync())!;
|
||||
Uint8List thumbData = thumbnail.getBytes();
|
||||
if (thumbData.length > 32 * 1024) {
|
||||
thumbData = Uint8List.fromList(image.encodeJpg(thumbnail,
|
||||
quality: 100 * 32 * 1024 ~/ thumbData.length));
|
||||
}
|
||||
await Weibo.instance.shareWebpage(
|
||||
title: 'title',
|
||||
description: 'share webpage',
|
||||
thumbData: thumbData.buffer.asUint8List(),
|
||||
webpageUrl: 'https://www.baidu.com',
|
||||
);
|
||||
},
|
||||
),
|
||||
],
|
||||
|
@ -7,206 +7,227 @@ packages:
|
||||
name: archive
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "3.1.2"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.5.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
version: "1.2.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.14.12"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "1.15.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "3.0.0"
|
||||
cupertino_icons:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: cupertino_icons
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.3"
|
||||
version: "1.0.2"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
ffi:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: ffi
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "6.1.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
flutter_cache_manager:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: flutter_cache_manager
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.0-nullsafety.1"
|
||||
flutter_test:
|
||||
dependency: "direct dev"
|
||||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
image:
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.13.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
image:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.12"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
version: "3.0.1"
|
||||
json_annotation:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "4.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.12.6"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.8"
|
||||
okhttp_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: okhttp_kit
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.3.0"
|
||||
path:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
version: "1.8.0"
|
||||
path_provider:
|
||||
dependency: "direct main"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.11"
|
||||
version: "2.0.1"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.0.1+1"
|
||||
version: "2.0.0"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.0.4+3"
|
||||
version: "2.0.0"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "2.0.1"
|
||||
path_provider_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_windows
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
version: "1.11.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
version: "4.0.2"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.0.0"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "2.0.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.13"
|
||||
quiver:
|
||||
version: "4.1.0"
|
||||
rxdart:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
name: rxdart
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "0.26.0"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -218,77 +239,112 @@ packages:
|
||||
name: source_span
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0"
|
||||
sqflite:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0+3"
|
||||
sqflite_common:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: sqflite_common
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0+2"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.1.0"
|
||||
synchronized:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: synchronized
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.2.15"
|
||||
version: "0.2.19"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
version: "1.3.0"
|
||||
uuid:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: uuid
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
version: "2.1.0"
|
||||
weibo_kit:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
path: ".."
|
||||
relative: true
|
||||
source: path
|
||||
version: "1.1.0"
|
||||
version: "2.0.0"
|
||||
win32:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: win32
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.4"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
version: "0.2.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
version: "5.0.2"
|
||||
sdks:
|
||||
dart: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.12.13+hotfix.5 <2.0.0"
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.24.0-10"
|
||||
|
@ -1,12 +1,14 @@
|
||||
name: weibo_kit_example
|
||||
description: Demonstrates how to use the weibo_kit plugin.
|
||||
version: 1.0.0+1000
|
||||
|
||||
# The following line prevents the package from being accidentally published to
|
||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
||||
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
|
||||
version: 1.0.0+100
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
@ -22,12 +24,10 @@ dependencies:
|
||||
|
||||
# The following adds the Cupertino Icons font to your application.
|
||||
# Use with the CupertinoIcons class for iOS style icons.
|
||||
cupertino_icons: ^0.1.3
|
||||
cupertino_icons: ^1.0.2
|
||||
|
||||
path: ^1.6.4
|
||||
path_provider: ^1.4.0
|
||||
|
||||
okhttp_kit: ^1.0.0
|
||||
image: ^3.0.1
|
||||
flutter_cache_manager: ^3.0.0-nullsafety.1
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
|
44
ios/.clang-format
Executable file
44
ios/.clang-format
Executable file
@ -0,0 +1,44 @@
|
||||
# 基础样式
|
||||
BasedOnStyle: LLVM
|
||||
|
||||
# 缩进宽度
|
||||
IndentWidth: 4
|
||||
|
||||
# 圆括号的换行方式
|
||||
BreakBeforeBraces: Attach
|
||||
|
||||
# 是否允许循环单行
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
|
||||
# 支持一行的if
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
|
||||
# switch的case缩进
|
||||
IndentCaseLabels: true
|
||||
|
||||
# 针对OC的block的缩进宽度
|
||||
ObjCBlockIndentWidth: 4
|
||||
|
||||
# 针对OC,属性名后加空格
|
||||
ObjCSpaceAfterProperty: true
|
||||
|
||||
# 每行字符的长度
|
||||
ColumnLimit: 0
|
||||
|
||||
# 注释对齐
|
||||
AlignTrailingComments: true
|
||||
|
||||
# 括号后加空格
|
||||
SpaceAfterCStyleCast: false
|
||||
|
||||
# 不在小括号里加空格
|
||||
SpacesInParentheses: false
|
||||
|
||||
# 不在中括号里加空格
|
||||
SpacesInSquareBrackets: false
|
||||
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
|
||||
AllowShortFunctionsOnASingleLine: false
|
@ -4,7 +4,7 @@
|
||||
#
|
||||
Pod::Spec.new do |s|
|
||||
s.name = 'weibo_kit'
|
||||
s.version = '1.1.0'
|
||||
s.version = '2.0.0'
|
||||
s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs.'
|
||||
s.description = <<-DESC
|
||||
A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs.
|
||||
|
@ -1,14 +1,21 @@
|
||||
import 'package:json_annotation/json_annotation.dart';
|
||||
|
||||
abstract class WeiboApiResp {
|
||||
WeiboApiResp({
|
||||
int errorCode,
|
||||
const WeiboApiResp({
|
||||
required this.errorCode,
|
||||
this.error,
|
||||
this.request,
|
||||
}) : errorCode = errorCode ?? ERROR_CODE_SUCCESS;
|
||||
});
|
||||
|
||||
static const int ERROR_CODE_SUCCESS = 0;
|
||||
|
||||
/// https://open.weibo.com/wiki/Help/error
|
||||
@JsonKey(
|
||||
defaultValue: ERROR_CODE_SUCCESS,
|
||||
)
|
||||
final int errorCode;
|
||||
final String error;
|
||||
final String request;
|
||||
final String? error;
|
||||
final String? request;
|
||||
|
||||
bool get isSuccessful => errorCode == ERROR_CODE_SUCCESS;
|
||||
}
|
||||
|
@ -4,15 +4,14 @@ import 'package:weibo_kit/src/model/api/weibo_api_resp.dart';
|
||||
part 'weibo_user_info_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
fieldRename: FieldRename.snake,
|
||||
)
|
||||
class WeiboUserInfoResp extends WeiboApiResp {
|
||||
WeiboUserInfoResp({
|
||||
int errorCode,
|
||||
String error,
|
||||
String request,
|
||||
const WeiboUserInfoResp({
|
||||
required int errorCode,
|
||||
String? error,
|
||||
String? request,
|
||||
this.id,
|
||||
this.idstr,
|
||||
this.screenName,
|
||||
@ -25,46 +24,42 @@ class WeiboUserInfoResp extends WeiboApiResp {
|
||||
this.avatarHd,
|
||||
}) : super(errorCode: errorCode, error: error, request: request);
|
||||
|
||||
factory WeiboUserInfoResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
factory WeiboUserInfoResp.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeiboUserInfoRespFromJson(json);
|
||||
|
||||
/// 用户UID(int64)
|
||||
final int id;
|
||||
final int? id;
|
||||
|
||||
/// 字符串型的用户 UID
|
||||
final String idstr;
|
||||
final String? idstr;
|
||||
|
||||
/// 用户昵称
|
||||
final String screenName;
|
||||
final String? screenName;
|
||||
|
||||
/// 友好显示名称
|
||||
final String name;
|
||||
final String? name;
|
||||
|
||||
/// 用户所在地
|
||||
final String location;
|
||||
final String? location;
|
||||
|
||||
/// 用户个人描述
|
||||
final String description;
|
||||
final String? description;
|
||||
|
||||
/// 用户头像地址,50×50像素
|
||||
final String profileImageUrl;
|
||||
final String? profileImageUrl;
|
||||
|
||||
/// 性别,m:男、f:女、n:未知
|
||||
final String gender;
|
||||
final String? gender;
|
||||
|
||||
/// 用户大头像地址
|
||||
final String avatarLarge;
|
||||
final String? avatarLarge;
|
||||
|
||||
/// 用户高清大头像地址
|
||||
final String avatarHd;
|
||||
final String? avatarHd;
|
||||
|
||||
bool isMale() {
|
||||
return gender == 'm';
|
||||
}
|
||||
bool get isMale => gender == 'm';
|
||||
|
||||
bool isFemale() {
|
||||
return gender == 'f';
|
||||
}
|
||||
bool get isFemale => gender == 'f';
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$WeiboUserInfoRespToJson(this);
|
||||
Map<String, dynamic> toJson() => _$WeiboUserInfoRespToJson(this);
|
||||
}
|
||||
|
@ -6,21 +6,21 @@ part of 'weibo_user_info_resp.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
WeiboUserInfoResp _$WeiboUserInfoRespFromJson(Map json) {
|
||||
WeiboUserInfoResp _$WeiboUserInfoRespFromJson(Map<String, dynamic> json) {
|
||||
return WeiboUserInfoResp(
|
||||
errorCode: json['error_code'] as int,
|
||||
error: json['error'] as String,
|
||||
request: json['request'] as String,
|
||||
id: json['id'] as int,
|
||||
idstr: json['idstr'] as String,
|
||||
screenName: json['screen_name'] as String,
|
||||
name: json['name'] as String,
|
||||
location: json['location'] as String,
|
||||
description: json['description'] as String,
|
||||
profileImageUrl: json['profile_image_url'] as String,
|
||||
gender: json['gender'] as String,
|
||||
avatarLarge: json['avatar_large'] as String,
|
||||
avatarHd: json['avatar_hd'] as String,
|
||||
errorCode: json['error_code'] as int? ?? 0,
|
||||
error: json['error'] as String?,
|
||||
request: json['request'] as String?,
|
||||
id: json['id'] as int?,
|
||||
idstr: json['idstr'] as String?,
|
||||
screenName: json['screen_name'] as String?,
|
||||
name: json['name'] as String?,
|
||||
location: json['location'] as String?,
|
||||
description: json['description'] as String?,
|
||||
profileImageUrl: json['profile_image_url'] as String?,
|
||||
gender: json['gender'] as String?,
|
||||
avatarLarge: json['avatar_large'] as String?,
|
||||
avatarHd: json['avatar_hd'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -4,27 +4,26 @@ import 'package:weibo_kit/src/model/sdk/weibo_sdk_resp.dart';
|
||||
part 'weibo_auth_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
)
|
||||
class WeiboAuthResp extends WeiboSdkResp {
|
||||
WeiboAuthResp({
|
||||
int errorCode,
|
||||
String errorMessage,
|
||||
required int errorCode,
|
||||
String? errorMessage,
|
||||
this.userId,
|
||||
this.accessToken,
|
||||
this.refreshToken,
|
||||
this.expiresIn,
|
||||
}) : super(errorCode: errorCode, errorMessage: errorMessage);
|
||||
|
||||
factory WeiboAuthResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
factory WeiboAuthResp.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeiboAuthRespFromJson(json);
|
||||
|
||||
final String userId;
|
||||
final String accessToken;
|
||||
final String refreshToken;
|
||||
final int expiresIn;
|
||||
final String? userId;
|
||||
final String? accessToken;
|
||||
final String? refreshToken;
|
||||
final int? expiresIn;
|
||||
|
||||
@override
|
||||
Map<dynamic, dynamic> toJson() => _$WeiboAuthRespToJson(this);
|
||||
Map<String, dynamic> toJson() => _$WeiboAuthRespToJson(this);
|
||||
}
|
||||
|
@ -6,14 +6,14 @@ part of 'weibo_auth_resp.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
WeiboAuthResp _$WeiboAuthRespFromJson(Map json) {
|
||||
WeiboAuthResp _$WeiboAuthRespFromJson(Map<String, dynamic> json) {
|
||||
return WeiboAuthResp(
|
||||
errorCode: json['errorCode'] as int,
|
||||
errorMessage: json['errorMessage'] as String,
|
||||
userId: json['userId'] as String,
|
||||
accessToken: json['accessToken'] as String,
|
||||
refreshToken: json['refreshToken'] as String,
|
||||
expiresIn: json['expiresIn'] as int,
|
||||
errorCode: json['errorCode'] as int? ?? 0,
|
||||
errorMessage: json['errorMessage'] as String?,
|
||||
userId: json['userId'] as String?,
|
||||
accessToken: json['accessToken'] as String?,
|
||||
refreshToken: json['refreshToken'] as String?,
|
||||
expiresIn: json['expiresIn'] as int?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,16 +3,15 @@ import 'package:json_annotation/json_annotation.dart';
|
||||
part 'weibo_sdk_resp.g.dart';
|
||||
|
||||
@JsonSerializable(
|
||||
anyMap: true,
|
||||
explicitToJson: true,
|
||||
)
|
||||
class WeiboSdkResp {
|
||||
WeiboSdkResp({
|
||||
int errorCode,
|
||||
const WeiboSdkResp({
|
||||
required this.errorCode,
|
||||
this.errorMessage,
|
||||
}) : errorCode = errorCode ?? SUCCESS;
|
||||
});
|
||||
|
||||
factory WeiboSdkResp.fromJson(Map<dynamic, dynamic> json) =>
|
||||
factory WeiboSdkResp.fromJson(Map<String, dynamic> json) =>
|
||||
_$WeiboSdkRespFromJson(json);
|
||||
|
||||
/// 成功
|
||||
@ -42,8 +41,15 @@ class WeiboSdkResp {
|
||||
/// 未知
|
||||
static const int UNKNOWN = -100;
|
||||
|
||||
@JsonKey(
|
||||
defaultValue: SUCCESS,
|
||||
)
|
||||
final int errorCode;
|
||||
final String errorMessage;
|
||||
final String? errorMessage;
|
||||
|
||||
Map<dynamic, dynamic> toJson() => _$WeiboSdkRespToJson(this);
|
||||
bool get isSuccessful => errorCode == SUCCESS;
|
||||
|
||||
bool get isCancelled => errorCode == USERCANCEL;
|
||||
|
||||
Map<String, dynamic> toJson() => _$WeiboSdkRespToJson(this);
|
||||
}
|
||||
|
@ -6,10 +6,10 @@ part of 'weibo_sdk_resp.dart';
|
||||
// JsonSerializableGenerator
|
||||
// **************************************************************************
|
||||
|
||||
WeiboSdkResp _$WeiboSdkRespFromJson(Map json) {
|
||||
WeiboSdkResp _$WeiboSdkRespFromJson(Map<String, dynamic> json) {
|
||||
return WeiboSdkResp(
|
||||
errorCode: json['errorCode'] as int,
|
||||
errorMessage: json['errorMessage'] as String,
|
||||
errorCode: json['errorCode'] as int? ?? 0,
|
||||
errorMessage: json['errorMessage'] as String?,
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -3,16 +3,18 @@ import 'dart:convert';
|
||||
import 'dart:io';
|
||||
import 'dart:typed_data';
|
||||
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:weibo_kit/src/model/api/weibo_user_info_resp.dart';
|
||||
import 'package:weibo_kit/src/model/sdk/weibo_auth_resp.dart';
|
||||
import 'package:weibo_kit/src/model/sdk/weibo_sdk_resp.dart';
|
||||
|
||||
class Weibo {
|
||||
Weibo() {
|
||||
_channel.setMethodCallHandler(_handleMethod);
|
||||
}
|
||||
///
|
||||
Weibo._();
|
||||
|
||||
static Weibo get instance => _instance;
|
||||
|
||||
static final Weibo _instance = Weibo._();
|
||||
|
||||
static const String _METHOD_REGISTERAPP = 'registerApp';
|
||||
static const String _METHOD_ISINSTALLED = 'isInstalled';
|
||||
@ -40,8 +42,9 @@ class Weibo {
|
||||
static const String _DEFAULT_REDIRECTURL =
|
||||
'https://api.weibo.com/oauth2/default.html';
|
||||
|
||||
final MethodChannel _channel =
|
||||
const MethodChannel('v7lin.github.io/weibo_kit');
|
||||
late final MethodChannel _channel =
|
||||
const MethodChannel('v7lin.github.io/weibo_kit')
|
||||
..setMethodCallHandler(_handleMethod);
|
||||
|
||||
final StreamController<WeiboAuthResp> _authRespStreamController =
|
||||
StreamController<WeiboAuthResp>.broadcast();
|
||||
@ -50,13 +53,11 @@ class Weibo {
|
||||
StreamController<WeiboSdkResp>.broadcast();
|
||||
|
||||
Future<void> registerApp({
|
||||
@required String appKey,
|
||||
@required List<String> scope,
|
||||
required String appKey,
|
||||
required List<String> scope,
|
||||
String redirectUrl =
|
||||
_DEFAULT_REDIRECTURL, // 新浪微博开放平台 -> 我的应用 -> 应用信息 -> 高级信息 -> OAuth2.0授权设置
|
||||
}) {
|
||||
assert(appKey != null && appKey.isNotEmpty);
|
||||
assert(scope != null && scope.isNotEmpty);
|
||||
return _channel.invokeMethod<void>(
|
||||
_METHOD_REGISTERAPP,
|
||||
<String, dynamic>{
|
||||
@ -71,11 +72,11 @@ class Weibo {
|
||||
switch (call.method) {
|
||||
case _METHOD_ONAUTHRESP:
|
||||
_authRespStreamController.add(
|
||||
WeiboAuthResp.fromJson(call.arguments as Map<dynamic, dynamic>));
|
||||
WeiboAuthResp.fromJson(call.arguments as Map<String, dynamic>));
|
||||
break;
|
||||
case _METHOD_ONSHAREMSGRESP:
|
||||
_shareMsgRespStreamController.add(
|
||||
WeiboSdkResp.fromJson(call.arguments as Map<dynamic, dynamic>));
|
||||
_shareMsgRespStreamController
|
||||
.add(WeiboSdkResp.fromJson(call.arguments as Map<String, dynamic>));
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -90,18 +91,16 @@ class Weibo {
|
||||
return _shareMsgRespStreamController.stream;
|
||||
}
|
||||
|
||||
Future<bool> isInstalled() {
|
||||
return _channel.invokeMethod<bool>(_METHOD_ISINSTALLED);
|
||||
Future<bool> isInstalled() async {
|
||||
return await _channel.invokeMethod<bool>(_METHOD_ISINSTALLED) ?? false;
|
||||
}
|
||||
|
||||
/// 登录
|
||||
Future<void> auth({
|
||||
@required String appKey,
|
||||
@required List<String> scope,
|
||||
required String appKey,
|
||||
required List<String> scope,
|
||||
String redirectUrl = _DEFAULT_REDIRECTURL,
|
||||
}) {
|
||||
assert(appKey != null && appKey.isNotEmpty);
|
||||
assert(scope != null && scope.isNotEmpty);
|
||||
return _channel.invokeMethod<void>(
|
||||
_METHOD_AUTH,
|
||||
<String, dynamic>{
|
||||
@ -114,13 +113,11 @@ class Weibo {
|
||||
|
||||
/// 用户信息
|
||||
Future<WeiboUserInfoResp> getUserInfo({
|
||||
@required String appkey,
|
||||
@required String userId,
|
||||
@required String accessToken,
|
||||
required String appkey,
|
||||
required String userId,
|
||||
required String accessToken,
|
||||
}) {
|
||||
assert(userId != null && userId.isNotEmpty);
|
||||
assert(accessToken != null && accessToken.isNotEmpty);
|
||||
Map<String, String> params = <String, String>{
|
||||
final Map<String, String> params = <String, String>{
|
||||
'uid': userId,
|
||||
};
|
||||
return HttpClient()
|
||||
@ -130,9 +127,9 @@ class Weibo {
|
||||
return request.close();
|
||||
}).then((HttpClientResponse response) async {
|
||||
if (response.statusCode == HttpStatus.ok) {
|
||||
String content = await utf8.decodeStream(response);
|
||||
final String content = await utf8.decodeStream(response);
|
||||
return WeiboUserInfoResp.fromJson(
|
||||
json.decode(content) as Map<dynamic, dynamic>);
|
||||
json.decode(content) as Map<String, dynamic>);
|
||||
}
|
||||
throw HttpException(
|
||||
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
||||
@ -147,10 +144,10 @@ class Weibo {
|
||||
) {
|
||||
params['source'] = appkey;
|
||||
params['access_token'] = accessToken;
|
||||
Uri baseUri = Uri.parse(baseUrl);
|
||||
Map<String, List<String>> queryParametersAll =
|
||||
final Uri baseUri = Uri.parse(baseUrl);
|
||||
final Map<String, List<String>> queryParametersAll =
|
||||
Map<String, List<String>>.of(baseUri.queryParametersAll);
|
||||
for (MapEntry<String, String> entry in params.entries) {
|
||||
for (final MapEntry<String, String> entry in params.entries) {
|
||||
queryParametersAll.remove(entry.key);
|
||||
queryParametersAll.putIfAbsent(entry.key, () => <String>[entry.value]);
|
||||
}
|
||||
@ -159,9 +156,8 @@ class Weibo {
|
||||
|
||||
/// 分享 - 文本
|
||||
Future<void> shareText({
|
||||
@required String text,
|
||||
required String text,
|
||||
}) {
|
||||
assert(text != null && text.length <= 1024);
|
||||
return _channel.invokeMethod<void>(
|
||||
_METHOD_SHARETEXT,
|
||||
<String, dynamic>{
|
||||
@ -172,9 +168,9 @@ class Weibo {
|
||||
|
||||
/// 分享 - 图片
|
||||
Future<void> shareImage({
|
||||
String text,
|
||||
Uint8List imageData,
|
||||
Uri imageUri,
|
||||
String? text,
|
||||
Uint8List? imageData,
|
||||
Uri? imageUri,
|
||||
}) {
|
||||
assert(text == null || text.length <= 1024);
|
||||
assert((imageData != null && imageData.lengthInBytes <= 2 * 1024 * 1024) ||
|
||||
@ -194,19 +190,15 @@ class Weibo {
|
||||
|
||||
/// 分享 - 网页
|
||||
Future<void> shareWebpage({
|
||||
@required String title,
|
||||
@required String description,
|
||||
@required Uint8List thumbData,
|
||||
@required String webpageUrl,
|
||||
required String title,
|
||||
required String description,
|
||||
required Uint8List thumbData,
|
||||
required String webpageUrl,
|
||||
}) {
|
||||
assert(title != null && title.isNotEmpty && title.length <= 512);
|
||||
assert(description != null &&
|
||||
description.isNotEmpty &&
|
||||
description.length <= 1024);
|
||||
assert(thumbData != null && thumbData.lengthInBytes <= 32 * 1024);
|
||||
assert(webpageUrl != null &&
|
||||
webpageUrl.isNotEmpty &&
|
||||
webpageUrl.length <= 255);
|
||||
assert(title.length <= 512);
|
||||
assert(description.isNotEmpty && description.length <= 1024);
|
||||
assert(thumbData.lengthInBytes <= 32 * 1024);
|
||||
assert(webpageUrl.length <= 255);
|
||||
return _channel.invokeMethod<void>(
|
||||
_METHOD_SHAREWEBPAGE,
|
||||
<String, dynamic>{
|
||||
|
@ -1,5 +1,5 @@
|
||||
class WeiboScope {
|
||||
WeiboScope._();
|
||||
const WeiboScope._();
|
||||
|
||||
static const String EMAIL = 'email';
|
||||
static const String DIRECT_MESSAGES_READ = 'direct_messages_read';
|
||||
|
279
pubspec.lock
279
pubspec.lock
@ -7,168 +7,182 @@ packages:
|
||||
name: _fe_analyzer_shared
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.0.0"
|
||||
version: "18.0.0"
|
||||
analyzer:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: analyzer
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.39.10"
|
||||
archive:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: archive
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.13"
|
||||
version: "1.2.0"
|
||||
args:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: args
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.0"
|
||||
version: "2.0.0"
|
||||
async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: async
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.1"
|
||||
version: "2.5.0"
|
||||
boolean_selector:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: boolean_selector
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
build:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.0"
|
||||
version: "2.0.0"
|
||||
build_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_config
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.4.2"
|
||||
version: "0.4.7"
|
||||
build_daemon:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_daemon
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
version: "2.1.10"
|
||||
build_resolvers:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_resolvers
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.9"
|
||||
version: "2.0.0"
|
||||
build_runner:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: build_runner
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.12.2"
|
||||
build_runner_core:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: build_runner_core
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "6.1.12"
|
||||
built_collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_collection
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "4.3.2"
|
||||
version: "5.0.0"
|
||||
built_value:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: built_value
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "7.1.0"
|
||||
version: "8.0.3"
|
||||
characters:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: charcode
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.3"
|
||||
version: "1.2.0"
|
||||
checked_yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: checked_yaml
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "2.0.1"
|
||||
cli_util:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: cli_util
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.3.0"
|
||||
clock:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: clock
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
code_builder:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: code_builder
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
version: "3.7.0"
|
||||
collection:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.14.12"
|
||||
version: "1.15.0"
|
||||
convert:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: convert
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.1"
|
||||
version: "3.0.0"
|
||||
crypto:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: crypto
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
csslib:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: csslib
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
version: "3.0.0"
|
||||
dart_style:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: dart_style
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.3.6"
|
||||
version: "1.3.14"
|
||||
fake_async:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fake_async
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
file:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "5.2.0"
|
||||
version: "6.1.0"
|
||||
fixnum:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: fixnum
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.10.11"
|
||||
version: "1.0.0"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
@ -185,245 +199,140 @@ packages:
|
||||
name: glob
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.0"
|
||||
graphs:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: graphs
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.2.0"
|
||||
html:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: html
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.14.0+3"
|
||||
version: "1.0.0"
|
||||
http_multi_server:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_multi_server
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.0"
|
||||
version: "3.0.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.1.4"
|
||||
image:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: image
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.12"
|
||||
intl:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: intl
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.16.1"
|
||||
version: "4.0.0"
|
||||
io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: io
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.3.4"
|
||||
version: "1.0.0"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: js
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.6.2"
|
||||
version: "0.6.3"
|
||||
json_annotation:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: json_annotation
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.1"
|
||||
version: "4.0.0"
|
||||
json_serializable:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: json_serializable
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.3.0"
|
||||
version: "4.0.3"
|
||||
logging:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: logging
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.11.4"
|
||||
version: "1.0.0"
|
||||
matcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.12.6"
|
||||
version: "0.12.10"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.8"
|
||||
version: "1.3.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: mime
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.9.6+3"
|
||||
node_interop:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_interop
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
node_io:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: node_io
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.1"
|
||||
okhttp_kit:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: okhttp_kit
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.0.0"
|
||||
package_config:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: package_config
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "2.0.0"
|
||||
path:
|
||||
dependency: "direct dev"
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.4"
|
||||
path_provider:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: path_provider
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.6.11"
|
||||
path_provider_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_linux
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.0.1+1"
|
||||
path_provider_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_macos
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.0.4+3"
|
||||
path_provider_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: path_provider_platform_interface
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.8.0"
|
||||
pedantic:
|
||||
dependency: "direct dev"
|
||||
description:
|
||||
name: pedantic
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.0"
|
||||
petitparser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: petitparser
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.4.0"
|
||||
platform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: platform
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
plugin_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: plugin_platform_interface
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.2"
|
||||
version: "1.11.0"
|
||||
pool:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pool
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
process:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: process
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.0.13"
|
||||
version: "1.5.0"
|
||||
pub_semver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pub_semver
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.4.4"
|
||||
version: "2.0.0"
|
||||
pubspec_parse:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: pubspec_parse
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.5"
|
||||
quiver:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: quiver
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.1.3"
|
||||
version: "1.0.0"
|
||||
shelf:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.7.5"
|
||||
version: "1.1.0"
|
||||
shelf_web_socket:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: shelf_web_socket
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.2.3"
|
||||
version: "1.0.1"
|
||||
sky_engine:
|
||||
dependency: transitive
|
||||
description: flutter
|
||||
@ -435,112 +344,98 @@ packages:
|
||||
name: source_gen
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.9.5"
|
||||
version: "0.9.10+4"
|
||||
source_span:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.7.0"
|
||||
version: "1.8.0"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stack_trace
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.9.3"
|
||||
version: "1.10.0"
|
||||
stream_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_channel
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.0"
|
||||
version: "2.1.0"
|
||||
stream_transform:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: stream_transform
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.2.0"
|
||||
version: "2.0.0"
|
||||
string_scanner:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: string_scanner
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.0.5"
|
||||
version: "1.1.0"
|
||||
term_glyph:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: term_glyph
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
version: "1.2.0"
|
||||
test_api:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.2.15"
|
||||
version: "0.2.19"
|
||||
timing:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: timing
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.1+2"
|
||||
version: "1.0.0"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.6"
|
||||
version: "1.3.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: vector_math
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.0.8"
|
||||
version: "2.1.0"
|
||||
watcher:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: watcher
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.9.7+15"
|
||||
version: "1.0.0"
|
||||
web_socket_channel:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web_socket_channel
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
xdg_directories:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xdg_directories
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "0.1.0"
|
||||
xml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: xml
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "3.6.1"
|
||||
version: "2.0.0"
|
||||
yaml:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: yaml
|
||||
url: "https://pub.flutter-io.cn"
|
||||
source: hosted
|
||||
version: "2.2.1"
|
||||
version: "3.1.0"
|
||||
sdks:
|
||||
dart: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.12.13+hotfix.5 <2.0.0"
|
||||
dart: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
15
pubspec.yaml
15
pubspec.yaml
@ -1,28 +1,23 @@
|
||||
name: weibo_kit
|
||||
description: A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Weibo SDKs.
|
||||
version: 1.1.0
|
||||
version: 2.0.0
|
||||
# author: v7lin <v7lin@qq.com>
|
||||
homepage: https://github.com/v7lin/fake_weibo
|
||||
homepage: https://github.com/rxreader/weibo_kit.git
|
||||
|
||||
environment:
|
||||
sdk: ">=2.7.0 <3.0.0"
|
||||
flutter: ">=1.10.0"
|
||||
sdk: ">=2.12.0 <3.0.0"
|
||||
flutter: ">=1.20.0"
|
||||
|
||||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
|
||||
json_annotation: '>=2.0.0 <4.0.0'
|
||||
json_annotation: ^4.0.0
|
||||
|
||||
dev_dependencies:
|
||||
flutter_test:
|
||||
sdk: flutter
|
||||
|
||||
path: ^1.6.4
|
||||
path_provider: ^1.4.0
|
||||
|
||||
okhttp_kit: ^1.0.0
|
||||
|
||||
pedantic:
|
||||
|
||||
build_runner:
|
||||
|
@ -10,7 +10,6 @@ void main() {
|
||||
TestWidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
const MethodChannel channel = MethodChannel('v7lin.github.io/weibo_kit');
|
||||
final Weibo weibo = Weibo();
|
||||
|
||||
setUp(() {
|
||||
channel.setMockMethodCallHandler((MethodCall call) async {
|
||||
@ -24,7 +23,7 @@ void main() {
|
||||
channel.name,
|
||||
channel.codec.encodeMethodCall(
|
||||
MethodCall('onAuthResp', json.decode('{"errorCode":-1}'))),
|
||||
(ByteData data) {
|
||||
(ByteData? data) {
|
||||
// mock success
|
||||
},
|
||||
));
|
||||
@ -36,7 +35,7 @@ void main() {
|
||||
channel.name,
|
||||
channel.codec.encodeMethodCall(
|
||||
MethodCall('onShareMsgResp', json.decode('{"errorCode":-1}'))),
|
||||
(ByteData data) {
|
||||
(ByteData? data) {
|
||||
// mock success
|
||||
},
|
||||
));
|
||||
@ -51,15 +50,15 @@ void main() {
|
||||
});
|
||||
|
||||
test('isInstalled', () async {
|
||||
expect(await weibo.isInstalled(), true);
|
||||
expect(await Weibo.instance.isInstalled(), true);
|
||||
});
|
||||
|
||||
test('auth', () async {
|
||||
StreamSubscription<WeiboAuthResp> sub =
|
||||
weibo.authResp().listen((WeiboAuthResp resp) {
|
||||
final StreamSubscription<WeiboAuthResp> sub =
|
||||
Weibo.instance.authResp().listen((WeiboAuthResp resp) {
|
||||
expect(resp.errorCode, WeiboSdkResp.USERCANCEL);
|
||||
});
|
||||
await weibo.auth(
|
||||
await Weibo.instance.auth(
|
||||
appKey: 'your weibo app key',
|
||||
scope: <String>[WeiboScope.ALL],
|
||||
);
|
||||
@ -67,11 +66,11 @@ void main() {
|
||||
});
|
||||
|
||||
test('share', () async {
|
||||
StreamSubscription<WeiboSdkResp> sub =
|
||||
weibo.shareMsgResp().listen((WeiboSdkResp resp) {
|
||||
final StreamSubscription<WeiboSdkResp> sub =
|
||||
Weibo.instance.shareMsgResp().listen((WeiboSdkResp resp) {
|
||||
expect(resp.errorCode, WeiboSdkResp.USERCANCEL);
|
||||
});
|
||||
await weibo.shareText(
|
||||
await Weibo.instance.shareText(
|
||||
text: 'share text',
|
||||
);
|
||||
await sub.cancel();
|
||||
|
Loading…
Reference in New Issue
Block a user