升级Flutter 3.0

This commit is contained in:
v7lin
2022-05-17 16:24:05 +08:00
parent e91670fef1
commit 51d09fcea7
56 changed files with 2426 additions and 1454 deletions

12
.github/FUNDING.yml vendored
View File

@ -1,12 +0,0 @@
# These are supported funding model platforms
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: https://v7lin.github.io/docsify/#/navbar/sponsor # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']

View File

@ -10,10 +10,12 @@ jobs:
matrix:
os: [macos-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
java-version: '8.x'
distribution: 'temurin'
java-version: '11'
cache: 'gradle'
- uses: subosito/flutter-action@v1
with:
channel: 'stable'
@ -32,10 +34,12 @@ jobs:
matrix:
os: [ubuntu-latest]
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
- uses: actions/checkout@v2
- uses: actions/setup-java@v2
with:
java-version: '8.x'
distribution: 'temurin'
java-version: '11'
cache: 'gradle'
- uses: subosito/flutter-action@v1
with:
channel: 'stable'
@ -45,5 +49,5 @@ jobs:
- run: flutter format --dry-run --set-exit-if-changed .
- run: flutter pub publish --dry-run
- run: flutter analyze lib example/lib
- run: sudo echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager "ndk;20.0.5594570"
- run: sudo echo "y" | sudo $ANDROID_HOME/tools/bin/sdkmanager "ndk;21.1.6352462"
- run: cd example; flutter build apk --debug

View File

@ -9,8 +9,8 @@ jobs:
name: Publish
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: sakebook/actions-flutter-pub-publisher@v1.3.0
- uses: actions/checkout@v2
- uses: sakebook/actions-flutter-pub-publisher@v1.4.0
with:
credential: ${{ secrets.CREDENTIAL_JSON }}
flutter_package: true

View File

@ -7,8 +7,8 @@ jobs:
name: Publish Manually
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: sakebook/actions-flutter-pub-publisher@v1.3.0
- uses: actions/checkout@v2
- uses: sakebook/actions-flutter-pub-publisher@v1.4.0
with:
credential: ${{ secrets.CREDENTIAL_JSON }}
flutter_package: true

53
.gitignore vendored
View File

@ -8,6 +8,7 @@
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
@ -21,57 +22,9 @@
#.vscode/
# Flutter/Dart/Pub related
# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
/pubspec.lock
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
build/
# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java
# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Flutter.podspec
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/Flutter/flutter_export_environment.sh
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
*.lock
.env

View File

@ -1,10 +1,33 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
# This file should be version controlled.
version:
revision: b041144f833e05cf463b8887fa12efdec9493488
revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
channel: stable
project_type: plugin
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- platform: android
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
- platform: ios
create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@ -1,3 +1,8 @@
## 4.0.0
* Flutter 3.0
* break change:
## 3.2.0
* pay no_pay

View File

@ -5,38 +5,42 @@
#
# For a list of lints, see: http://dart-lang.github.io/linter/lints/
# See the configuration guide for more
# https://github.com/dart-lang/sdk/tree/master/pkg/analyzer#configuring-the-analyzer
# https://github.com/dart-lang/sdk/tree/main/pkg/analyzer#configuring-the-analyzer
#
# There are other similar analysis options files in the flutter repos,
# which should be kept in sync with this file:
#
# - analysis_options.yaml (this file)
# - packages/flutter/lib/analysis_options_user.yaml
# - https://github.com/flutter/plugins/blob/master/analysis_options.yaml
# - https://github.com/flutter/engine/blob/master/analysis_options.yaml
# - https://github.com/flutter/packages/blob/master/analysis_options.yaml
#
# This file contains the analysis options used by Flutter tools, such as IntelliJ,
# Android Studio, and the `flutter analyze` command.
analyzer:
strong-mode:
implicit-casts: false
implicit-dynamic: false
language:
strict-raw-types: true
errors:
# treat missing required parameters as a warning (not a hint)
missing_required_param: warning
# treat missing returns as a warning (not a hint)
missing_return: warning
# allow having TODOs in the code
# allow having TODO comments in the code
todo: ignore
# allow self-reference to deprecated members (we do this because otherwise we have
# to annotate every member in every test, assert, etc, when we deprecate something)
deprecated_member_use_from_same_package: ignore
# Ignore analyzer hints for updating pubspecs when using Future or
# Stream and not importing dart:async
# Please see https://github.com/flutter/flutter/pull/24528 for details.
sdk_version_async_exported_from_core: ignore
# TODO(ianh): https://github.com/flutter/flutter/issues/74381
# Clean up existing unnecessary imports, and remove line to ignore.
unnecessary_import: ignore
# Turned off until null-safe rollout is complete.
unnecessary_null_comparison: ignore
exclude:
- "bin/cache/**"
# Ignore protoc generated files
- "dev/conductor/lib/proto/*"
#
- "lib/*.g.dart"
- "lib/**/*.g.dart"
@ -50,65 +54,71 @@ linter:
# - always_put_required_named_parameters_first # we prefer having parameters in the same order as fields https://github.com/flutter/flutter/issues/10219
- always_require_non_null_named_parameters
- always_specify_types
- always_use_package_imports # we do this commonly
# - always_use_package_imports # we do this commonly
- annotate_overrides
# - avoid_annotating_with_dynamic # conflicts with always_specify_types
# - avoid_as # required for implicit-casts: true
- avoid_bool_literals_in_conditional_expressions
# - avoid_catches_without_on_clauses # we do this commonly
# - avoid_catching_errors # we do this commonly
# - avoid_catches_without_on_clauses # blocked on https://github.com/dart-lang/linter/issues/3023
# - avoid_catching_errors # blocked on https://github.com/dart-lang/linter/issues/3023
- avoid_classes_with_only_static_members
# - avoid_double_and_int_checks # only useful when targeting JS runtime
- avoid_double_and_int_checks
- avoid_dynamic_calls
- avoid_empty_else
- avoid_equals_and_hash_code_on_mutable_classes
# - avoid_escaping_inner_quotes # not yet tested
- avoid_escaping_inner_quotes
- avoid_field_initializers_in_const_classes
# - avoid_final_parameters # incompatible with prefer_final_parameters
- avoid_function_literals_in_foreach_calls
# - avoid_implementing_value_types # not yet tested
- avoid_implementing_value_types
- avoid_init_to_null
# - avoid_js_rounded_ints # only useful when targeting JS runtime
- avoid_js_rounded_ints
# - avoid_multiple_declarations_per_line # seems to be a stylistic choice we don't subscribe to
- avoid_null_checks_in_equality_operators
# - avoid_positional_boolean_parameters # not yet tested
# - avoid_print # not yet tested
# - avoid_positional_boolean_parameters # would have been nice to enable this but by now there's too many places that break it
- avoid_print
# - avoid_private_typedef_functions # we prefer having typedef (discussion in https://github.com/flutter/flutter/pull/16356)
# - avoid_redundant_argument_values # not yet tested
- avoid_redundant_argument_values
- avoid_relative_lib_imports
- avoid_renaming_method_parameters
- avoid_return_types_on_setters
# - avoid_returning_null # there are plenty of valid reasons to return null
# - avoid_returning_null_for_future # not yet tested
# - avoid_returning_null # still violated by some pre-nnbd code that we haven't yet migrated
- avoid_returning_null_for_future
- avoid_returning_null_for_void
# - avoid_returning_this # there are plenty of valid reasons to return this
# - avoid_setters_without_getters # not yet tested
# - avoid_returning_this # there are enough valid reasons to return `this` that this lint ends up with too many false positives
- avoid_setters_without_getters
- avoid_shadowing_type_parameters
- avoid_single_cascade_in_expression_statements
- avoid_slow_async_io
# - avoid_type_to_string # we do this commonly
- avoid_type_to_string
- avoid_types_as_parameter_names
# - avoid_types_on_closure_parameters # conflicts with always_specify_types
# - avoid_unnecessary_containers # not yet tested
- avoid_unnecessary_containers
- avoid_unused_constructor_parameters
- avoid_void_async
# - avoid_web_libraries_in_flutter # not yet tested
# - avoid_web_libraries_in_flutter # we use web libraries in web-specific code, and our tests prevent us from using them elsewhere
- await_only_futures
- camel_case_extensions
- camel_case_types
- cancel_subscriptions
# - cascade_invocations # not yet tested
# - cascade_invocations # doesn't match the typical style of this repo
- cast_nullable_to_non_nullable
# - close_sinks # not reliable enough
# - comment_references # blocked on https://github.com/flutter/flutter/issues/20765
# - comment_references # blocked on https://github.com/dart-lang/linter/issues/1142
# - conditional_uri_does_not_exist # not yet tested
# - constant_identifier_names # needs an opt-out https://github.com/dart-lang/linter/issues/204
- control_flow_in_finally
# - curly_braces_in_flow_control_structures # not required by flutter style
# - diagnostic_describe_all_properties # not yet tested
- depend_on_referenced_packages
- deprecated_consistency
# - diagnostic_describe_all_properties # enabled only at the framework level (packages/flutter/lib)
- directives_ordering
# - do_not_use_environment # we do this commonly
# - do_not_use_environment # there are appropriate times to use the environment, especially in our tests and build logic
- empty_catches
- empty_constructor_bodies
- empty_statements
- eol_at_end_of_file
- exhaustive_cases
- file_names # not yet tested
- file_names
- flutter_style_todos
- hash_and_equals
- implementation_imports
@ -118,24 +128,28 @@ linter:
- leading_newlines_in_multiline_strings
- library_names
- library_prefixes
- library_private_types_in_public_api
# - lines_longer_than_80_chars # not required by flutter style
- list_remove_unrelated_type
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/sdk/issues/34181
# - missing_whitespace_between_adjacent_strings # not yet tested
# - literal_only_boolean_expressions # too many false positives: https://github.com/dart-lang/linter/issues/453
- missing_whitespace_between_adjacent_strings
- no_adjacent_strings_in_list
# - no_default_cases # too many false positives
- no_default_cases
- no_duplicate_case_values
- no_leading_underscores_for_library_prefixes
- no_leading_underscores_for_local_identifiers
- no_logic_in_create_state
# - no_runtimeType_toString # ok in tests; we enable this only in packages/
- non_constant_identifier_names
- noop_primitive_operations
- null_check_on_nullable_type_parameter
# - null_closures # not required by flutter style
- null_closures
# - omit_local_variable_types # opposite of always_specify_types
# - one_member_abstracts # too many false positives
# - only_throw_errors # https://github.com/flutter/flutter/issues/5792
- only_throw_errors # this does get disabled in a few places where we have legacy code that uses strings et al
- overridden_fields
- package_api_docs
# - package_names # non conforming packages in sdk
- package_names
- package_prefixed_library_names
# - parameter_assignments # we do this commonly
- prefer_adjacent_string_concatenation
@ -143,10 +157,10 @@ linter:
# - prefer_asserts_with_message # not required by flutter style
- prefer_collection_literals
- prefer_conditional_assignment
- prefer_const_constructors
# - prefer_const_constructors
- prefer_const_constructors_in_immutables
- prefer_const_declarations
- prefer_const_literals_to_create_immutables
# - prefer_const_literals_to_create_immutables
# - prefer_constructors_over_static_methods # far too many false positives
- prefer_contains
# - prefer_double_quotes # opposite of prefer_single_quotes
@ -155,33 +169,38 @@ linter:
- prefer_final_fields
- prefer_final_in_for_each
- prefer_final_locals
# - prefer_final_parameters # we should enable this one day when it can be auto-fixed (https://github.com/dart-lang/linter/issues/3104), see also parameter_assignments
- prefer_for_elements_to_map_fromIterable
- prefer_foreach
# - prefer_function_declarations_over_variables # not yet tested
- prefer_function_declarations_over_variables
- prefer_generic_function_type_aliases
- prefer_if_elements_to_conditional_expressions
- prefer_if_null_operators
- prefer_initializing_formals
- prefer_inlined_adds
# - prefer_int_literals # not yet tested
# - prefer_interpolation_to_compose_strings # not yet tested
# - prefer_int_literals # conflicts with https://github.com/flutter/flutter/wiki/Style-guide-for-Flutter-repo#use-double-literals-for-double-constants
- prefer_interpolation_to_compose_strings
- prefer_is_empty
- prefer_is_not_empty
- prefer_is_not_operator
- prefer_iterable_whereType
# - prefer_mixin # https://github.com/dart-lang/language/issues/32
# - prefer_null_aware_operators # disable until NNBD, see https://github.com/flutter/flutter/pull/32711#issuecomment-492930932
# - prefer_relative_imports # not yet tested
# - prefer_mixin # Has false positives, see https://github.com/dart-lang/linter/issues/3018
# - prefer_null_aware_method_calls # "call()" is confusing to people new to the language since it's not documented anywhere
- prefer_null_aware_operators
# - prefer_relative_imports
- prefer_single_quotes
- prefer_spread_collections
- prefer_typing_uninitialized_variables
- prefer_void_to_null
# - provide_deprecation_message # not yet tested
- provide_deprecation_message
# - public_member_api_docs # enabled on a case-by-case basis; see e.g. packages/analysis_options.yaml
- recursive_getters
# - sized_box_for_whitespace # not yet tested
# - require_trailing_commas # blocked on https://github.com/dart-lang/sdk/issues/47441
- secure_pubspec_urls
- sized_box_for_whitespace
# - sized_box_shrink_expand # not yet tested
- slash_for_doc_comments
# - sort_child_properties_last # not yet tested
- sort_child_properties_last
- sort_constructors_first
# - sort_pub_dependencies # prevents separating pinned transitive dependencies
- sort_unnamed_constructors_first
@ -190,36 +209,43 @@ linter:
- tighten_type_of_initializing_formals
# - type_annotate_public_apis # subset of always_specify_types
- type_init_formals
- unawaited_futures # too many false positives
# - unnecessary_await_in_return # not yet tested
# - unawaited_futures # too many false positives, especially with the way AnimationController works
- unnecessary_await_in_return
- unnecessary_brace_in_string_interps
- unnecessary_const
- unnecessary_constructor_name
# - unnecessary_final # conflicts with prefer_final_locals
- unnecessary_getters_setters
# - unnecessary_lambdas # has false positives: https://github.com/dart-lang/linter/issues/498
- unnecessary_late
- unnecessary_new
- unnecessary_null_aware_assignments
# - unnecessary_null_checks # not yet tested
- unnecessary_null_checks
- unnecessary_null_in_if_null_operators
- unnecessary_nullable_for_final_variable_declarations
- unnecessary_overrides
- unnecessary_parenthesis
# - unnecessary_raw_strings # not yet tested
# - unnecessary_raw_strings # what's "necessary" is a matter of opinion; consistency across strings can help readability more than this lint
- unnecessary_statements
- unnecessary_string_escapes
- unnecessary_string_interpolations
- unnecessary_this
- unrelated_type_equality_checks
# - unsafe_html # not yet tested
- unsafe_html
- use_build_context_synchronously
# - use_decorated_box # not yet tested
- use_full_hex_values_for_flutter_colors
# - use_function_type_syntax_for_parameters # not yet tested
- use_function_type_syntax_for_parameters
- use_if_null_to_convert_nulls_to_bools
- use_is_even_rather_than_modulo
# - use_key_in_widget_constructors # not yet tested
- use_key_in_widget_constructors
- use_late_for_private_fields_and_variables
- use_named_constants
- use_raw_strings
- use_rethrow_when_possible
# - use_setters_to_change_properties # not yet tested
- use_setters_to_change_properties
# - use_string_buffers # has false positives: https://github.com/dart-lang/sdk/issues/34182
- use_test_throws_matchers
# - use_to_and_as_if_applicable # has false positives, so we prefer to catch this by code-review
- valid_regexps
- void_checks

1
android/.gitignore vendored
View File

@ -6,3 +6,4 @@
.DS_Store
/build
/captures
.cxx

View File

@ -1,5 +1,5 @@
group 'io.github.v7lin.wechat_kit'
version '3.2.0'
version '4.0.0'
buildscript {
repositories {
@ -8,7 +8,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.1.2'
}
}
@ -24,6 +24,11 @@ apply plugin: 'com.android.library'
android {
compileSdkVersion 31
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
resourcePrefix 'wechat_kit'
defaultConfig {
@ -33,10 +38,6 @@ android {
consumerProguardFiles 'consumer-rules.pro'
}
lintOptions {
disable 'InvalidPackage'
}
flavorDimensions 'vendor'
productFlavors {
@ -53,4 +54,3 @@ dependencies {
//
vendorImplementation 'com.tencent.mm.opensdk:wechat-sdk-android-without-mta:6.8.0'
}

View File

@ -1,3 +0,0 @@
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true

View File

@ -1,5 +0,0 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip

View File

@ -22,9 +22,9 @@ import com.tencent.mm.opensdk.modelbiz.OpenRankList;
import com.tencent.mm.opensdk.modelbiz.OpenWebview;
import com.tencent.mm.opensdk.modelbiz.SubscribeMessage;
import com.tencent.mm.opensdk.modelbiz.WXLaunchMiniProgram;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessWebview;
import com.tencent.mm.opensdk.modelbiz.WXOpenCustomerServiceChat;
import com.tencent.mm.opensdk.modelbiz.WXOpenBusinessView;
import com.tencent.mm.opensdk.modelmsg.LaunchFromWX;
import com.tencent.mm.opensdk.modelmsg.SendAuth;
import com.tencent.mm.opensdk.modelmsg.SendMessageToWX;
@ -61,116 +61,7 @@ import io.flutter.plugin.common.PluginRegistry;
/**
* WechatKitPlugin
*/
public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.NewIntentListener, MethodCallHandler {
//
private static final String METHOD_REGISTERAPP = "registerApp";
private static final String METHOD_HANDLEINITIALWXREQ = "handleInitialWXReq";
private static final String METHOD_ISINSTALLED = "isInstalled";
private static final String METHOD_ISSUPPORTAPI = "isSupportApi";
private static final String METHOD_ISSUPPORTSTATEAPI = "isSupportStateAPI";
private static final String METHOD_OPENWECHAT = "openWechat";
private static final String METHOD_AUTH = "auth";
private static final String METHOD_STARTQRAUTH = "startQrauth";
private static final String METHOD_STOPQRAUTH = "stopQrauth";
private static final String METHOD_OPENURL = "openUrl";
private static final String METHOD_OPENRANKLIST = "openRankList";
private static final String METHOD_SHARETEXT = "shareText";
private static final String METHOD_SHAREIMAGE = "shareImage";
private static final String METHOD_SHAREFILE = "shareFile";
private static final String METHOD_SHAREEMOJI = "shareEmoji";
private static final String METHOD_SHAREMUSIC = "shareMusic";
private static final String METHOD_SHAREVIDEO = "shareVideo";
private static final String METHOD_SHAREWEBPAGE = "shareWebpage";
private static final String METHOD_SHAREMINIPROGRAM = "shareMiniProgram";
private static final String METHOD_SUBSCRIBEMSG = "subscribeMsg";
private static final String METHOD_LAUNCHMINIPROGRAM = "launchMiniProgram";
private static final String METHOD_OPENCUSTOMERSERVICECHAT = "openCustomerServiceChat";
private static final String METHOD_OPENBUSINESSVIEW = "openBusinessView";
private static final String METHOD_OPENBUSINESSWEBVIEW = "openBusinessWebview";
private static final String METHOD_PAY = "pay";
private static final String METHOD_ONLAUNCHFROMWXREQ = "onLaunchFromWXReq";
private static final String METHOD_ONSHOWMESSAGEFROMWXREQ = "onShowMessageFromWXReq";
private static final String METHOD_ONAUTHRESP = "onAuthResp";
private static final String METHOD_ONOPENURLRESP = "onOpenUrlResp";
private static final String METHOD_ONSHAREMSGRESP = "onShareMsgResp";
private static final String METHOD_ONSUBSCRIBEMSGRESP = "onSubscribeMsgResp";
private static final String METHOD_ONLAUNCHMINIPROGRAMRESP = "onLaunchMiniProgramResp";
private static final String METHOD_ONOPENCUSTOMERSERVICECHATRESP = "onOpenCustomerServiceChatResp";
private static final String METHOD_ONOPENBUSINESSVIEWRESP = "onOpenBusinessViewResp";
private static final String METHOD_ONOPENBUSINESSWEBVIEWRESP = "onOpenBusinessWebviewResp";
private static final String METHOD_ONPAYRESP = "onPayResp";
private static final String METHOD_ONAUTHGOTQRCODE = "onAuthGotQrcode";
private static final String METHOD_ONAUTHQRCODESCANNED = "onAuthQrcodeScanned";
private static final String METHOD_ONAUTHFINISH = "onAuthFinish";
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_STATE = "state";
private static final String ARGUMENT_KEY_NONCESTR = "noncestr";
private static final String ARGUMENT_KEY_TIMESTAMP = "timestamp";
private static final String ARGUMENT_KEY_SIGNATURE = "signature";
private static final String ARGUMENT_KEY_URL = "url";
private static final String ARGUMENT_KEY_QUERY = "query";
private static final String ARGUMENT_KEY_USERNAME = "username";
private static final String ARGUMENT_KEY_SCENE = "scene";
private static final String ARGUMENT_KEY_TEXT = "text";
private static final String ARGUMENT_KEY_TITLE = "title";
private static final String ARGUMENT_KEY_DESCRIPTION = "description";
private static final String ARGUMENT_KEY_THUMBDATA = "thumbData";
private static final String ARGUMENT_KEY_IMAGEDATA = "imageData";
private static final String ARGUMENT_KEY_IMAGEURI = "imageUri";
private static final String ARGUMENT_KEY_EMOJIDATA = "emojiData";
private static final String ARGUMENT_KEY_EMOJIURI = "emojiUri";
private static final String ARGUMENT_KEY_FILEDATA = "fileData";
private static final String ARGUMENT_KEY_FILEURI = "fileUri";
// private static final String ARGUMENT_KEY_FILEEXTENSION = "fileExtension";
private static final String ARGUMENT_KEY_MUSICURL = "musicUrl";
private static final String ARGUMENT_KEY_MUSICDATAURL = "musicDataUrl";
private static final String ARGUMENT_KEY_MUSICLOWBANDURL = "musicLowBandUrl";
private static final String ARGUMENT_KEY_MUSICLOWBANDDATAURL = "musicLowBandDataUrl";
private static final String ARGUMENT_KEY_VIDEOURL = "videoUrl";
private static final String ARGUMENT_KEY_VIDEOLOWBANDURL = "videoLowBandUrl";
private static final String ARGUMENT_KEY_WEBPAGEURL = "webpageUrl";
private static final String ARGUMENT_KEY_PATH = "path";
private static final String ARGUMENT_KEY_HDIMAGEDATA = "hdImageData";
private static final String ARGUMENT_KEY_WITHSHARETICKET = "withShareTicket";
private static final String ARGUMENT_KEY_TYPE = "type";
private static final String ARGUMENT_KEY_DISABLEFORWARD = "disableForward";
private static final String ARGUMENT_KEY_TEMPLATEID = "templateId";
private static final String ARGUMENT_KEY_RESERVED = "reserved";
private static final String ARGUMENT_KEY_CORPID = "corpId";
private static final String ARGUMENT_KEY_BUSINESSTYPE = "businessType";
private static final String ARGUMENT_KEY_QUERYINFO = "queryInfo";
private static final String ARGUMENT_KEY_PARTNERID = "partnerId";
private static final String ARGUMENT_KEY_PREPAYID = "prepayId";
private static final String ARGUMENT_KEY_PACKAGE = "package";
private static final String ARGUMENT_KEY_SIGN = "sign";
private static final String ARGUMENT_KEY_EXTINFO = "extInfo";
private static final String ARGUMENT_KEY_RESULT_ERRORCODE = "errorCode";
private static final String ARGUMENT_KEY_RESULT_ERRORMSG = "errorMsg";
private static final String ARGUMENT_KEY_RESULT_CODE = "code";
private static final String ARGUMENT_KEY_RESULT_STATE = "state";
private static final String ARGUMENT_KEY_RESULT_LANG = "lang";
private static final String ARGUMENT_KEY_RESULT_COUNTRY = "country";
private static final String ARGUMENT_KEY_RESULT_TEMPLATEID = "templateId";
private static final String ARGUMENT_KEY_RESULT_SCENE = "scene";
private static final String ARGUMENT_KEY_RESULT_ACTION = "action";
private static final String ARGUMENT_KEY_RESULT_RESERVED = "reserved";
private static final String ARGUMENT_KEY_RESULT_EXTMSG = "extMsg";
private static final String ARGUMENT_KEY_RESULT_BUSINESSTYPE = "businessType";
private static final String ARGUMENT_KEY_RESULT_RESULTINFO = "resultInfo";
private static final String ARGUMENT_KEY_RESULT_MESSAGEACTION = "messageAction";
private static final String ARGUMENT_KEY_RESULT_MESSAGEEXT = "messageExt";
private static final String ARGUMENT_KEY_RESULT_RETURNKEY = "returnKey";
private static final String ARGUMENT_KEY_RESULT_IMAGEDATA = "imageData";
private static final String ARGUMENT_KEY_RESULT_AUTHCODE = "authCode";
public class WechatKitPlugin implements FlutterPlugin, ActivityAware, PluginRegistry.NewIntentListener, MethodCallHandler {
/// 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
@ -190,7 +81,6 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
channel = new MethodChannel(binding.getBinaryMessenger(), "v7lin.github.io/wechat_kit");
channel.setMethodCallHandler(this);
applicationContext = binding.getApplicationContext();
}
@ -199,7 +89,6 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
channel.setMethodCallHandler(null);
channel = null;
applicationContext = null;
}
@ -230,7 +119,7 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
// --- NewIntentListener
@Override
public boolean onNewIntent(Intent intent) {
public boolean onNewIntent(@NonNull Intent intent) {
final Intent resp = WechatCallbackActivity.extraCallback(intent);
if (resp != null) {
if (iwxapi != null) {
@ -246,22 +135,22 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
public void onReq(BaseReq req) {
final Map<String, Object> map = new HashMap<>();
if (req instanceof LaunchFromWX.Req) {
LaunchFromWX.Req launchFromWXReq = (LaunchFromWX.Req) req;
map.put(ARGUMENT_KEY_RESULT_MESSAGEACTION, launchFromWXReq.messageAction);
map.put(ARGUMENT_KEY_RESULT_MESSAGEEXT, launchFromWXReq.messageExt);
map.put(ARGUMENT_KEY_RESULT_LANG, launchFromWXReq.lang);
map.put(ARGUMENT_KEY_RESULT_COUNTRY, launchFromWXReq.country);
final LaunchFromWX.Req launchFromWXReq = (LaunchFromWX.Req) req;
map.put("messageAction", launchFromWXReq.messageAction);
map.put("messageExt", launchFromWXReq.messageExt);
map.put("lang", launchFromWXReq.lang);
map.put("country", launchFromWXReq.country);
if (channel != null) {
channel.invokeMethod(METHOD_ONLAUNCHFROMWXREQ, map);
channel.invokeMethod("onLaunchFromWXReq", map);
}
} else if (req instanceof ShowMessageFromWX.Req) {
ShowMessageFromWX.Req showMessageFromWXReq = (ShowMessageFromWX.Req) req;
map.put(ARGUMENT_KEY_RESULT_MESSAGEACTION, showMessageFromWXReq.message.messageAction);
map.put(ARGUMENT_KEY_RESULT_MESSAGEEXT, showMessageFromWXReq.message.messageExt);
map.put(ARGUMENT_KEY_RESULT_LANG, showMessageFromWXReq.lang);
map.put(ARGUMENT_KEY_RESULT_COUNTRY, showMessageFromWXReq.country);
final ShowMessageFromWX.Req showMessageFromWXReq = (ShowMessageFromWX.Req) req;
map.put("messageAction", showMessageFromWXReq.message.messageAction);
map.put("messageExt", showMessageFromWXReq.message.messageExt);
map.put("lang", showMessageFromWXReq.lang);
map.put("country", showMessageFromWXReq.country);
if (channel != null) {
channel.invokeMethod(METHOD_ONSHOWMESSAGEFROMWXREQ, map);
channel.invokeMethod("onShowMessageFromWXReq", map);
}
}
}
@ -269,81 +158,81 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
@Override
public void onResp(BaseResp resp) {
final Map<String, Object> map = new HashMap<>();
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, resp.errCode);
map.put(ARGUMENT_KEY_RESULT_ERRORMSG, resp.errStr);
map.put("errorCode", resp.errCode);
map.put("errorMsg", resp.errStr);
if (resp instanceof SendAuth.Resp) {
// 授权
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
SendAuth.Resp authResp = (SendAuth.Resp) resp;
map.put(ARGUMENT_KEY_RESULT_CODE, authResp.code);
map.put(ARGUMENT_KEY_RESULT_STATE, authResp.state);
map.put(ARGUMENT_KEY_RESULT_LANG, authResp.lang);
map.put(ARGUMENT_KEY_RESULT_COUNTRY, authResp.country);
final SendAuth.Resp authResp = (SendAuth.Resp) resp;
map.put("code", authResp.code);
map.put("state", authResp.state);
map.put("lang", authResp.lang);
map.put("country", authResp.country);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONAUTHRESP, map);
channel.invokeMethod("onAuthResp", map);
}
} else if (resp instanceof OpenWebview.Resp) {
// 浏览器
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENURLRESP, map);
channel.invokeMethod("onOpenUrlResp", map);
}
} else if (resp instanceof SendMessageToWX.Resp) {
// 分享
if (channel != null) {
channel.invokeMethod(METHOD_ONSHAREMSGRESP, map);
channel.invokeMethod("onShareMsgResp", map);
}
} else if (resp instanceof SubscribeMessage.Resp) {
// 一次性订阅消息
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
SubscribeMessage.Resp subscribeMsgResp = (SubscribeMessage.Resp) resp;
map.put(ARGUMENT_KEY_RESULT_TEMPLATEID, subscribeMsgResp.templateID);
map.put(ARGUMENT_KEY_RESULT_SCENE, subscribeMsgResp.scene);
map.put(ARGUMENT_KEY_RESULT_ACTION, subscribeMsgResp.action);
map.put(ARGUMENT_KEY_RESULT_RESERVED, subscribeMsgResp.reserved);
final SubscribeMessage.Resp subscribeMsgResp = (SubscribeMessage.Resp) resp;
map.put("templateId", subscribeMsgResp.templateID);
map.put("scene", subscribeMsgResp.scene);
map.put("action", subscribeMsgResp.action);
map.put("reserved", subscribeMsgResp.reserved);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONSUBSCRIBEMSGRESP, map);
channel.invokeMethod("onSubscribeMsgResp", map);
}
} else if (resp instanceof WXLaunchMiniProgram.Resp) {
// 打开小程序
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
WXLaunchMiniProgram.Resp launchMiniProgramResp = (WXLaunchMiniProgram.Resp) resp;
map.put(ARGUMENT_KEY_RESULT_EXTMSG, launchMiniProgramResp.extMsg);
final WXLaunchMiniProgram.Resp launchMiniProgramResp = (WXLaunchMiniProgram.Resp) resp;
map.put("extMsg", launchMiniProgramResp.extMsg);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONLAUNCHMINIPROGRAMRESP, map);
channel.invokeMethod("onLaunchMiniProgramResp", map);
}
} else if (resp instanceof WXOpenCustomerServiceChat.Resp) {
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENCUSTOMERSERVICECHATRESP, map);
channel.invokeMethod("onOpenCustomerServiceChatResp", map);
}
} else if (resp instanceof WXOpenBusinessView.Resp) {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
WXOpenBusinessView.Resp openBusinessViewResp = (WXOpenBusinessView.Resp) resp;
map.put(ARGUMENT_KEY_RESULT_BUSINESSTYPE, openBusinessViewResp.businessType);
map.put(ARGUMENT_KEY_RESULT_EXTMSG, openBusinessViewResp.extMsg);
final WXOpenBusinessView.Resp openBusinessViewResp = (WXOpenBusinessView.Resp) resp;
map.put("businessType", openBusinessViewResp.businessType);
map.put("extMsg", openBusinessViewResp.extMsg);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENBUSINESSVIEWRESP, map);
channel.invokeMethod("onOpenBusinessViewResp", map);
}
} else if (resp instanceof WXOpenBusinessWebview.Resp) {
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
WXOpenBusinessWebview.Resp openBusinessWebviewResp = (WXOpenBusinessWebview.Resp) resp;
map.put(ARGUMENT_KEY_RESULT_BUSINESSTYPE, openBusinessWebviewResp.businessType);
map.put(ARGUMENT_KEY_RESULT_RESULTINFO, openBusinessWebviewResp.resultInfo);
final WXOpenBusinessWebview.Resp openBusinessWebviewResp = (WXOpenBusinessWebview.Resp) resp;
map.put("businessType", openBusinessWebviewResp.businessType);
map.put("resultInfo", openBusinessWebviewResp.resultInfo);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONOPENBUSINESSWEBVIEWRESP, map);
channel.invokeMethod("onOpenBusinessWebviewResp", map);
}
} else if (resp instanceof PayResp) {
// 支付
if (resp.errCode == BaseResp.ErrCode.ERR_OK) {
PayResp payResp = (PayResp) resp;
map.put(ARGUMENT_KEY_RESULT_RETURNKEY, payResp.returnKey);
final PayResp payResp = (PayResp) resp;
map.put("returnKey", payResp.returnKey);
}
if (channel != null) {
channel.invokeMethod(METHOD_ONPAYRESP, map);
channel.invokeMethod("onPayResp", map);
}
}
}
@ -353,48 +242,48 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
@Override
public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
if (METHOD_REGISTERAPP.equals(call.method)) {
if ("registerApp".equals(call.method)) {
registerApp(call, result);
} else if (METHOD_HANDLEINITIALWXREQ.equals(call.method)) {
} else if ("handleInitialWXReq".equals(call.method)) {
handleInitialWXReq(call, result);
} else if (METHOD_ISINSTALLED.equals(call.method)) {
} else if ("isInstalled".equals(call.method)) {
result.success(iwxapi != null && iwxapi.isWXAppInstalled());
} else if (METHOD_ISSUPPORTAPI.equals(call.method)) {
} else if ("isSupportApi".equals(call.method)) {
result.success(iwxapi != null && iwxapi.getWXAppSupportAPI() >= Build.OPENID_SUPPORTED_SDK_INT);
} else if (METHOD_ISSUPPORTSTATEAPI.equals(call.method)) {
} else if ("isSupportStateApi".equals(call.method)) {
result.success(iwxapi != null && iwxapi.getWXAppSupportAPI() >= Build.SUPPORTED_SEND_TO_STATUS);
} else if (METHOD_OPENWECHAT.equals(call.method)) {
} else if ("openWechat".equals(call.method)) {
result.success(iwxapi != null && iwxapi.openWXApp());
} else if (METHOD_AUTH.equals(call.method)) {
} else if ("auth".equals(call.method)) {
handleAuthCall(call, result);
} else if (METHOD_STARTQRAUTH.equals(call.method) ||
METHOD_STOPQRAUTH.equals(call.method)) {
} else if ("startQrauth".equals(call.method) ||
"stopQrauth".equals(call.method)) {
handleQRAuthCall(call, result);
} else if (METHOD_OPENURL.equals(call.method)) {
} else if ("openUrl".equals(call.method)) {
handleOpenUrlCall(call, result);
} else if (METHOD_OPENRANKLIST.equals(call.method)) {
} else if ("openRankList".equals(call.method)) {
handleOpenRankListCall(call, result);
} else if (METHOD_SHARETEXT.equals(call.method)) {
} else if ("shareText".equals(call.method)) {
handleShareTextCall(call, result);
} else if (METHOD_SHAREIMAGE.equals(call.method) ||
METHOD_SHAREFILE.equals(call.method) ||
METHOD_SHAREEMOJI.equals(call.method) ||
METHOD_SHAREMUSIC.equals(call.method) ||
METHOD_SHAREVIDEO.equals(call.method) ||
METHOD_SHAREWEBPAGE.equals(call.method) ||
METHOD_SHAREMINIPROGRAM.equals(call.method)) {
} else if ("shareImage".equals(call.method) ||
"shareFile".equals(call.method) ||
"shareEmoji".equals(call.method) ||
"shareMusic".equals(call.method) ||
"shareVideo".equals(call.method) ||
"shareWebpage".equals(call.method) ||
"shareMiniProgram".equals(call.method)) {
handleShareMediaCall(call, result);
} else if (METHOD_SUBSCRIBEMSG.equals(call.method)) {
} else if ("subscribeMsg".equals(call.method)) {
handleSubscribeMsgCall(call, result);
} else if (METHOD_LAUNCHMINIPROGRAM.equals(call.method)) {
} else if ("launchMiniProgram".equals(call.method)) {
handleLaunchMiniProgramCall(call, result);
} else if (METHOD_OPENCUSTOMERSERVICECHAT.equals(call.method)) {
} else if ("openCustomerServiceChat".equals(call.method)) {
handleOpenCustomerServiceChat(call, result);
} else if (METHOD_OPENBUSINESSVIEW.equals(call.method)) {
} else if ("openBusinessView".equals(call.method)) {
handleOpenBusinessView(call, result);
} else if (METHOD_OPENBUSINESSWEBVIEW.equals(call.method)) {
} else if ("openBusinessWebview".equals(call.method)) {
handleOpenBusinessWebview(call, result);
} else if (METHOD_PAY.equals(call.method)) {
} else if ("pay".equals(call.method)) {
handlePayCall(call, result);
} else {
result.notImplemented();
@ -402,8 +291,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
}
private void registerApp(@NonNull MethodCall call, @NonNull Result result) {
final String appId = call.argument(ARGUMENT_KEY_APPID);
// final String universalLink = call.argument(ARGUMENT_KEY_UNIVERSALLINK);
final String appId = call.argument("appId");
// final String universalLink = call.argument("universalLink");
iwxapi = WXAPIFactory.createWXAPI(applicationContext, appId);
iwxapi.registerApp(appId);
result.success(null);
@ -428,8 +317,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleAuthCall(@NonNull MethodCall call, @NonNull Result result) {
final SendAuth.Req req = new SendAuth.Req();
req.scope = call.argument(ARGUMENT_KEY_SCOPE);
req.state = call.argument(ARGUMENT_KEY_STATE);
req.scope = call.argument("scope");
req.state = call.argument("state");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -437,14 +326,14 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
}
private void handleQRAuthCall(@NonNull MethodCall call, @NonNull Result result) {
if (METHOD_STARTQRAUTH.equals(call.method)) {
final String appId = call.argument(ARGUMENT_KEY_APPID);
final String scope = call.argument(ARGUMENT_KEY_SCOPE);
final String noncestr = call.argument(ARGUMENT_KEY_NONCESTR);
final String timestamp = call.argument(ARGUMENT_KEY_TIMESTAMP);
final String signature = call.argument(ARGUMENT_KEY_SIGNATURE);
if ("startQrauth".equals(call.method)) {
final String appId = call.argument("appId");
final String scope = call.argument("scope");
final String noncestr = call.argument("noncestr");
final String timestamp = call.argument("timestamp");
final String signature = call.argument("signature");
qrauth.auth(appId, scope, noncestr, timestamp, signature, qrauthListener);
} else if (METHOD_STOPQRAUTH.equals(call.method)) {
} else if ("stopQrauth".equals(call.method)) {
qrauth.stopAuth();
}
result.success(null);
@ -454,33 +343,33 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
@Override
public void onAuthGotQrcode(@Deprecated String qrcodeImgPath, byte[] imgBuf) {
final Map<String, Object> map = new HashMap<>();
map.put(ARGUMENT_KEY_RESULT_IMAGEDATA, imgBuf);
map.put("imageData", imgBuf);
if (channel != null) {
channel.invokeMethod(METHOD_ONAUTHGOTQRCODE, map);
channel.invokeMethod("onAuthGotQrcode", map);
}
}
@Override
public void onQrcodeScanned() {
if (channel != null) {
channel.invokeMethod(METHOD_ONAUTHQRCODESCANNED, null);
channel.invokeMethod("onAuthQrcodeScanned", null);
}
}
@Override
public void onAuthFinish(OAuthErrCode errCode, String authCode) {
final Map<String, Object> map = new HashMap<>();
map.put(ARGUMENT_KEY_RESULT_ERRORCODE, errCode.getCode());
map.put(ARGUMENT_KEY_RESULT_AUTHCODE, authCode);
map.put("errorCode", errCode.getCode());
map.put("authCode", authCode);
if (channel != null) {
channel.invokeMethod(METHOD_ONAUTHFINISH, map);
channel.invokeMethod("onAuthFinish", map);
}
}
};
private void handleOpenUrlCall(@NonNull MethodCall call, @NonNull Result result) {
final OpenWebview.Req req = new OpenWebview.Req();
req.url = call.argument(ARGUMENT_KEY_URL);
req.url = call.argument("url");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -498,11 +387,11 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleShareTextCall(@NonNull MethodCall call, @NonNull Result result) {
final SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = call.method + ": " + System.currentTimeMillis();
req.scene = call.argument(ARGUMENT_KEY_SCENE);
String text = call.argument(ARGUMENT_KEY_TEXT);
WXMediaMessage message = new WXMediaMessage();
req.scene = call.argument("scene");
final String text = call.argument("text");
final WXMediaMessage message = new WXMediaMessage();
message.description = text.length() <= 1024 ? text : text.substring(0, 1024);// 必选项,否则无法分享
WXTextObject object = new WXTextObject();
final WXTextObject object = new WXTextObject();
object.text = text;
message.mediaObject = object;
req.message = message;
@ -515,67 +404,67 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleShareMediaCall(@NonNull MethodCall call, @NonNull Result result) {
final SendMessageToWX.Req req = new SendMessageToWX.Req();
req.transaction = call.method + ": " + System.currentTimeMillis();
req.scene = call.argument(ARGUMENT_KEY_SCENE);
req.scene = call.argument("scene");
final WXMediaMessage message = new WXMediaMessage();
message.title = call.argument(ARGUMENT_KEY_TITLE);
message.description = call.argument(ARGUMENT_KEY_DESCRIPTION);
message.thumbData = call.argument(ARGUMENT_KEY_THUMBDATA);
if (METHOD_SHAREIMAGE.equals(call.method)) {
message.title = call.argument("title");
message.description = call.argument("description");
message.thumbData = call.argument("thumbData");
if ("shareImage".equals(call.method)) {
final WXImageObject object = new WXImageObject();
if (call.hasArgument(ARGUMENT_KEY_IMAGEDATA)) {
object.imageData = call.argument(ARGUMENT_KEY_IMAGEDATA);
} else if (call.hasArgument(ARGUMENT_KEY_IMAGEURI)) {
String imageUri = call.argument(ARGUMENT_KEY_IMAGEURI);
if (call.hasArgument("imageData")) {
object.imageData = call.argument("imageData");
} else if (call.hasArgument("imageUri")) {
final String imageUri = call.argument("imageUri");
object.imagePath = getShareFilePath(imageUri);//Uri.parse(imageUri).getPath();
}
message.mediaObject = object;
} else if (METHOD_SHAREFILE.equals(call.method)) {
} else if ("shareFile".equals(call.method)) {
final WXFileObject object = new WXFileObject();
if (call.hasArgument(ARGUMENT_KEY_FILEDATA)) {
object.fileData = call.argument(ARGUMENT_KEY_FILEDATA);
} else if (call.hasArgument(ARGUMENT_KEY_FILEURI)) {
String fileUri = call.argument(ARGUMENT_KEY_FILEURI);
if (call.hasArgument("fileData")) {
object.fileData = call.argument("fileData");
} else if (call.hasArgument("fileUri")) {
final String fileUri = call.argument("fileUri");
object.filePath = getShareFilePath(fileUri);//Uri.parse(fileUri).getPath();
}
// String fileExtension = call.argument(ARGUMENT_KEY_FILEEXTENSION);
// final String fileExtension = call.argument("fileExtension");
message.mediaObject = object;
} else if (METHOD_SHAREEMOJI.equals(call.method)) {
} else if ("shareEmoji".equals(call.method)) {
final WXEmojiObject object = new WXEmojiObject();
if (call.hasArgument(ARGUMENT_KEY_EMOJIDATA)) {
object.emojiData = call.argument(ARGUMENT_KEY_EMOJIDATA);
} else if (call.hasArgument(ARGUMENT_KEY_EMOJIURI)) {
String emojiUri = call.argument(ARGUMENT_KEY_EMOJIURI);
if (call.hasArgument("emojiData")) {
object.emojiData = call.argument("emojiData");
} else if (call.hasArgument("emojiUri")) {
final String emojiUri = call.argument("emojiUri");
object.emojiPath = getShareFilePath(emojiUri);//Uri.parse(emojiUri).getPath();
}
message.mediaObject = object;
} else if (METHOD_SHAREMUSIC.equals(call.method)) {
} else if ("shareMusic".equals(call.method)) {
final WXMusicObject object = new WXMusicObject();
object.musicUrl = call.argument(ARGUMENT_KEY_MUSICURL);
object.musicDataUrl = call.argument(ARGUMENT_KEY_MUSICDATAURL);
object.musicLowBandUrl = call.argument(ARGUMENT_KEY_MUSICLOWBANDURL);
object.musicLowBandDataUrl = call.argument(ARGUMENT_KEY_MUSICLOWBANDDATAURL);
object.musicUrl = call.argument("musicUrl");
object.musicDataUrl = call.argument("musicDataUrl");
object.musicLowBandUrl = call.argument("musicLowBandUrl");
object.musicLowBandDataUrl = call.argument("musicLowBandDataUrl");
message.mediaObject = object;
} else if (METHOD_SHAREVIDEO.equals(call.method)) {
} else if ("shareVideo".equals(call.method)) {
final WXVideoObject object = new WXVideoObject();
object.videoUrl = call.argument(ARGUMENT_KEY_VIDEOURL);
object.videoLowBandUrl = call.argument(ARGUMENT_KEY_VIDEOLOWBANDURL);
object.videoUrl = call.argument("videoUrl");
object.videoLowBandUrl = call.argument("videoLowBandUrl");
message.mediaObject = object;
} else if (METHOD_SHAREWEBPAGE.equals(call.method)) {
} else if ("shareWebpage".equals(call.method)) {
final WXWebpageObject object = new WXWebpageObject();
object.webpageUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);
object.webpageUrl = call.argument("webpageUrl");
message.mediaObject = object;
} else if (METHOD_SHAREMINIPROGRAM.equals(call.method)) {
} else if ("shareMiniProgram".equals(call.method)) {
final WXMiniProgramObject object = new WXMiniProgramObject();
object.webpageUrl = call.argument(ARGUMENT_KEY_WEBPAGEURL);
object.userName = call.argument(ARGUMENT_KEY_USERNAME);
object.path = call.argument(ARGUMENT_KEY_PATH);
byte[] hdImageData = call.argument(ARGUMENT_KEY_HDIMAGEDATA);
object.webpageUrl = call.argument("webpageUrl");
object.userName = call.argument("username");
object.path = call.argument("path");
final byte[] hdImageData = call.argument("hdImageData");
if (hdImageData != null) {
message.thumbData = hdImageData;
}
object.withShareTicket = call.argument(ARGUMENT_KEY_WITHSHARETICKET);
object.miniprogramType = call.argument(ARGUMENT_KEY_TYPE);
boolean disableforward = call.argument(ARGUMENT_KEY_DISABLEFORWARD);
object.withShareTicket = call.argument("withShareTicket");
object.miniprogramType = call.argument("type");
final boolean disableforward = call.argument("disableForward");
object.disableforward = disableforward ? 1 : 0;
message.mediaObject = object;
}
@ -588,9 +477,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleSubscribeMsgCall(@NonNull MethodCall call, @NonNull Result result) {
final SubscribeMessage.Req req = new SubscribeMessage.Req();
req.scene = call.argument(ARGUMENT_KEY_SCENE);
req.templateID = call.argument(ARGUMENT_KEY_TEMPLATEID);
req.reserved = call.argument(ARGUMENT_KEY_RESERVED);
req.scene = call.argument("scene");
req.templateID = call.argument("templateId");
req.reserved = call.argument("reserved");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -599,9 +488,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleLaunchMiniProgramCall(@NonNull MethodCall call, @NonNull Result result) {
final WXLaunchMiniProgram.Req req = new WXLaunchMiniProgram.Req();
req.userName = call.argument(ARGUMENT_KEY_USERNAME);
req.path = call.argument(ARGUMENT_KEY_PATH);
req.miniprogramType = call.argument(ARGUMENT_KEY_TYPE);
req.userName = call.argument("username");
req.path = call.argument("path");
req.miniprogramType = call.argument("type");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -610,8 +499,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleOpenCustomerServiceChat(@NonNull MethodCall call, @NonNull Result result) {
final WXOpenCustomerServiceChat.Req req = new WXOpenCustomerServiceChat.Req();
req.corpId = call.argument(ARGUMENT_KEY_CORPID);
req.url = call.argument(ARGUMENT_KEY_URL);
req.corpId = call.argument("corpId");
req.url = call.argument("url");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -620,9 +509,9 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleOpenBusinessView(@NonNull MethodCall call, @NonNull Result result) {
final WXOpenBusinessView.Req req = new WXOpenBusinessView.Req();
req.businessType = call.argument(ARGUMENT_KEY_BUSINESSTYPE);
req.query = call.argument(ARGUMENT_KEY_QUERY);
req.extInfo = call.argument(ARGUMENT_KEY_EXTINFO);
req.businessType = call.argument("businessType");
req.query = call.argument("query");
req.extInfo = call.argument("extInfo");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -631,8 +520,8 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handleOpenBusinessWebview(@NonNull MethodCall call, @NonNull Result result) {
final WXOpenBusinessWebview.Req req = new WXOpenBusinessWebview.Req();
req.businessType = call.argument(ARGUMENT_KEY_BUSINESSTYPE);
req.queryInfo = call.argument(ARGUMENT_KEY_QUERYINFO);
req.businessType = call.argument("businessType");
req.queryInfo = call.argument("queryInfo");
if (iwxapi != null) {
iwxapi.sendReq(req);
}
@ -641,13 +530,13 @@ public final class WechatKitPlugin implements FlutterPlugin, ActivityAware, Plug
private void handlePayCall(@NonNull MethodCall call, @NonNull Result result) {
final PayReq req = new PayReq();
req.appId = call.argument(ARGUMENT_KEY_APPID);
req.partnerId = call.argument(ARGUMENT_KEY_PARTNERID);
req.prepayId = call.argument(ARGUMENT_KEY_PREPAYID);
req.nonceStr = call.argument(ARGUMENT_KEY_NONCESTR);
req.timeStamp = call.argument(ARGUMENT_KEY_TIMESTAMP);
req.packageValue = call.argument(ARGUMENT_KEY_PACKAGE);
req.sign = call.argument(ARGUMENT_KEY_SIGN);
req.appId = call.argument("appId");
req.partnerId = call.argument("partnerId");
req.prepayId = call.argument("prepayId");
req.nonceStr = call.argument("noncestr");
req.timeStamp = call.argument("timestamp");
req.packageValue = call.argument("package");
req.sign = call.argument("sign");
if (iwxapi != null) {
iwxapi.sendReq(req);
}

2
example/.gitignore vendored
View File

@ -8,6 +8,7 @@
.buildlog/
.history
.svn/
migrate_working_dir/
# IntelliJ related
*.iml
@ -23,7 +24,6 @@
# Flutter/Dart/Pub related
**/doc/api/
**/ios/Flutter/.last_build_id
**/ios/Podfile.lock
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies

View File

@ -1,10 +0,0 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: b041144f833e05cf463b8887fa12efdec9493488
channel: stable
project_type: app

View File

@ -8,9 +8,9 @@ This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@ -9,3 +9,5 @@ GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

View File

@ -27,13 +27,18 @@ apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
lintOptions {
disable 'InvalidPackage'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "io.github.v7lin.wechat_kit_example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.v7lin.wechat_kit_example">
<!-- Flutter needs it to communicate with the running application
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

View File

@ -1,10 +1,5 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.v7lin.wechat_kit_example">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:label="wechat_kit_example"
android:icon="@mipmap/ic_launcher">

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>

View File

@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -1,9 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
@ -12,7 +12,7 @@
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">@android:color/white</item>
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@ -1,6 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="io.github.v7lin.wechat_kit_example">
<!-- Flutter needs it to communicate with the running application
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>

View File

@ -6,7 +6,7 @@ buildscript {
}
dependencies {
classpath 'com.android.tools.build:gradle:4.1.0'
classpath 'com.android.tools.build:gradle:7.1.2'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}

View File

@ -1,4 +1,3 @@
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true

View File

@ -1,5 +1,6 @@
#Fri Jun 23 08:50:38 CEST 2017
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip

View File

@ -1,7 +1,3 @@
// Copyright 2014 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")

View File

@ -1,3 +1,4 @@
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
@ -18,6 +19,7 @@ Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/

View File

@ -3,7 +3,7 @@
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>

View File

@ -1,2 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"

View File

@ -1,2 +1,2 @@
#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"

46
example/ios/Podfile.lock Normal file
View File

@ -0,0 +1,46 @@
PODS:
- Flutter (1.0.0)
- FMDB (2.7.5):
- FMDB/standard (= 2.7.5)
- FMDB/standard (2.7.5)
- path_provider_ios (0.0.1):
- Flutter
- sqflite (0.0.2):
- Flutter
- FMDB (>= 2.7.5)
- wechat_kit (4.0.0):
- Flutter
- wechat_kit/pay (= 4.0.0)
- wechat_kit/pay (4.0.0):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`)
- sqflite (from `.symlinks/plugins/sqflite/ios`)
- wechat_kit (from `.symlinks/plugins/wechat_kit/ios`)
SPEC REPOS:
trunk:
- FMDB
EXTERNAL SOURCES:
Flutter:
:path: Flutter
path_provider_ios:
:path: ".symlinks/plugins/path_provider_ios/ios"
sqflite:
:path: ".symlinks/plugins/sqflite/ios"
wechat_kit:
:path: ".symlinks/plugins/wechat_kit/ios"
SPEC CHECKSUMS:
Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a
FMDB: 2ce00b547f966261cd18927a3ddb07cb6f3db82a
path_provider_ios: 14f3d2fd28c4fdb42f44e0f751d12861c43cee02
sqflite: 6d358c025f5b867b29ed92fc697fd34924e11904
wechat_kit: 334889808fcf75d434d9de87e058c691143d431e
PODFILE CHECKSUM: caccac501e88af75e8ed5a7a9625762fb5755e27
COCOAPODS: 1.11.2

View File

@ -3,12 +3,12 @@
archiveVersion = 1;
classes = {
};
objectVersion = 51;
objectVersion = 50;
objects = {
/* Begin PBXBuildFile section */
0A009A3402DAC340BC01BA13 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */; };
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
3A1FC0E9553EF41840956751 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; };
97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; };
@ -33,9 +33,9 @@
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
2A9F683624AF2A723305BFBA /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
33B35D8048C5A0A7E7E26649 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
5B47FD60C153DCE48E1A0D15 /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = "<group>"; };
7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = "<group>"; };
@ -47,8 +47,8 @@
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; };
CB8B4ED2736FBA3973EE42E5 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
DA21A54319640BE724F39D26 /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = "<group>"; };
FF329184F9C54092DB9EFEF8 /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -56,27 +56,28 @@
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
0A009A3402DAC340BC01BA13 /* libPods-Runner.a in Frameworks */,
3A1FC0E9553EF41840956751 /* libPods-Runner.a in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
46D9C1E399B6A633AF01F6AD /* Pods */ = {
04696AED717245F295202B26 /* Pods */ = {
isa = PBXGroup;
children = (
CB8B4ED2736FBA3973EE42E5 /* Pods-Runner.debug.xcconfig */,
33B35D8048C5A0A7E7E26649 /* Pods-Runner.release.xcconfig */,
2A9F683624AF2A723305BFBA /* Pods-Runner.profile.xcconfig */,
FF329184F9C54092DB9EFEF8 /* Pods-Runner.debug.xcconfig */,
DA21A54319640BE724F39D26 /* Pods-Runner.release.xcconfig */,
5B47FD60C153DCE48E1A0D15 /* Pods-Runner.profile.xcconfig */,
);
name = Pods;
path = Pods;
sourceTree = "<group>";
};
57BC2D71F0F7DCD915E8F520 /* Frameworks */ = {
136B8F9608382F11455A7715 /* Frameworks */ = {
isa = PBXGroup;
children = (
C744CCEB00ABFCFE847E0995 /* libPods-Runner.a */,
16A3C53D588E3E40E8CBC6EC /* libPods-Runner.a */,
);
name = Frameworks;
sourceTree = "<group>";
@ -98,8 +99,8 @@
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
46D9C1E399B6A633AF01F6AD /* Pods */,
57BC2D71F0F7DCD915E8F520 /* Frameworks */,
04696AED717245F295202B26 /* Pods */,
136B8F9608382F11455A7715 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -142,7 +143,7 @@
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
75534BAC7D3BD2B24D40A95E /* [CP] Check Pods Manifest.lock */,
6496D2B4FC35C84E9DFEE6A4 /* [CP] Check Pods Manifest.lock */,
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
@ -218,9 +219,9 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin\n";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
75534BAC7D3BD2B24D40A95E /* [CP] Check Pods Manifest.lock */ = {
6496D2B4FC35C84E9DFEE6A4 /* [CP] Check Pods Manifest.lock */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
@ -254,7 +255,7 @@
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build\n";
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
@ -349,20 +350,11 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 78W43A3TE2;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
@ -482,20 +474,11 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 78W43A3TE2;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";
@ -510,20 +493,11 @@
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
DEVELOPMENT_TEAM = 78W43A3TE2;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
INFOPLIST_FILE = Runner/Info.plist;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
LIBRARY_SEARCH_PATHS = (
"$(inherited)",
"$(PROJECT_DIR)/Flutter",
);
PRODUCT_BUNDLE_IDENTIFIER = io.github.v7lin.wechatKitExample;
PRODUCT_NAME = "$(TARGET_NAME)";
VERSIONING_SYSTEM = "apple-generic";

View File

@ -2,9 +2,7 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>com.apple.developer.associated-domains</key>
<array>
<string>applinks:app.666sdk.com</string>
</array>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
@ -38,8 +36,8 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -61,8 +59,6 @@
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"

View File

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>

View File

@ -4,6 +4,8 @@
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Wechat Kit</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@ -60,5 +62,7 @@
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
</dict>
</plist>

View File

@ -1,8 +1,9 @@
import 'dart:async';
import 'dart:io';
import 'dart:typed_data';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_cache_manager/file.dart';
import 'package:flutter_cache_manager/flutter_cache_manager.dart';
import 'package:image/image.dart' as image;
import 'package:path/path.dart' as path;
@ -16,15 +17,14 @@ const String WECHAT_APPSECRET = 'your wechat appSecret';
const String WECHAT_MINIAPPID = 'your wechat miniAppId';
void main() {
WidgetsFlutterBinding.ensureInitialized();
Wechat.instance.registerApp(
appId: WECHAT_APPID,
universalLink: WECHAT_UNIVERSAL_LINK,
);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({
super.key,
});
@override
Widget build(BuildContext context) {
return MaterialApp(
@ -34,6 +34,10 @@ class MyApp extends StatelessWidget {
}
class Home extends StatefulWidget {
const Home({
super.key,
});
@override
State<StatefulWidget> createState() {
return _HomeState();
@ -48,7 +52,7 @@ class _HomeState extends State<Home> {
@override
void initState() {
super.initState();
_respSubs = Wechat.instance.respStream().listen(_listenResp);
_respSubs = Wechat.respStream().listen(_listenResp);
}
void _listenResp(BaseResp resp) {
@ -78,91 +82,95 @@ class _HomeState extends State<Home> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Wechat Kit Demo'),
title: Text('Wechat Kit Demo'),
),
body: ListView(
children: <Widget>[
ListTile(
title: const Text('微信回调 - 冷启'),
title: Text('注册APP'),
onTap: () async {
await Wechat.instance.handleInitialWXReq();
await Wechat.registerApp(
appId: WECHAT_APPID,
universalLink: WECHAT_UNIVERSAL_LINK,
);
_showTips('注册APP', '注册成功');
},
),
ListTile(
title: const Text('环境检查'),
title: Text('微信回调 - 冷启'),
onTap: () async {
final String content =
'wechat: ${await Wechat.instance.isInstalled()} - ${await Wechat.instance.isSupportApi()}';
await Wechat.handleInitialWXReq();
},
),
ListTile(
title: Text('环境检查'),
onTap: () async {
final String content = 'wechat: ${await Wechat.isInstalled()} - ${await Wechat.isSupportApi()}';
_showTips('环境检查', content);
},
),
ListTile(
title: const Text('登录'),
title: Text('登录'),
onTap: () {
Wechat.instance.auth(
Wechat.auth(
scope: <String>[WechatScope.SNSAPI_USERINFO],
state: 'auth',
);
},
),
ListTile(
title: const Text('扫码登录'),
title: Text('扫码登录'),
onTap: () {
Navigator.of(context).push<void>(MaterialPageRoute<dynamic>(
builder: (BuildContext context) => const Qrauth(),
builder: (BuildContext context) => Qrauth(),
));
},
),
ListTile(
title: const Text('获取用户信息'),
title: Text('获取用户信息'),
onTap: () async {
if (_authResp != null && _authResp!.isSuccessful) {
final WechatAccessTokenResp accessTokenResp =
await WechatExtension.getAccessTokenUnionID(
final WechatAccessTokenResp accessTokenResp = await WechatExtension.getAccessTokenUnionID(
appId: WECHAT_APPID,
appSecret: WECHAT_APPSECRET,
code: _authResp!.code!,
);
if (accessTokenResp.isSuccessful) {
final WechatUserInfoResp userInfoResp =
await WechatExtension.getUserInfoUnionID(
final WechatUserInfoResp userInfoResp = await WechatExtension.getUserInfoUnionID(
openId: accessTokenResp.openid!,
accessToken: accessTokenResp.accessToken!,
);
if (userInfoResp.isSuccessful) {
_showTips('用户信息',
'${userInfoResp.nickname} - ${userInfoResp.sex}');
_showTips('用户信息', '${userInfoResp.nickname} - ${userInfoResp.sex}');
}
}
}
},
),
ListTile(
title: const Text('文字分享'),
title: Text('文字分享'),
onTap: () {
Wechat.instance.shareText(
Wechat.shareText(
scene: WechatScene.TIMELINE,
text: 'Share Text',
);
},
),
ListTile(
title: const Text('图片分享'),
title: Text('图片分享'),
onTap: () async {
final File file = await DefaultCacheManager().getSingleFile(
'https://www.baidu.com/img/bd_logo1.png?where=super');
await Wechat.instance.shareImage(
final File file = await DefaultCacheManager().getSingleFile('https://www.baidu.com/img/bd_logo1.png?where=super');
await Wechat.shareImage(
scene: WechatScene.SESSION,
imageUri: Uri.file(file.path),
);
},
),
ListTile(
title: const Text('文件分享'),
title: Text('文件分享'),
onTap: () async {
final File file = await DefaultCacheManager().getSingleFile(
'https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
await Wechat.instance.shareFile(
final File file = await DefaultCacheManager().getSingleFile('https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf');
await Wechat.shareFile(
scene: WechatScene.SESSION,
title: '测试文件',
fileUri: Uri.file(file.path),
@ -171,18 +179,15 @@ class _HomeState extends State<Home> {
},
),
ListTile(
title: const Text('Emoji分享'),
title: Text('Emoji分享'),
onTap: () async {
final File file = await DefaultCacheManager().getSingleFile(
'https://n.sinaimg.cn/tech/transform/695/w467h228/20191119/bf27-iipztfe9404360.gif');
final image.Image thumbnail =
image.decodeImage(file.readAsBytesSync())!;
final File file = await DefaultCacheManager().getSingleFile('https://n.sinaimg.cn/tech/transform/695/w467h228/20191119/bf27-iipztfe9404360.gif');
final image.Image thumbnail = image.decodeImage(file.readAsBytesSync())!;
Uint8List thumbData = thumbnail.getBytes();
if (thumbData.length > 32 * 1024) {
thumbData = Uint8List.fromList(image.encodeJpg(thumbnail,
quality: 100 * 32 * 1024 ~/ thumbData.length));
thumbData = Uint8List.fromList(image.encodeJpg(thumbnail, quality: 100 * 32 * 1024 ~/ thumbData.length));
}
await Wechat.instance.shareEmoji(
await Wechat.shareEmoji(
scene: WechatScene.SESSION,
thumbData: thumbData,
emojiUri: Uri.file(file.path),
@ -190,19 +195,19 @@ class _HomeState extends State<Home> {
},
),
ListTile(
title: const Text('网页分享'),
title: Text('网页分享'),
onTap: () {
Wechat.instance.shareWebpage(
Wechat.shareWebpage(
scene: WechatScene.TIMELINE,
webpageUrl: 'https://www.baidu.com',
);
},
),
ListTile(
title: const Text('支付'),
title: Text('支付'),
onTap: () {
// 微信 Demo 例子https://wxpay.wxutil.com/pub_v2/app/app_pay.php
Wechat.instance.pay(
Wechat.pay(
appId: WECHAT_APPID,
partnerId: '商户号',
prepayId: '预支付交易会话ID',
@ -214,12 +219,12 @@ class _HomeState extends State<Home> {
},
),
ListTile(
title: const Text('拉起小程序'),
title: Text('拉起小程序'),
onTap: () {
Wechat.instance.launchMiniProgram(
Wechat.launchMiniProgram(
userName: WECHAT_MINIAPPID,
path: 'page/page/index?uid=123',
type: WechatMiniProgram.preview,
type: WechatMiniProgram.PREVIEW,
);
},
),
@ -243,8 +248,8 @@ class _HomeState extends State<Home> {
class Qrauth extends StatefulWidget {
const Qrauth({
Key? key,
}) : super(key: key);
super.key,
});
@override
State<StatefulWidget> createState() {
@ -260,8 +265,7 @@ class _QrauthState extends State<Qrauth> {
@override
void initState() {
super.initState();
_qrauthRespSubs =
Wechat.instance.qrauthRespStream().listen(_listenQrauthResp);
_qrauthRespSubs = Wechat.qrauthRespStream().listen(_listenQrauthResp);
}
void _listenQrauthResp(QrauthResp resp) {
@ -270,11 +274,15 @@ class _QrauthState extends State<Qrauth> {
_qrcode = resp.imageData;
});
} else if (resp is QrcodeScannedResp) {
if (kDebugMode) {
print('QrcodeScanned');
}
} else if (resp is FinishResp) {
if (kDebugMode) {
print('resp: ${resp.errorCode} - ${resp.authCode}');
}
}
}
@override
void dispose() {
@ -286,44 +294,45 @@ class _QrauthState extends State<Qrauth> {
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Qrauth'),
title: Text('Qrauth'),
actions: <Widget>[
TextButton(
onPressed: () async {
final WechatAccessTokenResp accessToken =
await WechatExtension.getAccessToken(
final WechatAccessTokenResp accessToken = await WechatExtension.getAccessToken(
appId: WECHAT_APPID,
appSecret: WECHAT_APPSECRET,
);
if (kDebugMode) {
print(
'accessToken: ${accessToken.errorCode} - '
'${accessToken.errorMsg} - '
'${accessToken.accessToken}',
);
}
final WechatTicketResp ticket = await WechatExtension.getTicket(
accessToken: accessToken.accessToken!,
);
if (kDebugMode) {
print(
'accessToken: ${ticket.errorCode} - '
'${ticket.errorMsg} - '
'${ticket.ticket}',
);
await Wechat.instance.startQrauth(
}
await Wechat.startQrauth(
appId: WECHAT_APPID,
scope: <String>[WechatScope.SNSAPI_USERINFO],
noncestr: const Uuid().v1().toString().replaceAll('-', ''),
noncestr: Uuid().v1().replaceAll('-', ''),
ticket: ticket.ticket!,
);
},
child: const Text('got qr code'),
child: Text('got qr code'),
),
],
),
body: GestureDetector(
child: Center(
child: _qrcode != null
? Image.memory(_qrcode!)
: const Text('got qr code'),
child: _qrcode != null ? Image.memory(_qrcode!) : Text('got qr code'),
),
),
);

399
example/pubspec.lock Normal file
View File

@ -0,0 +1,399 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
archive:
dependency: transitive
description:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.0"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.8.2"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
characters:
dependency: transitive
description:
name: characters
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
clock:
dependency: transitive
description:
name: clock
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.16.0"
convert:
dependency: transitive
description:
name: convert
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.1"
crypto:
dependency: transitive
description:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.2"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.4"
fake_async:
dependency: transitive
description:
name: fake_async
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.0"
ffi:
dependency: transitive
description:
name: ffi
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.1"
file:
dependency: transitive
description:
name: file
url: "https://pub.dartlang.org"
source: hosted
version: "6.1.2"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_cache_manager:
dependency: "direct main"
description:
name: flutter_cache_manager
url: "https://pub.dartlang.org"
source: hosted
version: "3.3.0"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.1"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
http:
dependency: transitive
description:
name: http
url: "https://pub.dartlang.org"
source: hosted
version: "0.13.4"
http_parser:
dependency: transitive
description:
name: http_parser
url: "https://pub.dartlang.org"
source: hosted
version: "4.0.0"
image:
dependency: "direct main"
description:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.3"
json_annotation:
dependency: transitive
description:
name: json_annotation
url: "https://pub.dartlang.org"
source: hosted
version: "4.5.0"
lints:
dependency: transitive
description:
name: lints
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
matcher:
dependency: transitive
description:
name: matcher
url: "https://pub.dartlang.org"
source: hosted
version: "0.12.11"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
url: "https://pub.dartlang.org"
source: hosted
version: "0.1.4"
meta:
dependency: transitive
description:
name: meta
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
path:
dependency: "direct main"
description:
name: path
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.1"
path_provider:
dependency: transitive
description:
name: path_provider
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.10"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.14"
path_provider_ios:
dependency: transitive
description:
name: path_provider_ios
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.9"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.6"
path_provider_macos:
dependency: transitive
description:
name: path_provider_macos
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.4"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.6"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.11.1"
petitparser:
dependency: transitive
description:
name: petitparser
url: "https://pub.dartlang.org"
source: hosted
version: "5.0.0"
platform:
dependency: transitive
description:
name: platform
url: "https://pub.dartlang.org"
source: hosted
version: "3.1.0"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
process:
dependency: transitive
description:
name: process
url: "https://pub.dartlang.org"
source: hosted
version: "4.2.4"
rxdart:
dependency: transitive
description:
name: rxdart
url: "https://pub.dartlang.org"
source: hosted
version: "0.27.3"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.2"
sqflite:
dependency: transitive
description:
name: sqflite
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.2+1"
sqflite_common:
dependency: transitive
description:
name: sqflite_common
url: "https://pub.dartlang.org"
source: hosted
version: "2.2.1+1"
stack_trace:
dependency: transitive
description:
name: stack_trace
url: "https://pub.dartlang.org"
source: hosted
version: "1.10.0"
stream_channel:
dependency: transitive
description:
name: stream_channel
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.0"
synchronized:
dependency: transitive
description:
name: synchronized
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.0+2"
term_glyph:
dependency: transitive
description:
name: term_glyph
url: "https://pub.dartlang.org"
source: hosted
version: "1.2.0"
test_api:
dependency: transitive
description:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.4.9"
typed_data:
dependency: transitive
description:
name: typed_data
url: "https://pub.dartlang.org"
source: hosted
version: "1.3.1"
uuid:
dependency: "direct main"
description:
name: uuid
url: "https://pub.dartlang.org"
source: hosted
version: "3.0.6"
vector_math:
dependency: transitive
description:
name: vector_math
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.2"
wechat_kit:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "4.0.0"
wechat_kit_extension:
dependency: "direct main"
description:
name: wechat_kit_extension
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.0+1"
win32:
dependency: transitive
description:
name: win32
url: "https://pub.dartlang.org"
source: hosted
version: "2.6.1"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.0+1"
xml:
dependency: transitive
description:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "5.4.1"
sdks:
dart: ">=2.17.0 <3.0.0"
flutter: ">=2.8.1"

View File

@ -1,11 +1,21 @@
name: wechat_kit_example
description: Demonstrates how to use the wechat_kit plugin.
publish_to: 'none'
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+100
environment:
sdk: ">=2.12.0 <3.0.0"
sdk: ">=2.17.0 <3.0.0"
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
@ -17,14 +27,67 @@ dependencies:
# The example app is bundled with the plugin so we use a path dependency on
# the parent directory to use the current plugin's version.
path: ../
wechat_kit_extension: ^1.0.0
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
path: ^1.8.1
image: ^3.0.1
flutter_cache_manager: ^3.1.2
uuid: ^3.0.6
wechat_kit_extension: ^1.0.0
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

View File

@ -1,8 +1,16 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// utility in the flutter_test package. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
void main() {}
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wechat_kit_example/main.dart';
void main() {
testWidgets('smoke test', (WidgetTester tester) async {
});
}

1
ios/.gitignore vendored
View File

@ -34,4 +34,5 @@ Icon?
.tags*
/Flutter/Generated.xcconfig
/Flutter/ephemeral/
/Flutter/flutter_export_environment.sh

View File

@ -30,121 +30,6 @@ typedef void(^WechatKitWXReqRunnable)(void);
[registrar addMethodCallDelegate:instance channel:channel];
}
static NSString *const METHOD_REGISTERAPP = @"registerApp";
static NSString *const METHOD_HANDLEINITIALWXREQ = @"handleInitialWXReq";
static NSString *const METHOD_ISINSTALLED = @"isInstalled";
static NSString *const METHOD_ISSUPPORTAPI = @"isSupportApi";
static NSString *const METHOD_ISSUPPORTSTATEAPI = @"isSupportStateAPI";
static NSString *const METHOD_OPENWECHAT = @"openWechat";
static NSString *const METHOD_AUTH = @"auth";
static NSString *const METHOD_STARTQRAUTH = @"startQrauth";
static NSString *const METHOD_STOPQRAUTH = @"stopQrauth";
static NSString *const METHOD_OPENURL = @"openUrl";
static NSString *const METHOD_OPENRANKLIST = @"openRankList";
static NSString *const METHOD_SHARETEXT = @"shareText";
static NSString *const METHOD_SHAREIMAGE = @"shareImage";
static NSString *const METHOD_SHAREFILE = @"shareFile";
static NSString *const METHOD_SHAREEMOJI = @"shareEmoji";
static NSString *const METHOD_SHAREMUSIC = @"shareMusic";
static NSString *const METHOD_SHAREVIDEO = @"shareVideo";
static NSString *const METHOD_SHAREWEBPAGE = @"shareWebpage";
static NSString *const METHOD_SHAREMINIPROGRAM = @"shareMiniProgram";
static NSString *const METHOD_SUBSCRIBEMSG = @"subscribeMsg";
static NSString *const METHOD_LAUNCHMINIPROGRAM = @"launchMiniProgram";
static NSString *const METHOD_OPENCUSTOMERSERVICECHAT = @"openCustomerServiceChat";
static NSString *const METHOD_OPENBUSINESSVIEW = @"openBusinessView";
static NSString *const METHOD_OPENBUSINESSWEBVIEW = @"openBusinessWebview";
#ifndef NO_PAY
static NSString *const METHOD_PAY = @"pay";
#endif
static NSString *const METHOD_ONLAUNCHFROMWXREQ = @"onLaunchFromWXReq";
static NSString *const METHOD_ONSHOWMESSAGEFROMWXREQ = @"onShowMessageFromWXReq";
static NSString *const METHOD_ONAUTHRESP = @"onAuthResp";
static NSString *const METHOD_ONOPENURLRESP = @"onOpenUrlResp";
static NSString *const METHOD_ONSHAREMSGRESP = @"onShareMsgResp";
static NSString *const METHOD_ONSUBSCRIBEMSGRESP = @"onSubscribeMsgResp";
static NSString *const METHOD_ONLAUNCHMINIPROGRAMRESP = @"onLaunchMiniProgramResp";
static NSString *const METHOD_ONOPENCUSTOMERSERVICECHATRESP = @"onOpenCustomerServiceChatResp";
static NSString *const METHOD_ONOPENBUSINESSVIEWRESP = @"onOpenBusinessViewResp";
static NSString *const METHOD_ONOPENBUSINESSWEBVIEWRESP = @"onOpenBusinessWebviewResp";
#ifndef NO_PAY
static NSString *const METHOD_ONPAYRESP = @"onPayResp";
#endif
static NSString *const METHOD_ONAUTHGOTQRCODE = @"onAuthGotQrcode";
static NSString *const METHOD_ONAUTHQRCODESCANNED = @"onAuthQrcodeScanned";
static NSString *const METHOD_ONAUTHFINISH = @"onAuthFinish";
static NSString *const ARGUMENT_KEY_APPID = @"appId";
static NSString *const ARGUMENT_KEY_UNIVERSALLINK = @"universalLink";
static NSString *const ARGUMENT_KEY_SCOPE = @"scope";
static NSString *const ARGUMENT_KEY_STATE = @"state";
static NSString *const ARGUMENT_KEY_NONCESTR = @"noncestr";
static NSString *const ARGUMENT_KEY_TIMESTAMP = @"timestamp";
static NSString *const ARGUMENT_KEY_SIGNATURE = @"signature";
static NSString *const ARGUMENT_KEY_URL = @"url";
static NSString *const ARGUMENT_KEY_QUERY = @"query";
static NSString *const ARGUMENT_KEY_USERNAME = @"username";
static NSString *const ARGUMENT_KEY_SCENE = @"scene";
static NSString *const ARGUMENT_KEY_TEXT = @"text";
static NSString *const ARGUMENT_KEY_TITLE = @"title";
static NSString *const ARGUMENT_KEY_DESCRIPTION = @"description";
static NSString *const ARGUMENT_KEY_THUMBDATA = @"thumbData";
static NSString *const ARGUMENT_KEY_IMAGEDATA = @"imageData";
static NSString *const ARGUMENT_KEY_IMAGEURI = @"imageUri";
static NSString *const ARGUMENT_KEY_FILEDATA = @"fileData";
static NSString *const ARGUMENT_KEY_FILEURI = @"fileUri";
static NSString *const ARGUMENT_KEY_FILEEXTENSION = @"fileExtension";
static NSString *const ARGUMENT_KEY_EMOJIDATA = @"emojiData";
static NSString *const ARGUMENT_KEY_EMOJIURI = @"emojiUri";
static NSString *const ARGUMENT_KEY_MUSICURL = @"musicUrl";
static NSString *const ARGUMENT_KEY_MUSICDATAURL = @"musicDataUrl";
static NSString *const ARGUMENT_KEY_MUSICLOWBANDURL = @"musicLowBandUrl";
static NSString *const ARGUMENT_KEY_MUSICLOWBANDDATAURL =
@"musicLowBandDataUrl";
static NSString *const ARGUMENT_KEY_VIDEOURL = @"videoUrl";
static NSString *const ARGUMENT_KEY_VIDEOLOWBANDURL = @"videoLowBandUrl";
static NSString *const ARGUMENT_KEY_WEBPAGEURL = @"webpageUrl";
static NSString *const ARGUMENT_KEY_PATH = @"path";
static NSString *const ARGUMENT_KEY_HDIMAGEDATA = @"hdImageData";
static NSString *const ARGUMENT_KEY_WITHSHARETICKET = @"withShareTicket";
static NSString *const ARGUMENT_KEY_TYPE = @"type";
static NSString *const ARGUMENT_KEY_DISABLEFORWARD = @"disableForward";
static NSString *const ARGUMENT_KEY_TEMPLATEID = @"templateId";
static NSString *const ARGUMENT_KEY_RESERVED = @"reserved";
static NSString *const ARGUMENT_KEY_CORPID = @"corpId";
static NSString *const ARGUMENT_KEY_BUSINESSTYPE = @"businessType";
static NSString *const ARGUMENT_KEY_QUERYINFO = @"queryInfo";
#ifndef NO_PAY
static NSString *const ARGUMENT_KEY_PARTNERID = @"partnerId";
static NSString *const ARGUMENT_KEY_PREPAYID = @"prepayId";
// static NSString *const ARGUMENT_KEY_NONCESTR = @"noncestr";
// static NSString *const ARGUMENT_KEY_TIMESTAMP = @"timestamp";
static NSString *const ARGUMENT_KEY_PACKAGE = @"package";
static NSString *const ARGUMENT_KEY_SIGN = @"sign";
#endif
static NSString *const ARGUMENT_KEY_EXTINFO = @"extInfo";
static NSString *const ARGUMENT_KEY_RESULT_ERRORCODE = @"errorCode";
static NSString *const ARGUMENT_KEY_RESULT_ERRORMSG = @"errorMsg";
static NSString *const ARGUMENT_KEY_RESULT_CODE = @"code";
static NSString *const ARGUMENT_KEY_RESULT_STATE = @"state";
static NSString *const ARGUMENT_KEY_RESULT_LANG = @"lang";
static NSString *const ARGUMENT_KEY_RESULT_COUNTRY = @"country";
static NSString *const ARGUMENT_KEY_RESULT_TEMPLATEID = @"templateId";
static NSString *const ARGUMENT_KEY_RESULT_SCENE = @"scene";
static NSString *const ARGUMENT_KEY_RESULT_ACTION = @"action";
static NSString *const ARGUMENT_KEY_RESULT_RESERVED = @"reserved";
static NSString *const ARGUMENT_KEY_RESULT_EXTMSG = @"extMsg";
static NSString *const ARGUMENT_KEY_RESULT_BUSINESSTYPE = @"businessType";
static NSString *const ARGUMENT_KEY_RESULT_RESULTINFO = @"resultInfo";
static NSString *const ARGUMENT_KEY_RESULT_MESSAGEACTION = @"messageAction";
static NSString *const ARGUMENT_KEY_RESULT_MESSAGEEXT = @"messageExt";
static NSString *const ARGUMENT_KEY_RESULT_RETURNKEY = @"returnKey";
static NSString *const ARGUMENT_KEY_RESULT_IMAGEDATA = @"imageData";
static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (instancetype)initWithChannel:(FlutterMethodChannel *)channel {
self = [super init];
if (self) {
@ -159,13 +44,13 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleMethodCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
if ([METHOD_REGISTERAPP isEqualToString:call.method]) {
NSString *appId = call.arguments[ARGUMENT_KEY_APPID];
NSString *universalLink = call.arguments[ARGUMENT_KEY_UNIVERSALLINK];
if ([@"registerApp" isEqualToString:call.method]) {
NSString *appId = call.arguments[@"appId"];
NSString *universalLink = call.arguments[@"universalLink"];
[WXApi registerApp:appId universalLink:universalLink];
_isRunning = YES;
result(nil);
} else if ([METHOD_HANDLEINITIALWXREQ isEqualToString:call.method]) {
} else if ([@"handleInitialWXReq" isEqualToString:call.method]) {
if (!_handleInitialWXReqFlag) {
_handleInitialWXReqFlag = YES;
if (_initialWXReqRunnable != nil) {
@ -176,48 +61,48 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
} else {
result([FlutterError errorWithCode:@"FAILED" message:nil details:nil]);
}
} else if ([METHOD_ISINSTALLED isEqualToString:call.method]) {
} else if ([@"isInstalled" isEqualToString:call.method]) {
result([NSNumber numberWithBool:[WXApi isWXAppInstalled]]);
} else if ([METHOD_ISSUPPORTAPI isEqualToString:call.method]) {
} else if ([@"isSupportApi" isEqualToString:call.method]) {
result([NSNumber numberWithBool:[WXApi isWXAppSupportApi]]);
} else if ([METHOD_ISSUPPORTSTATEAPI isEqualToString:call.method]) {
} else if ([@"isSupportStateApi" isEqualToString:call.method]) {
result([NSNumber numberWithBool:[WXApi isWXAppSupportStateAPI]]);
} else if ([METHOD_OPENWECHAT isEqualToString:call.method]) {
} else if ([@"openWechat" isEqualToString:call.method]) {
result([NSNumber numberWithBool:[WXApi openWXApp]]);
} else if ([METHOD_AUTH isEqualToString:call.method]) {
} else if ([@"auth" isEqualToString:call.method]) {
[self handleAuthCall:call result:result];
} else if ([@"sendAuth" isEqualToString:call.method]) {
[self handleSendAuthCall:call result:result];
}else if ([METHOD_STARTQRAUTH isEqualToString:call.method] ||
[METHOD_STOPQRAUTH isEqualToString:call.method]) {
} else if ([@"startQrauth" isEqualToString:call.method] ||
[@"stopQrauth" isEqualToString:call.method]) {
[self handleQRAuthCall:call result:result];
} else if ([METHOD_OPENURL isEqualToString:call.method]) {
} else if ([@"openUrl" isEqualToString:call.method]) {
[self handleOpenUrlCall:call result:result];
} else if ([METHOD_OPENRANKLIST isEqualToString:call.method]) {
} else if ([@"openRankList" isEqualToString:call.method]) {
[self handleOpenRankListCall:call result:result];
} else if ([METHOD_SHARETEXT isEqualToString:call.method]) {
} else if ([@"shareText" isEqualToString:call.method]) {
[self handleShareTextCall:call result:result];
} else if ([METHOD_SHAREIMAGE isEqualToString:call.method] ||
[METHOD_SHAREFILE isEqualToString:call.method] ||
[METHOD_SHAREEMOJI isEqualToString:call.method] ||
[METHOD_SHAREMUSIC isEqualToString:call.method] ||
[METHOD_SHAREVIDEO isEqualToString:call.method] ||
[METHOD_SHAREWEBPAGE isEqualToString:call.method] ||
[METHOD_SHAREMINIPROGRAM isEqualToString:call.method]) {
} else if ([@"shareImage" isEqualToString:call.method] ||
[@"shareFile" isEqualToString:call.method] ||
[@"shareEmoji" isEqualToString:call.method] ||
[@"shareMusic" isEqualToString:call.method] ||
[@"shareVideo" isEqualToString:call.method] ||
[@"shareWebpage" isEqualToString:call.method] ||
[@"shareMiniProgram" isEqualToString:call.method]) {
[self handleShareMediaCall:call result:result];
} else if ([METHOD_SUBSCRIBEMSG isEqualToString:call.method]) {
} else if ([@"subscribeMsg" isEqualToString:call.method]) {
[self handleSubscribeMsgCall:call result:result];
} else if ([METHOD_LAUNCHMINIPROGRAM isEqualToString:call.method]) {
} else if ([@"launchMiniProgram" isEqualToString:call.method]) {
[self handleLaunchMiniProgramCall:call result:result];
} else if ([METHOD_OPENCUSTOMERSERVICECHAT isEqualToString:call.method]) {
} else if ([@"openCustomerServiceChat" isEqualToString:call.method]) {
[self handleOpenCustomerServiceChatCall:call result:result];
} else if ([METHOD_OPENBUSINESSVIEW isEqualToString:call.method]) {
} else if ([@"openBusinessView" isEqualToString:call.method]) {
[self handleOpenBusinessViewCall:call result:result];
} else if ([METHOD_OPENBUSINESSWEBVIEW isEqualToString:call.method]) {
} else if ([@"openBusinessWebview" isEqualToString:call.method]) {
[self handleOpenBusinessWebviewCall:call result:result];
}
#ifndef NO_PAY
else if ([METHOD_PAY isEqualToString:call.method]) {
else if ([@"pay" isEqualToString:call.method]) {
[self handlePayCall:call result:result];
}
#endif
@ -228,8 +113,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result {
SendAuthReq *req = [[SendAuthReq alloc] init];
req.scope = call.arguments[ARGUMENT_KEY_SCOPE];
req.state = call.arguments[ARGUMENT_KEY_STATE];
req.scope = call.arguments[@"scope"];
req.state = call.arguments[@"state"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -239,8 +124,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleSendAuthCall:(FlutterMethodCall *)call result:(FlutterResult)result {
SendAuthReq *req = [[SendAuthReq alloc] init];
req.scope = call.arguments[ARGUMENT_KEY_SCOPE];
req.state = call.arguments[ARGUMENT_KEY_STATE];
req.scope = call.arguments[@"scope"];
req.state = call.arguments[@"state"];
UIViewController *viewController = [[[[UIApplication sharedApplication] delegate] window] rootViewController];
[WXApi sendAuthReq:req
viewController:viewController
@ -253,19 +138,19 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleQRAuthCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
if ([METHOD_STARTQRAUTH isEqualToString:call.method]) {
NSString *appId = call.arguments[ARGUMENT_KEY_APPID];
NSString *scope = call.arguments[ARGUMENT_KEY_SCOPE];
NSString *noncestr = call.arguments[ARGUMENT_KEY_NONCESTR];
NSString *timestamp = call.arguments[ARGUMENT_KEY_TIMESTAMP];
NSString *signature = call.arguments[ARGUMENT_KEY_SIGNATURE];
if ([@"startQrauth" isEqualToString:call.method]) {
NSString *appId = call.arguments[@"appId"];
NSString *scope = call.arguments[@"scope"];
NSString *noncestr = call.arguments[@"noncestr"];
NSString *timestamp = call.arguments[@"timestamp"];
NSString *signature = call.arguments[@"signature"];
[_qrauth Auth:appId
nonceStr:noncestr
timeStamp:timestamp
scope:scope
signature:signature
schemeData:nil];
} else if ([METHOD_STOPQRAUTH isEqualToString:call.method]) {
} else if ([@"stopQrauth" isEqualToString:call.method]) {
[_qrauth StopAuth];
}
result(nil);
@ -274,7 +159,7 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleOpenUrlCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
OpenWebviewReq *req = [[OpenWebviewReq alloc] init];
req.url = call.arguments[ARGUMENT_KEY_URL];
req.url = call.arguments[@"url"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -295,10 +180,10 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleShareTextCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE];
NSNumber *scene = call.arguments[@"scene"];
req.scene = [scene intValue];
req.bText = YES;
req.text = call.arguments[ARGUMENT_KEY_TEXT];
req.text = call.arguments[@"text"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -309,84 +194,84 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleShareMediaCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
SendMessageToWXReq *req = [[SendMessageToWXReq alloc] init];
NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE];
NSNumber *scene = call.arguments[@"scene"];
req.scene = [scene intValue];
req.bText = NO;
WXMediaMessage *message = [WXMediaMessage message];
message.title = call.arguments[ARGUMENT_KEY_TITLE];
message.description = call.arguments[ARGUMENT_KEY_DESCRIPTION];
FlutterStandardTypedData *thumbData = call.arguments[ARGUMENT_KEY_THUMBDATA];
message.title = call.arguments[@"title"];
message.description = call.arguments[@"description"];
FlutterStandardTypedData *thumbData = call.arguments[@"thumbData"];
if (thumbData != nil) {
message.thumbData = thumbData.data;
}
if ([METHOD_SHAREIMAGE isEqualToString:call.method]) {
if ([@"shareImage" isEqualToString:call.method]) {
WXImageObject *mediaObject = [WXImageObject object];
FlutterStandardTypedData *imageData =
call.arguments[ARGUMENT_KEY_IMAGEDATA];
call.arguments[@"imageData"];
if (imageData != nil) {
mediaObject.imageData = imageData.data;
} else {
NSString *imageUri = call.arguments[ARGUMENT_KEY_IMAGEURI];
NSString *imageUri = call.arguments[@"imageUri"];
NSURL *imageUrl = [NSURL URLWithString:imageUri];
mediaObject.imageData = [NSData dataWithContentsOfFile:imageUrl.path];
}
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREFILE isEqualToString:call.method]) {
} else if ([@"shareFile" isEqualToString:call.method]) {
WXFileObject *mediaObject = [WXFileObject object];
FlutterStandardTypedData *fileData = call.arguments[ARGUMENT_KEY_FILEDATA];
FlutterStandardTypedData *fileData = call.arguments[@"fileData"];
if (fileData != nil) {
mediaObject.fileData = fileData.data;
} else {
NSString *fileUri = call.arguments[ARGUMENT_KEY_FILEURI];
NSString *fileUri = call.arguments[@"fileUri"];
NSURL *fileUrl = [NSURL URLWithString:fileUri];
mediaObject.fileData = [NSData dataWithContentsOfFile:fileUrl.path];
}
mediaObject.fileExtension = call.arguments[ARGUMENT_KEY_FILEEXTENSION];
mediaObject.fileExtension = call.arguments[@"fileExtension"];
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREEMOJI isEqualToString:call.method]) {
} else if ([@"shareEmoji" isEqualToString:call.method]) {
WXEmoticonObject *mediaObject = [WXEmoticonObject object];
FlutterStandardTypedData *emojiData =
call.arguments[ARGUMENT_KEY_EMOJIDATA];
call.arguments[@"emojiData"];
if (emojiData != nil) {
mediaObject.emoticonData = emojiData.data;
} else {
NSString *emojiUri = call.arguments[ARGUMENT_KEY_EMOJIURI];
NSString *emojiUri = call.arguments[@"emojiUri"];
NSURL *emojiUrl = [NSURL URLWithString:emojiUri];
mediaObject.emoticonData = [NSData dataWithContentsOfFile:emojiUrl.path];
}
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREMUSIC isEqualToString:call.method]) {
} else if ([@"shareMusic" isEqualToString:call.method]) {
WXMusicObject *mediaObject = [WXMusicObject object];
mediaObject.musicUrl = call.arguments[ARGUMENT_KEY_MUSICURL];
mediaObject.musicDataUrl = call.arguments[ARGUMENT_KEY_MUSICDATAURL];
mediaObject.musicLowBandUrl = call.arguments[ARGUMENT_KEY_MUSICLOWBANDURL];
mediaObject.musicUrl = call.arguments[@"musicUrl"];
mediaObject.musicDataUrl = call.arguments[@"musicDataUrl"];
mediaObject.musicLowBandUrl = call.arguments[@"musicLowBandUrl"];
mediaObject.musicLowBandDataUrl =
call.arguments[ARGUMENT_KEY_MUSICLOWBANDDATAURL];
call.arguments[@"musicLowBandDataUrl"];
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREVIDEO isEqualToString:call.method]) {
} else if ([@"shareVideo" isEqualToString:call.method]) {
WXVideoObject *mediaObject = [WXVideoObject object];
mediaObject.videoUrl = call.arguments[ARGUMENT_KEY_VIDEOURL];
mediaObject.videoLowBandUrl = call.arguments[ARGUMENT_KEY_VIDEOLOWBANDURL];
mediaObject.videoUrl = call.arguments[@"videoUrl"];
mediaObject.videoLowBandUrl = call.arguments[@"videoLowBandUrl"];
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREWEBPAGE isEqualToString:call.method]) {
} else if ([@"shareWebpage" isEqualToString:call.method]) {
WXWebpageObject *mediaObject = [WXWebpageObject object];
mediaObject.webpageUrl = call.arguments[ARGUMENT_KEY_WEBPAGEURL];
mediaObject.webpageUrl = call.arguments[@"webpageUrl"];
message.mediaObject = mediaObject;
} else if ([METHOD_SHAREMINIPROGRAM isEqualToString:call.method]) {
} else if ([@"shareMiniProgram" isEqualToString:call.method]) {
WXMiniProgramObject *mediaObject = [WXMiniProgramObject object];
mediaObject.webpageUrl = call.arguments[ARGUMENT_KEY_WEBPAGEURL];
mediaObject.userName = call.arguments[ARGUMENT_KEY_USERNAME];
mediaObject.path = call.arguments[ARGUMENT_KEY_PATH];
mediaObject.webpageUrl = call.arguments[@"webpageUrl"];
mediaObject.userName = call.arguments[@"username"];
mediaObject.path = call.arguments[@"path"];
FlutterStandardTypedData *hdImageData =
call.arguments[ARGUMENT_KEY_HDIMAGEDATA];
call.arguments[@"hdImageData"];
if (hdImageData != nil) {
mediaObject.hdImageData = hdImageData.data;
}
NSNumber *withShareTicket = call.arguments[ARGUMENT_KEY_WITHSHARETICKET];
NSNumber *withShareTicket = call.arguments[@"withShareTicket"];
mediaObject.withShareTicket = withShareTicket.boolValue;
NSNumber *miniProgramType = call.arguments[ARGUMENT_KEY_TYPE];
NSNumber *miniProgramType = call.arguments[@"type"];
mediaObject.miniProgramType = miniProgramType.unsignedIntegerValue;
NSNumber *disableForward = call.arguments[ARGUMENT_KEY_DISABLEFORWARD];
NSNumber *disableForward = call.arguments[@"disableForward"];
mediaObject.disableForward = disableForward.boolValue;
message.mediaObject = mediaObject;
}
@ -401,14 +286,14 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleSubscribeMsgCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXSubscribeMsgReq *req = [[WXSubscribeMsgReq alloc] init];
NSNumber *scene = call.arguments[ARGUMENT_KEY_SCENE];
NSNumber *scene = call.arguments[@"scene"];
#if __LP64__
req.scene = [scene unsignedIntValue];
#else
req.scene = [scene unsignedLongValue];
#endif
req.templateId = call.arguments[ARGUMENT_KEY_TEMPLATEID];
req.reserved = call.arguments[ARGUMENT_KEY_RESERVED];
req.templateId = call.arguments[@"templateId"];
req.reserved = call.arguments[@"reserved"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -419,9 +304,9 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleLaunchMiniProgramCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXLaunchMiniProgramReq *req = [[WXLaunchMiniProgramReq alloc] init];
req.userName = call.arguments[ARGUMENT_KEY_USERNAME];
req.path = call.arguments[ARGUMENT_KEY_PATH];
NSNumber *miniProgramType = call.arguments[ARGUMENT_KEY_TYPE];
req.userName = call.arguments[@"username"];
req.path = call.arguments[@"path"];
NSNumber *miniProgramType = call.arguments[@"type"];
req.miniProgramType = miniProgramType.unsignedIntegerValue;
[WXApi sendReq:req
completion:^(BOOL success){
@ -433,8 +318,8 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleOpenCustomerServiceChatCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXOpenCustomerServiceReq *req = [[WXOpenCustomerServiceReq alloc] init];
req.corpid = call.arguments[ARGUMENT_KEY_CORPID];
req.url = call.arguments[ARGUMENT_KEY_URL];
req.corpid = call.arguments[@"corpId"];
req.url = call.arguments[@"url"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -445,9 +330,9 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleOpenBusinessViewCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXOpenBusinessViewReq *req = [[WXOpenBusinessViewReq alloc] init];
req.businessType = call.arguments[ARGUMENT_KEY_BUSINESSTYPE];
req.query = call.arguments[ARGUMENT_KEY_QUERY];
req.extInfo = call.arguments[ARGUMENT_KEY_EXTINFO];
req.businessType = call.arguments[@"businessType"];
req.query = call.arguments[@"query"];
req.extInfo = call.arguments[@"extInfo"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -458,26 +343,26 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)handleOpenBusinessWebviewCall:(FlutterMethodCall *)call
result:(FlutterResult)result {
WXOpenBusinessWebViewReq *req = [[WXOpenBusinessWebViewReq alloc] init];
NSNumber *businessType = call.arguments[ARGUMENT_KEY_BUSINESSTYPE];
NSNumber *businessType = call.arguments[@"businessType"];
#if __LP64__
req.businessType = [businessType unsignedIntValue];
#else
req.businessType = [businessType unsignedLongValue];
#endif
req.queryInfoDic = call.arguments[ARGUMENT_KEY_QUERYINFO];
req.queryInfoDic = call.arguments[@"queryInfo"];
result(nil);
}
#ifndef NO_PAY
- (void)handlePayCall:(FlutterMethodCall *)call result:(FlutterResult)result {
PayReq *req = [[PayReq alloc] init];
req.partnerId = call.arguments[ARGUMENT_KEY_PARTNERID];
req.prepayId = call.arguments[ARGUMENT_KEY_PREPAYID];
req.nonceStr = call.arguments[ARGUMENT_KEY_NONCESTR];
NSString *timeStamp = call.arguments[ARGUMENT_KEY_TIMESTAMP];
req.partnerId = call.arguments[@"partnerId"];
req.prepayId = call.arguments[@"prepayId"];
req.nonceStr = call.arguments[@"noncestr"];
NSString *timeStamp = call.arguments[@"timestamp"];
req.timeStamp = [timeStamp intValue];
req.package = call.arguments[ARGUMENT_KEY_PACKAGE];
req.sign = call.arguments[ARGUMENT_KEY_SIGN];
req.package = call.arguments[@"package"];
req.sign = call.arguments[@"sign"];
[WXApi sendReq:req
completion:^(BOOL success){
// do nothing
@ -518,32 +403,32 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
if ([req isKindOfClass:[LaunchFromWXReq class]]) {
LaunchFromWXReq *launchFromWXReq = (LaunchFromWXReq *)req;
[dictionary setValue:launchFromWXReq.message.messageAction forKey:ARGUMENT_KEY_RESULT_MESSAGEACTION];
[dictionary setValue:launchFromWXReq.message.messageExt forKey:ARGUMENT_KEY_RESULT_MESSAGEEXT];
[dictionary setValue:launchFromWXReq.lang forKey:ARGUMENT_KEY_RESULT_LANG];
[dictionary setValue:launchFromWXReq.country forKey:ARGUMENT_KEY_RESULT_COUNTRY];
[dictionary setValue:launchFromWXReq.message.messageAction forKey:@"messageAction"];
[dictionary setValue:launchFromWXReq.message.messageExt forKey:@"messageExt"];
[dictionary setValue:launchFromWXReq.lang forKey:@"lang"];
[dictionary setValue:launchFromWXReq.country forKey:@"country"];
if (_isRunning) {
[_channel invokeMethod:METHOD_ONLAUNCHFROMWXREQ arguments:dictionary];
[_channel invokeMethod:@"onLaunchFromWXReq" arguments:dictionary];
} else {
__weak typeof(self) weakSelf = self;
_initialWXReqRunnable = ^() {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf -> _channel invokeMethod:METHOD_ONLAUNCHFROMWXREQ arguments:dictionary];
[strongSelf->_channel invokeMethod:@"onLaunchFromWXReq" arguments:dictionary];
};
}
} else if ([req isKindOfClass:[ShowMessageFromWXReq class]]) {
ShowMessageFromWXReq *showMessageFromWXReq = (ShowMessageFromWXReq *)req;
[dictionary setValue:showMessageFromWXReq.message.messageAction forKey:ARGUMENT_KEY_RESULT_MESSAGEACTION];
[dictionary setValue:showMessageFromWXReq.message.messageExt forKey:ARGUMENT_KEY_RESULT_MESSAGEEXT];
[dictionary setValue:showMessageFromWXReq.lang forKey:ARGUMENT_KEY_RESULT_LANG];
[dictionary setValue:showMessageFromWXReq.country forKey:ARGUMENT_KEY_RESULT_COUNTRY];
[dictionary setValue:showMessageFromWXReq.message.messageAction forKey:@"messageAction"];
[dictionary setValue:showMessageFromWXReq.message.messageExt forKey:@"messageExt"];
[dictionary setValue:showMessageFromWXReq.lang forKey:@"lang"];
[dictionary setValue:showMessageFromWXReq.country forKey:@"country"];
if (_isRunning) {
[_channel invokeMethod:METHOD_ONSHOWMESSAGEFROMWXREQ arguments:dictionary];
[_channel invokeMethod:@"onShowMessageFromWXReq" arguments:dictionary];
} else {
__weak typeof(self) weakSelf = self;
_initialWXReqRunnable = ^() {
__strong typeof(weakSelf) strongSelf = weakSelf;
[strongSelf -> _channel invokeMethod:METHOD_ONSHOWMESSAGEFROMWXREQ arguments:dictionary];
[strongSelf->_channel invokeMethod:@"onShowMessageFromWXReq" arguments:dictionary];
};
}
}
@ -552,75 +437,75 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
- (void)onResp:(BaseResp *)resp {
NSMutableDictionary *dictionary = [NSMutableDictionary dictionary];
[dictionary setValue:[NSNumber numberWithInt:resp.errCode]
forKey:ARGUMENT_KEY_RESULT_ERRORCODE];
forKey:@"errorCode"];
if (resp.errStr != nil) {
[dictionary setValue:resp.errStr forKey:ARGUMENT_KEY_RESULT_ERRORMSG];
[dictionary setValue:resp.errStr forKey:@"errorMsg"];
}
if ([resp isKindOfClass:[SendAuthResp class]]) {
// 授权
if (resp.errCode == WXSuccess) {
SendAuthResp *authResp = (SendAuthResp *)resp;
[dictionary setValue:authResp.code forKey:ARGUMENT_KEY_RESULT_CODE];
[dictionary setValue:authResp.state forKey:ARGUMENT_KEY_RESULT_STATE];
[dictionary setValue:authResp.lang forKey:ARGUMENT_KEY_RESULT_LANG];
[dictionary setValue:authResp.country forKey:ARGUMENT_KEY_RESULT_COUNTRY];
[dictionary setValue:authResp.code forKey:@"code"];
[dictionary setValue:authResp.state forKey:@"state"];
[dictionary setValue:authResp.lang forKey:@"lang"];
[dictionary setValue:authResp.country forKey:@"country"];
}
[_channel invokeMethod:METHOD_ONAUTHRESP arguments:dictionary];
[_channel invokeMethod:@"onAuthResp" arguments:dictionary];
} else if ([resp isKindOfClass:[OpenWebviewResp class]]) {
// 浏览器
[_channel invokeMethod:METHOD_ONOPENURLRESP arguments:dictionary];
[_channel invokeMethod:@"onOpenUrlResp" arguments:dictionary];
} else if ([resp isKindOfClass:[SendMessageToWXResp class]]) {
// 分享
[_channel invokeMethod:METHOD_ONSHAREMSGRESP arguments:dictionary];
[_channel invokeMethod:@"onShareMsgResp" arguments:dictionary];
} else if ([resp isKindOfClass:[WXSubscribeMsgResp class]]) {
// 一次性订阅消息
if (resp.errCode == WXSuccess) {
WXSubscribeMsgResp *subscribeMsgResp = (WXSubscribeMsgResp *)resp;
[dictionary setValue:subscribeMsgResp.templateId
forKey:ARGUMENT_KEY_RESULT_TEMPLATEID];
forKey:@"templateId"];
[dictionary
setValue:[NSNumber numberWithUnsignedInt:subscribeMsgResp.scene]
forKey:ARGUMENT_KEY_RESULT_SCENE];
forKey:@"scene"];
[dictionary setValue:subscribeMsgResp.action
forKey:ARGUMENT_KEY_RESULT_ACTION];
forKey:@"action"];
[dictionary setValue:subscribeMsgResp.reserved
forKey:ARGUMENT_KEY_RESULT_RESERVED];
forKey:@"reserved"];
}
[_channel invokeMethod:METHOD_ONSUBSCRIBEMSGRESP arguments:dictionary];
[_channel invokeMethod:@"onSubscribeMsgResp" arguments:dictionary];
} else if ([resp isKindOfClass:[WXLaunchMiniProgramResp class]]) {
// 打开小程序
if (resp.errCode == WXSuccess) {
WXLaunchMiniProgramResp *launchMiniProgramResp =
(WXLaunchMiniProgramResp *)resp;
[dictionary setValue:launchMiniProgramResp.extMsg
forKey:ARGUMENT_KEY_RESULT_EXTMSG];
forKey:@"extMsg"];
}
[_channel invokeMethod:METHOD_ONLAUNCHMINIPROGRAMRESP arguments:dictionary];
[_channel invokeMethod:@"onLaunchMiniProgramResp" arguments:dictionary];
} else if ([resp isKindOfClass:[WXOpenCustomerServiceResp class]]) {
[_channel invokeMethod:METHOD_ONOPENCUSTOMERSERVICECHATRESP arguments:dictionary];
[_channel invokeMethod:@"onOpenCustomerServiceChatResp" arguments:dictionary];
} else if ([resp isKindOfClass:[WXOpenBusinessViewResp class]]) {
if (resp.errCode == WXSuccess) {
WXOpenBusinessViewResp *openBusinessViewResp = (WXOpenBusinessViewResp *)resp;
[dictionary setValue:openBusinessViewResp.businessType forKey:ARGUMENT_KEY_RESULT_BUSINESSTYPE];
[dictionary setValue:openBusinessViewResp.extMsg forKey:ARGUMENT_KEY_RESULT_EXTMSG];
[dictionary setValue:openBusinessViewResp.businessType forKey:@"businessType"];
[dictionary setValue:openBusinessViewResp.extMsg forKey:@"extMsg"];
}
[_channel invokeMethod:METHOD_ONOPENBUSINESSVIEWRESP arguments:dictionary];
[_channel invokeMethod:@"onOpenBusinessViewResp" arguments:dictionary];
} else if ([resp isKindOfClass:[WXOpenBusinessWebViewResp class]]) {
if (resp.errCode == WXSuccess) {
WXOpenBusinessWebViewResp *openBusinessWebviewResp = (WXOpenBusinessWebViewResp *)resp;
[dictionary setValue:[NSNumber numberWithUnsignedInt:openBusinessWebviewResp.businessType] forKey:ARGUMENT_KEY_RESULT_BUSINESSTYPE];
[dictionary setValue:openBusinessWebviewResp.result forKey:ARGUMENT_KEY_RESULT_RESULTINFO];
[dictionary setValue:[NSNumber numberWithUnsignedInt:openBusinessWebviewResp.businessType] forKey:@"businessType"];
[dictionary setValue:openBusinessWebviewResp.result forKey:@"resultInfo"];
}
[_channel invokeMethod:METHOD_ONOPENBUSINESSWEBVIEWRESP arguments:dictionary];
[_channel invokeMethod:@"onOpenBusinessWebviewResp" arguments:dictionary];
}
#ifndef NO_PAY
else if ([resp isKindOfClass:[PayResp class]]) {
// 支付
if (resp.errCode == WXSuccess) {
PayResp *payResp = (PayResp *)resp;
[dictionary setValue:payResp.returnKey forKey:ARGUMENT_KEY_RESULT_RETURNKEY];
[dictionary setValue:payResp.returnKey forKey:@"returnKey"];
}
[_channel invokeMethod:METHOD_ONPAYRESP arguments:dictionary];
[_channel invokeMethod:@"onPayResp" arguments:dictionary];
}
#endif
}
@ -633,21 +518,21 @@ static NSString *const ARGUMENT_KEY_RESULT_AUTHCODE = @"authCode";
imageData = UIImageJPEGRepresentation(image, 1);
}
NSDictionary *dictionary = @{
ARGUMENT_KEY_RESULT_IMAGEDATA : imageData,
@"imageData" : imageData,
};
[_channel invokeMethod:METHOD_ONAUTHGOTQRCODE arguments:dictionary];
[_channel invokeMethod:@"onAuthGotQrcode" arguments:dictionary];
}
- (void)onQrcodeScanned {
[_channel invokeMethod:METHOD_ONAUTHQRCODESCANNED arguments:nil];
[_channel invokeMethod:@"onAuthQrcodeScanned" arguments:nil];
}
- (void)onAuthFinish:(int)errCode AuthCode:(NSString *)authCode {
NSDictionary *dictionary = @{
ARGUMENT_KEY_RESULT_ERRORCODE : [NSNumber numberWithInt:errCode],
ARGUMENT_KEY_RESULT_AUTHCODE : authCode,
@"errorCode" : [NSNumber numberWithInt:errCode],
@"authCode" : authCode,
};
[_channel invokeMethod:METHOD_ONAUTHFINISH arguments:dictionary];
[_channel invokeMethod:@"onAuthFinish" arguments:dictionary];
}
@end

View File

@ -1,6 +1,6 @@
#
# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html.
# Run `pod lib lint wechat_kit.podspec' to validate before publishing.
# Run `pod lib lint wechat_kit.podspec` to validate before publishing.
#
if defined?($WechatKitSubspec)
@ -11,19 +11,19 @@ end
Pod::Spec.new do |s|
s.name = 'wechat_kit'
s.version = '3.2.0'
s.version = '4.0.0'
s.summary = 'The Flutter plugin for WeChat SDKs.'
s.description = <<-DESC
A powerful Flutter plugin allowing developers to auth/pay/share with native Android & iOS WeChat SDKs.
DESC
s.homepage = 'https://github.com/RxReader/wechat_kit'
s.homepage = 'http://example.com'
s.license = { :file => '../LICENSE' }
s.author = { 'RxReader' => 'email@example.com' }
s.author = { 'Your Company' => 'email@example.com' }
s.source = { :path => '.' }
s.source_files = 'Classes/**/*'
s.public_header_files = 'Classes/**/*.h'
s.dependency 'Flutter'
s.platform = :ios, '8.0'
s.platform = :ios, '9.0'
s.static_framework = true
# s.default_subspecs = :none

600
lib/src/wechat.dart Executable file → Normal file
View File

@ -1,335 +1,129 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/services.dart';
import 'package:wechat_kit/src/model/qrauth.dart';
import 'package:wechat_kit/src/model/req.dart';
import 'package:wechat_kit/src/model/resp.dart';
import 'package:wechat_kit/src/wechat_constant.dart';
import 'package:wechat_kit/src/wechat_kit_platform_interface.dart';
/// The Wechat instance.
class Wechat {
Wechat._();
static Wechat get instance => _instance;
static late final Wechat _instance = Wechat._();
static const String _METHOD_REGISTERAPP = 'registerApp';
static const String _METHOD_HANDLEINITIALWXREQ = 'handleInitialWXReq';
static const String _METHOD_ISINSTALLED = 'isInstalled';
static const String _METHOD_ISSUPPORTAPI = 'isSupportApi';
static const String _METHOD_ISSUPPORTSTATEAPI = 'isSupportStateAPI';
static const String _METHOD_OPENWECHAT = 'openWechat';
static const String _METHOD_AUTH = 'auth';
static const String _METHOD_STARTQRAUTH = 'startQrauth';
static const String _METHOD_STOPQRAUTH = 'stopQrauth';
static const String _METHOD_OPENURL = 'openUrl';
static const String _METHOD_OPENRANKLIST = 'openRankList';
static const String _METHOD_SHARETEXT = 'shareText';
static const String _METHOD_SHAREIMAGE = 'shareImage';
static const String _METHOD_SHAREFILE = 'shareFile';
static const String _METHOD_SHAREEMOJI = 'shareEmoji';
static const String _METHOD_SHAREMUSIC = 'shareMusic';
static const String _METHOD_SHAREVIDEO = 'shareVideo';
static const String _METHOD_SHAREWEBPAGE = 'shareWebpage';
static const String _METHOD_SHAREMINIPROGRAM = 'shareMiniProgram';
static const String _METHOD_SUBSCRIBEMSG = 'subscribeMsg';
static const String _METHOD_LAUNCHMINIPROGRAM = 'launchMiniProgram';
static const String _METHOD_OPENCUSTOMERSERVICECHAT =
'openCustomerServiceChat';
static const String _METHOD_OPENBUSINESSVIEW = 'openBusinessView';
static const String _METHOD_OPENBUSINESSWEBVIEW = 'openBusinessWebview';
static const String _METHOD_PAY = 'pay';
static const String _METHOD_ONLAUNCHFROMWXREQ = 'onLaunchFromWXReq';
static const String _METHOD_ONSHOWMESSAGEFROMWXREQ = 'onShowMessageFromWXReq';
static const String _METHOD_ONAUTHRESP = 'onAuthResp';
static const String _METHOD_ONOPENURLRESP = 'onOpenUrlResp';
static const String _METHOD_ONSHAREMSGRESP = 'onShareMsgResp';
static const String _METHOD_ONSUBSCRIBEMSGRESP = 'onSubscribeMsgResp';
static const String _METHOD_ONLAUNCHMINIPROGRAMRESP =
'onLaunchMiniProgramResp';
static const String _METHOD_ONOPENCUSTOMERSERVICECHATRESP =
'onOpenCustomerServiceChatResp';
static const String _METHOD_ONOPENBUSINESSVIEWRESP = 'onOpenBusinessViewResp';
static const String _METHOD_ONOPENBUSINESSWEBVIEWRESP =
'onOpenBusinessWebviewResp';
static const String _METHOD_ONPAYRESP = 'onPayResp';
static const String _METHOD_ONAUTHGOTQRCODE = 'onAuthGotQrcode';
static const String _METHOD_ONAUTHQRCODESCANNED = 'onAuthQrcodeScanned';
static const String _METHOD_ONAUTHFINISH = 'onAuthFinish';
static const String _ARGUMENT_KEY_APPID = 'appId';
static const String _ARGUMENT_KEY_UNIVERSALLINK = 'universalLink';
static const String _ARGUMENT_KEY_SCOPE = 'scope';
static const String _ARGUMENT_KEY_STATE = 'state';
static const String _ARGUMENT_KEY_NONCESTR = 'noncestr';
static const String _ARGUMENT_KEY_TIMESTAMP = 'timestamp';
static const String _ARGUMENT_KEY_SIGNATURE = 'signature';
static const String _ARGUMENT_KEY_URL = 'url';
static const String _ARGUMENT_KEY_QUERY = 'query';
static const String _ARGUMENT_KEY_USERNAME = 'username';
static const String _ARGUMENT_KEY_SCENE = 'scene';
static const String _ARGUMENT_KEY_TEXT = 'text';
static const String _ARGUMENT_KEY_TITLE = 'title';
static const String _ARGUMENT_KEY_DESCRIPTION = 'description';
static const String _ARGUMENT_KEY_THUMBDATA = 'thumbData';
static const String _ARGUMENT_KEY_IMAGEDATA = 'imageData';
static const String _ARGUMENT_KEY_IMAGEURI = 'imageUri';
static const String _ARGUMENT_KEY_FILEDATA = 'fileData';
static const String _ARGUMENT_KEY_FILEURI = 'fileUri';
static const String _ARGUMENT_KEY_FILEEXTENSION = 'fileExtension';
static const String _ARGUMENT_KEY_EMOJIDATA = 'emojiData';
static const String _ARGUMENT_KEY_EMOJIURI = 'emojiUri';
static const String _ARGUMENT_KEY_MUSICURL = 'musicUrl';
static const String _ARGUMENT_KEY_MUSICDATAURL = 'musicDataUrl';
static const String _ARGUMENT_KEY_MUSICLOWBANDURL = 'musicLowBandUrl';
static const String _ARGUMENT_KEY_MUSICLOWBANDDATAURL = 'musicLowBandDataUrl';
static const String _ARGUMENT_KEY_VIDEOURL = 'videoUrl';
static const String _ARGUMENT_KEY_VIDEOLOWBANDURL = 'videoLowBandUrl';
static const String _ARGUMENT_KEY_WEBPAGEURL = 'webpageUrl';
static const String _ARGUMENT_KEY_PATH = 'path';
static const String _ARGUMENT_KEY_HDIMAGEDATA = 'hdImageData';
static const String _ARGUMENT_KEY_WITHSHARETICKET = 'withShareTicket';
static const String _ARGUMENT_KEY_TYPE = 'type';
static const String _ARGUMENT_KEY_DISABLEFORWARD = 'disableForward';
static const String _ARGUMENT_KEY_TEMPLATEID = 'templateId';
static const String _ARGUMENT_KEY_RESERVED = 'reserved';
static const String _ARGUMENT_KEY_CORPID = 'corpId';
static const String _ARGUMENT_KEY_BUSINESSTYPE = 'businessType';
static const String _ARGUMENT_KEY_QUERYINFO = 'queryInfo';
static const String _ARGUMENT_KEY_PARTNERID = 'partnerId';
static const String _ARGUMENT_KEY_PREPAYID = 'prepayId';
static const String _ARGUMENT_KEY_PACKAGE = 'package';
static const String _ARGUMENT_KEY_SIGN = 'sign';
static const String _ARGUMENT_KEY_EXTINFO = 'extInfo';
static const String _SCHEME_FILE = 'file';
late final MethodChannel _channel =
const MethodChannel('v7lin.github.io/wechat_kit')
..setMethodCallHandler(_handleMethod);
final StreamController<BaseReq> _reqStreamController =
StreamController<BaseReq>.broadcast();
final StreamController<BaseResp> _respStreamController =
StreamController<BaseResp>.broadcast();
final StreamController<QrauthResp> _qrauthRespStreamController =
StreamController<QrauthResp>.broadcast();
const Wechat._();
/// 向微信注册应用
Future<void> registerApp({
static Future<void> registerApp({
required String appId,
required String? universalLink,
}) {
assert(!Platform.isIOS || (universalLink?.isNotEmpty ?? false));
return _channel.invokeMethod<void>(
_METHOD_REGISTERAPP,
<String, dynamic>{
_ARGUMENT_KEY_APPID: appId,
_ARGUMENT_KEY_UNIVERSALLINK: universalLink,
},
return WechatKitPlatform.instance.registerApp(
appId: appId,
universalLink: universalLink,
);
}
/// 微信回调 - 冷启
Future<void> handleInitialWXReq() {
return _channel.invokeMethod<void>(_METHOD_HANDLEINITIALWXREQ);
}
Future<dynamic> _handleMethod(MethodCall call) async {
// 优先处理不需要参数的请求
if (call.method == _METHOD_ONAUTHQRCODESCANNED) {
_qrauthRespStreamController.add(const QrcodeScannedResp());
return;
}
final Map<String, dynamic> _data =
(call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>();
switch (call.method) {
// onReq
case _METHOD_ONLAUNCHFROMWXREQ:
_reqStreamController.add(LaunchFromWXReq.fromJson(_data));
break;
case _METHOD_ONSHOWMESSAGEFROMWXREQ:
_reqStreamController.add(ShowMessageFromWXReq.fromJson(_data));
break;
// onResp
case _METHOD_ONAUTHRESP:
_respStreamController.add(AuthResp.fromJson(_data));
break;
case _METHOD_ONOPENURLRESP:
_respStreamController.add(OpenUrlResp.fromJson(_data));
break;
case _METHOD_ONSHAREMSGRESP:
_respStreamController.add(ShareMsgResp.fromJson(_data));
break;
case _METHOD_ONSUBSCRIBEMSGRESP:
_respStreamController.add(SubscribeMsgResp.fromJson(_data));
break;
case _METHOD_ONLAUNCHMINIPROGRAMRESP:
_respStreamController.add(LaunchMiniProgramResp.fromJson(_data));
break;
case _METHOD_ONOPENCUSTOMERSERVICECHATRESP:
_respStreamController.add(OpenCustomerServiceChatResp.fromJson(_data));
break;
case _METHOD_ONOPENBUSINESSVIEWRESP:
_respStreamController.add(OpenBusinessViewResp.fromJson(_data));
break;
case _METHOD_ONOPENBUSINESSWEBVIEWRESP:
_respStreamController.add(OpenBusinessWebviewResp.fromJson(_data));
break;
case _METHOD_ONPAYRESP:
_respStreamController.add(PayResp.fromJson(_data));
break;
// onQrauth
case _METHOD_ONAUTHGOTQRCODE:
_qrauthRespStreamController.add(GotQrcodeResp.fromJson(_data));
break;
case _METHOD_ONAUTHFINISH:
_qrauthRespStreamController.add(FinishResp.fromJson(_data));
break;
}
///
static Stream<BaseReq> reqStream() {
return WechatKitPlatform.instance.reqStream();
}
///
Stream<BaseReq> reqStream() {
return _reqStreamController.stream;
}
///
Stream<BaseResp> respStream() {
return _respStreamController.stream;
static Stream<BaseResp> respStream() {
return WechatKitPlatform.instance.respStream();
}
/// 扫码登录
Stream<QrauthResp> qrauthRespStream() {
return _qrauthRespStreamController.stream;
static Stream<QrauthResp> qrauthRespStream() {
return WechatKitPlatform.instance.qrauthRespStream();
}
/// 微信回调 - 冷启
static Future<void> handleInitialWXReq() {
return WechatKitPlatform.instance.handleInitialWXReq();
}
/// 检测微信是否已安装
Future<bool> isInstalled() async {
return await _channel.invokeMethod<bool>(_METHOD_ISINSTALLED) ?? false;
static Future<bool> isInstalled() {
return WechatKitPlatform.instance.isInstalled();
}
/// 判断当前微信的版本是否支持OpenApi
Future<bool> isSupportApi() async {
return await _channel.invokeMethod<bool>(_METHOD_ISSUPPORTAPI) ?? false;
static Future<bool> isSupportApi() {
return WechatKitPlatform.instance.isSupportApi();
}
/// 判断当前微信的版本是否支持分享微信状态功能
Future<bool> isSupportStateAPI() async {
return await _channel.invokeMethod<bool>(_METHOD_ISSUPPORTSTATEAPI) ??
false;
static Future<bool> isSupportStateApi() {
return WechatKitPlatform.instance.isSupportStateApi();
}
/// 打开微信
Future<bool> openWechat() async {
return await _channel.invokeMethod<bool>(_METHOD_OPENWECHAT) ?? false;
static Future<bool> openWechat() {
return WechatKitPlatform.instance.openWechat();
}
// --- 微信APP授权登录
/// 授权登录
Future<void> auth({
static Future<void> auth({
required List<String> scope,
String? state,
int type = WechatAuthType.NORMAL,
}) {
return _channel.invokeMethod<void>(_METHOD_AUTH, <String, dynamic>{
_ARGUMENT_KEY_SCOPE: scope.join(','), // Scope
if (state != null) _ARGUMENT_KEY_STATE: state,
});
}
/// iOS未安装微信授权登录
Future<void> sendAuth({
required List<String> scope,
String? state,
}) {
assert(Platform.isIOS);
return _channel.invokeMethod<void>('sendAuth', <String, dynamic>{
_ARGUMENT_KEY_SCOPE: scope.join(','), // Scope
if (state != null) _ARGUMENT_KEY_STATE: state,
});
return WechatKitPlatform.instance.auth(
scope: scope,
state: state,
type: type,
);
}
// --- 微信APP扫码登录
/// 调用微信 API 获得 ticket开始扫码登录
Future<void> startQrauth({
static Future<void> startQrauth({
required String appId,
required List<String> scope,
required String noncestr,
required String ticket,
}) {
final String timestamp = '${DateTime.now().millisecondsSinceEpoch}';
final String content = 'appid=$appId'
'&noncestr=$noncestr'
'&sdk_ticket=$ticket'
'&timestamp=$timestamp';
final String signature = hex.encode(
sha1.convert(utf8.encode(content)).bytes,
);
return _channel.invokeMethod<void>(
_METHOD_STARTQRAUTH,
<String, dynamic>{
_ARGUMENT_KEY_APPID: appId,
_ARGUMENT_KEY_SCOPE: scope.join(','), // Scope
_ARGUMENT_KEY_NONCESTR: noncestr,
_ARGUMENT_KEY_TIMESTAMP: timestamp,
_ARGUMENT_KEY_SIGNATURE: signature,
},
return WechatKitPlatform.instance.startQrauth(
appId: appId,
scope: scope,
noncestr: noncestr,
ticket: ticket,
);
}
/// 暂停扫码登录请求
Future<void> stopQrauth() {
return _channel.invokeMethod<void>(_METHOD_STOPQRAUTH);
static Future<void> stopQrauth() {
return WechatKitPlatform.instance.stopQrauth();
}
//
/// 打开指定网页
Future<void> openUrl({
static Future<void> openUrl({
required String url,
}) {
assert(url.length <= 10 * 1024);
return _channel.invokeMethod<void>(
_METHOD_OPENURL,
<String, dynamic>{
_ARGUMENT_KEY_URL: url,
},
);
return WechatKitPlatform.instance.openUrl(url: url);
}
/// 打开硬件排行榜
Future<void> openRankList() {
return _channel.invokeMethod<void>(_METHOD_OPENRANKLIST);
static Future<void> openRankList() {
return WechatKitPlatform.instance.openRankList();
}
/// 分享 - 文本
Future<void> shareText({
static Future<void> shareText({
required int scene,
required String text,
}) {
assert(text.length <= 10 * 1024);
return _channel.invokeMethod<void>(
_METHOD_SHARETEXT,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
_ARGUMENT_KEY_TEXT: text,
},
return WechatKitPlatform.instance.shareText(
scene: scene,
text: text,
);
}
/// 分享 - 图片
Future<void> shareImage({
static Future<void> shareImage({
required int scene,
String? title,
String? description,
@ -337,31 +131,18 @@ class Wechat {
Uint8List? imageData,
Uri? imageUri,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(imageData != null && imageData.lengthInBytes <= 25 * 1024 * 1024) ||
(imageUri != null &&
imageUri.isScheme(_SCHEME_FILE) &&
imageUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(imageUri).lengthSync() <= 25 * 1024 * 1024),
);
return _channel.invokeMethod<void>(
_METHOD_SHAREIMAGE,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
if (imageData != null) _ARGUMENT_KEY_IMAGEDATA: imageData,
if (imageUri != null) _ARGUMENT_KEY_IMAGEURI: imageUri.toString(),
},
return WechatKitPlatform.instance.shareImage(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
imageData: imageData,
imageUri: imageUri,
);
}
/// 分享 - 文件
Future<void> shareFile({
static Future<void> shareFile({
required int scene,
String? title,
String? description,
@ -370,33 +151,19 @@ class Wechat {
Uri? fileUri,
String? fileExtension,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(fileData != null && fileData.lengthInBytes <= 10 * 1024 * 1024) ||
(fileUri != null &&
fileUri.isScheme(_SCHEME_FILE) &&
fileUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(fileUri).lengthSync() <= 10 * 1024 * 1024),
);
assert(Platform.isAndroid || (fileExtension?.isNotEmpty ?? false));
return _channel.invokeMethod<void>(
_METHOD_SHAREFILE,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
if (fileData != null) _ARGUMENT_KEY_FILEDATA: fileData,
if (fileUri != null) _ARGUMENT_KEY_FILEURI: fileUri.toString(),
if (fileExtension != null) _ARGUMENT_KEY_FILEEXTENSION: fileExtension,
},
return WechatKitPlatform.instance.shareFile(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
fileData: fileData,
fileUri: fileUri,
fileExtension: fileExtension,
);
}
/// 分享 - Emoji/GIF
Future<void> shareEmoji({
static Future<void> shareEmoji({
required int scene,
String? title,
String? description,
@ -404,31 +171,18 @@ class Wechat {
Uint8List? emojiData,
Uri? emojiUri,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData.lengthInBytes <= 32 * 1024);
assert(
(emojiData != null && emojiData.lengthInBytes <= 10 * 1024 * 1024) ||
(emojiUri != null &&
emojiUri.isScheme(_SCHEME_FILE) &&
emojiUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(emojiUri).lengthSync() <= 10 * 1024 * 1024),
);
return _channel.invokeMethod<void>(
_METHOD_SHAREEMOJI,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
_ARGUMENT_KEY_THUMBDATA: thumbData,
if (emojiData != null) _ARGUMENT_KEY_EMOJIDATA: emojiData,
if (emojiUri != null) _ARGUMENT_KEY_EMOJIURI: emojiUri.toString(),
},
return WechatKitPlatform.instance.shareEmoji(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
emojiData: emojiData,
emojiUri: emojiUri,
);
}
/// 分享 - 音乐
Future<void> shareMediaMusic({
static Future<void> shareMediaMusic({
required int scene,
String? title,
String? description,
@ -438,32 +192,20 @@ class Wechat {
String? musicLowBandUrl,
String? musicLowBandDataUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(musicUrl != null && musicUrl.length <= 10 * 1024) ||
(musicLowBandUrl != null && musicLowBandUrl.length <= 10 * 1024),
);
return _channel.invokeMethod<void>(
_METHOD_SHAREMUSIC,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
if (musicUrl != null) _ARGUMENT_KEY_MUSICURL: musicUrl,
if (musicDataUrl != null) _ARGUMENT_KEY_MUSICDATAURL: musicDataUrl,
if (musicLowBandUrl != null)
_ARGUMENT_KEY_MUSICLOWBANDURL: musicLowBandUrl,
if (musicLowBandDataUrl != null)
_ARGUMENT_KEY_MUSICLOWBANDDATAURL: musicLowBandDataUrl,
},
return WechatKitPlatform.instance.shareMediaMusic(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
musicUrl: musicUrl,
musicDataUrl: musicDataUrl,
musicLowBandUrl: musicLowBandUrl,
musicLowBandDataUrl: musicLowBandDataUrl,
);
}
/// 分享 - 视频
Future<void> shareVideo({
static Future<void> shareVideo({
required int scene,
String? title,
String? description,
@ -471,53 +213,35 @@ class Wechat {
String? videoUrl,
String? videoLowBandUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(videoUrl != null && videoUrl.length <= 10 * 1024) ||
(videoLowBandUrl != null && videoLowBandUrl.length <= 10 * 1024),
);
return _channel.invokeMethod<void>(
_METHOD_SHAREVIDEO,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
if (videoUrl != null) _ARGUMENT_KEY_VIDEOURL: videoUrl,
if (videoLowBandUrl != null)
_ARGUMENT_KEY_VIDEOLOWBANDURL: videoLowBandUrl,
},
return WechatKitPlatform.instance.shareVideo(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
videoUrl: videoUrl,
videoLowBandUrl: videoLowBandUrl,
);
}
/// 分享 - 网页
Future<void> shareWebpage({
static Future<void> shareWebpage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(webpageUrl.length <= 10 * 1024);
return _channel.invokeMethod<void>(
_METHOD_SHAREWEBPAGE,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
_ARGUMENT_KEY_WEBPAGEURL: webpageUrl,
},
return WechatKitPlatform.instance.shareWebpage(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
webpageUrl: webpageUrl,
);
}
/// 分享 - 小程序 - 目前只支持分享到会话
Future<void> shareMiniProgram({
static Future<void> shareMiniProgram({
required int scene,
String? title,
String? description,
@ -527,77 +251,58 @@ class Wechat {
String? path,
Uint8List? hdImageData,
bool withShareTicket = false,
int type = WechatMiniProgram.release,
int type = WechatMiniProgram.RELEASE,
bool disableForward = false,
}) {
assert(scene == WechatScene.SESSION);
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(hdImageData == null || hdImageData.lengthInBytes <= 128 * 1024);
return _channel.invokeMethod<void>(
_METHOD_SHAREMINIPROGRAM,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene, // Scene
if (title != null) _ARGUMENT_KEY_TITLE: title,
if (description != null) _ARGUMENT_KEY_DESCRIPTION: description,
if (thumbData != null) _ARGUMENT_KEY_THUMBDATA: thumbData,
_ARGUMENT_KEY_WEBPAGEURL: webpageUrl,
_ARGUMENT_KEY_USERNAME: userName,
if (path != null) _ARGUMENT_KEY_PATH: path,
if (hdImageData != null) _ARGUMENT_KEY_HDIMAGEDATA: hdImageData,
_ARGUMENT_KEY_WITHSHARETICKET: withShareTicket,
_ARGUMENT_KEY_TYPE: type,
_ARGUMENT_KEY_DISABLEFORWARD: disableForward,
},
return WechatKitPlatform.instance.shareMiniProgram(
scene: scene,
title: title,
description: description,
thumbData: thumbData,
webpageUrl: webpageUrl,
userName: userName,
path: path,
hdImageData: hdImageData,
withShareTicket: withShareTicket,
type: type,
disableForward: disableForward,
);
}
/// 一次性订阅消息
Future<void> subscribeMsg({
static Future<void> subscribeMsg({
required int scene,
required String templateId,
String? reserved,
}) {
assert(templateId.length <= 1024);
assert(reserved == null || reserved.length <= 1024);
return _channel.invokeMethod<void>(
_METHOD_SUBSCRIBEMSG,
<String, dynamic>{
_ARGUMENT_KEY_SCENE: scene,
_ARGUMENT_KEY_TEMPLATEID: templateId,
if (reserved != null) _ARGUMENT_KEY_RESERVED: reserved,
},
return WechatKitPlatform.instance.subscribeMsg(
scene: scene,
templateId: templateId,
reserved: reserved,
);
}
/// 打开小程序
Future<void> launchMiniProgram({
static Future<void> launchMiniProgram({
required String userName,
String? path,
int type = WechatMiniProgram.release,
int type = WechatMiniProgram.RELEASE,
}) {
return _channel.invokeMethod<void>(
_METHOD_LAUNCHMINIPROGRAM,
<String, dynamic>{
_ARGUMENT_KEY_USERNAME: userName,
if (path != null) _ARGUMENT_KEY_PATH: path,
_ARGUMENT_KEY_TYPE: type,
},
return WechatKitPlatform.instance.launchMiniProgram(
userName: userName,
path: path,
type: type,
);
}
/// 打开微信客服
Future<void> openCustomerServiceChat({
static Future<void> openCustomerServiceChat({
required String corpId,
required String url,
}) {
return _channel.invokeMethod<void>(
_METHOD_OPENCUSTOMERSERVICECHAT,
<String, dynamic>{
_ARGUMENT_KEY_CORPID: corpId,
_ARGUMENT_KEY_URL: url,
},
return WechatKitPlatform.instance.openCustomerServiceChat(
corpId: corpId,
url: url,
);
}
@ -605,34 +310,28 @@ class Wechat {
/// * 免确认模式https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_7.shtml
/// * 需确认授权https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_11.shtml
/// * 拉起小程序https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter6_1_23.shtml
Future<void> openBusinessView({
static Future<void> openBusinessView({
required String businessType,
String? query,
String? extInfo,
}) {
return _channel.invokeMethod<void>(
_METHOD_OPENBUSINESSVIEW,
<String, dynamic>{
_ARGUMENT_KEY_BUSINESSTYPE: businessType,
if (query != null) _ARGUMENT_KEY_QUERY: query,
if (extInfo != null) _ARGUMENT_KEY_EXTINFO: extInfo,
},
return WechatKitPlatform.instance.openBusinessView(
businessType: businessType,
query: query,
extInfo: extInfo,
);
}
/// APP纯签约
/// * APP纯签约-预签约接口https://pay.weixin.qq.com/wiki/doc/api/xiaowei.php?chapter=19_5
/// * APP纯签约-预签约接口https://pay.weixin.qq.com/wiki/doc/api/pap_jt_v2.php?chapter=19_5&index=2_2
Future<void> openBusinessWebview({
static Future<void> openBusinessWebview({
required int businessType,
Map<String, String>? resultInfo,
}) {
return _channel.invokeMethod<void>(
_METHOD_OPENBUSINESSWEBVIEW,
<String, dynamic>{
_ARGUMENT_KEY_BUSINESSTYPE: businessType,
if (resultInfo != null) _ARGUMENT_KEY_QUERYINFO: resultInfo,
},
return WechatKitPlatform.instance.openBusinessWebview(
businessType: businessType,
resultInfo: resultInfo,
);
}
@ -643,7 +342,7 @@ class Wechat {
/// * 默认包含支付,参考 https://github.com/RxReader/wechat_kit/blob/master/example/ios/Podfile
/// 修改 `$WechatKitSubspec = 'no_pay'` 可切换为不包含支付。
/// * 不含「iOS 支付」调用会抛出 [MissingPluginException]。
Future<void> pay({
static Future<void> pay({
required String appId,
required String partnerId,
required String prepayId,
@ -652,17 +351,14 @@ class Wechat {
required String timeStamp,
required String sign,
}) {
return _channel.invokeMethod<void>(
_METHOD_PAY,
<String, dynamic>{
_ARGUMENT_KEY_APPID: appId,
_ARGUMENT_KEY_PARTNERID: partnerId,
_ARGUMENT_KEY_PREPAYID: prepayId,
_ARGUMENT_KEY_NONCESTR: nonceStr,
_ARGUMENT_KEY_TIMESTAMP: timeStamp,
_ARGUMENT_KEY_PACKAGE: package,
_ARGUMENT_KEY_SIGN: sign,
},
return WechatKitPlatform.instance.pay(
appId: appId,
partnerId: partnerId,
prepayId: prepayId,
package: package,
nonceStr: nonceStr,
timeStamp: timeStamp,
sign: sign,
);
}
}

View File

@ -8,6 +8,16 @@ class WechatScope {
static const String SNSAPI_USERINFO = 'snsapi_userinfo';
}
class WechatAuthType {
const WechatAuthType._();
/// APP授权
static const int NORMAL = 0;
/// WEB授权
static const int WEB = 1;
}
class WechatScene {
const WechatScene._();
@ -42,11 +52,11 @@ class WechatMiniProgram {
const WechatMiniProgram._();
/// 正式版
static const int release = 0;
static const int RELEASE = 0;
/// 测试版
static const int test = 1;
static const int TEST = 1;
/// 体验版
static const int preview = 2;
static const int PREVIEW = 2;
}

View File

@ -0,0 +1,549 @@
import 'dart:async';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:convert/convert.dart';
import 'package:crypto/crypto.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/services.dart';
import 'package:wechat_kit/src/model/qrauth.dart';
import 'package:wechat_kit/src/model/req.dart';
import 'package:wechat_kit/src/model/resp.dart';
import 'package:wechat_kit/src/wechat_constant.dart';
import 'package:wechat_kit/src/wechat_kit_platform_interface.dart';
/// An implementation of [WechatKitPlatform] that uses method channels.
class MethodChannelWechatKit extends WechatKitPlatform {
/// The method channel used to interact with the native platform.
@visibleForTesting
late final MethodChannel methodChannel = const MethodChannel('v7lin.github.io/wechat_kit')..setMethodCallHandler(_handleMethod);
final StreamController<BaseReq> _reqStreamController = StreamController<BaseReq>.broadcast();
final StreamController<BaseResp> _respStreamController = StreamController<BaseResp>.broadcast();
final StreamController<QrauthResp> _qrauthRespStreamController = StreamController<QrauthResp>.broadcast();
Future<dynamic> _handleMethod(MethodCall call) async {
// 优先处理不需要参数的请求
if (call.method == 'onAuthQrcodeScanned') {
_qrauthRespStreamController.add(const QrcodeScannedResp());
return;
}
final Map<String, dynamic> data = (call.arguments as Map<dynamic, dynamic>).cast<String, dynamic>();
switch (call.method) {
// onReq
case 'onLaunchFromWXReq':
_reqStreamController.add(LaunchFromWXReq.fromJson(data));
break;
case 'onShowMessageFromWXReq':
_reqStreamController.add(ShowMessageFromWXReq.fromJson(data));
break;
// onResp
case 'onAuthResp':
_respStreamController.add(AuthResp.fromJson(data));
break;
case 'onOpenUrlResp':
_respStreamController.add(OpenUrlResp.fromJson(data));
break;
case 'onShareMsgResp':
_respStreamController.add(ShareMsgResp.fromJson(data));
break;
case 'onSubscribeMsgResp':
_respStreamController.add(SubscribeMsgResp.fromJson(data));
break;
case 'onLaunchMiniProgramResp':
_respStreamController.add(LaunchMiniProgramResp.fromJson(data));
break;
case 'onOpenCustomerServiceChatResp':
_respStreamController.add(OpenCustomerServiceChatResp.fromJson(data));
break;
case 'onOpenBusinessViewResp':
_respStreamController.add(OpenBusinessViewResp.fromJson(data));
break;
case 'onOpenBusinessWebviewResp':
_respStreamController.add(OpenBusinessWebviewResp.fromJson(data));
break;
case 'onPayResp':
_respStreamController.add(PayResp.fromJson(data));
break;
// onQrauth
case 'onAuthGotQrcode':
_qrauthRespStreamController.add(GotQrcodeResp.fromJson(data));
break;
case 'onAuthFinish':
_qrauthRespStreamController.add(FinishResp.fromJson(data));
break;
}
}
@override
Future<void> registerApp({
required String appId,
required String? universalLink,
}) {
assert(!Platform.isIOS || (universalLink?.isNotEmpty ?? false));
return methodChannel.invokeMethod<void>(
'registerApp',
<String, dynamic>{
'appId': appId,
'universalLink': universalLink,
},
);
}
@override
Stream<BaseReq> reqStream() {
return _reqStreamController.stream;
}
@override
Stream<BaseResp> respStream() {
return _respStreamController.stream;
}
@override
Stream<QrauthResp> qrauthRespStream() {
return _qrauthRespStreamController.stream;
}
@override
Future<void> handleInitialWXReq() {
return methodChannel.invokeMethod<void>('handleInitialWXReq');
}
@override
Future<bool> isInstalled() async {
return await methodChannel.invokeMethod<bool>('isInstalled') ?? false;
}
@override
Future<bool> isSupportApi() async {
return await methodChannel.invokeMethod<bool>('isSupportApi') ?? false;
}
@override
Future<bool> isSupportStateApi() async {
return await methodChannel.invokeMethod<bool>('isSupportStateApi') ?? false;
}
@override
Future<bool> openWechat() async {
return await methodChannel.invokeMethod<bool>('openWechat') ?? false;
}
// --- 微信APP授权登录
@override
Future<void> auth({
required List<String> scope,
String? state,
int type = WechatAuthType.NORMAL,
}) {
assert((Platform.isAndroid && type == WechatAuthType.NORMAL) || (Platform.isIOS && <int>[WechatAuthType.NORMAL, WechatAuthType.WEB].contains(type)));
return methodChannel.invokeMethod<void>('auth', <String, dynamic>{
'scope': scope.join(','), // Scope
if (state != null) 'state': state,
'type': type,
});
}
// --- 微信APP扫码登录
@override
Future<void> startQrauth({
required String appId,
required List<String> scope,
required String noncestr,
required String ticket,
}) {
final String timestamp = '${DateTime.now().millisecondsSinceEpoch}';
final String content = 'appid=$appId'
'&noncestr=$noncestr'
'&sdk_ticket=$ticket'
'&timestamp=$timestamp';
final String signature = hex.encode(
sha1.convert(utf8.encode(content)).bytes,
);
return methodChannel.invokeMethod<void>(
'startQrauth',
<String, dynamic>{
'appId': appId,
'scope': scope.join(','), // Scope
'noncestr': noncestr,
'timestamp': timestamp,
'signature': signature,
},
);
}
@override
Future<void> stopQrauth() {
return methodChannel.invokeMethod<void>('stopQrauth');
}
//
@override
Future<void> openUrl({
required String url,
}) {
assert(url.length <= 10 * 1024);
return methodChannel.invokeMethod<void>(
'openUrl',
<String, dynamic>{
'url': url,
},
);
}
@override
Future<void> openRankList() {
return methodChannel.invokeMethod<void>('openRankList');
}
@override
Future<void> shareText({
required int scene,
required String text,
}) {
assert(text.length <= 10 * 1024);
return methodChannel.invokeMethod<void>(
'shareText',
<String, dynamic>{
'scene': scene, // Scene
'text': text,
},
);
}
@override
Future<void> shareImage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? imageData,
Uri? imageUri,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(imageData != null && imageData.lengthInBytes <= 25 * 1024 * 1024) ||
(imageUri != null &&
imageUri.isScheme('file') &&
imageUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(imageUri).lengthSync() <= 25 * 1024 * 1024),
);
return methodChannel.invokeMethod<void>(
'shareImage',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
if (imageData != null) 'imageData': imageData,
if (imageUri != null) 'imageUri': imageUri.toString(),
},
);
}
@override
Future<void> shareFile({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? fileData,
Uri? fileUri,
String? fileExtension,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(fileData != null && fileData.lengthInBytes <= 10 * 1024 * 1024) ||
(fileUri != null &&
fileUri.isScheme('file') &&
fileUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(fileUri).lengthSync() <= 10 * 1024 * 1024),
);
assert(Platform.isAndroid || (fileExtension?.isNotEmpty ?? false));
return methodChannel.invokeMethod<void>(
'shareFile',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
if (fileData != null) 'fileData': fileData,
if (fileUri != null) 'fileUri': fileUri.toString(),
if (fileExtension != null) 'fileExtension': fileExtension,
},
);
}
@override
Future<void> shareEmoji({
required int scene,
String? title,
String? description,
required Uint8List thumbData,
Uint8List? emojiData,
Uri? emojiUri,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData.lengthInBytes <= 32 * 1024);
assert(
(emojiData != null && emojiData.lengthInBytes <= 10 * 1024 * 1024) ||
(emojiUri != null &&
emojiUri.isScheme('file') &&
emojiUri.toFilePath().length <= 10 * 1024 &&
File.fromUri(emojiUri).lengthSync() <= 10 * 1024 * 1024),
);
return methodChannel.invokeMethod<void>(
'shareEmoji',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
'thumbData': thumbData,
if (emojiData != null) 'emojiData': emojiData,
if (emojiUri != null) 'emojiUri': emojiUri.toString(),
},
);
}
@override
Future<void> shareMediaMusic({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? musicUrl,
String? musicDataUrl,
String? musicLowBandUrl,
String? musicLowBandDataUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(musicUrl != null && musicUrl.length <= 10 * 1024) ||
(musicLowBandUrl != null && musicLowBandUrl.length <= 10 * 1024),
);
return methodChannel.invokeMethod<void>(
'shareMusic',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
if (musicUrl != null) 'musicUrl': musicUrl,
if (musicDataUrl != null) 'musicDataUrl': musicDataUrl,
if (musicLowBandUrl != null)
'musicLowBandUrl': musicLowBandUrl,
if (musicLowBandDataUrl != null)
'musicLowBandDataUrl': musicLowBandDataUrl,
},
);
}
@override
Future<void> shareVideo({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? videoUrl,
String? videoLowBandUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(
(videoUrl != null && videoUrl.length <= 10 * 1024) ||
(videoLowBandUrl != null && videoLowBandUrl.length <= 10 * 1024),
);
return methodChannel.invokeMethod<void>(
'shareVideo',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
if (videoUrl != null) 'videoUrl': videoUrl,
if (videoLowBandUrl != null)
'videoLowBandUrl': videoLowBandUrl,
},
);
}
@override
Future<void> shareWebpage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
}) {
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(webpageUrl.length <= 10 * 1024);
return methodChannel.invokeMethod<void>(
'shareWebpage',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
'webpageUrl': webpageUrl,
},
);
}
@override
Future<void> shareMiniProgram({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
required String userName,
String? path,
Uint8List? hdImageData,
bool withShareTicket = false,
int type = WechatMiniProgram.RELEASE,
bool disableForward = false,
}) {
assert(scene == WechatScene.SESSION);
assert(title == null || title.length <= 512);
assert(description == null || description.length <= 1024);
assert(thumbData == null || thumbData.lengthInBytes <= 32 * 1024);
assert(hdImageData == null || hdImageData.lengthInBytes <= 128 * 1024);
return methodChannel.invokeMethod<void>(
'shareMiniProgram',
<String, dynamic>{
'scene': scene, // Scene
if (title != null) 'title': title,
if (description != null) 'description': description,
if (thumbData != null) 'thumbData': thumbData,
'webpageUrl': webpageUrl,
'username': userName,
if (path != null) 'path': path,
if (hdImageData != null) 'hdImageData': hdImageData,
'withShareTicket': withShareTicket,
'type': type,
'disableForward': disableForward,
},
);
}
@override
Future<void> subscribeMsg({
required int scene,
required String templateId,
String? reserved,
}) {
assert(templateId.length <= 1024);
assert(reserved == null || reserved.length <= 1024);
return methodChannel.invokeMethod<void>(
'subscribeMsg',
<String, dynamic>{
'scene': scene,
'templateId': templateId,
if (reserved != null) 'reserved': reserved,
},
);
}
@override
Future<void> launchMiniProgram({
required String userName,
String? path,
int type = WechatMiniProgram.RELEASE,
}) {
return methodChannel.invokeMethod<void>(
'launchMiniProgram',
<String, dynamic>{
'username': userName,
if (path != null) 'path': path,
'type': type,
},
);
}
@override
Future<void> openCustomerServiceChat({
required String corpId,
required String url,
}) {
return methodChannel.invokeMethod<void>(
'openCustomerServiceChat',
<String, dynamic>{
'corpId': corpId,
'url': url,
},
);
}
@override
Future<void> openBusinessView({
required String businessType,
String? query,
String? extInfo,
}) {
return methodChannel.invokeMethod<void>(
'openBusinessView',
<String, dynamic>{
'businessType': businessType,
if (query != null) 'query': query,
if (extInfo != null) 'extInfo': extInfo,
},
);
}
@override
Future<void> openBusinessWebview({
required int businessType,
Map<String, String>? resultInfo,
}) {
return methodChannel.invokeMethod<void>(
'openBusinessWebview',
<String, dynamic>{
'businessType': businessType,
if (resultInfo != null) 'queryInfo': resultInfo,
},
);
}
@override
Future<void> pay({
required String appId,
required String partnerId,
required String prepayId,
required String package,
required String nonceStr,
required String timeStamp,
required String sign,
}) {
return methodChannel.invokeMethod<void>(
'pay',
<String, dynamic>{
'appId': appId,
'partnerId': partnerId,
'prepayId': prepayId,
'noncestr': nonceStr,
'timestamp': timeStamp,
'package': package,
'sign': sign,
},
);
}
}

View File

@ -0,0 +1,247 @@
import 'dart:typed_data';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:wechat_kit/src/model/qrauth.dart';
import 'package:wechat_kit/src/model/req.dart';
import 'package:wechat_kit/src/model/resp.dart';
import 'package:wechat_kit/src/wechat_constant.dart';
import 'package:wechat_kit/src/wechat_kit_method_channel.dart';
abstract class WechatKitPlatform extends PlatformInterface {
/// Constructs a WechatKitPlatform.
WechatKitPlatform() : super(token: _token);
static final Object _token = Object();
static WechatKitPlatform _instance = MethodChannelWechatKit();
/// The default instance of [WechatKitPlatform] to use.
///
/// Defaults to [MethodChannelWechatKit].
static WechatKitPlatform get instance => _instance;
/// Platform-specific implementations should set this with their own
/// platform-specific class that extends [WechatKitPlatform] when
/// they register themselves.
static set instance(WechatKitPlatform instance) {
PlatformInterface.verifyToken(instance, _token);
_instance = instance;
}
Future<void> registerApp({
required String appId,
required String? universalLink,
}) {
throw UnimplementedError('registerApp({required appId, required universalLink}) has not been implemented.');
}
Stream<BaseReq> reqStream() {
throw UnimplementedError('reqStream() has not been implemented.');
}
Stream<BaseResp> respStream() {
throw UnimplementedError('respStream() has not been implemented.');
}
Stream<QrauthResp> qrauthRespStream() {
throw UnimplementedError('qrauthRespStream() has not been implemented.');
}
Future<void> handleInitialWXReq() {
throw UnimplementedError('handleInitialWXReq() has not been implemented.');
}
Future<bool> isInstalled() {
throw UnimplementedError('isInstalled() has not been implemented.');
}
Future<bool> isSupportApi() {
throw UnimplementedError('isSupportApi() has not been implemented.');
}
Future<bool> isSupportStateApi() {
throw UnimplementedError('isSupportStateApi() has not been implemented.');
}
Future<bool> openWechat() {
throw UnimplementedError('openWechat() has not been implemented.');
}
// --- 微信APP授权登录
Future<void> auth({
required List<String> scope,
String? state,
int type = WechatAuthType.NORMAL,
}) {
throw UnimplementedError('auth({required scope, state, type}) has not been implemented.');
}
// --- 微信APP扫码登录
Future<void> startQrauth({
required String appId,
required List<String> scope,
required String noncestr,
required String ticket,
}) {
throw UnimplementedError('startQrauth({required appId, required scope, required noncestr, required ticket}) has not been implemented.');
}
Future<void> stopQrauth() {
throw UnimplementedError('stopQrauth() has not been implemented.');
}
//
Future<void> openUrl({
required String url,
}) {
throw UnimplementedError('openUrl({required url}) has not been implemented.');
}
Future<void> openRankList() {
throw UnimplementedError('openRankList() has not been implemented.');
}
Future<void> shareText({
required int scene,
required String text,
}) {
throw UnimplementedError('shareText({required scene, required text}) has not been implemented.');
}
Future<void> shareImage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? imageData,
Uri? imageUri,
}) {
throw UnimplementedError('shareImage({required scene, title, description, thumbData, imageData, imageUri}) has not been implemented.');
}
Future<void> shareFile({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? fileData,
Uri? fileUri,
String? fileExtension,
}) {
throw UnimplementedError('shareFile({required scene, title, description, thumbData, fileData, fileUri, fileExtension}) has not been implemented.');
}
Future<void> shareEmoji({
required int scene,
String? title,
String? description,
required Uint8List thumbData,
Uint8List? emojiData,
Uri? emojiUri,
}) {
throw UnimplementedError('shareEmoji({required scene, title, description, required thumbData, emojiData, emojiUri}) has not been implemented.');
}
Future<void> shareMediaMusic({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? musicUrl,
String? musicDataUrl,
String? musicLowBandUrl,
String? musicLowBandDataUrl,
}) {
throw UnimplementedError('shareMediaMusic({required scene, title, description, thumbData, musicUrl, musicDataUrl, musicLowBandUrl, musicLowBandDataUrl}) has not been implemented.');
}
Future<void> shareVideo({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? videoUrl,
String? videoLowBandUrl,
}) {
throw UnimplementedError('shareVideo({required scene, title, description, thumbData, videoUrl, videoLowBandUrl}) has not been implemented.');
}
Future<void> shareWebpage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
}) {
throw UnimplementedError('shareWebpage({required scene, title, description, thumbData, required webpageUrl}) has not been implemented.');
}
Future<void> shareMiniProgram({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
required String userName,
String? path,
Uint8List? hdImageData,
bool withShareTicket = false,
int type = WechatMiniProgram.RELEASE,
bool disableForward = false,
}) {
throw UnimplementedError('shareMiniProgram({required scene, title, description, thumbData, required webpageUrl, required userName, path, hdImageData, withShareTicket, type, disableForward}) has not been implemented.');
}
Future<void> subscribeMsg({
required int scene,
required String templateId,
String? reserved,
}) {
throw UnimplementedError('subscribeMsg({required scene, required templateId, reserved}) has not been implemented.');
}
Future<void> launchMiniProgram({
required String userName,
String? path,
int type = WechatMiniProgram.RELEASE,
}) {
throw UnimplementedError('launchMiniProgram({required userName, path, type}) has not been implemented.');
}
Future<void> openCustomerServiceChat({
required String corpId,
required String url,
}) {
throw UnimplementedError('openCustomerServiceChat({required corpId, required url}) has not been implemented.');
}
Future<void> openBusinessView({
required String businessType,
String? query,
String? extInfo,
}) {
throw UnimplementedError('openBusinessView({required businessType, query, extInfo}) has not been implemented.');
}
Future<void> openBusinessWebview({
required int businessType,
Map<String, String>? resultInfo,
}) {
throw UnimplementedError('openBusinessWebview({required businessType, resultInfo}) has not been implemented.');
}
Future<void> pay({
required String appId,
required String partnerId,
required String prepayId,
required String package,
required String nonceStr,
required String timeStamp,
required String sign,
}) {
throw UnimplementedError('pay({required appId, required partnerId, required prepayId, required package, required nonceStr, required timeStamp, required sign}) has not been implemented.');
}
}

0
lib/wechat_kit.dart Executable file → Normal file
View File

View File

@ -1,27 +1,27 @@
name: wechat_kit
description: A powerful Flutter plugin allowing developers to auth/share/pay with natvie Android & iOS Wechat SDKs.
version: 3.2.0
version: 4.0.0
# author: v7lin <v7lin@qq.com>
homepage: https://github.com/rxreader/wechat_kit
environment:
sdk: ">=2.12.0 <3.0.0"
flutter: ">=2.0.0"
sdk: ">=2.17.0 <3.0.0"
flutter: ">=2.5.0"
dependencies:
flutter:
sdk: flutter
plugin_platform_interface: ^2.0.2
convert: ^3.0.0
crypto: ^3.0.0
convert: ^3.0.1
crypto: ^3.0.2
json_annotation: ^4.0.0
json_annotation: ^4.5.0
dev_dependencies:
flutter_test:
sdk: flutter
pedantic:
flutter_lints: ^2.0.0
build_runner:
json_serializable:
@ -29,11 +29,17 @@ dev_dependencies:
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
# The following section is specific to Flutter packages.
flutter:
# This section identifies this Flutter project as a plugin project.
# The 'pluginClass' and Android 'package' identifiers should not ordinarily
# be modified. They are used by the tooling to maintain consistency when
# The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
# which should be registered in the plugin registry. This is required for
# using method channels.
# The Android 'package' specifies package in which the registered class is.
# This is required for using method channels on Android.
# The 'ffiPlugin' specifies that native code should be built and bundled.
# This is required for using `dart:ffi`.
# All these are used by the tooling to maintain consistency when
# adding or updating assets for this project.
plugin:
platforms:
@ -52,7 +58,7 @@ flutter:
# https://flutter.dev/assets-and-images/#from-packages
#
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# https://flutter.dev/assets-and-images/#resolution-aware
# To add custom fonts to your plugin package, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a

View File

@ -0,0 +1,27 @@
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:wechat_kit/src/wechat_kit_method_channel.dart';
void main() {
final MethodChannelWechatKit platform = MethodChannelWechatKit();
const MethodChannel channel = MethodChannel('v7lin.github.io/wechat_kit');
TestWidgetsFlutterBinding.ensureInitialized();
setUp(() {
channel.setMockMethodCallHandler((MethodCall methodCall) async {
switch (methodCall.method) {
case 'isInstalled':
return true;
}
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
test('isInstalled', () async {
expect(await platform.isInstalled(), true);
});
}

View File

@ -1,138 +0,0 @@
import 'dart:async';
import 'dart:convert';
import 'package:flutter/services.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:pedantic/pedantic.dart';
import 'package:wechat_kit/wechat_kit.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
const MethodChannel channel = MethodChannel('v7lin.github.io/wechat_kit');
setUp(() {
channel.setMockMethodCallHandler((MethodCall call) async {
switch (call.method) {
case 'registerApp':
return null;
case 'isInstalled':
return true;
case 'isSupportApi':
return true;
case 'openWechat':
return true;
case 'auth':
unawaited(channel.binaryMessenger.handlePlatformMessage(
channel.name,
channel.codec.encodeMethodCall(MethodCall(
'onAuthResp',
json.decode(
'{"country":"CN","code":null,"errorCode":-2,"state":null,"lang":"zh_CN","errorMsg":null}'))),
(ByteData? data) {
print('mock ${channel.name} ${call.method}');
},
));
return null;
case 'startQrauth':
case 'stopQrauth':
throw PlatformException(code: '0', message: '懒得去mock');
case 'openUrl':
case 'openRankList':
throw PlatformException(code: '0', message: '懒得去mock');
case 'shareText':
case 'shareImage':
case 'shareEmoji':
case 'shareMusic':
case 'shareVideo':
case 'shareWebpage':
case 'shareMiniProgram':
unawaited(channel.binaryMessenger.handlePlatformMessage(
channel.name,
channel.codec.encodeMethodCall(MethodCall('onShareMsgResp',
json.decode('{"errorCode":0,"errorMsg":null}'))),
(ByteData? data) {
print('mock ${channel.name} ${call.method}');
},
));
return null;
case 'subscribeMsg':
case 'launchMiniProgram':
throw PlatformException(code: '0', message: '懒得去mock');
case 'pay':
unawaited(channel.binaryMessenger.handlePlatformMessage(
channel.name,
channel.codec.encodeMethodCall(MethodCall(
'onPayResp',
json.decode(
'{"errorCode":-2,"returnKey":"","errorMsg":null}'))),
(ByteData? data) {
print('mock ${channel.name} ${call.method}');
},
));
return null;
}
throw PlatformException(code: '0', message: '想啥呢升级插件不想升级Mock');
});
});
tearDown(() {
channel.setMockMethodCallHandler(null);
});
test('isInstalled', () async {
expect(await Wechat.instance.isInstalled(), true);
});
test('isSupportApi', () async {
expect(await Wechat.instance.isSupportApi(), true);
});
test('auth', () async {
final StreamSubscription<BaseResp> subs =
Wechat.instance.respStream().listen((BaseResp resp) {
expect(resp.runtimeType, AuthResp);
expect(resp.errorCode, BaseResp.ERRORCODE_USERCANCEL);
});
await Wechat.instance.auth(
scope: <String>[
WechatScope.SNSAPI_USERINFO,
],
);
await Future<void>.delayed(const Duration(seconds: 1));
await subs.cancel();
});
test('share', () async {
final StreamSubscription<BaseResp> subs =
Wechat.instance.respStream().listen((BaseResp resp) {
expect(resp.runtimeType, ShareMsgResp);
expect(resp.errorCode, BaseResp.ERRORCODE_SUCCESS);
});
await Wechat.instance.shareText(
scene: WechatScene.SESSION,
text: 'share text',
);
await Future<void>.delayed(const Duration(seconds: 1));
await subs.cancel();
});
test('pay', () async {
final StreamSubscription<BaseResp> subs =
Wechat.instance.respStream().listen((BaseResp resp) {
expect(resp.runtimeType, PayResp);
expect(resp.errorCode, BaseResp.ERRORCODE_USERCANCEL);
});
await Wechat.instance.pay(
appId: 'mock',
partnerId: 'mock',
prepayId: 'mock',
package: 'mock',
nonceStr: 'mock',
timeStamp: 'mock',
sign: 'mock',
);
await Future<void>.delayed(const Duration(seconds: 1));
await subs.cancel();
});
}

273
test/wechat_test.dart Normal file
View File

@ -0,0 +1,273 @@
import 'dart:typed_data';
import 'package:flutter_test/flutter_test.dart';
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
import 'package:wechat_kit/src/model/qrauth.dart';
import 'package:wechat_kit/src/model/req.dart';
import 'package:wechat_kit/src/model/resp.dart';
import 'package:wechat_kit/src/wechat.dart';
import 'package:wechat_kit/src/wechat_constant.dart';
import 'package:wechat_kit/src/wechat_kit_method_channel.dart';
import 'package:wechat_kit/src/wechat_kit_platform_interface.dart';
class MockWechatKitPlatform with MockPlatformInterfaceMixin implements WechatKitPlatform {
@override
Future<void> registerApp({
required String appId,
required String? universalLink,
}) {
throw UnimplementedError();
}
@override
Stream<BaseReq> reqStream() {
throw UnimplementedError();
}
@override
Stream<BaseResp> respStream() {
throw UnimplementedError();
}
@override
Stream<QrauthResp> qrauthRespStream() {
throw UnimplementedError();
}
@override
Future<void> handleInitialWXReq() {
throw UnimplementedError();
}
@override
Future<bool> isInstalled() {
return Future<bool>.value(true);
}
@override
Future<bool> isSupportApi() {
throw UnimplementedError();
}
@override
Future<bool> isSupportStateApi() {
throw UnimplementedError();
}
@override
Future<bool> openWechat() {
throw UnimplementedError();
}
// --- 微信APP授权登录
@override
Future<void> auth({
required List<String> scope,
String? state,
int type = WechatAuthType.NORMAL,
}) {
throw UnimplementedError();
}
// --- 微信APP扫码登录
@override
Future<void> startQrauth({
required String appId,
required List<String> scope,
required String noncestr,
required String ticket,
}) {
throw UnimplementedError();
}
@override
Future<void> stopQrauth() {
throw UnimplementedError();
}
//
@override
Future<void> openUrl({
required String url,
}) {
throw UnimplementedError();
}
@override
Future<void> openRankList() {
throw UnimplementedError();
}
@override
Future<void> shareText({
required int scene,
required String text,
}) {
throw UnimplementedError();
}
@override
Future<void> shareImage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? imageData,
Uri? imageUri,
}) {
throw UnimplementedError();
}
@override
Future<void> shareFile({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
Uint8List? fileData,
Uri? fileUri,
String? fileExtension,
}) {
throw UnimplementedError();
}
@override
Future<void> shareEmoji({
required int scene,
String? title,
String? description,
required Uint8List thumbData,
Uint8List? emojiData,
Uri? emojiUri,
}) {
throw UnimplementedError();
}
@override
Future<void> shareMediaMusic({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? musicUrl,
String? musicDataUrl,
String? musicLowBandUrl,
String? musicLowBandDataUrl,
}) {
throw UnimplementedError();
}
@override
Future<void> shareVideo({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
String? videoUrl,
String? videoLowBandUrl,
}) {
throw UnimplementedError();
}
@override
Future<void> shareWebpage({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
}) {
throw UnimplementedError();
}
@override
Future<void> shareMiniProgram({
required int scene,
String? title,
String? description,
Uint8List? thumbData,
required String webpageUrl,
required String userName,
String? path,
Uint8List? hdImageData,
bool withShareTicket = false,
int type = WechatMiniProgram.RELEASE,
bool disableForward = false,
}) {
throw UnimplementedError();
}
@override
Future<void> subscribeMsg({
required int scene,
required String templateId,
String? reserved,
}) {
throw UnimplementedError();
}
@override
Future<void> launchMiniProgram({
required String userName,
String? path,
int type = WechatMiniProgram.RELEASE,
}) {
throw UnimplementedError();
}
@override
Future<void> openCustomerServiceChat({
required String corpId,
required String url,
}) {
throw UnimplementedError();
}
@override
Future<void> openBusinessView({
required String businessType,
String? query,
String? extInfo,
}) {
throw UnimplementedError();
}
@override
Future<void> openBusinessWebview({
required int businessType,
Map<String, String>? resultInfo,
}) {
throw UnimplementedError();
}
@override
Future<void> pay({
required String appId,
required String partnerId,
required String prepayId,
required String package,
required String nonceStr,
required String timeStamp,
required String sign,
}) {
throw UnimplementedError();
}
}
void main() {
final WechatKitPlatform initialPlatform = WechatKitPlatform.instance;
test('$MethodChannelWechatKit is the default instance', () {
expect(initialPlatform, isInstanceOf<MethodChannelWechatKit>());
});
test('getPlatformVersion', () async {
final MockWechatKitPlatform fakePlatform = MockWechatKitPlatform();
WechatKitPlatform.instance = fakePlatform;
expect(await Wechat.isInstalled(), true);
});
}