mirror of
https://github.com/RxReader/tencent_kit.git
synced 2025-05-30 15:15:07 +08:00
nullsafety
This commit is contained in:
12
.drone.yml
12
.drone.yml
@ -16,19 +16,9 @@ steps:
|
|||||||
# - name: pub-cache
|
# - name: pub-cache
|
||||||
# path: /opt/flutter/.pub-cache
|
# path: /opt/flutter/.pub-cache
|
||||||
# commands:
|
# commands:
|
||||||
|
# - flutter pub run build_runner clean
|
||||||
# - flutter pub run build_runner build --delete-conflicting-outputs
|
# - 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"
|
# 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
|
#- name: ios-format
|
||||||
# image: v7lin/clang
|
# image: v7lin/clang
|
||||||
|
4
.gitignore
vendored
4
.gitignore
vendored
@ -6,6 +6,6 @@
|
|||||||
|
|
||||||
build/
|
build/
|
||||||
|
|
||||||
# custom
|
#
|
||||||
.idea/
|
|
||||||
*.iml
|
*.iml
|
||||||
|
.idea/
|
||||||
|
@ -1,3 +1,9 @@
|
|||||||
|
## 2.1.0
|
||||||
|
|
||||||
|
* nullsafety
|
||||||
|
* 不再支持 Android embedding v1
|
||||||
|
* Tencent 单例
|
||||||
|
|
||||||
## 2.0.1
|
## 2.0.1
|
||||||
|
|
||||||
* 优化
|
* 优化
|
||||||
|
@ -159,6 +159,9 @@ Capabilities -> Associated Domain -> Domain -> applinks:${your applinks}
|
|||||||
|QQ|不支持|不支持|支持|支持|不支持|支持|
|
|QQ|不支持|不支持|支持|支持|不支持|支持|
|
||||||
|QZone|支持|不支持|不支持|不支持|不支持|支持|
|
|QZone|支持|不支持|不支持|不支持|不支持|支持|
|
||||||
|
|
||||||
|
* break change
|
||||||
|
* 2.1.0: nullsafety & 不再支持 Android embedding v1 & Tencent 单例
|
||||||
|
|
||||||
* snapshot
|
* snapshot
|
||||||
|
|
||||||
```
|
```
|
||||||
|
@ -37,7 +37,7 @@ analyzer:
|
|||||||
# Please see https://github.com/flutter/flutter/pull/24528 for details.
|
# Please see https://github.com/flutter/flutter/pull/24528 for details.
|
||||||
sdk_version_async_exported_from_core: ignore
|
sdk_version_async_exported_from_core: ignore
|
||||||
exclude:
|
exclude:
|
||||||
- "**/*.g.dart"
|
- "lib/*.g.dart"
|
||||||
|
|
||||||
linter:
|
linter:
|
||||||
rules:
|
rules:
|
||||||
@ -49,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_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_require_non_null_named_parameters
|
||||||
- always_specify_types
|
- always_specify_types
|
||||||
|
- always_use_package_imports # we do this commonly
|
||||||
- annotate_overrides
|
- annotate_overrides
|
||||||
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
|
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
|
||||||
# - avoid_as # required for implicit-casts: true
|
# - avoid_as # required for implicit-casts: true
|
||||||
@ -59,6 +60,7 @@ linter:
|
|||||||
# - avoid_double_and_int_checks # only useful when targeting JS runtime
|
# - avoid_double_and_int_checks # only useful when targeting JS runtime
|
||||||
- avoid_empty_else
|
- avoid_empty_else
|
||||||
- avoid_equals_and_hash_code_on_mutable_classes
|
- avoid_equals_and_hash_code_on_mutable_classes
|
||||||
|
# - avoid_escaping_inner_quotes # not yet tested
|
||||||
- avoid_field_initializers_in_const_classes
|
- avoid_field_initializers_in_const_classes
|
||||||
- avoid_function_literals_in_foreach_calls
|
- avoid_function_literals_in_foreach_calls
|
||||||
# - avoid_implementing_value_types # not yet tested
|
# - avoid_implementing_value_types # not yet tested
|
||||||
@ -77,9 +79,10 @@ linter:
|
|||||||
- avoid_returning_null_for_void
|
- avoid_returning_null_for_void
|
||||||
# - avoid_returning_this # there are plenty of valid reasons to return this
|
# - avoid_returning_this # there are plenty of valid reasons to return this
|
||||||
# - avoid_setters_without_getters # not yet tested
|
# - 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_single_cascade_in_expression_statements
|
||||||
- avoid_slow_async_io
|
- avoid_slow_async_io
|
||||||
|
# - avoid_type_to_string # we do this commonly
|
||||||
- avoid_types_as_parameter_names
|
- avoid_types_as_parameter_names
|
||||||
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
|
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
|
||||||
# - avoid_unnecessary_containers # not yet tested
|
# - avoid_unnecessary_containers # not yet tested
|
||||||
@ -91,65 +94,71 @@ linter:
|
|||||||
- camel_case_types
|
- camel_case_types
|
||||||
- cancel_subscriptions
|
- cancel_subscriptions
|
||||||
# - cascade_invocations # not yet tested
|
# - cascade_invocations # not yet tested
|
||||||
|
- cast_nullable_to_non_nullable
|
||||||
# - close_sinks # not reliable enough
|
# - close_sinks # not reliable enough
|
||||||
# - comment_references # blocked on https://github.com/flutter/flutter/issues/20765
|
# - 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
|
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
|
||||||
- control_flow_in_finally
|
- 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
|
# - diagnostic_describe_all_properties # not yet tested
|
||||||
- directives_ordering
|
- directives_ordering
|
||||||
|
# - do_not_use_environment # we do this commonly
|
||||||
- empty_catches
|
- empty_catches
|
||||||
- empty_constructor_bodies
|
- empty_constructor_bodies
|
||||||
- empty_statements
|
- empty_statements
|
||||||
- file_names
|
- exhaustive_cases
|
||||||
|
- file_names # not yet tested
|
||||||
- flutter_style_todos
|
- flutter_style_todos
|
||||||
- hash_and_equals
|
- hash_and_equals
|
||||||
- implementation_imports
|
- implementation_imports
|
||||||
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
# - invariant_booleans # too many false positives: https://github.com/dart-lang/linter/issues/811
|
||||||
- iterable_contains_unrelated_type
|
- 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_names
|
||||||
- library_prefixes
|
- library_prefixes
|
||||||
# - lines_longer_than_80_chars # not yet tested
|
# - lines_longer_than_80_chars # not required by flutter style
|
||||||
- list_remove_unrelated_type
|
- list_remove_unrelated_type
|
||||||
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
|
||||||
# - missing_whitespace_between_adjacent_strings # not yet tested
|
# - missing_whitespace_between_adjacent_strings # not yet tested
|
||||||
- no_adjacent_strings_in_list
|
- no_adjacent_strings_in_list
|
||||||
|
# - no_default_cases # too many false positives
|
||||||
- no_duplicate_case_values
|
- no_duplicate_case_values
|
||||||
# - no_logic_in_create_state # not yet tested
|
- no_logic_in_create_state
|
||||||
# - no_runtimeType_toString # not yet tested
|
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
|
||||||
- non_constant_identifier_names
|
- 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
|
# - omit_local_variable_types # opposite of always_specify_types
|
||||||
# - one_member_abstracts # too many false positives
|
# - one_member_abstracts # too many false positives
|
||||||
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
|
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
|
||||||
- overridden_fields
|
- overridden_fields
|
||||||
- package_api_docs
|
- package_api_docs
|
||||||
- package_names
|
# - package_names # non conforming packages in sdk
|
||||||
- package_prefixed_library_names
|
- package_prefixed_library_names
|
||||||
# - parameter_assignments # we do this commonly
|
# - parameter_assignments # we do this commonly
|
||||||
- prefer_adjacent_string_concatenation
|
- prefer_adjacent_string_concatenation
|
||||||
- prefer_asserts_in_initializer_lists
|
- 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_collection_literals
|
||||||
- prefer_conditional_assignment
|
- prefer_conditional_assignment
|
||||||
- prefer_const_constructors
|
- prefer_const_constructors
|
||||||
- prefer_const_constructors_in_immutables
|
- prefer_const_constructors_in_immutables
|
||||||
- prefer_const_declarations
|
- prefer_const_declarations
|
||||||
- prefer_const_literals_to_create_immutables
|
- 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_contains
|
||||||
# - prefer_double_quotes # opposite of prefer_single_quotes
|
# - prefer_double_quotes # opposite of prefer_single_quotes
|
||||||
- prefer_equal_for_default_values
|
- 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_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_fields
|
||||||
# - prefer_final_in_for_each
|
- prefer_final_in_for_each
|
||||||
# - prefer_final_locals
|
- prefer_final_locals
|
||||||
- prefer_for_elements_to_map_fromIterable
|
- prefer_for_elements_to_map_fromIterable
|
||||||
# - prefer_foreach
|
- prefer_foreach
|
||||||
# - prefer_function_declarations_over_variables # not yet tested
|
# - prefer_function_declarations_over_variables # not yet tested
|
||||||
- prefer_generic_function_type_aliases
|
- prefer_generic_function_type_aliases
|
||||||
# - prefer_if_elements_to_conditional_expressions
|
- prefer_if_elements_to_conditional_expressions
|
||||||
- prefer_if_null_operators
|
- prefer_if_null_operators
|
||||||
- prefer_initializing_formals
|
- prefer_initializing_formals
|
||||||
- prefer_inlined_adds
|
- prefer_inlined_adds
|
||||||
@ -169,13 +178,15 @@ linter:
|
|||||||
# - provide_deprecation_message # not yet tested
|
# - provide_deprecation_message # not yet tested
|
||||||
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
|
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
|
||||||
- recursive_getters
|
- recursive_getters
|
||||||
|
# - sized_box_for_whitespace # not yet tested
|
||||||
- slash_for_doc_comments
|
- slash_for_doc_comments
|
||||||
# - sort_child_properties_last # not yet tested
|
# - sort_child_properties_last # not yet tested
|
||||||
- sort_constructors_first
|
- sort_constructors_first
|
||||||
- sort_pub_dependencies
|
# - sort_pub_dependencies # prevents separating pinned transitive dependencies
|
||||||
- sort_unnamed_constructors_first
|
- sort_unnamed_constructors_first
|
||||||
- test_types_in_equals
|
- test_types_in_equals
|
||||||
- throw_in_finally
|
- throw_in_finally
|
||||||
|
- tighten_type_of_initializing_formals
|
||||||
# - type_annotate_public_apis # subset of always_specify_types
|
# - type_annotate_public_apis # subset of always_specify_types
|
||||||
- type_init_formals
|
- type_init_formals
|
||||||
- unawaited_futures # too many false positives
|
- unawaited_futures # too many false positives
|
||||||
@ -187,18 +198,24 @@ linter:
|
|||||||
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
|
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
|
||||||
- unnecessary_new
|
- unnecessary_new
|
||||||
- unnecessary_null_aware_assignments
|
- unnecessary_null_aware_assignments
|
||||||
|
# - unnecessary_null_checks # not yet tested
|
||||||
- unnecessary_null_in_if_null_operators
|
- unnecessary_null_in_if_null_operators
|
||||||
|
- unnecessary_nullable_for_final_variable_declarations
|
||||||
- unnecessary_overrides
|
- unnecessary_overrides
|
||||||
- unnecessary_parenthesis
|
- unnecessary_parenthesis
|
||||||
|
# - unnecessary_raw_strings # not yet tested
|
||||||
- unnecessary_statements
|
- unnecessary_statements
|
||||||
|
- unnecessary_string_escapes
|
||||||
- unnecessary_string_interpolations
|
- unnecessary_string_interpolations
|
||||||
- unnecessary_this
|
- unnecessary_this
|
||||||
- unrelated_type_equality_checks
|
- unrelated_type_equality_checks
|
||||||
# - unsafe_html # not yet tested
|
# - unsafe_html # not yet tested
|
||||||
- use_full_hex_values_for_flutter_colors
|
- use_full_hex_values_for_flutter_colors
|
||||||
# - use_function_type_syntax_for_parameters # not yet tested
|
# - use_function_type_syntax_for_parameters # not yet tested
|
||||||
|
- use_is_even_rather_than_modulo
|
||||||
# - use_key_in_widget_constructors # not yet tested
|
# - use_key_in_widget_constructors # not yet tested
|
||||||
- use_late_for_private_fields_and_variables
|
- use_late_for_private_fields_and_variables
|
||||||
|
- use_raw_strings
|
||||||
- use_rethrow_when_possible
|
- use_rethrow_when_possible
|
||||||
# - use_setters_to_change_properties # not yet tested
|
# - use_setters_to_change_properties # not yet tested
|
||||||
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
|
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
group 'io.github.v7lin.tencent_kit'
|
group 'io.github.v7lin.tencent_kit'
|
||||||
version '2.0.1'
|
version '2.1.0'
|
||||||
|
|
||||||
buildscript {
|
buildscript {
|
||||||
repositories {
|
repositories {
|
||||||
@ -8,7 +8,7 @@ buildscript {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.4'
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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,514 +0,0 @@
|
|||||||
package io.github.v7lin.tencent_kit;
|
|
||||||
|
|
||||||
import android.app.Activity;
|
|
||||||
import android.content.ComponentName;
|
|
||||||
import android.content.Context;
|
|
||||||
import android.content.Intent;
|
|
||||||
import android.content.pm.PackageInfo;
|
|
||||||
import android.content.pm.PackageManager;
|
|
||||||
import android.content.pm.ProviderInfo;
|
|
||||||
import android.net.Uri;
|
|
||||||
import android.os.Bundle;
|
|
||||||
import android.text.TextUtils;
|
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
|
||||||
import androidx.annotation.Nullable;
|
|
||||||
|
|
||||||
import com.tencent.connect.common.Constants;
|
|
||||||
import com.tencent.connect.share.QQShare;
|
|
||||||
import com.tencent.connect.share.QzonePublish;
|
|
||||||
import com.tencent.connect.share.QzoneShare;
|
|
||||||
import com.tencent.tauth.IUiListener;
|
|
||||||
import com.tencent.tauth.Tencent;
|
|
||||||
import com.tencent.tauth.UiError;
|
|
||||||
|
|
||||||
import org.json.JSONException;
|
|
||||||
import org.json.JSONObject;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.HashMap;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import io.flutter.plugin.common.BinaryMessenger;
|
|
||||||
import io.flutter.plugin.common.MethodCall;
|
|
||||||
import io.flutter.plugin.common.MethodChannel;
|
|
||||||
import io.flutter.plugin.common.PluginRegistry;
|
|
||||||
import io.github.v7lin.tencent_kit.content.TencentKitFileProvider;
|
|
||||||
|
|
||||||
public class TencentKit implements MethodChannel.MethodCallHandler, PluginRegistry.ActivityResultListener {
|
|
||||||
|
|
||||||
private static class TencentScene {
|
|
||||||
static final int SCENE_QQ = 0;
|
|
||||||
static final int SCENE_QZONE = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class TencentRetCode {
|
|
||||||
// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
|
||||||
// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
|
||||||
static final int RET_SUCCESS = 0;
|
|
||||||
// 网络异常,或服务器返回的数据格式不正确导致无法解析
|
|
||||||
static final int RET_FAILED = 1;
|
|
||||||
static final int RET_COMMON = -1;
|
|
||||||
static final int RET_USERCANCEL = -2;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
private static final String METHOD_REGISTERAPP = "registerApp";
|
|
||||||
private static final String METHOD_ISQQINSTALLED = "isQQInstalled";
|
|
||||||
private static final String METHOD_ISTIMINSTALLED = "isTIMInstalled";
|
|
||||||
private static final String METHOD_LOGIN = "login";
|
|
||||||
private static final String METHOD_LOGOUT = "logout";
|
|
||||||
private static final String METHOD_SHAREMOOD = "shareMood";
|
|
||||||
private static final String METHOD_SHARETEXT = "shareText";
|
|
||||||
private static final String METHOD_SHAREIMAGE = "shareImage";
|
|
||||||
private static final String METHOD_SHAREMUSIC = "shareMusic";
|
|
||||||
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
|
|
||||||
|
|
||||||
private static final String METHOD_ONLOGINRESP = "onLoginResp";
|
|
||||||
private static final String METHOD_ONSHARERESP = "onShareResp";
|
|
||||||
|
|
||||||
private static final String ARGUMENT_KEY_APPID = "appId";
|
|
||||||
// private static final String ARGUMENT_KEY_UNIVERSALLINK = "universalLink";
|
|
||||||
private static final String ARGUMENT_KEY_SCOPE = "scope";
|
|
||||||
private static final String ARGUMENT_KEY_SCENE = "scene";
|
|
||||||
private static final String ARGUMENT_KEY_TITLE = "title";
|
|
||||||
private static final String ARGUMENT_KEY_SUMMARY = "summary";
|
|
||||||
private static final String ARGUMENT_KEY_IMAGEURI = "imageUri";
|
|
||||||
private static final String ARGUMENT_KEY_IMAGEURIS = "imageUris";
|
|
||||||
private static final String ARGUMENT_KEY_VIDEOURI = "videoUri";
|
|
||||||
private static final String ARGUMENT_KEY_MUSICURL = "musicUrl";
|
|
||||||
private static final String ARGUMENT_KEY_TARGETURL = "targetUrl";
|
|
||||||
private static final String ARGUMENT_KEY_APPNAME = "appName";
|
|
||||||
private static final String ARGUMENT_KEY_EXTINT = "extInt";
|
|
||||||
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_RET = "ret";
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_MSG = "msg";
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_OPENID = "openid";
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_ACCESS_TOKEN = "access_token";
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_EXPIRES_IN = "expires_in";
|
|
||||||
private static final String ARGUMENT_KEY_RESULT_CREATE_AT = "create_at";
|
|
||||||
|
|
||||||
private static final String SCHEME_FILE = "file";
|
|
||||||
|
|
||||||
//
|
|
||||||
|
|
||||||
private Context applicationContext;
|
|
||||||
private Activity activity;
|
|
||||||
|
|
||||||
private MethodChannel channel;
|
|
||||||
private Tencent tencent;
|
|
||||||
|
|
||||||
public TencentKit() {
|
|
||||||
super();
|
|
||||||
}
|
|
||||||
|
|
||||||
public TencentKit(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/tencent_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)) {
|
|
||||||
final String appId = call.argument(ARGUMENT_KEY_APPID);
|
|
||||||
// final String universalLink = call.argument(ARGUMENT_KEY_UNIVERSALLINK);
|
|
||||||
String authority = null;
|
|
||||||
try {
|
|
||||||
ProviderInfo providerInfo = applicationContext.getPackageManager().getProviderInfo(new ComponentName(applicationContext, TencentKitFileProvider.class), PackageManager.MATCH_DEFAULT_ONLY);
|
|
||||||
authority = providerInfo.authority;
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
// ignore
|
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(authority)) {
|
|
||||||
tencent = Tencent.createInstance(appId, applicationContext, authority);
|
|
||||||
} else {
|
|
||||||
tencent = Tencent.createInstance(appId, applicationContext);
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
} else if (METHOD_ISQQINSTALLED.equals(call.method)) {
|
|
||||||
result.success(isAppInstalled(applicationContext, "com.tencent.mobileqq"));
|
|
||||||
} else if (METHOD_ISTIMINSTALLED.equals(call.method)) {
|
|
||||||
result.success(isAppInstalled(applicationContext, "com.tencent.tim"));
|
|
||||||
} else if (METHOD_LOGIN.equals(call.method)) {
|
|
||||||
login(call, result);
|
|
||||||
} else if (METHOD_LOGOUT.equals(call.method)) {
|
|
||||||
logout(call, result);
|
|
||||||
} else if (METHOD_SHAREMOOD.equals(call.method)) {
|
|
||||||
shareMood(call, result);
|
|
||||||
} else if (METHOD_SHARETEXT.equals(call.method)) {
|
|
||||||
shareText(call, result);
|
|
||||||
} else if (METHOD_SHAREIMAGE.equals(call.method)) {
|
|
||||||
shareImage(call, result);
|
|
||||||
} else if (METHOD_SHAREMUSIC.equals(call.method)) {
|
|
||||||
shareMusic(call, result);
|
|
||||||
} else if (METHOD_SHAREWEBPAGE.equals(call.method)) {
|
|
||||||
shareWebpage(call, result);
|
|
||||||
} else {
|
|
||||||
result.notImplemented();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void login(MethodCall call, MethodChannel.Result result) {
|
|
||||||
String scope = call.argument(ARGUMENT_KEY_SCOPE);
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.login(activity, scope, loginListener);
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IUiListener loginListener = new IUiListener() {
|
|
||||||
@Override
|
|
||||||
public void onComplete(Object o) {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
try {
|
|
||||||
if (o != null && o instanceof JSONObject) {
|
|
||||||
JSONObject object = (JSONObject) o;
|
|
||||||
int ret = !object.isNull(ARGUMENT_KEY_RESULT_RET) ? object.getInt(ARGUMENT_KEY_RESULT_RET) : TencentRetCode.RET_FAILED;
|
|
||||||
String msg = !object.isNull(ARGUMENT_KEY_RESULT_MSG) ? object.getString(ARGUMENT_KEY_RESULT_MSG) : null;
|
|
||||||
if (ret == TencentRetCode.RET_SUCCESS) {
|
|
||||||
String openId = !object.isNull(ARGUMENT_KEY_RESULT_OPENID) ? object.getString(ARGUMENT_KEY_RESULT_OPENID) : null;
|
|
||||||
String accessToken = !object.isNull(ARGUMENT_KEY_RESULT_ACCESS_TOKEN) ? object.getString(ARGUMENT_KEY_RESULT_ACCESS_TOKEN) : null;
|
|
||||||
int expiresIn = !object.isNull(ARGUMENT_KEY_RESULT_EXPIRES_IN) ? object.getInt(ARGUMENT_KEY_RESULT_EXPIRES_IN) : 0;
|
|
||||||
long createAt = System.currentTimeMillis();
|
|
||||||
if (!TextUtils.isEmpty(openId) && !TextUtils.isEmpty(accessToken)) {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_SUCCESS);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_OPENID, openId);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_ACCESS_TOKEN, accessToken);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_EXPIRES_IN, expiresIn);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_CREATE_AT, createAt);
|
|
||||||
} else {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, "openId or accessToken is null.");
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, e.getMessage());
|
|
||||||
}
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(UiError uiError) {
|
|
||||||
// 登录失败
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, uiError.errorMessage);
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel() {
|
|
||||||
// 取消登录
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_USERCANCEL);
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWarning(int code) {
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
private void logout(MethodCall call, MethodChannel.Result result) {
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.logout(applicationContext);
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareMood(MethodCall call, MethodChannel.Result result) {
|
|
||||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
|
||||||
if (scene == TencentScene.SCENE_QZONE) {
|
|
||||||
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
|
||||||
List<String> imageUris = call.argument(ARGUMENT_KEY_IMAGEURIS);
|
|
||||||
String videoUri = call.argument(ARGUMENT_KEY_VIDEOURI);
|
|
||||||
|
|
||||||
Bundle params = new Bundle();
|
|
||||||
if (!TextUtils.isEmpty(summary)) {
|
|
||||||
params.putString(QzonePublish.PUBLISH_TO_QZONE_SUMMARY, summary);
|
|
||||||
}
|
|
||||||
if (imageUris != null && !imageUris.isEmpty()) {
|
|
||||||
ArrayList<String> uris = new ArrayList<>();
|
|
||||||
for (String imageUri : imageUris) {
|
|
||||||
uris.add(Uri.parse(imageUri).getPath());
|
|
||||||
}
|
|
||||||
params.putStringArrayList(QzonePublish.PUBLISH_TO_QZONE_IMAGE_URL, uris);
|
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(videoUri)) {
|
|
||||||
String videoPath = Uri.parse(videoUri).getPath();
|
|
||||||
params.putString(QzonePublish.PUBLISH_TO_QZONE_VIDEO_PATH, videoPath);
|
|
||||||
params.putInt(QzonePublish.PUBLISH_TO_QZONE_KEY_TYPE, QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHVIDEO);
|
|
||||||
} else {
|
|
||||||
params.putInt(QzonePublish.PUBLISH_TO_QZONE_KEY_TYPE, QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
|
|
||||||
}
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.publishToQzone(activity, params, shareListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareText(MethodCall call, MethodChannel.Result result) {
|
|
||||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
|
||||||
if (scene == TencentScene.SCENE_QQ) {
|
|
||||||
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
|
||||||
Intent sendIntent = new Intent();
|
|
||||||
sendIntent.setAction(Intent.ACTION_SEND);
|
|
||||||
sendIntent.putExtra(Intent.EXTRA_TEXT, summary);
|
|
||||||
sendIntent.setType("text/*");
|
|
||||||
// 普通大众版 > 办公简洁版 > 急速轻聊版
|
|
||||||
PackageManager packageManager = applicationContext.getPackageManager();
|
|
||||||
List<PackageInfo> infos = packageManager.getInstalledPackages(0);
|
|
||||||
if (infos != null && !infos.isEmpty()) {
|
|
||||||
for (String packageName : Arrays.asList("com.tencent.mobileqq", "com.tencent.tim", "com.tencent.qqlite")) {
|
|
||||||
for (PackageInfo info : infos) {
|
|
||||||
if (packageName.equals(info.packageName)) {
|
|
||||||
sendIntent.setPackage(packageName);
|
|
||||||
if (sendIntent.resolveActivity(applicationContext.getPackageManager()) != null) {
|
|
||||||
sendIntent.setComponent(new ComponentName(packageName, "com.tencent.mobileqq.activity.JumpActivity"));
|
|
||||||
activity.startActivity(sendIntent);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareImage(MethodCall call, MethodChannel.Result result) {
|
|
||||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
|
||||||
if (scene == TencentScene.SCENE_QQ) {
|
|
||||||
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
|
||||||
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
|
||||||
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
|
||||||
|
|
||||||
Bundle params = new Bundle();
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, Uri.parse(imageUri).getPath());
|
|
||||||
if (!TextUtils.isEmpty(appName)) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
|
||||||
}
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.shareToQQ(activity, params, shareListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareMusic(MethodCall call, MethodChannel.Result result) {
|
|
||||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
|
||||||
if (scene == TencentScene.SCENE_QQ) {
|
|
||||||
String title = call.argument(ARGUMENT_KEY_TITLE);
|
|
||||||
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
|
||||||
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
|
||||||
String musicUrl = call.argument(ARGUMENT_KEY_MUSICURL);
|
|
||||||
String targetUrl = call.argument(ARGUMENT_KEY_TARGETURL);
|
|
||||||
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
|
||||||
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
|
||||||
|
|
||||||
Bundle params = new Bundle();
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_AUDIO);
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
|
|
||||||
if (!TextUtils.isEmpty(summary)) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
|
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(imageUri)) {
|
|
||||||
Uri uri = Uri.parse(imageUri);
|
|
||||||
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, uri.getPath());
|
|
||||||
} else {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, musicUrl);
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
|
||||||
if (!TextUtils.isEmpty(appName)) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
|
||||||
}
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.shareToQQ(activity, params, shareListener);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void shareWebpage(MethodCall call, MethodChannel.Result result) {
|
|
||||||
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
|
||||||
String title = call.argument(ARGUMENT_KEY_TITLE);
|
|
||||||
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
|
||||||
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
|
||||||
String targetUrl = call.argument(ARGUMENT_KEY_TARGETURL);
|
|
||||||
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
|
||||||
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
|
||||||
|
|
||||||
Bundle params = new Bundle();
|
|
||||||
switch (scene) {
|
|
||||||
case TencentScene.SCENE_QQ:
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
|
|
||||||
if (!TextUtils.isEmpty(summary)) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
|
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(imageUri)) {
|
|
||||||
Uri uri = Uri.parse(imageUri);
|
|
||||||
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, uri.getPath());
|
|
||||||
} else {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUri);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
|
||||||
if (!TextUtils.isEmpty(appName)) {
|
|
||||||
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
|
||||||
}
|
|
||||||
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.shareToQQ(activity, params, shareListener);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case TencentScene.SCENE_QZONE:
|
|
||||||
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
|
|
||||||
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
|
|
||||||
if (!TextUtils.isEmpty(summary)) {
|
|
||||||
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, summary);
|
|
||||||
}
|
|
||||||
if (!TextUtils.isEmpty(imageUri)) {
|
|
||||||
ArrayList<String> uris = new ArrayList<>();
|
|
||||||
Uri uri = Uri.parse(imageUri);
|
|
||||||
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
|
||||||
uris.add(uri.getPath());
|
|
||||||
} else {
|
|
||||||
uris.add(imageUri);
|
|
||||||
}
|
|
||||||
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, uris);
|
|
||||||
}
|
|
||||||
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
|
||||||
if (tencent != null) {
|
|
||||||
tencent.shareToQzone(activity, params, shareListener);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
result.success(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
private IUiListener shareListener = new IUiListener() {
|
|
||||||
@Override
|
|
||||||
public void onComplete(Object o) {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
try {
|
|
||||||
if (o != null && o instanceof JSONObject) {
|
|
||||||
JSONObject object = (JSONObject) o;
|
|
||||||
int ret = !object.isNull(ARGUMENT_KEY_RESULT_RET) ? object.getInt(ARGUMENT_KEY_RESULT_RET) : TencentRetCode.RET_FAILED;
|
|
||||||
String msg = !object.isNull(ARGUMENT_KEY_RESULT_MSG) ? object.getString(ARGUMENT_KEY_RESULT_MSG) : null;
|
|
||||||
if (ret == TencentRetCode.RET_SUCCESS) {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_SUCCESS);
|
|
||||||
} else {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} catch (JSONException e) {
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, e.getMessage());
|
|
||||||
}
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onError(UiError error) {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_MSG, error.errorMessage);
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onCancel() {
|
|
||||||
Map<String, Object> map = new HashMap<>();
|
|
||||||
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_USERCANCEL);
|
|
||||||
if (channel != null) {
|
|
||||||
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void onWarning(int code) {
|
|
||||||
if (code == Constants.ERROR_NO_AUTHORITY) {
|
|
||||||
// 如果authorities为空,sdk会回调这个接口,提醒开发者适配FileProvider
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// --- ActivityResultListener
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
|
||||||
switch (requestCode) {
|
|
||||||
case Constants.REQUEST_LOGIN:
|
|
||||||
return Tencent.onActivityResultData(requestCode, resultCode, data, loginListener);
|
|
||||||
case Constants.REQUEST_QQ_SHARE:
|
|
||||||
case Constants.REQUEST_QZONE_SHARE:
|
|
||||||
return Tencent.onActivityResultData(requestCode, resultCode, data, shareListener);
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ---
|
|
||||||
|
|
||||||
private static boolean isAppInstalled(Context context, String packageName) {
|
|
||||||
PackageInfo packageInfo = null;
|
|
||||||
try {
|
|
||||||
packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
|
||||||
}
|
|
||||||
return packageInfo != null;
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,62 +1,135 @@
|
|||||||
package io.github.v7lin.tencent_kit;
|
package io.github.v7lin.tencent_kit;
|
||||||
|
|
||||||
|
import android.content.ComponentName;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.content.Intent;
|
||||||
|
import android.content.pm.PackageInfo;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
|
import android.content.pm.ProviderInfo;
|
||||||
|
import android.net.Uri;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.text.TextUtils;
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
|
|
||||||
|
import com.tencent.connect.common.Constants;
|
||||||
|
import com.tencent.connect.share.QQShare;
|
||||||
|
import com.tencent.connect.share.QzonePublish;
|
||||||
|
import com.tencent.connect.share.QzoneShare;
|
||||||
|
import com.tencent.tauth.IUiListener;
|
||||||
|
import com.tencent.tauth.Tencent;
|
||||||
|
import com.tencent.tauth.UiError;
|
||||||
|
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
import io.flutter.embedding.engine.plugins.FlutterPlugin;
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
|
||||||
import io.flutter.plugin.common.PluginRegistry;
|
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.ActivityResultListener;
|
||||||
|
import io.github.v7lin.tencent_kit.content.TencentKitFileProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TencentKitPlugin
|
* TencentKitPlugin
|
||||||
*/
|
*/
|
||||||
public class TencentKitPlugin implements FlutterPlugin, ActivityAware {
|
public class TencentKitPlugin implements FlutterPlugin, ActivityAware, ActivityResultListener, MethodCallHandler {
|
||||||
// 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
|
private static class TencentScene {
|
||||||
// plugin registration via this function while apps migrate to use the new Android APIs
|
static final int SCENE_QQ = 0;
|
||||||
// post-flutter-1.12 via https://flutter.dev/go/android-project-migration.
|
static final int SCENE_QZONE = 1;
|
||||||
//
|
|
||||||
// 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(PluginRegistry.Registrar registrar) {
|
|
||||||
TencentKit tencentKit = new TencentKit(registrar.context(), registrar.activity());
|
|
||||||
registrar.addActivityResultListener(tencentKit);
|
|
||||||
tencentKit.startListening(registrar.messenger());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static class TencentRetCode {
|
||||||
|
// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||||
|
// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||||
|
static final int RET_SUCCESS = 0;
|
||||||
|
// 网络异常,或服务器返回的数据格式不正确导致无法解析
|
||||||
|
static final int RET_FAILED = 1;
|
||||||
|
static final int RET_COMMON = -1;
|
||||||
|
static final int RET_USERCANCEL = -2;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
|
||||||
|
private static final String METHOD_REGISTERAPP = "registerApp";
|
||||||
|
private static final String METHOD_ISQQINSTALLED = "isQQInstalled";
|
||||||
|
private static final String METHOD_ISTIMINSTALLED = "isTIMInstalled";
|
||||||
|
private static final String METHOD_LOGIN = "login";
|
||||||
|
private static final String METHOD_LOGOUT = "logout";
|
||||||
|
private static final String METHOD_SHAREMOOD = "shareMood";
|
||||||
|
private static final String METHOD_SHARETEXT = "shareText";
|
||||||
|
private static final String METHOD_SHAREIMAGE = "shareImage";
|
||||||
|
private static final String METHOD_SHAREMUSIC = "shareMusic";
|
||||||
|
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
|
||||||
|
|
||||||
|
private static final String METHOD_ONLOGINRESP = "onLoginResp";
|
||||||
|
private static final String METHOD_ONSHARERESP = "onShareResp";
|
||||||
|
|
||||||
|
private static final String ARGUMENT_KEY_APPID = "appId";
|
||||||
|
// private static final String ARGUMENT_KEY_UNIVERSALLINK = "universalLink";
|
||||||
|
private static final String ARGUMENT_KEY_SCOPE = "scope";
|
||||||
|
private static final String ARGUMENT_KEY_SCENE = "scene";
|
||||||
|
private static final String ARGUMENT_KEY_TITLE = "title";
|
||||||
|
private static final String ARGUMENT_KEY_SUMMARY = "summary";
|
||||||
|
private static final String ARGUMENT_KEY_IMAGEURI = "imageUri";
|
||||||
|
private static final String ARGUMENT_KEY_IMAGEURIS = "imageUris";
|
||||||
|
private static final String ARGUMENT_KEY_VIDEOURI = "videoUri";
|
||||||
|
private static final String ARGUMENT_KEY_MUSICURL = "musicUrl";
|
||||||
|
private static final String ARGUMENT_KEY_TARGETURL = "targetUrl";
|
||||||
|
private static final String ARGUMENT_KEY_APPNAME = "appName";
|
||||||
|
private static final String ARGUMENT_KEY_EXTINT = "extInt";
|
||||||
|
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_RET = "ret";
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_MSG = "msg";
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_OPENID = "openid";
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_ACCESS_TOKEN = "access_token";
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_EXPIRES_IN = "expires_in";
|
||||||
|
private static final String ARGUMENT_KEY_RESULT_CREATE_AT = "create_at";
|
||||||
|
|
||||||
|
private static final String SCHEME_FILE = "file";
|
||||||
|
|
||||||
|
/// 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;
|
||||||
|
|
||||||
|
private Tencent tencent;
|
||||||
|
|
||||||
// --- FlutterPlugin
|
// --- FlutterPlugin
|
||||||
|
|
||||||
private final TencentKit tencentKit;
|
|
||||||
|
|
||||||
private ActivityPluginBinding pluginBinding;
|
|
||||||
|
|
||||||
public TencentKitPlugin() {
|
|
||||||
tencentKit = new TencentKit();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
tencentKit.setApplicationContext(binding.getApplicationContext());
|
channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/tencent_kit");
|
||||||
tencentKit.setActivity(null);
|
channel.setMethodCallHandler(this);
|
||||||
tencentKit.startListening(binding.getBinaryMessenger());
|
applicationContext = binding.getApplicationContext();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
|
||||||
tencentKit.stopListening();
|
channel.setMethodCallHandler(null);
|
||||||
tencentKit.setActivity(null);
|
channel = null;
|
||||||
tencentKit.setApplicationContext(null);
|
applicationContext = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ActivityAware
|
// --- ActivityAware
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
|
public void onAttachedToActivity(@NonNull ActivityPluginBinding binding) {
|
||||||
tencentKit.setActivity(binding.getActivity());
|
activityPluginBinding = binding;
|
||||||
pluginBinding = binding;
|
activityPluginBinding.addActivityResultListener(this);
|
||||||
pluginBinding.addActivityResultListener(tencentKit);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -71,8 +144,389 @@ public class TencentKitPlugin implements FlutterPlugin, ActivityAware {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void onDetachedFromActivity() {
|
public void onDetachedFromActivity() {
|
||||||
tencentKit.setActivity(null);
|
activityPluginBinding.removeActivityResultListener(this);
|
||||||
pluginBinding.removeActivityResultListener(tencentKit);
|
activityPluginBinding = null;
|
||||||
pluginBinding = null;
|
}
|
||||||
|
|
||||||
|
// --- ActivityResultListener
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onActivityResult(int requestCode, int resultCode, Intent data) {
|
||||||
|
switch (requestCode) {
|
||||||
|
case Constants.REQUEST_LOGIN:
|
||||||
|
return Tencent.onActivityResultData(requestCode, resultCode, data, loginListener);
|
||||||
|
case Constants.REQUEST_QQ_SHARE:
|
||||||
|
case Constants.REQUEST_QZONE_SHARE:
|
||||||
|
return Tencent.onActivityResultData(requestCode, resultCode, data, shareListener);
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// --- MethodCallHandler
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
if (METHOD_REGISTERAPP.equals(call.method)) {
|
||||||
|
final String appId = call.argument(ARGUMENT_KEY_APPID);
|
||||||
|
// final String universalLink = call.argument(ARGUMENT_KEY_UNIVERSALLINK);
|
||||||
|
String authority = null;
|
||||||
|
try {
|
||||||
|
ProviderInfo providerInfo = applicationContext.getPackageManager().getProviderInfo(new ComponentName(applicationContext, TencentKitFileProvider.class), PackageManager.MATCH_DEFAULT_ONLY);
|
||||||
|
authority = providerInfo.authority;
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(authority)) {
|
||||||
|
tencent = Tencent.createInstance(appId, applicationContext, authority);
|
||||||
|
} else {
|
||||||
|
tencent = Tencent.createInstance(appId, applicationContext);
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
} else if (METHOD_ISQQINSTALLED.equals(call.method)) {
|
||||||
|
result.success(isAppInstalled(applicationContext, "com.tencent.mobileqq"));
|
||||||
|
} else if (METHOD_ISTIMINSTALLED.equals(call.method)) {
|
||||||
|
result.success(isAppInstalled(applicationContext, "com.tencent.tim"));
|
||||||
|
} else if (METHOD_LOGIN.equals(call.method)) {
|
||||||
|
login(call, result);
|
||||||
|
} else if (METHOD_LOGOUT.equals(call.method)) {
|
||||||
|
logout(call, result);
|
||||||
|
} else if (METHOD_SHAREMOOD.equals(call.method)) {
|
||||||
|
shareMood(call, result);
|
||||||
|
} else if (METHOD_SHARETEXT.equals(call.method)) {
|
||||||
|
shareText(call, result);
|
||||||
|
} else if (METHOD_SHAREIMAGE.equals(call.method)) {
|
||||||
|
shareImage(call, result);
|
||||||
|
} else if (METHOD_SHAREMUSIC.equals(call.method)) {
|
||||||
|
shareMusic(call, result);
|
||||||
|
} else if (METHOD_SHAREWEBPAGE.equals(call.method)) {
|
||||||
|
shareWebpage(call, result);
|
||||||
|
} else {
|
||||||
|
result.notImplemented();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void login(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
String scope = call.argument(ARGUMENT_KEY_SCOPE);
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.login(activityPluginBinding.getActivity(), scope, loginListener);
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IUiListener loginListener = new IUiListener() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(Object o) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (o != null && o instanceof JSONObject) {
|
||||||
|
JSONObject object = (JSONObject) o;
|
||||||
|
int ret = !object.isNull(ARGUMENT_KEY_RESULT_RET) ? object.getInt(ARGUMENT_KEY_RESULT_RET) : TencentRetCode.RET_FAILED;
|
||||||
|
String msg = !object.isNull(ARGUMENT_KEY_RESULT_MSG) ? object.getString(ARGUMENT_KEY_RESULT_MSG) : null;
|
||||||
|
if (ret == TencentRetCode.RET_SUCCESS) {
|
||||||
|
String openId = !object.isNull(ARGUMENT_KEY_RESULT_OPENID) ? object.getString(ARGUMENT_KEY_RESULT_OPENID) : null;
|
||||||
|
String accessToken = !object.isNull(ARGUMENT_KEY_RESULT_ACCESS_TOKEN) ? object.getString(ARGUMENT_KEY_RESULT_ACCESS_TOKEN) : null;
|
||||||
|
int expiresIn = !object.isNull(ARGUMENT_KEY_RESULT_EXPIRES_IN) ? object.getInt(ARGUMENT_KEY_RESULT_EXPIRES_IN) : 0;
|
||||||
|
long createAt = System.currentTimeMillis();
|
||||||
|
if (!TextUtils.isEmpty(openId) && !TextUtils.isEmpty(accessToken)) {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_SUCCESS);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_OPENID, openId);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_ACCESS_TOKEN, accessToken);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_EXPIRES_IN, expiresIn);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_CREATE_AT, createAt);
|
||||||
|
} else {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, "openId or accessToken is null.");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, e.getMessage());
|
||||||
|
}
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(UiError uiError) {
|
||||||
|
// 登录失败
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, uiError.errorMessage);
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
// 取消登录
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_USERCANCEL);
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONLOGINRESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWarning(int code) {
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private void logout(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.logout(applicationContext);
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareMood(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||||
|
if (scene == TencentScene.SCENE_QZONE) {
|
||||||
|
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
||||||
|
List<String> imageUris = call.argument(ARGUMENT_KEY_IMAGEURIS);
|
||||||
|
String videoUri = call.argument(ARGUMENT_KEY_VIDEOURI);
|
||||||
|
|
||||||
|
Bundle params = new Bundle();
|
||||||
|
if (!TextUtils.isEmpty(summary)) {
|
||||||
|
params.putString(QzonePublish.PUBLISH_TO_QZONE_SUMMARY, summary);
|
||||||
|
}
|
||||||
|
if (imageUris != null && !imageUris.isEmpty()) {
|
||||||
|
ArrayList<String> uris = new ArrayList<>();
|
||||||
|
for (String imageUri : imageUris) {
|
||||||
|
uris.add(Uri.parse(imageUri).getPath());
|
||||||
|
}
|
||||||
|
params.putStringArrayList(QzonePublish.PUBLISH_TO_QZONE_IMAGE_URL, uris);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(videoUri)) {
|
||||||
|
String videoPath = Uri.parse(videoUri).getPath();
|
||||||
|
params.putString(QzonePublish.PUBLISH_TO_QZONE_VIDEO_PATH, videoPath);
|
||||||
|
params.putInt(QzonePublish.PUBLISH_TO_QZONE_KEY_TYPE, QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHVIDEO);
|
||||||
|
} else {
|
||||||
|
params.putInt(QzonePublish.PUBLISH_TO_QZONE_KEY_TYPE, QzonePublish.PUBLISH_TO_QZONE_TYPE_PUBLISHMOOD);
|
||||||
|
}
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.publishToQzone(activityPluginBinding.getActivity(), params, shareListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareText(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||||
|
if (scene == TencentScene.SCENE_QQ) {
|
||||||
|
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
||||||
|
Intent sendIntent = new Intent();
|
||||||
|
sendIntent.setAction(Intent.ACTION_SEND);
|
||||||
|
sendIntent.putExtra(Intent.EXTRA_TEXT, summary);
|
||||||
|
sendIntent.setType("text/*");
|
||||||
|
// 普通大众版 > 办公简洁版 > 急速轻聊版
|
||||||
|
PackageManager packageManager = applicationContext.getPackageManager();
|
||||||
|
List<PackageInfo> infos = packageManager.getInstalledPackages(0);
|
||||||
|
if (infos != null && !infos.isEmpty()) {
|
||||||
|
for (String packageName : Arrays.asList("com.tencent.mobileqq", "com.tencent.tim", "com.tencent.qqlite")) {
|
||||||
|
for (PackageInfo info : infos) {
|
||||||
|
if (packageName.equals(info.packageName)) {
|
||||||
|
sendIntent.setPackage(packageName);
|
||||||
|
if (sendIntent.resolveActivity(applicationContext.getPackageManager()) != null) {
|
||||||
|
sendIntent.setComponent(new ComponentName(packageName, "com.tencent.mobileqq.activity.JumpActivity"));
|
||||||
|
activityPluginBinding.getActivity().startActivity(sendIntent);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareImage(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||||
|
if (scene == TencentScene.SCENE_QQ) {
|
||||||
|
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
||||||
|
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
||||||
|
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
||||||
|
|
||||||
|
Bundle params = new Bundle();
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_IMAGE);
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_IMAGE_LOCAL_URL, Uri.parse(imageUri).getPath());
|
||||||
|
if (!TextUtils.isEmpty(appName)) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
||||||
|
}
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.shareToQQ(activityPluginBinding.getActivity(), params, shareListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareMusic(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||||
|
if (scene == TencentScene.SCENE_QQ) {
|
||||||
|
String title = call.argument(ARGUMENT_KEY_TITLE);
|
||||||
|
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
||||||
|
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
||||||
|
String musicUrl = call.argument(ARGUMENT_KEY_MUSICURL);
|
||||||
|
String targetUrl = call.argument(ARGUMENT_KEY_TARGETURL);
|
||||||
|
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
||||||
|
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
||||||
|
|
||||||
|
Bundle params = new Bundle();
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_AUDIO);
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
|
||||||
|
if (!TextUtils.isEmpty(summary)) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(imageUri)) {
|
||||||
|
Uri uri = Uri.parse(imageUri);
|
||||||
|
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, uri.getPath());
|
||||||
|
} else {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_AUDIO_URL, musicUrl);
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
||||||
|
if (!TextUtils.isEmpty(appName)) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
||||||
|
}
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.shareToQQ(activityPluginBinding.getActivity(), params, shareListener);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void shareWebpage(@NonNull MethodCall call, @NonNull Result result) {
|
||||||
|
int scene = call.argument(ARGUMENT_KEY_SCENE);
|
||||||
|
String title = call.argument(ARGUMENT_KEY_TITLE);
|
||||||
|
String summary = call.argument(ARGUMENT_KEY_SUMMARY);
|
||||||
|
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
|
||||||
|
String targetUrl = call.argument(ARGUMENT_KEY_TARGETURL);
|
||||||
|
String appName = call.argument(ARGUMENT_KEY_APPNAME);
|
||||||
|
int extInt = call.argument(ARGUMENT_KEY_EXTINT);
|
||||||
|
|
||||||
|
Bundle params = new Bundle();
|
||||||
|
switch (scene) {
|
||||||
|
case TencentScene.SCENE_QQ:
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_KEY_TYPE, QQShare.SHARE_TO_QQ_TYPE_DEFAULT);
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_TITLE, title);
|
||||||
|
if (!TextUtils.isEmpty(summary)) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_SUMMARY, summary);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(imageUri)) {
|
||||||
|
Uri uri = Uri.parse(imageUri);
|
||||||
|
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, uri.getPath());
|
||||||
|
} else {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_IMAGE_URL, imageUri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
||||||
|
if (!TextUtils.isEmpty(appName)) {
|
||||||
|
params.putString(QQShare.SHARE_TO_QQ_APP_NAME, appName);
|
||||||
|
}
|
||||||
|
params.putInt(QQShare.SHARE_TO_QQ_EXT_INT, extInt);
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.shareToQQ(activityPluginBinding.getActivity(), params, shareListener);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case TencentScene.SCENE_QZONE:
|
||||||
|
params.putInt(QzoneShare.SHARE_TO_QZONE_KEY_TYPE, QzoneShare.SHARE_TO_QZONE_TYPE_IMAGE_TEXT);
|
||||||
|
params.putString(QzoneShare.SHARE_TO_QQ_TITLE, title);
|
||||||
|
if (!TextUtils.isEmpty(summary)) {
|
||||||
|
params.putString(QzoneShare.SHARE_TO_QQ_SUMMARY, summary);
|
||||||
|
}
|
||||||
|
if (!TextUtils.isEmpty(imageUri)) {
|
||||||
|
ArrayList<String> uris = new ArrayList<>();
|
||||||
|
Uri uri = Uri.parse(imageUri);
|
||||||
|
if (TextUtils.equals(SCHEME_FILE, uri.getScheme())) {
|
||||||
|
uris.add(uri.getPath());
|
||||||
|
} else {
|
||||||
|
uris.add(imageUri);
|
||||||
|
}
|
||||||
|
params.putStringArrayList(QzoneShare.SHARE_TO_QQ_IMAGE_URL, uris);
|
||||||
|
}
|
||||||
|
params.putString(QzoneShare.SHARE_TO_QQ_TARGET_URL, targetUrl);
|
||||||
|
if (tencent != null) {
|
||||||
|
tencent.shareToQzone(activityPluginBinding.getActivity(), params, shareListener);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
result.success(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IUiListener shareListener = new IUiListener() {
|
||||||
|
@Override
|
||||||
|
public void onComplete(Object o) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
try {
|
||||||
|
if (o != null && o instanceof JSONObject) {
|
||||||
|
JSONObject object = (JSONObject) o;
|
||||||
|
int ret = !object.isNull(ARGUMENT_KEY_RESULT_RET) ? object.getInt(ARGUMENT_KEY_RESULT_RET) : TencentRetCode.RET_FAILED;
|
||||||
|
String msg = !object.isNull(ARGUMENT_KEY_RESULT_MSG) ? object.getString(ARGUMENT_KEY_RESULT_MSG) : null;
|
||||||
|
if (ret == TencentRetCode.RET_SUCCESS) {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_SUCCESS);
|
||||||
|
} else {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (JSONException e) {
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, e.getMessage());
|
||||||
|
}
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onError(UiError error) {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_COMMON);
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_MSG, error.errorMessage);
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onCancel() {
|
||||||
|
Map<String, Object> map = new HashMap<>();
|
||||||
|
map.put(ARGUMENT_KEY_RESULT_RET, TencentRetCode.RET_USERCANCEL);
|
||||||
|
if (channel != null) {
|
||||||
|
channel.invokeMethod(METHOD_ONSHARERESP, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onWarning(int code) {
|
||||||
|
if (code == Constants.ERROR_NO_AUTHORITY) {
|
||||||
|
// 如果authorities为空,sdk会回调这个接口,提醒开发者适配FileProvider
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
private static boolean isAppInstalled(Context context, String packageName) {
|
||||||
|
PackageInfo packageInfo = null;
|
||||||
|
try {
|
||||||
|
packageInfo = context.getPackageManager().getPackageInfo(packageName, 0);
|
||||||
|
} catch (PackageManager.NameNotFoundException e) {
|
||||||
|
}
|
||||||
|
return packageInfo != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
7
example/.gitignore
vendored
7
example/.gitignore
vendored
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
# Flutter/Dart/Pub related
|
# Flutter/Dart/Pub related
|
||||||
**/doc/api/
|
**/doc/api/
|
||||||
|
**/ios/Flutter/.last_build_id
|
||||||
.dart_tool/
|
.dart_tool/
|
||||||
.flutter-plugins
|
.flutter-plugins
|
||||||
.flutter-plugins-dependencies
|
.flutter-plugins-dependencies
|
||||||
@ -39,5 +40,7 @@ app.*.symbols
|
|||||||
# Obfuscation related
|
# Obfuscation related
|
||||||
app.*.map.json
|
app.*.map.json
|
||||||
|
|
||||||
# Exceptions to above rules.
|
# Android Studio will place build artifacts here
|
||||||
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
|
/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
|
/gradlew.bat
|
||||||
/local.properties
|
/local.properties
|
||||||
GeneratedPluginRegistrant.java
|
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 {
|
dependencies {
|
||||||
classpath 'com.android.tools.build:gradle:3.5.4'
|
classpath 'com.android.tools.build:gradle:4.1.0'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME
|
|||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
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
|
||||||
|
@ -2,12 +2,16 @@ import 'dart:async';
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:okhttp_kit/okhttp_kit.dart';
|
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
|
||||||
import 'package:path/path.dart' as path;
|
|
||||||
import 'package:path_provider/path_provider.dart' as path_provider;
|
|
||||||
import 'package:tencent_kit/tencent_kit.dart';
|
import 'package:tencent_kit/tencent_kit.dart';
|
||||||
|
|
||||||
void main() => runApp(MyApp());
|
const String _TENCENT_APPID = 'your tencent appId';
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
Tencent.instance.registerApp(appId: _TENCENT_APPID);
|
||||||
|
runApp(MyApp());
|
||||||
|
}
|
||||||
|
|
||||||
class MyApp extends StatelessWidget {
|
class MyApp extends StatelessWidget {
|
||||||
@override
|
@override
|
||||||
@ -26,39 +30,33 @@ class Home extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _HomeState extends State<Home> {
|
class _HomeState extends State<Home> {
|
||||||
static const String _TENCENT_APPID = 'your tencent appId';
|
late final StreamSubscription<TencentLoginResp> _login =
|
||||||
|
Tencent.instance.loginResp().listen(_listenLogin);
|
||||||
|
late final StreamSubscription<TencentSdkResp> _share =
|
||||||
|
Tencent.instance.shareResp().listen(_listenShare);
|
||||||
|
|
||||||
final Tencent _tencent = Tencent()..registerApp(appId: _TENCENT_APPID);
|
TencentLoginResp? _loginResp;
|
||||||
|
|
||||||
StreamSubscription<TencentLoginResp> _login;
|
|
||||||
StreamSubscription<TencentShareResp> _share;
|
|
||||||
|
|
||||||
TencentLoginResp _loginResp;
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_login = _tencent.loginResp().listen(_listenLogin);
|
|
||||||
_share = _tencent.shareResp().listen(_listenShare);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenLogin(TencentLoginResp resp) {
|
void _listenLogin(TencentLoginResp resp) {
|
||||||
_loginResp = resp;
|
_loginResp = resp;
|
||||||
String content = 'login: ${resp.openid} - ${resp.accessToken}';
|
final String content = 'login: ${resp.openid} - ${resp.accessToken}';
|
||||||
_showTips('登录', content);
|
_showTips('登录', content);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _listenShare(TencentShareResp resp) {
|
void _listenShare(TencentSdkResp resp) {
|
||||||
String content = 'share: ${resp.ret} - ${resp.msg}';
|
final String content = 'share: ${resp.ret} - ${resp.msg}';
|
||||||
_showTips('分享', content);
|
_showTips('分享', content);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
_login?.cancel();
|
_login.cancel();
|
||||||
_login = null;
|
_share.cancel();
|
||||||
_share?.cancel();
|
|
||||||
_share = null;
|
|
||||||
super.dispose();
|
super.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,15 +71,15 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('环境检查'),
|
title: const Text('环境检查'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
String content =
|
final String content =
|
||||||
'QQ install: ${await _tencent.isQQInstalled()}\nTIM install: ${await _tencent.isTIMInstalled()}';
|
'QQ install: ${await Tencent.instance.isQQInstalled()}\nTIM install: ${await Tencent.instance.isTIMInstalled()}';
|
||||||
_showTips('环境检查', content);
|
_showTips('环境检查', content);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('登录'),
|
title: const Text('登录'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_tencent.login(
|
Tencent.instance.login(
|
||||||
scope: <String>[TencentScope.GET_SIMPLE_USERINFO],
|
scope: <String>[TencentScope.GET_SIMPLE_USERINFO],
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -89,13 +87,13 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('获取用户信息'),
|
title: const Text('获取用户信息'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (_loginResp != null &&
|
if ((_loginResp?.isSuccessful ?? false) &&
|
||||||
_loginResp.isSuccessful &&
|
!(_loginResp!.isExpired ?? true)) {
|
||||||
!_loginResp.isExpired) {
|
final TencentUserInfoResp userInfo =
|
||||||
TencentUserInfoResp userInfo = await _tencent.getUserInfo(
|
await Tencent.instance.getUserInfo(
|
||||||
appId: _TENCENT_APPID,
|
appId: _TENCENT_APPID,
|
||||||
openid: _loginResp.openid,
|
openid: _loginResp!.openid!,
|
||||||
accessToken: _loginResp.accessToken,
|
accessToken: _loginResp!.accessToken!,
|
||||||
);
|
);
|
||||||
if (userInfo.isSuccessful) {
|
if (userInfo.isSuccessful) {
|
||||||
_showTips('用户信息',
|
_showTips('用户信息',
|
||||||
@ -109,11 +107,11 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('获取UnionID'),
|
title: const Text('获取UnionID'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
if (_loginResp != null &&
|
if ((_loginResp?.isSuccessful ?? false) &&
|
||||||
_loginResp.isSuccessful &&
|
!(_loginResp!.isExpired ?? true)) {
|
||||||
!_loginResp.isExpired) {
|
final TencentUnionidResp unionid =
|
||||||
TencentUnionidResp unionid = await _tencent.getUnionId(
|
await Tencent.instance.getUnionId(
|
||||||
accessToken: _loginResp.accessToken,
|
accessToken: _loginResp!.accessToken!,
|
||||||
);
|
);
|
||||||
if (unionid.isSuccessful) {
|
if (unionid.isSuccessful) {
|
||||||
_showTips('UnionID',
|
_showTips('UnionID',
|
||||||
@ -128,7 +126,7 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('分享说说'),
|
title: const Text('分享说说'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_tencent.shareMood(
|
Tencent.instance.shareMood(
|
||||||
scene: TencentScene.SCENE_QZONE,
|
scene: TencentScene.SCENE_QZONE,
|
||||||
summary: '分享测试',
|
summary: '分享测试',
|
||||||
);
|
);
|
||||||
@ -137,7 +135,7 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('文本分享'),
|
title: const Text('文本分享'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_tencent.shareText(
|
Tencent.instance.shareText(
|
||||||
scene: TencentScene.SCENE_QQ,
|
scene: TencentScene.SCENE_QQ,
|
||||||
summary: '分享测试',
|
summary: '分享测试',
|
||||||
);
|
);
|
||||||
@ -146,37 +144,18 @@ class _HomeState extends State<Home> {
|
|||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('图片分享'),
|
title: const Text('图片分享'),
|
||||||
onTap: () async {
|
onTap: () async {
|
||||||
OkHttpClient client = OkHttpClientBuilder().build();
|
final File file = await DefaultCacheManager().getSingleFile(
|
||||||
Response resp = await client
|
'https://www.baidu.com/img/bd_logo1.png?where=super');
|
||||||
.newCall(RequestBuilder()
|
await Tencent.instance.shareImage(
|
||||||
.get()
|
|
||||||
.url(HttpUrl.parse(
|
|
||||||
'https://www.baidu.com/img/bd_logo1.png?where=super'))
|
|
||||||
.build())
|
|
||||||
.enqueue();
|
|
||||||
if (resp.isSuccessful()) {
|
|
||||||
Directory saveDir = Platform.isIOS
|
|
||||||
? await path_provider.getApplicationDocumentsDirectory()
|
|
||||||
: await path_provider.getExternalStorageDirectory();
|
|
||||||
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 _tencent.shareImage(
|
|
||||||
scene: TencentScene.SCENE_QQ,
|
scene: TencentScene.SCENE_QQ,
|
||||||
imageUri: Uri.file(saveFile.path),
|
imageUri: Uri.file(file.path),
|
||||||
);
|
);
|
||||||
}
|
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
ListTile(
|
ListTile(
|
||||||
title: const Text('网页分享'),
|
title: const Text('网页分享'),
|
||||||
onTap: () {
|
onTap: () {
|
||||||
_tencent.shareWebpage(
|
Tencent.instance.shareWebpage(
|
||||||
scene: TencentScene.SCENE_QQ,
|
scene: TencentScene.SCENE_QQ,
|
||||||
title: 'title',
|
title: 'title',
|
||||||
targetUrl: 'https://www.baidu.com/',
|
targetUrl: 'https://www.baidu.com/',
|
||||||
|
@ -1,212 +1,233 @@
|
|||||||
# Generated by pub
|
# Generated by pub
|
||||||
# See https://dart.dev/tools/pub/glossary#lockfile
|
# See https://dart.dev/tools/pub/glossary#lockfile
|
||||||
packages:
|
packages:
|
||||||
|
archive:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: archive
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.1.2"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0-nullsafety.1"
|
version: "2.5.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.1"
|
version: "2.1.0"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.3"
|
version: "1.1.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.1"
|
version: "1.1.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0-nullsafety.3"
|
version: "1.15.0"
|
||||||
convert:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: convert
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.1"
|
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "3.0.0"
|
||||||
cupertino_icons:
|
cupertino_icons:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: cupertino_icons
|
name: cupertino_icons
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "1.0.2"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
ffi:
|
ffi:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: ffi
|
name: ffi
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.3"
|
version: "1.0.0"
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.1"
|
version: "6.1.0"
|
||||||
fixnum:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: fixnum
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.10.11"
|
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
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:
|
flutter_test:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
intl:
|
http:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: intl
|
name: http
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.16.1"
|
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: transitive
|
||||||
|
description:
|
||||||
|
name: image
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "4.0.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.10-nullsafety.1"
|
version: "0.12.10"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.3"
|
version: "1.3.0"
|
||||||
okhttp_kit:
|
|
||||||
dependency: "direct main"
|
|
||||||
description:
|
|
||||||
name: okhttp_kit
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
path:
|
path:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety.1"
|
version: "1.8.0"
|
||||||
path_provider:
|
path_provider:
|
||||||
dependency: "direct main"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider
|
name: path_provider
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.27"
|
version: "2.0.1"
|
||||||
path_provider_linux:
|
path_provider_linux:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_linux
|
name: path_provider_linux
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.1+2"
|
version: "2.0.0"
|
||||||
path_provider_macos:
|
path_provider_macos:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_macos
|
name: path_provider_macos
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4+8"
|
version: "2.0.0"
|
||||||
path_provider_platform_interface:
|
path_provider_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_platform_interface
|
name: path_provider_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.1"
|
||||||
path_provider_windows:
|
path_provider_windows:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path_provider_windows
|
name: path_provider_windows
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.0.4+3"
|
version: "2.0.0"
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.2"
|
version: "1.11.0"
|
||||||
|
petitparser:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: petitparser
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "4.0.2"
|
||||||
platform:
|
platform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: platform
|
name: platform
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "3.0.0"
|
||||||
plugin_platform_interface:
|
plugin_platform_interface:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: plugin_platform_interface
|
name: plugin_platform_interface
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.3"
|
version: "2.0.0"
|
||||||
process:
|
process:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: process
|
name: process
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.0.13"
|
version: "4.1.0"
|
||||||
|
rxdart:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: rxdart
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "0.26.0"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -218,77 +239,112 @@ packages:
|
|||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety.2"
|
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:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0-nullsafety.1"
|
version: "1.10.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.1"
|
version: "2.1.0"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.1"
|
version: "1.1.0"
|
||||||
|
synchronized:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: synchronized
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.0"
|
||||||
tencent_kit:
|
tencent_kit:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
path: ".."
|
path: ".."
|
||||||
relative: true
|
relative: true
|
||||||
source: path
|
source: path
|
||||||
version: "2.0.1"
|
version: "2.1.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.19-nullsafety.2"
|
version: "0.2.19"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.3"
|
version: "1.3.0"
|
||||||
|
uuid:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: uuid
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "3.0.1"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.3"
|
version: "2.1.0"
|
||||||
win32:
|
win32:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: win32
|
name: win32
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.7.4+1"
|
version: "2.0.4"
|
||||||
xdg_directories:
|
xdg_directories:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: xdg_directories
|
name: xdg_directories
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.2"
|
version: "0.2.0"
|
||||||
|
xml:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: xml
|
||||||
|
url: "https://pub.flutter-io.cn"
|
||||||
|
source: hosted
|
||||||
|
version: "5.0.2"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.10.0-110 <2.11.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.12.13+hotfix.5 <2.0.0"
|
flutter: ">=1.24.0-10"
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
name: tencent_kit_example
|
name: tencent_kit_example
|
||||||
description: Demonstrates how to use the tencent_kit plugin.
|
description: Demonstrates how to use the tencent_kit plugin.
|
||||||
version: 1.0.0+1000
|
|
||||||
# The following line prevents the package from being accidentally published to
|
# The following line prevents the package from being accidentally published to
|
||||||
# pub.dev using `pub publish`. This is preferred for private packages.
|
# 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
|
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
|
||||||
|
|
||||||
|
version: 1.0.0+100
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
@ -22,12 +24,9 @@ dependencies:
|
|||||||
|
|
||||||
# The following adds the Cupertino Icons font to your application.
|
# The following adds the Cupertino Icons font to your application.
|
||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^0.1.3
|
cupertino_icons: ^1.0.2
|
||||||
|
|
||||||
path: ^1.6.4
|
flutter_cache_manager: ^3.0.0-nullsafety.1
|
||||||
path_provider: ^1.4.0
|
|
||||||
|
|
||||||
okhttp_kit: ^1.0.0
|
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
#
|
#
|
||||||
Pod::Spec.new do |s|
|
Pod::Spec.new do |s|
|
||||||
s.name = 'tencent_kit'
|
s.name = 'tencent_kit'
|
||||||
s.version = '2.0.1'
|
s.version = '2.1.0'
|
||||||
s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.'
|
s.summary = 'A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.'
|
||||||
s.description = <<-DESC
|
s.description = <<-DESC
|
||||||
A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
||||||
|
@ -2,7 +2,7 @@ import 'package:json_annotation/json_annotation.dart';
|
|||||||
|
|
||||||
abstract class TencentApiResp {
|
abstract class TencentApiResp {
|
||||||
const TencentApiResp({
|
const TencentApiResp({
|
||||||
this.ret,
|
required this.ret,
|
||||||
this.msg,
|
this.msg,
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -14,7 +14,7 @@ abstract class TencentApiResp {
|
|||||||
defaultValue: RET_SUCCESS,
|
defaultValue: RET_SUCCESS,
|
||||||
)
|
)
|
||||||
final int ret;
|
final int ret;
|
||||||
final String msg;
|
final String? msg;
|
||||||
|
|
||||||
bool get isSuccessful => ret == RET_SUCCESS;
|
bool get isSuccessful => ret == RET_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,8 @@ part 'tencent_user_info_resp.g.dart';
|
|||||||
)
|
)
|
||||||
class TencentUserInfoResp extends TencentApiResp {
|
class TencentUserInfoResp extends TencentApiResp {
|
||||||
const TencentUserInfoResp({
|
const TencentUserInfoResp({
|
||||||
int ret,
|
required int ret,
|
||||||
String msg,
|
String? msg,
|
||||||
this.isLost,
|
this.isLost,
|
||||||
this.nickname,
|
this.nickname,
|
||||||
this.gender,
|
this.gender,
|
||||||
@ -36,58 +36,58 @@ class TencentUserInfoResp extends TencentApiResp {
|
|||||||
factory TencentUserInfoResp.fromJson(Map<String, dynamic> json) =>
|
factory TencentUserInfoResp.fromJson(Map<String, dynamic> json) =>
|
||||||
_$TencentUserInfoRespFromJson(json);
|
_$TencentUserInfoRespFromJson(json);
|
||||||
|
|
||||||
final int isLost;
|
final int? isLost;
|
||||||
final String nickname;
|
final String? nickname;
|
||||||
final String gender; // 男/女
|
final String? gender; // 男/女
|
||||||
final int genderType; // 男/女 - 1
|
final int? genderType; // 男/女 - 1
|
||||||
final String province;
|
final String? province;
|
||||||
final String city;
|
final String? city;
|
||||||
final String year;
|
final String? year;
|
||||||
final String constellation;
|
final String? constellation;
|
||||||
final String figureurl;
|
final String? figureurl;
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'figureurl_1',
|
name: 'figureurl_1',
|
||||||
)
|
)
|
||||||
final String figureurl1;
|
final String? figureurl1;
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'figureurl_2',
|
name: 'figureurl_2',
|
||||||
)
|
)
|
||||||
final String figureurl2;
|
final String? figureurl2;
|
||||||
final String figureurlQq; // 140 * 140
|
final String? figureurlQq; // 140 * 140
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'figureurl_qq_1',
|
name: 'figureurl_qq_1',
|
||||||
)
|
)
|
||||||
final String figureurlQq1; // 大小为40×40像素的QQ头像URL。
|
final String? figureurlQq1; // 大小为40×40像素的QQ头像URL。
|
||||||
@JsonKey(
|
@JsonKey(
|
||||||
name: 'figureurl_qq_2',
|
name: 'figureurl_qq_2',
|
||||||
)
|
)
|
||||||
final String
|
final String?
|
||||||
figureurlQq2; // 大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有。
|
figureurlQq2; // 大小为100×100像素的QQ头像URL。需要注意,不是所有的用户都拥有QQ的100x100的头像,但40x40像素则是一定会有。
|
||||||
final String figureurlType;
|
final String? figureurlType;
|
||||||
final String isYellowVip;
|
final String? isYellowVip;
|
||||||
final String vip;
|
final String? vip;
|
||||||
final String yellowVipLevel;
|
final String? yellowVipLevel;
|
||||||
final String level;
|
final String? level;
|
||||||
final String isYellowYearVip;
|
final String? isYellowYearVip;
|
||||||
|
|
||||||
bool get isMale => gender == '男';
|
bool get isMale => gender == '男';
|
||||||
|
|
||||||
bool get isFemale => gender == '女';
|
bool get isFemale => gender == '女';
|
||||||
|
|
||||||
String get headImgUrl {
|
String? get headImgUrl {
|
||||||
if (figureurlQq != null && figureurlQq.isNotEmpty) {
|
if (figureurlQq?.isNotEmpty ?? false) {
|
||||||
return figureurlQq;
|
return figureurlQq;
|
||||||
}
|
}
|
||||||
if (figureurlQq2 != null && figureurlQq2.isNotEmpty) {
|
if (figureurlQq2?.isNotEmpty ?? false) {
|
||||||
return figureurlQq2;
|
return figureurlQq2;
|
||||||
}
|
}
|
||||||
if (figureurlQq1 != null && figureurlQq1.isNotEmpty) {
|
if (figureurlQq1?.isNotEmpty ?? false) {
|
||||||
return figureurlQq1;
|
return figureurlQq1;
|
||||||
}
|
}
|
||||||
if (figureurl2 != null && figureurl2.isNotEmpty) {
|
if (figureurl2?.isNotEmpty ?? false) {
|
||||||
return figureurl2;
|
return figureurl2;
|
||||||
}
|
}
|
||||||
if (figureurl1 != null && figureurl1.isNotEmpty) {
|
if (figureurl1?.isNotEmpty ?? false) {
|
||||||
return figureurl1;
|
return figureurl1;
|
||||||
}
|
}
|
||||||
return figureurl;
|
return figureurl;
|
||||||
|
@ -8,28 +8,28 @@ part of 'tencent_user_info_resp.dart';
|
|||||||
|
|
||||||
TencentUserInfoResp _$TencentUserInfoRespFromJson(Map<String, dynamic> json) {
|
TencentUserInfoResp _$TencentUserInfoRespFromJson(Map<String, dynamic> json) {
|
||||||
return TencentUserInfoResp(
|
return TencentUserInfoResp(
|
||||||
ret: json['ret'] as int ?? 0,
|
ret: json['ret'] as int? ?? 0,
|
||||||
msg: json['msg'] as String,
|
msg: json['msg'] as String?,
|
||||||
isLost: json['is_lost'] as int,
|
isLost: json['is_lost'] as int?,
|
||||||
nickname: json['nickname'] as String,
|
nickname: json['nickname'] as String?,
|
||||||
gender: json['gender'] as String,
|
gender: json['gender'] as String?,
|
||||||
genderType: json['gender_type'] as int,
|
genderType: json['gender_type'] as int?,
|
||||||
province: json['province'] as String,
|
province: json['province'] as String?,
|
||||||
city: json['city'] as String,
|
city: json['city'] as String?,
|
||||||
year: json['year'] as String,
|
year: json['year'] as String?,
|
||||||
constellation: json['constellation'] as String,
|
constellation: json['constellation'] as String?,
|
||||||
figureurl: json['figureurl'] as String,
|
figureurl: json['figureurl'] as String?,
|
||||||
figureurl1: json['figureurl_1'] as String,
|
figureurl1: json['figureurl_1'] as String?,
|
||||||
figureurl2: json['figureurl_2'] as String,
|
figureurl2: json['figureurl_2'] as String?,
|
||||||
figureurlQq: json['figureurl_qq'] as String,
|
figureurlQq: json['figureurl_qq'] as String?,
|
||||||
figureurlQq1: json['figureurl_qq_1'] as String,
|
figureurlQq1: json['figureurl_qq_1'] as String?,
|
||||||
figureurlQq2: json['figureurl_qq_2'] as String,
|
figureurlQq2: json['figureurl_qq_2'] as String?,
|
||||||
figureurlType: json['figureurl_type'] as String,
|
figureurlType: json['figureurl_type'] as String?,
|
||||||
isYellowVip: json['is_yellow_vip'] as String,
|
isYellowVip: json['is_yellow_vip'] as String?,
|
||||||
vip: json['vip'] as String,
|
vip: json['vip'] as String?,
|
||||||
yellowVipLevel: json['yellow_vip_level'] as String,
|
yellowVipLevel: json['yellow_vip_level'] as String?,
|
||||||
level: json['level'] as String,
|
level: json['level'] as String?,
|
||||||
isYellowYearVip: json['is_yellow_year_vip'] as String,
|
isYellowYearVip: json['is_yellow_year_vip'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,8 +9,8 @@ part 'tencent_login_resp.g.dart';
|
|||||||
)
|
)
|
||||||
class TencentLoginResp extends TencentSdkResp {
|
class TencentLoginResp extends TencentSdkResp {
|
||||||
const TencentLoginResp({
|
const TencentLoginResp({
|
||||||
int ret,
|
required int ret,
|
||||||
String msg,
|
String? msg,
|
||||||
this.openid,
|
this.openid,
|
||||||
this.accessToken,
|
this.accessToken,
|
||||||
this.expiresIn,
|
this.expiresIn,
|
||||||
@ -20,13 +20,15 @@ class TencentLoginResp extends TencentSdkResp {
|
|||||||
factory TencentLoginResp.fromJson(Map<String, dynamic> json) =>
|
factory TencentLoginResp.fromJson(Map<String, dynamic> json) =>
|
||||||
_$TencentLoginRespFromJson(json);
|
_$TencentLoginRespFromJson(json);
|
||||||
|
|
||||||
final String openid;
|
final String? openid;
|
||||||
final String accessToken;
|
final String? accessToken;
|
||||||
final int expiresIn;
|
final int? expiresIn;
|
||||||
final int createAt;
|
final int? createAt;
|
||||||
|
|
||||||
bool get isExpired =>
|
bool? get isExpired => isSuccessful
|
||||||
DateTime.now().millisecondsSinceEpoch - createAt >= expiresIn * 1000;
|
? DateTime.now().millisecondsSinceEpoch - createAt! >= expiresIn! * 1000
|
||||||
|
: null;
|
||||||
|
|
||||||
|
@override
|
||||||
Map<String, dynamic> toJson() => _$TencentLoginRespToJson(this);
|
Map<String, dynamic> toJson() => _$TencentLoginRespToJson(this);
|
||||||
}
|
}
|
||||||
|
@ -8,12 +8,12 @@ part of 'tencent_login_resp.dart';
|
|||||||
|
|
||||||
TencentLoginResp _$TencentLoginRespFromJson(Map<String, dynamic> json) {
|
TencentLoginResp _$TencentLoginRespFromJson(Map<String, dynamic> json) {
|
||||||
return TencentLoginResp(
|
return TencentLoginResp(
|
||||||
ret: json['ret'] as int ?? 0,
|
ret: json['ret'] as int? ?? 0,
|
||||||
msg: json['msg'] as String,
|
msg: json['msg'] as String?,
|
||||||
openid: json['openid'] as String,
|
openid: json['openid'] as String?,
|
||||||
accessToken: json['access_token'] as String,
|
accessToken: json['access_token'] as String?,
|
||||||
expiresIn: json['expires_in'] as int,
|
expiresIn: json['expires_in'] as int?,
|
||||||
createAt: json['create_at'] as int,
|
createAt: json['create_at'] as int?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,20 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
import 'package:json_annotation/json_annotation.dart';
|
||||||
|
|
||||||
abstract class TencentSdkResp {
|
part 'tencent_sdk_resp.g.dart';
|
||||||
|
|
||||||
|
@JsonSerializable(
|
||||||
|
explicitToJson: true,
|
||||||
|
fieldRename: FieldRename.snake,
|
||||||
|
)
|
||||||
|
class TencentSdkResp {
|
||||||
const TencentSdkResp({
|
const TencentSdkResp({
|
||||||
this.ret,
|
required this.ret,
|
||||||
this.msg,
|
this.msg,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
factory TencentSdkResp.fromJson(Map<String, dynamic> json) =>
|
||||||
|
_$TencentSdkRespFromJson(json);
|
||||||
|
|
||||||
/// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
/// 网络请求成功发送至服务器,并且服务器返回数据格式正确
|
||||||
/// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
/// 这里包括所请求业务操作失败的情况,例如没有授权等原因导致
|
||||||
static const int RET_SUCCESS = 0;
|
static const int RET_SUCCESS = 0;
|
||||||
@ -21,9 +30,11 @@ abstract class TencentSdkResp {
|
|||||||
defaultValue: RET_SUCCESS,
|
defaultValue: RET_SUCCESS,
|
||||||
)
|
)
|
||||||
final int ret;
|
final int ret;
|
||||||
final String msg;
|
final String? msg;
|
||||||
|
|
||||||
bool get isSuccessful => ret == RET_SUCCESS;
|
bool get isSuccessful => ret == RET_SUCCESS;
|
||||||
|
|
||||||
bool get isCancelled => ret == RET_USERCANCEL;
|
bool get isCancelled => ret == RET_USERCANCEL;
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson() => _$TencentSdkRespToJson(this);
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,19 @@
|
|||||||
// GENERATED CODE - DO NOT MODIFY BY HAND
|
// GENERATED CODE - DO NOT MODIFY BY HAND
|
||||||
|
|
||||||
part of 'tencent_share_resp.dart';
|
part of 'tencent_sdk_resp.dart';
|
||||||
|
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
// JsonSerializableGenerator
|
// JsonSerializableGenerator
|
||||||
// **************************************************************************
|
// **************************************************************************
|
||||||
|
|
||||||
TencentShareResp _$TencentShareRespFromJson(Map<String, dynamic> json) {
|
TencentSdkResp _$TencentSdkRespFromJson(Map<String, dynamic> json) {
|
||||||
return TencentShareResp(
|
return TencentSdkResp(
|
||||||
ret: json['ret'] as int ?? 0,
|
ret: json['ret'] as int? ?? 0,
|
||||||
msg: json['msg'] as String,
|
msg: json['msg'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Map<String, dynamic> _$TencentShareRespToJson(TencentShareResp instance) =>
|
Map<String, dynamic> _$TencentSdkRespToJson(TencentSdkResp instance) =>
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
'ret': instance.ret,
|
'ret': instance.ret,
|
||||||
'msg': instance.msg,
|
'msg': instance.msg,
|
@ -1,20 +0,0 @@
|
|||||||
import 'package:json_annotation/json_annotation.dart';
|
|
||||||
import 'package:tencent_kit/src/model/sdk/tencent_sdk_resp.dart';
|
|
||||||
|
|
||||||
part 'tencent_share_resp.g.dart';
|
|
||||||
|
|
||||||
@JsonSerializable(
|
|
||||||
explicitToJson: true,
|
|
||||||
fieldRename: FieldRename.snake,
|
|
||||||
)
|
|
||||||
class TencentShareResp extends TencentSdkResp {
|
|
||||||
const TencentShareResp({
|
|
||||||
int ret,
|
|
||||||
String msg,
|
|
||||||
}) : super(ret: ret, msg: msg);
|
|
||||||
|
|
||||||
factory TencentShareResp.fromJson(Map<String, dynamic> json) =>
|
|
||||||
_$TencentShareRespFromJson(json);
|
|
||||||
|
|
||||||
Map<String, dynamic> toJson() => _$TencentShareRespToJson(this);
|
|
||||||
}
|
|
@ -8,7 +8,7 @@ part 'tencent_unionid_resp.g.dart';
|
|||||||
)
|
)
|
||||||
class TencentUnionidResp {
|
class TencentUnionidResp {
|
||||||
const TencentUnionidResp({
|
const TencentUnionidResp({
|
||||||
this.error,
|
required this.error,
|
||||||
this.errorDescription,
|
this.errorDescription,
|
||||||
this.clientId,
|
this.clientId,
|
||||||
this.openid,
|
this.openid,
|
||||||
@ -22,10 +22,10 @@ class TencentUnionidResp {
|
|||||||
defaultValue: ERROR_SUCCESS,
|
defaultValue: ERROR_SUCCESS,
|
||||||
)
|
)
|
||||||
final int error;
|
final int error;
|
||||||
final String errorDescription;
|
final String? errorDescription;
|
||||||
final String clientId;
|
final String? clientId;
|
||||||
final String openid;
|
final String? openid;
|
||||||
final String unionid;
|
final String? unionid;
|
||||||
|
|
||||||
static const int ERROR_SUCCESS = 0;
|
static const int ERROR_SUCCESS = 0;
|
||||||
|
|
||||||
|
@ -8,11 +8,11 @@ part of 'tencent_unionid_resp.dart';
|
|||||||
|
|
||||||
TencentUnionidResp _$TencentUnionidRespFromJson(Map<String, dynamic> json) {
|
TencentUnionidResp _$TencentUnionidRespFromJson(Map<String, dynamic> json) {
|
||||||
return TencentUnionidResp(
|
return TencentUnionidResp(
|
||||||
error: json['error'] as int ?? 0,
|
error: json['error'] as int? ?? 0,
|
||||||
errorDescription: json['error_description'] as String,
|
errorDescription: json['error_description'] as String?,
|
||||||
clientId: json['client_id'] as String,
|
clientId: json['client_id'] as String?,
|
||||||
openid: json['openid'] as String,
|
openid: json['openid'] as String?,
|
||||||
unionid: json['unionid'] as String,
|
unionid: json['unionid'] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,20 +2,21 @@ import 'dart:async';
|
|||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
|
||||||
import 'package:flutter/foundation.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:tencent_kit/src/model/api/tencent_user_info_resp.dart';
|
import 'package:tencent_kit/src/model/api/tencent_user_info_resp.dart';
|
||||||
import 'package:tencent_kit/src/model/sdk/tencent_login_resp.dart';
|
import 'package:tencent_kit/src/model/sdk/tencent_login_resp.dart';
|
||||||
import 'package:tencent_kit/src/model/sdk/tencent_share_resp.dart';
|
import 'package:tencent_kit/src/model/sdk/tencent_sdk_resp.dart';
|
||||||
import 'package:tencent_kit/src/model/unionid/tencent_unionid_resp.dart';
|
import 'package:tencent_kit/src/model/unionid/tencent_unionid_resp.dart';
|
||||||
import 'package:tencent_kit/src/tencent_constant.dart';
|
import 'package:tencent_kit/src/tencent_constant.dart';
|
||||||
|
|
||||||
///
|
///
|
||||||
class Tencent {
|
class Tencent {
|
||||||
///
|
///
|
||||||
Tencent() {
|
Tencent._();
|
||||||
_channel.setMethodCallHandler(_handleMethod);
|
|
||||||
}
|
static Tencent get instance => _instance;
|
||||||
|
|
||||||
|
static final Tencent _instance = Tencent._();
|
||||||
|
|
||||||
static const String _METHOD_REGISTERAPP = 'registerApp';
|
static const String _METHOD_REGISTERAPP = 'registerApp';
|
||||||
static const String _METHOD_ISQQINSTALLED = 'isQQInstalled';
|
static const String _METHOD_ISQQINSTALLED = 'isQQInstalled';
|
||||||
@ -47,14 +48,15 @@ class Tencent {
|
|||||||
|
|
||||||
static const String _SCHEME_FILE = 'file';
|
static const String _SCHEME_FILE = 'file';
|
||||||
|
|
||||||
final MethodChannel _channel =
|
late final MethodChannel _channel =
|
||||||
const MethodChannel('v7lin.github.io/tencent_kit');
|
const MethodChannel('v7lin.github.io/tencent_kit')
|
||||||
|
..setMethodCallHandler(_handleMethod);
|
||||||
|
|
||||||
final StreamController<TencentLoginResp> _loginRespStreamController =
|
final StreamController<TencentLoginResp> _loginRespStreamController =
|
||||||
StreamController<TencentLoginResp>.broadcast();
|
StreamController<TencentLoginResp>.broadcast();
|
||||||
|
|
||||||
final StreamController<TencentShareResp> _shareRespStreamController =
|
final StreamController<TencentSdkResp> _shareRespStreamController =
|
||||||
StreamController<TencentShareResp>.broadcast();
|
StreamController<TencentSdkResp>.broadcast();
|
||||||
|
|
||||||
Future<dynamic> _handleMethod(MethodCall call) async {
|
Future<dynamic> _handleMethod(MethodCall call) async {
|
||||||
switch (call.method) {
|
switch (call.method) {
|
||||||
@ -63,7 +65,7 @@ class Tencent {
|
|||||||
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
|
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
|
||||||
break;
|
break;
|
||||||
case _METHOD_ONSHARERESP:
|
case _METHOD_ONSHARERESP:
|
||||||
_shareRespStreamController.add(TencentShareResp.fromJson(
|
_shareRespStreamController.add(TencentSdkResp.fromJson(
|
||||||
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
|
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>()));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -71,10 +73,9 @@ class Tencent {
|
|||||||
|
|
||||||
/// 向 Open_SDK 注册
|
/// 向 Open_SDK 注册
|
||||||
Future<void> registerApp({
|
Future<void> registerApp({
|
||||||
@required String appId,
|
required String appId,
|
||||||
String universalLink,
|
String? universalLink,
|
||||||
}) {
|
}) {
|
||||||
assert(appId?.isNotEmpty ?? false);
|
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_REGISTERAPP,
|
_METHOD_REGISTERAPP,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -91,25 +92,24 @@ class Tencent {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// 分享
|
/// 分享
|
||||||
Stream<TencentShareResp> shareResp() {
|
Stream<TencentSdkResp> shareResp() {
|
||||||
return _shareRespStreamController.stream;
|
return _shareRespStreamController.stream;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查QQ是否已安装
|
/// 检查QQ是否已安装
|
||||||
Future<bool> isQQInstalled() {
|
Future<bool> isQQInstalled() async {
|
||||||
return _channel.invokeMethod<bool>(_METHOD_ISQQINSTALLED);
|
return await _channel.invokeMethod<bool>(_METHOD_ISQQINSTALLED) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 检查QQ是否已安装
|
/// 检查QQ是否已安装
|
||||||
Future<bool> isTIMInstalled() {
|
Future<bool> isTIMInstalled() async {
|
||||||
return _channel.invokeMethod<bool>(_METHOD_ISTIMINSTALLED);
|
return await _channel.invokeMethod<bool>(_METHOD_ISTIMINSTALLED) ?? false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 登录
|
/// 登录
|
||||||
Future<void> login({
|
Future<void> login({
|
||||||
@required List<String> scope,
|
required List<String> scope,
|
||||||
}) {
|
}) {
|
||||||
assert(scope?.isNotEmpty ?? false);
|
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_LOGIN,
|
_METHOD_LOGIN,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -126,13 +126,10 @@ class Tencent {
|
|||||||
/// 用户信息
|
/// 用户信息
|
||||||
/// https://wiki.connect.qq.com/get_user_info
|
/// https://wiki.connect.qq.com/get_user_info
|
||||||
Future<TencentUserInfoResp> getUserInfo({
|
Future<TencentUserInfoResp> getUserInfo({
|
||||||
@required String appId,
|
required String appId,
|
||||||
@required String openid,
|
required String openid,
|
||||||
@required String accessToken,
|
required String accessToken,
|
||||||
}) {
|
}) {
|
||||||
assert(appId?.isNotEmpty ?? false);
|
|
||||||
assert(openid?.isNotEmpty ?? false);
|
|
||||||
assert(accessToken?.isNotEmpty ?? false);
|
|
||||||
return HttpClient()
|
return HttpClient()
|
||||||
.getUrl(Uri.parse(
|
.getUrl(Uri.parse(
|
||||||
'https://graph.qq.com/user/get_user_info?access_token=$accessToken&oauth_consumer_key=$appId&openid=$openid'))
|
'https://graph.qq.com/user/get_user_info?access_token=$accessToken&oauth_consumer_key=$appId&openid=$openid'))
|
||||||
@ -140,9 +137,10 @@ class Tencent {
|
|||||||
return request.close();
|
return request.close();
|
||||||
}).then((HttpClientResponse response) async {
|
}).then((HttpClientResponse response) async {
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
ContentType contentType = response.headers.contentType;
|
final ContentType? contentType = response.headers.contentType;
|
||||||
Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8;
|
final Encoding encoding =
|
||||||
String content = await encoding.decodeStream(response);
|
Encoding.getByName(contentType?.charset) ?? utf8;
|
||||||
|
final String content = await encoding.decodeStream(response);
|
||||||
return TencentUserInfoResp.fromJson(
|
return TencentUserInfoResp.fromJson(
|
||||||
json.decode(content) as Map<String, dynamic>);
|
json.decode(content) as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
@ -154,10 +152,9 @@ class Tencent {
|
|||||||
/// UnionID
|
/// UnionID
|
||||||
/// https://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
|
/// https://wiki.connect.qq.com/unionid%E4%BB%8B%E7%BB%8D
|
||||||
Future<TencentUnionidResp> getUnionId({
|
Future<TencentUnionidResp> getUnionId({
|
||||||
@required String accessToken,
|
required String accessToken,
|
||||||
String unionid = '1',
|
String unionid = '1',
|
||||||
}) {
|
}) {
|
||||||
assert(accessToken?.isNotEmpty ?? false);
|
|
||||||
return HttpClient()
|
return HttpClient()
|
||||||
.getUrl(Uri.parse(
|
.getUrl(Uri.parse(
|
||||||
'https://graph.qq.com/oauth2.0/me?access_token=$accessToken&unionid=$unionid'))
|
'https://graph.qq.com/oauth2.0/me?access_token=$accessToken&unionid=$unionid'))
|
||||||
@ -165,18 +162,21 @@ class Tencent {
|
|||||||
return request.close();
|
return request.close();
|
||||||
}).then((HttpClientResponse response) async {
|
}).then((HttpClientResponse response) async {
|
||||||
if (response.statusCode == HttpStatus.ok) {
|
if (response.statusCode == HttpStatus.ok) {
|
||||||
ContentType contentType = response.headers.contentType;
|
final ContentType? contentType = response.headers.contentType;
|
||||||
Encoding encoding = Encoding.getByName(contentType?.charset) ?? utf8;
|
final Encoding encoding =
|
||||||
String callback = await encoding.decodeStream(response);
|
Encoding.getByName(contentType?.charset) ?? utf8;
|
||||||
|
final String callback = await encoding.decodeStream(response);
|
||||||
// 腾讯有毒 callback( $json );
|
// 腾讯有毒 callback( $json );
|
||||||
RegExp exp = RegExp(r'callback\( (.*) \)\;');
|
final RegExp exp = RegExp(r'callback\( (.*) \)\;');
|
||||||
Match match = exp.firstMatch(callback);
|
final Match? match = exp.firstMatch(callback);
|
||||||
if (match.groupCount == 1) {
|
if (match?.groupCount == 1) {
|
||||||
String content = match.group(1);
|
final String? content = match!.group(1);
|
||||||
|
if (content != null) {
|
||||||
return TencentUnionidResp.fromJson(
|
return TencentUnionidResp.fromJson(
|
||||||
json.decode(content) as Map<String, dynamic>);
|
json.decode(content) as Map<String, dynamic>);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
throw HttpException(
|
throw HttpException(
|
||||||
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
'HttpResponse statusCode: ${response.statusCode}, reasonPhrase: ${response.reasonPhrase}.');
|
||||||
});
|
});
|
||||||
@ -184,18 +184,17 @@ class Tencent {
|
|||||||
|
|
||||||
/// 分享 - 说说
|
/// 分享 - 说说
|
||||||
Future<void> shareMood({
|
Future<void> shareMood({
|
||||||
@required int scene,
|
required int scene,
|
||||||
String summary,
|
String? summary,
|
||||||
List<Uri> imageUris,
|
List<Uri>? imageUris,
|
||||||
Uri videoUri,
|
Uri? videoUri,
|
||||||
}) {
|
}) {
|
||||||
assert(scene == TencentScene.SCENE_QZONE);
|
assert(scene == TencentScene.SCENE_QZONE);
|
||||||
assert((summary?.isNotEmpty ?? false) ||
|
assert((summary?.isNotEmpty ?? false) ||
|
||||||
(imageUris?.isNotEmpty ?? false) ||
|
|
||||||
(videoUri != null && videoUri.isScheme(_SCHEME_FILE)) ||
|
|
||||||
((imageUris?.isNotEmpty ?? false) &&
|
((imageUris?.isNotEmpty ?? false) &&
|
||||||
imageUris.every((Uri element) =>
|
imageUris!
|
||||||
element != null && element.isScheme(_SCHEME_FILE))));
|
.every((Uri element) => element.isScheme(_SCHEME_FILE))) ||
|
||||||
|
(videoUri != null && videoUri.isScheme(_SCHEME_FILE)));
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_SHAREMOOD,
|
_METHOD_SHAREMOOD,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -203,7 +202,7 @@ class Tencent {
|
|||||||
if (summary?.isNotEmpty ?? false) _ARGUMENT_KEY_SUMMARY: summary,
|
if (summary?.isNotEmpty ?? false) _ARGUMENT_KEY_SUMMARY: summary,
|
||||||
if (imageUris?.isNotEmpty ?? false)
|
if (imageUris?.isNotEmpty ?? false)
|
||||||
_ARGUMENT_KEY_IMAGEURIS:
|
_ARGUMENT_KEY_IMAGEURIS:
|
||||||
imageUris.map((Uri imageUri) => imageUri.toString()).toList(),
|
imageUris!.map((Uri imageUri) => imageUri.toString()).toList(),
|
||||||
if (videoUri != null) _ARGUMENT_KEY_VIDEOURI: videoUri.toString(),
|
if (videoUri != null) _ARGUMENT_KEY_VIDEOURI: videoUri.toString(),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
@ -211,11 +210,10 @@ class Tencent {
|
|||||||
|
|
||||||
/// 分享 - 文本(Android调用的是系统API,故而不会有回调)
|
/// 分享 - 文本(Android调用的是系统API,故而不会有回调)
|
||||||
Future<void> shareText({
|
Future<void> shareText({
|
||||||
@required int scene,
|
required int scene,
|
||||||
@required String summary,
|
required String summary,
|
||||||
}) {
|
}) {
|
||||||
assert(scene == TencentScene.SCENE_QQ);
|
assert(scene == TencentScene.SCENE_QQ);
|
||||||
assert(summary?.isNotEmpty ?? false);
|
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_SHARETEXT,
|
_METHOD_SHARETEXT,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -227,13 +225,13 @@ class Tencent {
|
|||||||
|
|
||||||
/// 分享 - 图片
|
/// 分享 - 图片
|
||||||
Future<void> shareImage({
|
Future<void> shareImage({
|
||||||
@required int scene,
|
required int scene,
|
||||||
@required Uri imageUri,
|
required Uri imageUri,
|
||||||
String appName,
|
String? appName,
|
||||||
int extInt = TencentQZoneFlag.DEFAULT,
|
int extInt = TencentQZoneFlag.DEFAULT,
|
||||||
}) {
|
}) {
|
||||||
assert(scene == TencentScene.SCENE_QQ);
|
assert(scene == TencentScene.SCENE_QQ);
|
||||||
assert(imageUri != null && imageUri.isScheme(_SCHEME_FILE));
|
assert(imageUri.isScheme(_SCHEME_FILE));
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_SHAREIMAGE,
|
_METHOD_SHAREIMAGE,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -247,19 +245,16 @@ class Tencent {
|
|||||||
|
|
||||||
/// 分享 - 音乐
|
/// 分享 - 音乐
|
||||||
Future<void> shareMusic({
|
Future<void> shareMusic({
|
||||||
@required int scene,
|
required int scene,
|
||||||
@required String title,
|
required String title,
|
||||||
String summary,
|
String? summary,
|
||||||
Uri imageUri,
|
Uri? imageUri,
|
||||||
@required String musicUrl,
|
required String musicUrl,
|
||||||
@required String targetUrl,
|
required String targetUrl,
|
||||||
String appName,
|
String? appName,
|
||||||
int extInt = TencentQZoneFlag.DEFAULT,
|
int extInt = TencentQZoneFlag.DEFAULT,
|
||||||
}) {
|
}) {
|
||||||
assert(scene == TencentScene.SCENE_QQ);
|
assert(scene == TencentScene.SCENE_QQ);
|
||||||
assert(title?.isNotEmpty ?? false);
|
|
||||||
assert(musicUrl?.isNotEmpty ?? false);
|
|
||||||
assert(targetUrl?.isNotEmpty ?? false);
|
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_SHAREMUSIC,
|
_METHOD_SHAREMUSIC,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
@ -277,16 +272,14 @@ class Tencent {
|
|||||||
|
|
||||||
/// 分享 - 网页
|
/// 分享 - 网页
|
||||||
Future<void> shareWebpage({
|
Future<void> shareWebpage({
|
||||||
@required int scene,
|
required int scene,
|
||||||
@required String title,
|
required String title,
|
||||||
String summary,
|
String? summary,
|
||||||
Uri imageUri,
|
Uri? imageUri,
|
||||||
@required String targetUrl,
|
required String targetUrl,
|
||||||
String appName,
|
String? appName,
|
||||||
int extInt = TencentQZoneFlag.DEFAULT,
|
int extInt = TencentQZoneFlag.DEFAULT,
|
||||||
}) {
|
}) {
|
||||||
assert(title?.isNotEmpty ?? false);
|
|
||||||
assert(targetUrl?.isNotEmpty ?? false);
|
|
||||||
return _channel.invokeMethod<void>(
|
return _channel.invokeMethod<void>(
|
||||||
_METHOD_SHAREWEBPAGE,
|
_METHOD_SHAREWEBPAGE,
|
||||||
<String, dynamic>{
|
<String, dynamic>{
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
class TencentScope {
|
class TencentScope {
|
||||||
TencentScope._();
|
const TencentScope._();
|
||||||
|
|
||||||
/// 发表一条说说到QQ空间(需要申请权限)
|
/// 发表一条说说到QQ空间(需要申请权限)
|
||||||
static const String OPEN_PERMISSION_ADD_TOPIC = 'add_topic';
|
static const String OPEN_PERMISSION_ADD_TOPIC = 'add_topic';
|
||||||
@ -45,7 +45,7 @@ class TencentScope {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TencentScene {
|
class TencentScene {
|
||||||
TencentScene._();
|
const TencentScene._();
|
||||||
|
|
||||||
/// QQ
|
/// QQ
|
||||||
static const int SCENE_QQ = 0;
|
static const int SCENE_QQ = 0;
|
||||||
@ -55,7 +55,7 @@ class TencentScene {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class TencentQZoneFlag {
|
class TencentQZoneFlag {
|
||||||
TencentQZoneFlag._();
|
const TencentQZoneFlag._();
|
||||||
|
|
||||||
/// 默认是不隐藏分享到QZone按钮且不自动打开分享到QZone的对话框
|
/// 默认是不隐藏分享到QZone按钮且不自动打开分享到QZone的对话框
|
||||||
static const int DEFAULT = 0;
|
static const int DEFAULT = 0;
|
||||||
|
@ -4,7 +4,6 @@ export 'src/model/api/tencent_api_resp.dart';
|
|||||||
export 'src/model/api/tencent_user_info_resp.dart';
|
export 'src/model/api/tencent_user_info_resp.dart';
|
||||||
export 'src/model/sdk/tencent_login_resp.dart';
|
export 'src/model/sdk/tencent_login_resp.dart';
|
||||||
export 'src/model/sdk/tencent_sdk_resp.dart';
|
export 'src/model/sdk/tencent_sdk_resp.dart';
|
||||||
export 'src/model/sdk/tencent_share_resp.dart';
|
|
||||||
export 'src/model/unionid/tencent_unionid_resp.dart';
|
export 'src/model/unionid/tencent_unionid_resp.dart';
|
||||||
export 'src/tencent.dart';
|
export 'src/tencent.dart';
|
||||||
export 'src/tencent_constant.dart';
|
export 'src/tencent_constant.dart';
|
||||||
|
238
pubspec.lock
238
pubspec.lock
@ -7,189 +7,182 @@ packages:
|
|||||||
name: _fe_analyzer_shared
|
name: _fe_analyzer_shared
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "14.0.0"
|
version: "18.0.0"
|
||||||
analyzer:
|
analyzer:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: analyzer
|
name: analyzer
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.41.2"
|
version: "1.2.0"
|
||||||
args:
|
args:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: args
|
name: args
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.0"
|
version: "2.0.0"
|
||||||
async:
|
async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: async
|
name: async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.5.0-nullsafety.1"
|
version: "2.5.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: boolean_selector
|
name: boolean_selector
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.1"
|
version: "2.1.0"
|
||||||
build:
|
build:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build
|
name: build
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.6.1"
|
version: "2.0.0"
|
||||||
build_config:
|
build_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_config
|
name: build_config
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.4.5"
|
version: "0.4.7"
|
||||||
build_daemon:
|
build_daemon:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_daemon
|
name: build_daemon
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.6"
|
version: "2.1.10"
|
||||||
build_resolvers:
|
build_resolvers:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_resolvers
|
name: build_resolvers
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.5.2"
|
version: "2.0.0"
|
||||||
build_runner:
|
build_runner:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: build_runner
|
name: build_runner
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.11.0"
|
version: "1.12.2"
|
||||||
build_runner_core:
|
build_runner_core:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: build_runner_core
|
name: build_runner_core
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "6.1.6"
|
version: "6.1.12"
|
||||||
built_collection:
|
built_collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_collection
|
name: built_collection
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.3.2"
|
version: "5.0.0"
|
||||||
built_value:
|
built_value:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: built_value
|
name: built_value
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "7.1.0"
|
version: "8.0.3"
|
||||||
characters:
|
characters:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: characters
|
name: characters
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.3"
|
version: "1.1.0"
|
||||||
charcode:
|
charcode:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: charcode
|
name: charcode
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
checked_yaml:
|
checked_yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: checked_yaml
|
name: checked_yaml
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.0.4"
|
version: "2.0.1"
|
||||||
cli_util:
|
cli_util:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: cli_util
|
name: cli_util
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "0.3.0"
|
||||||
clock:
|
clock:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: clock
|
name: clock
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.1"
|
version: "1.1.0"
|
||||||
code_builder:
|
code_builder:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: code_builder
|
name: code_builder
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.6.0"
|
version: "3.7.0"
|
||||||
collection:
|
collection:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: collection
|
name: collection
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.15.0-nullsafety.3"
|
version: "1.15.0"
|
||||||
convert:
|
convert:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: convert
|
name: convert
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.1"
|
version: "3.0.0"
|
||||||
crypto:
|
crypto:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: crypto
|
name: crypto
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.5"
|
version: "3.0.0"
|
||||||
dart_style:
|
dart_style:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: dart_style
|
name: dart_style
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.11"
|
version: "1.3.14"
|
||||||
fake_async:
|
fake_async:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fake_async
|
name: fake_async
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
ffi:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: ffi
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.3"
|
|
||||||
file:
|
file:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: file
|
name: file
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "5.2.1"
|
version: "6.1.0"
|
||||||
fixnum:
|
fixnum:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: fixnum
|
name: fixnum
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.10.11"
|
version: "1.0.0"
|
||||||
flutter:
|
flutter:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -206,231 +199,140 @@ packages:
|
|||||||
name: glob
|
name: glob
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "2.0.0"
|
||||||
graphs:
|
graphs:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: graphs
|
name: graphs
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.0"
|
version: "1.0.0"
|
||||||
http_multi_server:
|
http_multi_server:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_multi_server
|
name: http_multi_server
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.0"
|
version: "3.0.0"
|
||||||
http_parser:
|
http_parser:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: http_parser
|
name: http_parser
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.4"
|
version: "4.0.0"
|
||||||
intl:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: intl
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.16.1"
|
|
||||||
io:
|
io:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: io
|
name: io
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.4"
|
version: "1.0.0"
|
||||||
js:
|
js:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: js
|
name: js
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.6.2"
|
version: "0.6.3"
|
||||||
json_annotation:
|
json_annotation:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
name: json_annotation
|
name: json_annotation
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.1.1"
|
version: "4.0.0"
|
||||||
json_serializable:
|
json_serializable:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: json_serializable
|
name: json_serializable
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "3.5.1"
|
version: "4.0.3"
|
||||||
logging:
|
logging:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: logging
|
name: logging
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.11.4"
|
version: "1.0.0"
|
||||||
matcher:
|
matcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: matcher
|
name: matcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.12.10-nullsafety.1"
|
version: "0.12.10"
|
||||||
meta:
|
meta:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: meta
|
name: meta
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.3"
|
version: "1.3.0"
|
||||||
mime:
|
mime:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: mime
|
name: mime
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.7"
|
version: "1.0.0"
|
||||||
node_interop:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: node_interop
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.1"
|
|
||||||
node_io:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: node_io
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.2.0"
|
|
||||||
okhttp_kit:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: okhttp_kit
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.2"
|
|
||||||
package_config:
|
package_config:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: package_config
|
name: package_config
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.3"
|
version: "2.0.0"
|
||||||
path:
|
path:
|
||||||
dependency: "direct dev"
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: path
|
name: path
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety.1"
|
version: "1.8.0"
|
||||||
path_provider:
|
|
||||||
dependency: "direct dev"
|
|
||||||
description:
|
|
||||||
name: path_provider
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.6.27"
|
|
||||||
path_provider_linux:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_provider_linux
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.1+2"
|
|
||||||
path_provider_macos:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_provider_macos
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.4+8"
|
|
||||||
path_provider_platform_interface:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_provider_platform_interface
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.0.4"
|
|
||||||
path_provider_windows:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: path_provider_windows
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.0.4+3"
|
|
||||||
pedantic:
|
pedantic:
|
||||||
dependency: "direct dev"
|
dependency: "direct dev"
|
||||||
description:
|
description:
|
||||||
name: pedantic
|
name: pedantic
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.9.2"
|
version: "1.11.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.3"
|
|
||||||
pool:
|
pool:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pool
|
name: pool
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.0"
|
version: "1.5.0"
|
||||||
process:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: process
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "3.0.13"
|
|
||||||
pub_semver:
|
pub_semver:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pub_semver
|
name: pub_semver
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.4.4"
|
version: "2.0.0"
|
||||||
pubspec_parse:
|
pubspec_parse:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: pubspec_parse
|
name: pubspec_parse
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.7"
|
version: "1.0.0"
|
||||||
quiver:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: quiver
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "2.1.5"
|
|
||||||
shelf:
|
shelf:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf
|
name: shelf
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.7.9"
|
version: "1.1.0"
|
||||||
shelf_web_socket:
|
shelf_web_socket:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: shelf_web_socket
|
name: shelf_web_socket
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.4"
|
version: "1.0.1"
|
||||||
sky_engine:
|
sky_engine:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description: flutter
|
description: flutter
|
||||||
@ -442,112 +344,98 @@ packages:
|
|||||||
name: source_gen
|
name: source_gen
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.10+1"
|
version: "0.9.10+4"
|
||||||
source_span:
|
source_span:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.0-nullsafety.2"
|
version: "1.8.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stack_trace
|
name: stack_trace
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.10.0-nullsafety.1"
|
version: "1.10.0"
|
||||||
stream_channel:
|
stream_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_channel
|
name: stream_channel
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.1"
|
version: "2.1.0"
|
||||||
stream_transform:
|
stream_transform:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: stream_transform
|
name: stream_transform
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "2.0.0"
|
||||||
string_scanner:
|
string_scanner:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: string_scanner
|
name: string_scanner
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.1.0-nullsafety.1"
|
version: "1.1.0"
|
||||||
term_glyph:
|
term_glyph:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: term_glyph
|
name: term_glyph
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0-nullsafety.1"
|
version: "1.2.0"
|
||||||
test_api:
|
test_api:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.19-nullsafety.2"
|
version: "0.2.19"
|
||||||
timing:
|
timing:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: timing
|
name: timing
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.1.1+3"
|
version: "1.0.0"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: typed_data
|
name: typed_data
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.3.0-nullsafety.3"
|
version: "1.3.0"
|
||||||
vector_math:
|
vector_math:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: vector_math
|
name: vector_math
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.1.0-nullsafety.3"
|
version: "2.1.0"
|
||||||
watcher:
|
watcher:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: watcher
|
name: watcher
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.9.7+15"
|
version: "1.0.0"
|
||||||
web_socket_channel:
|
web_socket_channel:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: web_socket_channel
|
name: web_socket_channel
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.2.0"
|
version: "2.0.0"
|
||||||
win32:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: win32
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "1.7.4+1"
|
|
||||||
xdg_directories:
|
|
||||||
dependency: transitive
|
|
||||||
description:
|
|
||||||
name: xdg_directories
|
|
||||||
url: "https://pub.flutter-io.cn"
|
|
||||||
source: hosted
|
|
||||||
version: "0.1.2"
|
|
||||||
yaml:
|
yaml:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
name: yaml
|
name: yaml
|
||||||
url: "https://pub.flutter-io.cn"
|
url: "https://pub.flutter-io.cn"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.2.1"
|
version: "3.1.0"
|
||||||
sdks:
|
sdks:
|
||||||
dart: ">=2.10.0 <2.11.0"
|
dart: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.12.13+hotfix.5 <2.0.0"
|
flutter: ">=1.20.0"
|
||||||
|
13
pubspec.yaml
13
pubspec.yaml
@ -1,28 +1,23 @@
|
|||||||
name: tencent_kit
|
name: tencent_kit
|
||||||
description: A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
description: A powerful Flutter plugin allowing developers to auth/share with natvie Android & iOS Tencent SDKs.
|
||||||
version: 2.0.1
|
version: 2.1.0
|
||||||
# author: v7lin <v7lin@qq.com>
|
# author: v7lin <v7lin@qq.com>
|
||||||
homepage: https://github.com/v7lin/fake_tencent
|
homepage: https://github.com/v7lin/fake_tencent
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
flutter: ">=1.10.0"
|
flutter: ">=1.20.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
json_annotation: '>=2.0.0 <4.0.0'
|
json_annotation: ^4.0.0
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
path: ^1.6.4
|
|
||||||
path_provider: ^1.4.0
|
|
||||||
|
|
||||||
okhttp_kit: ^1.0.0
|
|
||||||
|
|
||||||
pedantic:
|
pedantic:
|
||||||
|
|
||||||
build_runner:
|
build_runner:
|
||||||
|
@ -10,7 +10,6 @@ void main() {
|
|||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
const MethodChannel channel = MethodChannel('v7lin.github.io/tencent_kit');
|
const MethodChannel channel = MethodChannel('v7lin.github.io/tencent_kit');
|
||||||
final Tencent tencent = Tencent();
|
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
channel.setMockMethodCallHandler((MethodCall call) async {
|
channel.setMockMethodCallHandler((MethodCall call) async {
|
||||||
@ -26,7 +25,7 @@ void main() {
|
|||||||
channel.name,
|
channel.name,
|
||||||
channel.codec.encodeMethodCall(
|
channel.codec.encodeMethodCall(
|
||||||
MethodCall('onLoginResp', json.decode('{"ret":-2}'))),
|
MethodCall('onLoginResp', json.decode('{"ret":-2}'))),
|
||||||
(ByteData data) {
|
(ByteData? data) {
|
||||||
// mock success
|
// mock success
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@ -42,7 +41,7 @@ void main() {
|
|||||||
channel.name,
|
channel.name,
|
||||||
channel.codec.encodeMethodCall(
|
channel.codec.encodeMethodCall(
|
||||||
MethodCall('onShareResp', json.decode('{"ret":0}'))),
|
MethodCall('onShareResp', json.decode('{"ret":0}'))),
|
||||||
(ByteData data) {
|
(ByteData? data) {
|
||||||
// mock success
|
// mock success
|
||||||
},
|
},
|
||||||
));
|
));
|
||||||
@ -57,30 +56,30 @@ void main() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test('isQQInstalled', () async {
|
test('isQQInstalled', () async {
|
||||||
expect(await tencent.isQQInstalled(), true);
|
expect(await Tencent.instance.isQQInstalled(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('isTIMInstalled', () async {
|
test('isTIMInstalled', () async {
|
||||||
expect(await tencent.isTIMInstalled(), true);
|
expect(await Tencent.instance.isTIMInstalled(), true);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('login', () async {
|
test('login', () async {
|
||||||
StreamSubscription<TencentLoginResp> sub =
|
final StreamSubscription<TencentLoginResp> sub =
|
||||||
tencent.loginResp().listen((TencentLoginResp resp) {
|
Tencent.instance.loginResp().listen((TencentLoginResp resp) {
|
||||||
expect(resp.ret, TencentSdkResp.RET_USERCANCEL);
|
expect(resp.ret, TencentSdkResp.RET_USERCANCEL);
|
||||||
});
|
});
|
||||||
await tencent.login(
|
await Tencent.instance.login(
|
||||||
scope: <String>[TencentScope.GET_SIMPLE_USERINFO],
|
scope: <String>[TencentScope.GET_SIMPLE_USERINFO],
|
||||||
);
|
);
|
||||||
await sub.cancel();
|
await sub.cancel();
|
||||||
});
|
});
|
||||||
|
|
||||||
test('share', () async {
|
test('share', () async {
|
||||||
StreamSubscription<TencentShareResp> sub =
|
final StreamSubscription<TencentSdkResp> sub =
|
||||||
tencent.shareResp().listen((TencentShareResp resp) {
|
Tencent.instance.shareResp().listen((TencentSdkResp resp) {
|
||||||
expect(resp.ret, TencentSdkResp.RET_SUCCESS);
|
expect(resp.ret, TencentSdkResp.RET_SUCCESS);
|
||||||
});
|
});
|
||||||
await tencent.shareMood(
|
await Tencent.instance.shareMood(
|
||||||
scene: TencentScene.SCENE_QZONE,
|
scene: TencentScene.SCENE_QZONE,
|
||||||
summary: 'share text',
|
summary: 'share text',
|
||||||
);
|
);
|
||||||
|
Reference in New Issue
Block a user