Commit f386c125bba2c49222175b36301343f697317fbe

Authored by weixin_45529955
1 parent 82702a0d

删.git

Showing 94 changed files with 4653 additions and 2 deletions

Too many changes to show.

To preserve performance only 94 of 94+ files are displayed.

@@ -5180,7 +5180,7 @@ class InvicationPageState extends State<InvicationPage> @@ -5180,7 +5180,7 @@ class InvicationPageState extends State<InvicationPage>
5180 5180
5181 //跳转 5181 //跳转
5182 if (reserverPhone != null) { 5182 if (reserverPhone != null) {
5183 - List<String> phoneNumber = [reserverPhone!,'18765434543']; 5183 + List<String> phoneNumber = [reserverPhone!];
5184 5184
5185 try { 5185 try {
5186 String _result = await sendSMS( 5186 String _result = await sendSMS(
1 -Subproject commit a5349371525462b1d1b6cfa4cf4d2a59503f1435  
  1 +zq.xcuserdatad/
  2 +!contents.xcworkspacedata
  3 +.DS_Store
  4 +xcuserdata/
  5 +!xcschemes/
  6 +!xcbaselines/
  7 +.editorconfig
  8 +.idea
  9 +build/
  10 +
  11 +### PreCI ###
  12 +.codecc
  1 +{
  2 + "preCI.localCodeCheck.filter.whitePath": "",
  3 + "preCI.localCodeCheck.filter.skipPath": ".*/\\.codecc/.*,.*/\\.git,.*/\\.git/.*,.*/\\.svn/.*",
  4 + "preCI.localCodeCheck.preCommit": "none",
  5 + "preCI.localCodeCheck.prePush": "none",
  6 + "preCI.pipeline.yamlFilePath": "build.yml",
  7 + "preCI.localCodeCheck.toolType": "binary",
  8 + "preCI.localCodeCheck.checkerSet.JAVA": [
  9 + "standard_java"
  10 + ],
  11 + "preCI.localCodeCheck.checkerSet.OC/OC++": [
  12 + "bkcheck_oc_rule"
  13 + ],
  14 + "preCI.localCodeCheck.checkerSet.Other": [
  15 + "standard_scc"
  16 + ],
  17 + "preCI.localCodeCheck.checkerSet.C/C++": [
  18 + "standard_cpp"
  19 + ],
  20 + "preCI.localCodeCheck.checkerSet.Kotlin": [
  21 + "standard_kotlin"
  22 + ]
  23 +}
  1 +## V1.3.4
  2 +* use TPNS iOS SDK 1.4.0.5
  3 +
  4 +## V1.3.3
  5 +* use TPNS iOS SDK 1.4.0.4
  6 +
  7 +## V1.3.2
  8 +* build.gradle add namespace
  9 +
  10 +## V1.3.1
  11 +* use Android SDK 1.4.3.8
  12 +
  13 +## V1.3.0
  14 +* iOS support privacyInfo
  15 +* use TPNS iOS SDK 1.4.0.1
  16 +
  17 +## V1.2.9
  18 +* demo support null safety
  19 +* use TPNS iOS SDK 1.4.0.0
  20 +
  21 +## V1.2.8
  22 +* Standard iOS/Android callback
  23 +
  24 +## V1.2.7
  25 +* Use TPNS Android SDK 1.4.0.1
  26 +* Use TPNS iOS SDK 1.3.9.8
  27 +* configureClusterDomainName api support Android
  28 +
  29 +## V1.2.6
  30 +* Use TPNS iOS SDK 1.3.9.7
  31 +
  32 +## V1.2.5
  33 +* Use TPNS iOS SDK 1.3.9.6
  34 +
  35 +## V1.2.4
  36 +* Use TPNS Android SDK 1.4.0.1
  37 +
  38 +## V1.2.3
  39 +* Use TPNS iOS SDK 1.3.9.5
  40 +
  41 +## V1.2.2
  42 +* Use TPNS iOS SDK 1.3.9.4
  43 +
  44 +## V1.2.1
  45 +* Use TPNS iOS SDK 1.3.9.3
  46 +
  47 +## V1.2.0
  48 +* Use TPNS iOS SDK 1.3.9.2
  49 +* Change API Doc
  50 +
  51 +## V1.1.9
  52 +* Add iOS CallBack xgPushNetworkConnected
  53 +
  54 +## V1.1.8
  55 +* Use TPNS iOS SDK 1.3.9.1
  56 +
  57 +## V1.1.7
  58 +* Use TPNS Android SDK 1.3.4.3
  59 +* Use TPNS iOS SDK 1.3.9.0
  60 +
  61 +## V1.1.6
  62 +* Use TPNS Android SDK 1.3.2.0
  63 +
  64 +## V1.1.5
  65 +* Use TPNS Android SDK 1.2.7.1
  66 +* Add Api for attributes operation
  67 +
  68 +## V1.1.4
  69 +* Use TPNS iOS SDK 1.3.4.1
  70 +
  71 +## V1.1.3
  72 +* update TPNS Android SDK 1.2.3.1
  73 +* remove redundant manifest configuration in android
  74 +
  75 +## V1.1.2
  76 +* iOS start add optional notification online display
  77 +* Use TPNS iOS SDK 1.3.3.0
  78 +
  79 +## V1.1.1_oc
  80 +
  81 +* plugin delete swift file
  82 +
  83 +## V1.1.1
  84 +
  85 +* Support null safety
  86 +* Use TPNS iOS SDK 1.3.1.1
  87 +
  88 +## V1.0.7
  89 +
  90 +* Use TPNS iOS SDK 1.2.9.0
  91 +* Use TPNS Android SDK 1.2.2.4
  92 +* Add badge configuration api for Android
  93 +
  94 +## V1.0.6
  95 +* Fix api setAccount() not compatible with old version flutter binder
  96 +* Add api getOtherPushType for Android
  97 +
  98 +## V1.0.5
  99 +* Add Api getOtherPushToken for Android
  100 +
  101 +## V1.0.4
  102 +* Account and Tag API updates
  103 +* Add set ApplicationBadge on iOS
  104 +* Modify callback method on Android
  105 +
  106 +## V1.0.3
  107 +* Use TPNS iOS SDK 1.2.7.2
  108 +* Use TPNS Android SDK 1.2.0.2 此版本较旧版本有包名变更,请注意参考 README.md 修改混淆配置;请注意修改 OPPO 通道混淆配置:
  109 +
  110 +## V1.0.1
  111 +* Use TPNS iOS SDK 1.2.6.0
  112 +
  113 +## V1.0.0
  114 +* Use TPNS iOS SDK 1.2.5.4
  115 +* Use TPNS Android SDK 1.1.5.2
  1 +MIT License
  2 +
  3 +Copyright (c) 2020 Tencent
  4 +
  5 +Permission is hereby granted, free of charge, to any person obtaining a copy
  6 +of this software and associated documentation files (the "Software"), to deal
  7 +in the Software without restriction, including without limitation the rights
  8 +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9 +copies of the Software, and to permit persons to whom the Software is
  10 +furnished to do so, subject to the following conditions:
  11 +
  12 +The above copyright notice and this permission notice shall be included in all
  13 +copies or substantial portions of the Software.
  14 +
  15 +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16 +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17 +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18 +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19 +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20 +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  21 +SOFTWARE.
  1 +# tpns_flutter_plugin
  2 +
  3 +## 安装
  4 +- 在工程 pubspec.yaml 中加入 dependencies,在命令行中运行:flutter pub get进行安装
  5 +```yaml
  6 + dependencies:
  7 + tpns_flutter_plugin:
  8 + git:
  9 + url: https://github.com/TencentCloud/TPNS-Flutter-Plugin
  10 + ref: V1.3.4
  11 +```
  12 +
  13 +- 注意:由于TPNS插件名变更xg_flutter_plugin->tpns_flutter_plugin,更新插件时V1.0.4及以上版本请使用tpns_flutter_plugin
  14 +
  15 +
  16 +## 使用
  17 +
  18 +### 集群域名配置(如果您的应用非广州集群请按照以下方法进行域名配置,广州集群请忽略)
  19 +**说明** : 此接口V1.2.7开始支持安卓,若您插件版本>=1.2.7,建议您将原来的Manifest对应域名设置删除,以接口为准.
  20 +#### 集群域名:
  21 + 中国上海:tpns.sh.tencent.com
  22 + 中国香港:tpns.hk.tencent.com
  23 + 新加坡:tpns.sgp.tencent.com
  24 +- 需要在注册方法startXg之前调用以下域名配置函数
  25 + - domainStr 对应集群域名
  26 +```dart
  27 + void configureClusterDomainName(String domainStr);
  28 +```
  29 +
  30 +### iOS
  31 +
  32 +- 执行flutter pub get安装好插件后进入iOS文件目录(cd ios)执行:pod install安装依赖库
  33 +- 在 xcode8 之后需要点开推送选项: TARGETS -> Capabilities -> Push Notification 设为 on 状态
  34 +
  35 +```dart
  36 + import 'package:tpns_flutter_plugin/tpns_flutter_plugin.dart';
  37 +```
  38 +
  39 + 说明(接口使用参考/tpns_flutter_plugin/example/lib/main.dart和/tpns_flutter_plugin/example/lib/ios/homeTest.dart文件)
  40 +
  41 +
  42 +
  43 +
  44 +### Android
  45 +#### 1. 环境配置
  46 +```groovy
  47 + android: {
  48 + ....
  49 + defaultConfig {
  50 + applicationId "替换成自己应用 ID"
  51 + ...
  52 + ndk {
  53 + /// 选择要添加的对应.so 库。
  54 + abiFilters 'armeabi', 'armeabi-v7a', 'x86', 'x86_64', 'mips', 'mips64', 'arm64-v8a',
  55 + }
  56 + //
  57 + manifestPlaceholders = [
  58 + XG_ACCESS_ID : "替换自己的ACCESS_ID", // 信鸽官网注册所得ACCESS_ID
  59 + XG_ACCESS_KEY : "替换自己的ACCESS_KEY", // 信鸽官网注册所得ACCESS_KEY
  60 +
  61 + ]
  62 + }
  63 + }
  64 +```
  65 +
  66 +
  67 +
  68 +#### 2. 代码混淆
  69 +```
  70 + -keep public class * extends android.app.Service
  71 + -keep public class * extends android.content.BroadcastReceiver
  72 + -keep class com.tencent.android.tpush.** {*;}
  73 + -keep class com.tencent.tpns.baseapi.** {*;}
  74 + -keep class com.tencent.tpns.mqttchannel.** {*;}
  75 + -keep class com.tencent.tpns.dataacquisition.** {*;}
  76 +
  77 + -keep class com.tencent.bigdata.baseapi.** {*;} // TPNS-Android-SDK 1.2.0.1 及以上版本不需要此条配置
  78 + -keep class com.tencent.bigdata.mqttchannel.** {*;} // TPNS-Android-SDK 1.2.0.1 及以上版本不需要此条配置
  79 +```
  80 +
  81 +#### 3. 厂商通道接入说明
  82 +
  83 +**说明** : 提供安卓各厂商通道接入方法。
  84 +
  85 +[点击查看](./documents/vendor.md)
  86 +
  87 +
  88 +
  89 +### 启用推送
  90 + /// iOS前台收到通知不希望展示时可将withInAppAlert参数置为false
  91 + /// android 接入厂商通道时,请在此注册方法前调用各厂商通道参数配置接口
  92 +```dart
  93 + void startXg(String accessId, String accessKey, {bool withInAppAlert = true});
  94 +```
  95 +
  96 +### APIs
  97 +
  98 +**说明** : 提供TPNS的所有业务接口。
  99 +
  100 +[点击查看](./documents/APIs.md)
  101 +
  102 +
  103 +### TPNS-Flutter 使用常见问题参考
  104 +[点击查看](https://cloud.tencent.com/document/product/548/48803)
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea/workspace.xml
  5 +/.idea/libraries
  6 +.DS_Store
  7 +/build
  8 +/captures
  1 +group 'com.tencent.tpns.plugin'
  2 +version '1.0-SNAPSHOT'
  3 +
  4 +buildscript {
  5 + ext.kotlin_version = '1.5.31'
  6 + repositories {
  7 + mavenCentral()
  8 + google()
  9 + jcenter()
  10 + }
  11 +
  12 + dependencies {
  13 + classpath 'com.android.tools.build:gradle:3.5.0'
  14 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  15 + }
  16 +}
  17 +
  18 +rootProject.allprojects {
  19 + repositories {
  20 + mavenCentral()
  21 + google()
  22 + jcenter()
  23 + }
  24 +}
  25 +
  26 +apply plugin: 'com.android.library'
  27 +apply plugin: 'kotlin-android'
  28 +
  29 +android {
  30 + namespace "com.tencent.tpns"
  31 + compileSdkVersion 31
  32 +
  33 + sourceSets {
  34 + main.java.srcDirs += 'src/main/kotlin'
  35 + }
  36 + defaultConfig {
  37 + minSdkVersion 16
  38 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  39 + }
  40 + lintOptions {
  41 + disable 'InvalidPackage'
  42 + }
  43 +}
  44 +
  45 +dependencies {
  46 + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  47 + //添加以下依赖
  48 + implementation 'com.tencent.tpns:tpns:1.4.3.8-release'
  49 + compileOnly files('libs/flutter.jar')
  50 +}
  1 +org.gradle.jvmargs=-Xmx1536M
  2 +android.enableR8=true
  3 +android.useAndroidX=true
  4 +android.enableJetifier=true
  1 +distributionBase=GRADLE_USER_HOME
  2 +distributionPath=wrapper/dists
  3 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.2-bin.zip
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.tencent.tpns.plugin">
  3 +
  4 + <application>
  5 +
  6 + <!-- 【可选】APP实现的Receiver,用于接收消息透传和操作结果的回调,请根据需要添加 -->
  7 + <!-- YOUR_PACKAGE_PATH.CustomPushReceiver需要改为自己的Receiver: -->
  8 + <receiver android:name="com.tencent.tpns.plugin.XGMessageReceiver"
  9 + android:exported="true">
  10 + <intent-filter>
  11 + <!-- 接收消息透传 -->
  12 + <action android:name="com.tencent.android.xg.vip.action.PUSH_MESSAGE" />
  13 + <!-- 监听注册、反注册、设置/删除标签、通知被点击等处理结果 -->
  14 + <action android:name="com.tencent.android.xg.vip.action.FEEDBACK" />
  15 + </intent-filter>
  16 + </receiver>
  17 + </application>
  18 +
  19 +</manifest>
  1 +package com.tencent.tpns.plugin;
  2 +
  3 +import android.util.Log;
  4 +import android.content.Context;
  5 +import android.content.pm.PackageInfo;
  6 +import android.content.pm.PackageManager;
  7 +import android.content.pm.PackageManager.NameNotFoundException;
  8 +import android.os.Build;
  9 +import android.telephony.TelephonyManager;
  10 +import android.text.TextUtils;
  11 +
  12 +import java.io.BufferedReader;
  13 +import java.io.IOException;
  14 +import java.io.InputStreamReader;
  15 +import java.util.UUID;
  16 +
  17 +/**
  18 + * 获取系统设备信息的工具类
  19 + */
  20 +public class DeviceInfoUtil {
  21 +
  22 + /* 获取手机唯一序列号 */
  23 + public static String getDeviceId(Context context) {
  24 + TelephonyManager tm =
  25 + (TelephonyManager) context.getSystemService(Context.TELEPHONY_SERVICE);
  26 + String deviceId = tm.getDeviceId();// 手机设备ID,这个ID会被用为用户访问统计
  27 + if (deviceId == null) {
  28 + deviceId = UUID.randomUUID().toString().replaceAll("-", "");
  29 + }
  30 + return deviceId;
  31 + }
  32 +
  33 + /* 获取操作系统版本号 */
  34 + public static String getOsVersion() {
  35 + return Build.VERSION.RELEASE;
  36 + }
  37 +
  38 + /* 获取手机型号 */
  39 + public static String getModel() {
  40 + return Build.MODEL;
  41 + }
  42 +
  43 + /* 获取手机厂商 */
  44 + public static String getManufacturers() {
  45 + return Build.MANUFACTURER;
  46 + }
  47 +
  48 + /* 获取app的版本信息 */
  49 + public static int getVersionCode(Context context) {
  50 + PackageManager manager = context.getPackageManager();
  51 + try {
  52 + PackageInfo packageInfo = manager.getPackageInfo(context.getPackageName(), 0);
  53 + return packageInfo.versionCode;// 系统版本号
  54 + } catch (NameNotFoundException e) {
  55 + e.printStackTrace();
  56 + }
  57 + return 0;
  58 + }
  59 +
  60 + public static String getVersionName(Context context) {
  61 + PackageManager manager = context.getPackageManager();
  62 + try {
  63 + PackageInfo packageInfo = manager.getPackageInfo(context.getPackageName(), 0);
  64 + return packageInfo.versionName;// 系统版本名
  65 + } catch (NameNotFoundException e) {
  66 + e.printStackTrace();
  67 + }
  68 + return "";
  69 + }
  70 +
  71 + /**
  72 + * getSystemProperty
  73 + *
  74 + * @param propName property name
  75 + * @return result
  76 + */
  77 + public static String getSystemProperty(String propName) {
  78 + String line;
  79 + BufferedReader input = null;
  80 + try {
  81 + Process p = Runtime.getRuntime().exec("getprop " + propName);
  82 + input = new BufferedReader(new InputStreamReader(p.getInputStream()), 1024);
  83 + line = input.readLine();
  84 + input.close();
  85 + } catch (IOException ex) {
  86 + return null;
  87 + } finally {
  88 + if (input != null) {
  89 + try {
  90 + input.close();
  91 + } catch (IOException e) {
  92 + Log.d("DeviceInfoUtil", "close bufferedReader error " + e.toString());
  93 + }
  94 + }
  95 + }
  96 + return line;
  97 + }
  98 +
  99 + /**
  100 + * 判断 google miui emui meizu oppo vivo 360 Rom
  101 + *
  102 + * @return result
  103 + */
  104 +
  105 + public static boolean isGoogleRom() {
  106 + String property = getSystemProperty("ro.product.vendor.manufacturer");
  107 + return !TextUtils.isEmpty(property) && property.toLowerCase().contains("google");
  108 + }
  109 +
  110 + public static boolean isMiuiRom() {
  111 + String property = getSystemProperty("ro.miui.ui.version.name");
  112 + return !TextUtils.isEmpty(property);
  113 + }
  114 +
  115 + public static boolean isEmuiRom() {
  116 + String property = getSystemProperty("ro.build.version.emui");
  117 + return !TextUtils.isEmpty(property);
  118 + }
  119 +
  120 + public static boolean isMeizuRom() {
  121 + String property = getSystemProperty("ro.build.display.id");
  122 + return property != null && property.toLowerCase().contains("flyme");
  123 + }
  124 +
  125 + public static boolean isOppoRom() {
  126 + String property = getSystemProperty("ro.build.version.opporom");
  127 + return !TextUtils.isEmpty(property);
  128 + }
  129 +
  130 + public static boolean isVivoRom() {
  131 + String property = getSystemProperty("ro.vivo.os.version");
  132 + return !TextUtils.isEmpty(property);
  133 + }
  134 +
  135 + public static boolean is360Rom() {
  136 + return Build.MANUFACTURER != null
  137 + && (Build.MANUFACTURER.toLowerCase().contains("qiku")
  138 + || Build.MANUFACTURER.contains("360"));
  139 + }
  140 +}
  1 +package com.tencent.tpns.plugin;
  2 +
  3 +public interface Extras {
  4 + //参数
  5 + String DEBUG = "enableDebug";
  6 + String TAG_NAME = "tagName"; //tag名称
  7 + String TAG_NAMES = "tagNames"; //tag名称集合
  8 + String ATTRIBUTES = "attributes";
  9 + String CONTENT = "content"; //
  10 + String RESULT_CODE = "resultCode";
  11 + String MESSAGE = "message";
  12 + String PUSH_TOKEN = "pushToken";
  13 + String TITLE = "title";
  14 + String CUSTOM_MESSAGE = "customMessage";
  15 + String PUSH_CHANNEL = "pushChannel";
  16 + String NOTIFACTION_ID = "notifactionId";
  17 + String NOTIFACTION_ACTION_TYPE = "notifactionActionType";
  18 + String MSG_ID = "msgId";
  19 + String ACTIVITY = "activity";
  20 + String ACTIVITY_NAME = "activityName";
  21 + String ACTION_TYPE = "actionType";
  22 + String ACCOUNT = "account";
  23 + String ACCOUNT_TYPE = "accountType";
  24 + String APP_KEY = "appKey";
  25 + String APP_ID = "appId";
  26 + String HEADER_BEAT_INTERVAL_MS = "heartBeatIntervalMs";
  27 + String XG_PUSH_DID_SET_BADGE = "xgPushDidSetBadge";
  28 + String BADGE_NUM = "badgeNum";
  29 + String CHANNEL_ID = "channelId";
  30 + String CHANNEL_NAME = "channelName";
  31 + String ENABLE_VIBRATION = "enableVibration";
  32 + String ENABLE_LIGHTS = "enableLights";
  33 + String ENABLE_SOUND = "enableSound";
  34 + String SOUND_FILE_NAME = "soundFileName";
  35 + String ADDR = "addr";
  36 + String ACCESSID = "accessId";
  37 + String ACCESSKEY = "accessKey";
  38 +
  39 + //Flutter调用native的函数名称
  40 + String FOR_FLUTTER_METHOD_SET_ACCESSID = "setAccessId";
  41 + String FOR_FLUTTER_METHOD_SET_ACCESSKEY = "setAccessKey";
  42 + String FOR_FLUTTER_METHOD_SET_SERVERSUFFIX = "setServerSuffix";
  43 + String FOR_FLUTTER_METHOD_REG_PUSH = "regPush";
  44 + String FOR_FLUTTER_METHOD_UNREGISTER_PUSH = "stopXg";
  45 + String FOR_FLUTTER_METHOD_SET_TAG = "setXgTag";
  46 + String FOR_FLUTTER_METHOD_SET_TAGS = "setXgTags";
  47 + String FOR_FLUTTER_METHOD_ADD_TAGS = "addXgTags";
  48 + String FOR_FLUTTER_METHOD_DELETE_TAG = "deleteXgTag";
  49 + String FOR_FLUTTER_METHOD_DELETE_TAGS = "deleteXgTags";
  50 + String FOR_FLUTTER_METHOD_CLEAN_TAGS = "cleanXgTags";
  51 + String FOR_FLUTTER_METHOD_GET_TOKEN = "xgToken";
  52 + String FOR_FLUTTER_METHOD_GET_SDK_VERSION = "xgSdkVersion";
  53 + String FOR_FLUTTER_METHOD_BIND_ACCOUNT = "bindAccount";
  54 + String FOR_FLUTTER_METHOD_APPEND_ACCOUNT = "appendAccount";
  55 + String FOR_FLUTTER_METHOD_DEL_ACCOUNT = "delAccount";
  56 + String FOR_FLUTTER_METHOD_DEL_ALL_ACCOUNT = "delAllAccount";
  57 + String FOR_FLUTTER_METHOD_UPSERT_ATTRIBUTES = "upsertAttributes";
  58 + String FOR_FLUTTER_METHOD_DEL_ATTRIBUTES = "delAttributes";
  59 + String FOR_FLUTTER_METHOD_CLEAR_AND_APPEND_ATTRIBUTES = "clearAndAppendAttributes";
  60 + String FOR_FLUTTER_METHOD_CLEAR_ATTRIBUTES = "clearAttributes";
  61 + String FOR_FLUTTER_METHOD_ENABLE_OTHER_PUSH = "enableOtherPush";
  62 + String FOR_FLUTTER_METHOD_ENABLE_OTHER_PUSH2 = "enableOtherPush2";
  63 + String FOR_FLUTTER_METHOD_GET_OTHER_PUSH_TOKEN = "getOtherPushToken";
  64 + String FOR_FLUTTER_METHOD_GET_OTHER_PUSH_TYPE = "getOtherPushType";
  65 + String FOR_FLUTTER_METHOD_ENABLE_PULL_UP_OTHER_APP = "enablePullUpOtherApp";
  66 + String FOR_FLUTTER_METHOD_SET_BADGE_NUM = "setBadgeNum";
  67 + String FOR_FLUTTER_METHOD_RESET_BADGE_NUM = "resetBadgeNum";
  68 + String FOR_FLUTTER_METHOD_CANCEL_ALL_NOTIFICATION = "cancelAllNotification";
  69 + String FOR_FLUTTER_METHOD_CREATE_NOTIFICATION_CHANNEL = "createNotificationChannel";
  70 + String FOR_FLUTTER_METHOD_SET_MI_PUSH_APP_ID = "setMiPushAppId";
  71 + String FOR_FLUTTER_METHOD_SET_MI_PUSH_APP_KEY = "setMiPushAppKey";
  72 + String FOR_FLUTTER_METHOD_SET_MZ_PUSH_ID = "setMzPushAppId";
  73 + String FOR_FLUTTER_METHOD_SET_MZ_PUSH_KEY = "setMzPushAppKey";
  74 + String FOR_FLUTTER_METHOD_ENABLE_OPPO_NOTIFICATION = "enableOppoNotification";
  75 + String FOR_FLUTTER_METHOD_SET_OPPO_PUSH_APP_ID = "setOppoPushAppId";
  76 + String FOR_FLUTTER_METHOD_SET_OPPO_PUSH_APP_KEY = "setOppoPushAppKey";
  77 + String FOR_FLUTTER_METHOD_IS_MIUI_ROM = "isMiuiRom";
  78 + String FOR_FLUTTER_METHOD_IS_EMUI_ROM = "isEmuiRom";
  79 + String FOR_FLUTTER_METHOD_IS_MEIZU_ROM = "isMeizuRom";
  80 + String FOR_FLUTTER_METHOD_IS_OPPO_ROM = "isOppoRom";
  81 + String FOR_FLUTTER_METHOD_IS_VIVO_ROM = "isVivoRom";
  82 + String FOR_FLUTTER_METHOD_IS_360_ROM = "is360Rom";
  83 + String FOR_FLUTTER_METHOD_IS_FCM_ROM = "isFcmRom";
  84 + String FOR_FLUTTER_METHOD_IS_GOOGLE_ROM = "isGoogleRom";
  85 + String FOR_FLUTTER_METHOD_ENABLE_DEBUG = "setEnableDebug";
  86 + String FOR_FLUTTER_METHOD_SET_HEADER_BEAT_INTERVAL_MS = "setHeartbeatIntervalMs";
  87 +
  88 +
  89 + //调用Flutter的函数名称
  90 + String ON_REGISTERED_DEVICE_TOKEN = "onRegisteredDeviceToken"; //注册失败回调
  91 + String ON_REGISTERED_DONE = "onRegisteredDone"; //注册成功回调
  92 + String UN_REGISTERED = "unRegistered"; //反注册回调
  93 + String ON_RECEIVE_NOTIFICATION_RESPONSE = "onReceiveNotificationResponse"; //收到通知
  94 + String ON_RECEIVE_MESSAGE = "onReceiveMessage"; //收到透传通知
  95 + String XG_PUSH_DID_BIND_WITH_IDENENTIFIER = "xgPushDidBindWithIdentifier"; // 绑定账号跟标签
  96 + String XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER = "xgPushDidUnbindWithIdentifier"; //解绑账号跟标签
  97 + String XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER = "xgPushDidUpdatedBindedIdentifier"; //更新账号跟标签
  98 + String XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER = "xgPushDidClearAllIdentifiers"; //清除账号跟标签
  99 + String XG_PUSH_CLICK_ACTION = "xgPushClickAction"; //通知点击事件
  100 +}
  1 +package com.tencent.tpns.plugin;
  2 +
  3 +
  4 +import android.os.Handler;
  5 +import android.os.Looper;
  6 +
  7 +
  8 +public class MainHandler extends Handler {
  9 + private static volatile MainHandler instance;
  10 +
  11 + public static MainHandler getInstance() {
  12 + if (null == instance) {
  13 + synchronized (MainHandler.class) {
  14 + if (null == instance) {
  15 + instance = new MainHandler();
  16 + }
  17 + }
  18 + }
  19 + return instance;
  20 + }
  21 +
  22 + private MainHandler() {
  23 + super(Looper.getMainLooper());
  24 + }
  25 +
  26 +}
  1 +package com.tencent.tpns.plugin;
  2 +
  3 +import android.content.Context;
  4 +import android.os.Handler;
  5 +import android.os.Message;
  6 +import android.text.TextUtils;
  7 +import android.util.Log;
  8 +import com.tencent.android.tpush.XGPushBaseReceiver;
  9 +import com.tencent.android.tpush.XGPushClickedResult;
  10 +import com.tencent.android.tpush.XGPushRegisterResult;
  11 +import com.tencent.android.tpush.XGPushShowedResult;
  12 +import com.tencent.android.tpush.XGPushTextMessage;
  13 +
  14 +import java.util.HashMap;
  15 +import java.util.Map;
  16 +
  17 +public class XGMessageReceiver extends XGPushBaseReceiver {
  18 +
  19 + private static final String TAG = "XGMessageReceiver";
  20 +
  21 + private static ReceiverHandler receiverHandler;
  22 +
  23 + private class ReceiverHandler extends Handler {
  24 +
  25 + private Context context;
  26 + private XGPushClickedResult clickedResult;
  27 +
  28 + public ReceiverHandler(Context context, XGPushClickedResult clickedResult) {
  29 + this.context = context;
  30 + this.clickedResult = clickedResult;
  31 + }
  32 +
  33 + @Override
  34 + public void handleMessage(Message msg) {
  35 + super.handleMessage(msg);
  36 + Log.i(TAG, "ReceiverHandler handleMessage from XgFlutterPlugin init");
  37 + processClickActionToFlutter(context, clickedResult);
  38 + receiverHandler = null;
  39 + }
  40 + }
  41 +
  42 + /**
  43 + * 通知点击冷启动时,MethodChannel 初始化和点击回调的触发时机不固定,可能导致点击回调触发时,MethodChannel 还未初始化。
  44 + *
  45 + * 此处再 MethodChannel 初始化时尝试触发一次 handler,补偿冷启动时点击事件回调给 flutter
  46 + */
  47 + public static void sendHandlerMessage(){
  48 + if (receiverHandler != null) {
  49 + Message m = receiverHandler.obtainMessage();
  50 + m.sendToTarget();
  51 + } else {
  52 + Log.i(TAG, "ReceiverHandler sendHandlerMessage XgFlutterPlugin already init");
  53 + }
  54 + }
  55 +
  56 + @Override
  57 + public void onRegisterResult(Context context, int errorCode, XGPushRegisterResult message) {
  58 + try {
  59 + if (XgFlutterPlugin.instance == null) {
  60 + Log.w(TAG, "XgFlutterPlugin.instance has not initialized");
  61 + return;
  62 + }
  63 + if (context == null || message == null) {
  64 + String msg = "TPNS token: null" + " error: context==null||message == null";
  65 + XgFlutterPlugin.instance.toFlutterMethod(Extras.ON_REGISTERED_DEVICE_TOKEN, msg);
  66 + return;
  67 + }
  68 + if (errorCode == XGPushBaseReceiver.SUCCESS) {
  69 + String token = message.getToken();
  70 + // 过滤掉厂商通道注册结果
  71 + if (!TextUtils.isEmpty(token)) {
  72 + String msg = token;
  73 + XgFlutterPlugin.instance.toFlutterMethod(Extras.ON_REGISTERED_DONE, msg);
  74 + }
  75 + } else {
  76 + String msg = "TPNS token: " + message.getToken() + " error: " + errorCode;
  77 + XgFlutterPlugin.instance.toFlutterMethod(Extras.ON_REGISTERED_DEVICE_TOKEN, msg);
  78 + }
  79 + } catch (Throwable e) {
  80 + Log.w(TAG, "onRegisterResult error: " + e.toString());
  81 + }
  82 + }
  83 +
  84 + @Override
  85 + public void onUnregisterResult(Context context, int errorCode) {
  86 + try {
  87 + if (XgFlutterPlugin.instance == null) {
  88 + Log.w(TAG, "XgFlutterPlugin.instance has not initialized");
  89 + return;
  90 + }
  91 + if (context == null) {
  92 + String msg = "context == null---->Unregister failure";
  93 + XgFlutterPlugin.instance.toFlutterMethod(Extras.UN_REGISTERED, msg);
  94 + return;
  95 + }
  96 + String text = "";
  97 + if (errorCode == XGPushBaseReceiver.SUCCESS) {
  98 + String msg = "Unregister successful";
  99 + XgFlutterPlugin.instance.toFlutterMethod(Extras.UN_REGISTERED, msg);
  100 + } else {
  101 + String msg = "Unregister failure---->code==" + errorCode;
  102 + XgFlutterPlugin.instance.toFlutterMethod(Extras.UN_REGISTERED, msg);
  103 + }
  104 + } catch (Throwable e) {
  105 + Log.w(TAG, "onUnregisterResult error: " + e.toString());
  106 + }
  107 + }
  108 +
  109 + @Override
  110 + public void onSetTagResult(Context context, int errorCode, String s) {
  111 +
  112 + }
  113 +
  114 + @Override
  115 + public void onDeleteTagResult(Context context, int errorCode, String s) {
  116 +
  117 + }
  118 +
  119 + @Override
  120 + public void onSetAccountResult(Context context, int i, String s) {
  121 +
  122 + }
  123 +
  124 + @Override
  125 + public void onDeleteAccountResult(Context context, int i, String s) {
  126 +
  127 + }
  128 +
  129 + @Override
  130 + public void onSetAttributeResult(Context context, int i, String s) {
  131 +
  132 + }
  133 +
  134 + @Override
  135 + public void onDeleteAttributeResult(Context context, int i, String s) {
  136 +
  137 + }
  138 +
  139 + @Override
  140 + public void onQueryTagsResult(Context context, int i, String s, String o) {
  141 +
  142 + }
  143 +
  144 + @Override
  145 + public void onTextMessage(Context context, XGPushTextMessage message) {
  146 + try {
  147 + if (XgFlutterPlugin.instance == null) {
  148 + Log.w(TAG, "XgFlutterPlugin.instance has not initialized");
  149 + return;
  150 + }
  151 + long msgId = message.getMsgId();
  152 + String content = message.getContent();
  153 + String customContent = message.getCustomContent();
  154 + String title = message.getTitle();
  155 + int pushChannel = message.getPushChannel();
  156 + Map<String, Object> para = new HashMap<>();
  157 + para.put(Extras.MSG_ID, msgId);
  158 + para.put(Extras.TITLE, title);
  159 + para.put(Extras.CONTENT, content);
  160 + para.put(Extras.CUSTOM_MESSAGE, customContent);
  161 + para.put(Extras.PUSH_CHANNEL, pushChannel);
  162 + //交由Flutter自主处理
  163 + XgFlutterPlugin.instance.toFlutterMethod(Extras.ON_RECEIVE_MESSAGE, para);
  164 + } catch (Throwable e) {
  165 + Log.w(TAG, "onTextMessage error: " + e.toString());
  166 + }
  167 + }
  168 +
  169 + @Override
  170 + public void onNotificationClickedResult(Context context, XGPushClickedResult notifiShowedRlt) {
  171 + try {
  172 + if (XgFlutterPlugin.instance == null) {
  173 + Log.w(TAG, "XgFlutterPlugin.instance has not initialized");
  174 + receiverHandler = new ReceiverHandler(context, notifiShowedRlt);
  175 + } else {
  176 + processClickActionToFlutter(context, notifiShowedRlt);
  177 + }
  178 + } catch (Throwable e) {
  179 + Log.w(TAG, "onNotificationClickedResult error: " + e.toString());
  180 + }
  181 + }
  182 +
  183 + private void processClickActionToFlutter(Context context, XGPushClickedResult notifiShowedRlt) {
  184 + try {
  185 + if (context == null || notifiShowedRlt == null) {
  186 + Map<String, Object> para = new HashMap<>();
  187 + para.put(Extras.RESULT_CODE, -1);
  188 + para.put(Extras.MESSAGE, "通知栏展示失败----context == null || notifiShowedRlt == null");
  189 +// XgFlutterPlugin.instance.toFlutterMethod(
  190 +// Extras.TO_FLUTTER_METHOD_NOTIFACTION_SHOW_RESULT, para);
  191 + return;
  192 + }
  193 + String content = notifiShowedRlt.getContent();
  194 + String customContent = notifiShowedRlt.getCustomContent();
  195 + String title = notifiShowedRlt.getTitle();
  196 + int notificationActionType = notifiShowedRlt.getNotificationActionType();
  197 + long msgId = notifiShowedRlt.getMsgId();
  198 + String activityName = notifiShowedRlt.getActivityName();
  199 + long actionType = notifiShowedRlt.getActionType();
  200 +
  201 + Map<String, Object> para = new HashMap<>();
  202 + para.put(Extras.TITLE, title);
  203 + para.put(Extras.CONTENT, content);
  204 + para.put(Extras.CUSTOM_MESSAGE, customContent);
  205 + para.put(Extras.MSG_ID, msgId);
  206 + para.put(Extras.NOTIFACTION_ACTION_TYPE, notificationActionType);
  207 + para.put(Extras.ACTIVITY_NAME, activityName);
  208 + para.put(Extras.ACTION_TYPE, actionType);
  209 + //交由Flutter自主处理
  210 + XgFlutterPlugin.instance.toFlutterMethod(Extras.XG_PUSH_CLICK_ACTION, para);
  211 + } catch (Throwable e) {
  212 + Log.w(TAG, "processClickActionToFlutter error: " + e.toString());
  213 + }
  214 + }
  215 +
  216 + @Override
  217 + public void onNotificationShowedResult(Context context, XGPushShowedResult message) {
  218 + try {
  219 + if (XgFlutterPlugin.instance == null) {
  220 + Log.w(TAG, "XgFlutterPlugin.instance has not initialized");
  221 + return;
  222 + }
  223 + if (context == null || message == null) {
  224 + Map<String, Object> para = new HashMap<>();
  225 + para.put(Extras.RESULT_CODE, -1);
  226 + para.put(Extras.MESSAGE, "点击通知失败----context == null || XGPushClickedResult == null");
  227 + // XgFlutterPlugin.instance.toFlutterMethod(
  228 + // Extras.TO_FLUTTER_METHOD_NOTIFACTION_SHOW_RESULT, para);
  229 + return;
  230 + }
  231 + String content = message.getContent();
  232 + String customContent = message.getCustomContent();
  233 + int notifactionId = message.getNotifactionId();
  234 + String title = message.getTitle();
  235 + long msgId = message.getMsgId();
  236 + String activityPath = message.getActivity();
  237 + int pushChannel = message.getPushChannel();
  238 + int notificationActionType = message.getNotificationActionType();
  239 + Map<String, Object> para = new HashMap<>();
  240 + para.put(Extras.CONTENT, content);
  241 + para.put(Extras.CUSTOM_MESSAGE, customContent);
  242 + para.put(Extras.TITLE, title);
  243 + para.put(Extras.PUSH_CHANNEL, pushChannel);
  244 + para.put(Extras.NOTIFACTION_ID, notifactionId);
  245 + para.put(Extras.MSG_ID, msgId);
  246 + para.put(Extras.ACTIVITY, activityPath);
  247 + para.put(Extras.NOTIFACTION_ACTION_TYPE, notificationActionType);
  248 + //交由Flutter自主处理
  249 + XgFlutterPlugin.instance.toFlutterMethod(Extras.ON_RECEIVE_NOTIFICATION_RESPONSE, para);
  250 + } catch (Throwable e) {
  251 + Log.w(TAG, "onNotificationShowedResult error: " + e.toString());
  252 + }
  253 + }
  254 +}
  1 +package com.tencent.tpns.plugin
  2 +
  3 +import android.net.Uri;
  4 +import android.util.Log
  5 +import androidx.annotation.NonNull
  6 +import com.tencent.android.tpush.XGIOperateCallback
  7 +import com.tencent.android.tpush.XGPushConfig
  8 +import com.tencent.tpns.baseapi.XGApiConfig
  9 +import com.tencent.android.tpush.XGPushManager
  10 +import com.tencent.android.tpush.XGPushConstants
  11 +import io.flutter.embedding.engine.plugins.FlutterPlugin
  12 +import io.flutter.plugin.common.MethodCall
  13 +import io.flutter.plugin.common.MethodChannel
  14 +import io.flutter.plugin.common.MethodChannel.MethodCallHandler
  15 +import io.flutter.plugin.common.PluginRegistry.Registrar
  16 +import java.util.*
  17 +
  18 +
  19 +public class XgFlutterPlugin : FlutterPlugin, MethodCallHandler {
  20 +
  21 +
  22 + private var TAG = "| XgpushpPlugin | Flutter | Android | "
  23 +
  24 + constructor() {
  25 + instance = this
  26 + }
  27 +
  28 + constructor(binding: FlutterPlugin.FlutterPluginBinding, methodChannel: MethodChannel) {
  29 + mPluginBinding = binding
  30 + channel = methodChannel
  31 + instance = this
  32 + }
  33 +
  34 + constructor(mRegistrar: Registrar, mChannel: MethodChannel) {
  35 + channel = mChannel
  36 + registrar = mRegistrar
  37 + instance = this
  38 + }
  39 +
  40 + companion object {
  41 + lateinit var instance: XgFlutterPlugin
  42 + lateinit var mPluginBinding: FlutterPlugin.FlutterPluginBinding
  43 + lateinit var channel: MethodChannel
  44 + lateinit var registrar: Registrar
  45 + @JvmStatic
  46 + fun registerWith(registrar: Registrar) {
  47 + val channel = MethodChannel(registrar.messenger(), "tpns_flutter_plugin")
  48 + channel.setMethodCallHandler(XgFlutterPlugin(registrar, channel))
  49 +
  50 + Log.i("| XgpushpPlugin | Flutter | Android | ", "methodChannel registerWith XgFlutterPlugin")
  51 + Log.i("| XgpushpPlugin | Flutter | Android | ", "instance = " + instance)
  52 + }
  53 +
  54 + fun checkPluginBindingInit() : Boolean {
  55 + return this::mPluginBinding.isInitialized
  56 + }
  57 +
  58 + // 为兼容老版本 Flutter 项目插件加载方式,结合 kotlin lateinit 对象特性,
  59 + // 需要在判断 mPluginBinding == mull 之前先判断是否有初始化
  60 + fun isPluginBindingValid() : Boolean {
  61 + if (checkPluginBindingInit()) {
  62 +// Log.i("| XgpushpPlugin | Flutter | Android | ",
  63 +// "mPluginBinding initialzed, " + (mPluginBinding != null))
  64 + return mPluginBinding != null
  65 + } else {
  66 + Log.i("| XgpushpPlugin | Flutter | Android | ", "mPluginBinding not initialzed")
  67 + return false
  68 + }
  69 + }
  70 + }
  71 +
  72 + override fun onMethodCall(@NonNull p0: MethodCall, @NonNull p1: MethodChannel.Result) {
  73 + Log.i(TAG, p0.method)
  74 + if (!isPluginBindingValid() && registrar == null) {
  75 + Log.i(TAG, "调用native的函数" + p0.method + "失败mPluginBinding==null&&registrar==null")
  76 + return
  77 + }
  78 + when (p0.method) {
  79 + Extras.FOR_FLUTTER_METHOD_REG_PUSH -> regPush(p0, p1)
  80 + Extras.FOR_FLUTTER_METHOD_UNREGISTER_PUSH -> stopXg(p0, p1)
  81 + Extras.FOR_FLUTTER_METHOD_SET_TAG -> setXgTag(p0, p1)
  82 + Extras.FOR_FLUTTER_METHOD_SET_TAGS -> setXgTags(p0, p1)
  83 + Extras.FOR_FLUTTER_METHOD_ADD_TAGS -> addXgTags(p0, p1)
  84 + Extras.FOR_FLUTTER_METHOD_DELETE_TAG -> deleteXgTag(p0, p1)
  85 + Extras.FOR_FLUTTER_METHOD_DELETE_TAGS -> deleteXgTags(p0, p1)
  86 + Extras.FOR_FLUTTER_METHOD_CLEAN_TAGS -> cleanXgTags(p0, p1)
  87 + Extras.FOR_FLUTTER_METHOD_GET_TOKEN -> xgToken(p0, p1)
  88 + Extras.FOR_FLUTTER_METHOD_GET_SDK_VERSION -> xgSdkVersion(p0, p1)
  89 + Extras.FOR_FLUTTER_METHOD_BIND_ACCOUNT -> bindAccount(p0, p1)
  90 + Extras.FOR_FLUTTER_METHOD_APPEND_ACCOUNT -> appendAccount(p0, p1)
  91 + Extras.FOR_FLUTTER_METHOD_DEL_ACCOUNT -> delAccount(p0, p1)
  92 + Extras.FOR_FLUTTER_METHOD_DEL_ALL_ACCOUNT -> delAllAccount(p0, p1)
  93 + Extras.FOR_FLUTTER_METHOD_UPSERT_ATTRIBUTES -> upsertAttributes(p0, p1)
  94 + Extras.FOR_FLUTTER_METHOD_DEL_ATTRIBUTES -> delAttributes(p0, p1)
  95 + Extras.FOR_FLUTTER_METHOD_CLEAR_AND_APPEND_ATTRIBUTES -> clearAndAppendAttributes(p0, p1)
  96 + Extras.FOR_FLUTTER_METHOD_CLEAR_ATTRIBUTES -> clearAttributes(p0, p1)
  97 + Extras.FOR_FLUTTER_METHOD_ENABLE_OTHER_PUSH -> enableOtherPush(p0, p1)
  98 + Extras.FOR_FLUTTER_METHOD_ENABLE_OTHER_PUSH2 -> enableOtherPush2(p0, p1)
  99 + Extras.FOR_FLUTTER_METHOD_GET_OTHER_PUSH_TOKEN -> getOtherPushToken(p0, p1)
  100 + Extras.FOR_FLUTTER_METHOD_GET_OTHER_PUSH_TYPE -> getOtherPushType(p0, p1)
  101 + Extras.FOR_FLUTTER_METHOD_ENABLE_PULL_UP_OTHER_APP -> enablePullUpOtherApp(p0, p1)
  102 + Extras.FOR_FLUTTER_METHOD_SET_BADGE_NUM -> setBadgeNum(p0, p1)
  103 + Extras.FOR_FLUTTER_METHOD_RESET_BADGE_NUM -> resetBadgeNum(p0, p1)
  104 + Extras.FOR_FLUTTER_METHOD_CANCEL_ALL_NOTIFICATION -> cancelAllNotification(p0, p1);
  105 + Extras.FOR_FLUTTER_METHOD_CREATE_NOTIFICATION_CHANNEL -> createNotificationChannel(p0, p1);
  106 + Extras.FOR_FLUTTER_METHOD_SET_MI_PUSH_APP_ID -> setMiPushAppId(p0, p1)
  107 + Extras.FOR_FLUTTER_METHOD_SET_MI_PUSH_APP_KEY -> setMiPushAppKey(p0, p1)
  108 + Extras.FOR_FLUTTER_METHOD_SET_MZ_PUSH_ID -> setMzPushAppId(p0, p1)
  109 + Extras.FOR_FLUTTER_METHOD_SET_MZ_PUSH_KEY -> setMzPushAppKey(p0, p1)
  110 + Extras.FOR_FLUTTER_METHOD_ENABLE_OPPO_NOTIFICATION -> enableOppoNotification(p0, p1)
  111 + Extras.FOR_FLUTTER_METHOD_SET_OPPO_PUSH_APP_KEY -> setOppoPushAppKey(p0, p1)
  112 + Extras.FOR_FLUTTER_METHOD_SET_OPPO_PUSH_APP_ID -> setOppoPushAppId(p0, p1)
  113 + Extras.FOR_FLUTTER_METHOD_IS_MIUI_ROM -> isMiuiRom(p0, p1)
  114 + Extras.FOR_FLUTTER_METHOD_IS_EMUI_ROM -> isEmuiRom(p0, p1)
  115 + Extras.FOR_FLUTTER_METHOD_IS_MEIZU_ROM -> isMeizuRom(p0, p1)
  116 + Extras.FOR_FLUTTER_METHOD_IS_OPPO_ROM -> isOppoRom(p0, p1)
  117 + Extras.FOR_FLUTTER_METHOD_IS_VIVO_ROM -> isVivoRom(p0, p1)
  118 + Extras.FOR_FLUTTER_METHOD_IS_FCM_ROM -> isFcmRom(p0, p1)
  119 + Extras.FOR_FLUTTER_METHOD_IS_GOOGLE_ROM -> isGoogleRom(p0, p1)
  120 + Extras.FOR_FLUTTER_METHOD_IS_360_ROM -> is360Rom(p0, p1)
  121 + Extras.FOR_FLUTTER_METHOD_ENABLE_DEBUG -> setEnableDebug(p0, p1)
  122 + Extras.FOR_FLUTTER_METHOD_SET_HEADER_BEAT_INTERVAL_MS -> setHeartbeatIntervalMs(p0, p1)
  123 + Extras.FOR_FLUTTER_METHOD_SET_SERVERSUFFIX -> setServerSuffix(p0, p1)
  124 + Extras.FOR_FLUTTER_METHOD_SET_ACCESSID -> setAccessId(p0, p1)
  125 + Extras.FOR_FLUTTER_METHOD_SET_ACCESSKEY -> setAccessKey(p0, p1)
  126 + }
  127 + }
  128 +
  129 +
  130 + /**
  131 + * 调用Flutter 函数
  132 + *
  133 + * @param methodName 函数名称
  134 + * @param para 参数
  135 + */
  136 + fun toFlutterMethod(methodName: String, para: Map<String, Any?>?) {
  137 + Log.i(TAG, "调用Flutter=>${methodName}")
  138 + MainHandler.getInstance().post { channel.invokeMethod(methodName, para) }
  139 + }
  140 +
  141 + fun toFlutterMethod(methodName: String, para: String) {
  142 + Log.i(TAG, "调用Flutter=>${methodName}")
  143 + MainHandler.getInstance().post { channel.invokeMethod(methodName, para) }
  144 + }
  145 +
  146 + /**
  147 + * 设置accessId
  148 + */
  149 + private fun setAccessId(call: MethodCall, result: MethodChannel.Result) {
  150 + val map = call.arguments<Map<String, String>>()
  151 + val accessId = map[Extras.ACCESSID] as String
  152 + val value = accessId.toLong();
  153 + Log.i(TAG, "调用信鸽SDK-->setAccessId()-----accessId=${value}")
  154 + XGPushConfig.setAccessId(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, value);
  155 + }
  156 + /**
  157 + * 设置accessKey
  158 + */
  159 + private fun setAccessKey(call: MethodCall, result: MethodChannel.Result) {
  160 + val map = call.arguments<Map<String, String>>()
  161 + val accessKey = map[Extras.ACCESSKEY]
  162 + Log.i(TAG, "调用信鸽SDK-->setAccessKey()-----accessKey=${accessKey}")
  163 + XGPushConfig.setAccessKey(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, accessKey);
  164 + }
  165 +
  166 + /**
  167 + * 设置接入域名
  168 + */
  169 + private fun setServerSuffix(call: MethodCall, result: MethodChannel.Result) {
  170 + val map = call.arguments<Map<String, String>>()
  171 + val addr = map[Extras.ADDR]
  172 + Log.i(TAG, "调用信鸽SDK-->setServerSuffix()-----addr=${addr}")
  173 + XGApiConfig.setServerSuffix(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, addr);
  174 + }
  175 +
  176 + /**
  177 + * 信鸽推送注册
  178 + */
  179 + fun regPush(call: MethodCall?, result: MethodChannel.Result?) {
  180 + Log.i(TAG, "调用信鸽SDK-->registerPush()")
  181 + XGPushManager.registerPush(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext)
  182 + }
  183 +
  184 + fun mRegPush(methodName: String, para: Map<String, Any?>?) {
  185 + MainHandler.getInstance().post { channel.invokeMethod("startXg", para) }
  186 + }
  187 +
  188 + /**
  189 + * 开启Debug模式
  190 + */
  191 + private fun setEnableDebug(call: MethodCall, result: MethodChannel.Result) {
  192 + val map = call.arguments<HashMap<String, Any>>()
  193 + val debug = map[Extras.DEBUG] as Boolean
  194 + Log.i(TAG, "调用信鸽SDK-->enableDebug()----->isDebug=${debug}")
  195 + XGPushConfig.enableDebug(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, debug)
  196 + }
  197 +
  198 + /**
  199 + * 设置心跳时间间隔
  200 + */
  201 + fun setHeartbeatIntervalMs(call: MethodCall, result: MethodChannel.Result) {
  202 + val map = call.arguments<HashMap<String, Any>>()
  203 + val interval = map[Extras.HEADER_BEAT_INTERVAL_MS] as Int
  204 + Log.i(TAG, "调用信鸽SDK-->setHeartbeatIntervalMs()----->interval=${interval}")
  205 + XGPushConfig.setHeartbeatIntervalMs(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, interval)
  206 + }
  207 +
  208 + /**
  209 + * 反注册
  210 + *
  211 + *
  212 + * 当用户已退出或 App 被关闭,不再需要接收推送时,可以取消注册 App,即反注册。
  213 + * (一旦设备反注册,直到这个设备重新注册成功期间内,下发的消息该设备都无法收到)
  214 + *
  215 + * @param call 方法
  216 + * @param result 结果
  217 + */
  218 + fun stopXg(call: MethodCall?, result: MethodChannel.Result?) {
  219 + Log.i(TAG, "调用信鸽SDK-->unregisterPush()")
  220 + XGPushManager.unregisterPush(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext)
  221 + }
  222 +
  223 + /**
  224 + * 设置标签,单个标签 call传参为TagName
  225 + *
  226 + * @param call 方法
  227 + * @param result 结果
  228 + */
  229 + fun setXgTag(call: MethodCall, result: MethodChannel.Result?) {
  230 + val map = call.arguments<HashMap<String, String>>()
  231 + val tagName = map[Extras.TAG_NAME]
  232 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  233 + Log.i(TAG, "调用信鸽SDK-->setTag()---->tagName${tagName}")
  234 + XGPushManager.setTag(context, tagName, object : XGIOperateCallback {
  235 + override fun onSuccess(p0: Any?, p1: Int) {
  236 + Log.i(TAG, "setTag successful")
  237 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "setTag successful")
  238 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  239 + }
  240 +
  241 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  242 + Log.i(TAG, "setTag failure")
  243 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  244 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  245 + }
  246 + })
  247 + }
  248 +
  249 + /**
  250 + * 设置多tag call传参为List<String>tag的集合
  251 + * 一次设置多个标签,会覆盖这个设备之前设置的标签。
  252 + *
  253 + * @param call 方法
  254 + * @param result 结果
  255 + </String> */
  256 + fun setXgTags(call: MethodCall, result: MethodChannel.Result?) {
  257 + val map = call.arguments<Map<String, List<String>>>()
  258 + val tags = HashSet<String>(map[Extras.TAG_NAMES])
  259 + //operateName用户定义的操作名称,回调结果会原样返回,用于标识回调属于哪次操作。
  260 + val operateName = "setTags:" + System.currentTimeMillis()
  261 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  262 + Log.i(TAG, "调用信鸽SDK-->setTags()")
  263 + XGPushManager.setTags(context, operateName, tags, object : XGIOperateCallback {
  264 + override fun onSuccess(p0: Any?, p1: Int) {
  265 + Log.i(TAG, "setTags successful")
  266 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "setTags successful")
  267 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  268 + }
  269 +
  270 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  271 + Log.i(TAG, "setTags failure")
  272 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  273 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  274 + }
  275 + })
  276 + }
  277 +
  278 + /**
  279 + * 添加多个标签 call传参为List<String>tag的集合 每个 tag 不能超过40字节(超过会抛弃)不能包含空格(含有空格会删除空格)
  280 + * 最多设置1000个 tag,超过部分会抛弃
  281 + * 一次设置多个标签,会覆盖这个设备之前设置的标签。
  282 + *
  283 + *
  284 + * 如果新增的标签的格式为 "test:2 level:2",则会删除这个设备的全部历史标签,再新增 test:2 和 level。
  285 + * 如果新增的标签有部分不带:号,如 "test:2 level",则会删除这个设备的全部历史标签,再新增 test:2 和 level 标签。
  286 + *
  287 + *
  288 + * 新增的 tags 中,:号为后台关键字,请根据具体的业务场景使用。
  289 + * 此接口调用的时候需要间隔一段时间(建议大于5s),否则可能造成更新失败。
  290 + *
  291 + * @param call 方法
  292 + * @param result 结果
  293 + </String> */
  294 + fun addXgTags(call: MethodCall, result: MethodChannel.Result?) {
  295 + val map = call.arguments<Map<String, List<String>>>()
  296 + val tags = HashSet<String>(map[Extras.TAG_NAMES])
  297 + //operateName用户定义的操作名称,回调结果会原样返回,用于标识回调属于哪次操作。
  298 + val operateName = "addTags:" + System.currentTimeMillis()
  299 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  300 + Log.i(TAG, "调用信鸽SDK-->addTags()")
  301 + XGPushManager.addTags(context, operateName, tags, object : XGIOperateCallback {
  302 + override fun onSuccess(p0: Any?, p1: Int) {
  303 + Log.i(TAG, "addTags successful")
  304 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "addTags successful")
  305 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  306 + }
  307 +
  308 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  309 + Log.i(TAG, "addTags failure")
  310 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  311 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  312 + }
  313 + })
  314 + }
  315 +
  316 + /**
  317 + * 删除指定标签 call传参为TagName需要删除的标签名称
  318 + *
  319 + * @param call 方法
  320 + * @param result 结果
  321 + */
  322 + fun deleteXgTag(call: MethodCall, result: MethodChannel.Result?) {
  323 + val map = call.arguments<Map<String, String>>()
  324 + val tagName = map[Extras.TAG_NAME]
  325 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  326 + Log.i(TAG, "调用信鸽SDK-->deleteTag()----tagName=${tagName}")
  327 + XGPushManager.deleteTag(context, tagName, object : XGIOperateCallback {
  328 + override fun onSuccess(p0: Any?, p1: Int) {
  329 + Log.i(TAG, "deleteTag successful")
  330 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "deleteTag successful")
  331 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  332 + }
  333 +
  334 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  335 + Log.i(TAG, "deleteTag failure")
  336 + val para = "deleteTag failure----->code=${p1}--->message=${p2}"
  337 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  338 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  339 + }
  340 + })
  341 + }
  342 +
  343 +
  344 + /**
  345 + * 删除多个标签 call传参为List<String>tag的集合 每个标签是一个 String。限制:
  346 + * 每个 tag 不能超过40字节(超过会抛弃),不能包含空格(含有空格会删除空格)。最多设置1000个tag,超过部分会抛弃。
  347 + *
  348 + * @param call 方法
  349 + * @param result 结果
  350 + </String> */
  351 + fun deleteXgTags(call: MethodCall, result: MethodChannel.Result?) {
  352 + val map = call.arguments<Map<String, List<String>>>()
  353 + val tags = HashSet<String>(map[Extras.TAG_NAMES])
  354 + //operateName用户定义的操作名称,回调结果会原样返回,用于标识回调属于哪次操作。
  355 + val operateName = "deleteTags:" + System.currentTimeMillis()
  356 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  357 + Log.i(TAG, "调用信鸽SDK-->deleteTags()----operateName=${operateName}")
  358 + XGPushManager.deleteTags(context, operateName, tags, object : XGIOperateCallback {
  359 + override fun onSuccess(p0: Any?, p1: Int) {
  360 + Log.i(TAG, "deleteTags successful")
  361 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "deleteTags successful")
  362 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  363 + }
  364 +
  365 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  366 + Log.i(TAG, "deleteTags failure")
  367 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  368 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  369 + }
  370 + })
  371 + }
  372 +
  373 +
  374 + /**
  375 + * 清楚所有标签
  376 + *
  377 + * @param call 方法
  378 + * @param result 结果
  379 + */
  380 + fun cleanXgTags(call: MethodCall?, result: MethodChannel.Result?) { //operateName用户定义的操作名称,回调结果会原样返回,用于标识回调属于哪次操作。
  381 + val operateName = "cleanTags:" + System.currentTimeMillis()
  382 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  383 + Log.i(TAG, "调用信鸽SDK-->cleanTags()----operateName=${operateName}")
  384 + XGPushManager.cleanTags(context, operateName, object : XGIOperateCallback {
  385 + override fun onSuccess(p0: Any?, p1: Int) {
  386 + Log.i(TAG, "cleanTags successful")
  387 + val paraDict = mapOf("code" to 0,"type" to "tag", "msg" to "cleanTags successful")
  388 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  389 + }
  390 +
  391 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  392 + Log.i(TAG, "cleanTags failure")
  393 + val paraDict = mapOf("code" to p1,"type" to "tag", "msg" to p2)
  394 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  395 + }
  396 + })
  397 + }
  398 +
  399 + /**
  400 + * 获取Xg的token
  401 + * App 第一次注册会产生 Token,之后一直存在手机上,不管以后注销注册操作,该 Token 一直存在,
  402 + * 当 App 完全卸载重装了 Token 会发生变化。不同 App 之间的 Token 不一样。
  403 + */
  404 + fun xgToken(call: MethodCall?, result: MethodChannel.Result) {
  405 + val token: String = XGPushConfig.getToken(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext)
  406 + Log.i(TAG, "调用信鸽SDK-->getToken()----token=${token}")
  407 + result.success(token)
  408 + }
  409 +
  410 + fun xgSdkVersion(call: MethodCall?, result: MethodChannel.Result) {
  411 + val sdkVersion: String = XGPushConstants.SDK_VERSION
  412 + Log.i(TAG, "调用信鸽SDK-->SDK_VERSION----${sdkVersion}")
  413 + result.success(sdkVersion)
  414 + }
  415 +
  416 + fun getAccountType(accountType: String): Int {
  417 + when (accountType) {
  418 + "UNKNOWN" -> return XGPushManager.AccountType.UNKNOWN.getValue()
  419 + "CUSTOM" -> return XGPushManager.AccountType.CUSTOM.getValue()
  420 +// "IDFA" -> return XGPushManager.AccountType.IDFA.getValue()
  421 + "PHONE_NUMBER" -> return XGPushManager.AccountType.PHONE_NUMBER.getValue()
  422 + "WX_OPEN_ID" -> return XGPushManager.AccountType.WX_OPEN_ID.getValue()
  423 + "QQ_OPEN_ID" -> return XGPushManager.AccountType.QQ_OPEN_ID.getValue()
  424 + "EMAIL" -> return XGPushManager.AccountType.EMAIL.getValue()
  425 + "SINA_WEIBO" -> return XGPushManager.AccountType.SINA_WEIBO.getValue()
  426 + "ALIPAY" -> return XGPushManager.AccountType.ALIPAY.getValue()
  427 + "TAOBAO" -> return XGPushManager.AccountType.TAOBAO.getValue()
  428 + "DOUBAN" -> return XGPushManager.AccountType.DOUBAN.getValue()
  429 + "FACEBOOK" -> return XGPushManager.AccountType.FACEBOOK.getValue()
  430 + "TWITTER" -> return XGPushManager.AccountType.TWITTER.getValue()
  431 + "GOOGLE" -> return XGPushManager.AccountType.GOOGLE.getValue()
  432 + "BAIDU" -> return XGPushManager.AccountType.BAIDU.getValue()
  433 + "JINGDONG" -> return XGPushManager.AccountType.JINGDONG.getValue()
  434 + "LINKEDIN" -> return XGPushManager.AccountType.LINKEDIN.getValue()
  435 + "IMEI" -> return XGPushManager.AccountType.IMEI.getValue()
  436 + else -> return XGPushManager.AccountType.UNKNOWN.getValue()
  437 + }
  438 + }
  439 +
  440 + /**
  441 + * 绑定账号注册
  442 + * 推荐有账号体系的App使用(此接口会覆盖设备之前绑定过的账号,仅当前注册的账号生效)
  443 + *
  444 + * @param call String 账号
  445 + * @param result 结果
  446 + */
  447 + fun bindAccount(call: MethodCall, result: MethodChannel.Result?) {
  448 + val map = call.arguments<Map<String, String>>()
  449 + val account = map[Extras.ACCOUNT]
  450 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  451 + var accountType: String = (map[Extras.ACCOUNT_TYPE]) ?: "UNKNOWN"
  452 + Log.i(TAG, "调用信鸽SDK-->bindAccount()----account=${account}, accountType=${accountType}")
  453 + XGPushManager.bindAccount(context, account, getAccountType(accountType), object : XGIOperateCallback {
  454 + override fun onSuccess(p0: Any?, p1: Int) {
  455 + Log.i(TAG, "bindAccount successful")
  456 + val paraDict = mapOf("code" to 0,"type" to "account", "msg" to "bindAccount successful")
  457 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  458 + }
  459 +
  460 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  461 + Log.i(TAG, "bindAccount failure")
  462 + val paraDict = mapOf("code" to p1,"type" to "account", "msg" to p2)
  463 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  464 + }
  465 + })
  466 + }
  467 +
  468 + /**
  469 + * 添加账号
  470 + * 推荐有账号体系的App使用(此接口保留之前的账号,只做增加操作,一个token下最多只能有10个账号超过限制会自动顶掉之前绑定的账号)
  471 + *
  472 + * @param call String 账号
  473 + * @param result 结果
  474 + */
  475 + fun appendAccount(call: MethodCall, result: MethodChannel.Result?) {
  476 + val map = call.arguments<Map<String, String>>()
  477 + val account = map[Extras.ACCOUNT]
  478 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  479 + var accountType: String = (map[Extras.ACCOUNT_TYPE]) ?: "UNKNOWN"
  480 + Log.i(TAG, "调用信鸽SDK-->appendAccount()----account=${account}, accountType=${accountType}")
  481 + XGPushManager.appendAccount(context, account, getAccountType(accountType), object : XGIOperateCallback {
  482 + override fun onSuccess(p0: Any?, p1: Int) {
  483 + Log.i(TAG, "appendAccount successful")
  484 + val paraDict = mapOf("code" to 0,"type" to "account", "msg" to "appendAccount successful")
  485 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  486 + }
  487 +
  488 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  489 + Log.i(TAG, "appendAccount failure")
  490 + val paraDict = mapOf("code" to p1,"type" to "account", "msg" to p2)
  491 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  492 + }
  493 + })
  494 + }
  495 +
  496 + /**
  497 + * 解除指定账号绑定
  498 + * 账号解绑只是解除 Token 与 App 账号的关联,若使用全量/标签/Token 推送仍然能收到通知/消息。
  499 + *
  500 + * @param call String账号
  501 + * @param result 结果
  502 + */
  503 + fun delAccount(call: MethodCall, result: MethodChannel.Result?) {
  504 + val map = call.arguments<Map<String, String>>()
  505 + val account = map[Extras.ACCOUNT]
  506 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  507 + var accountType: String = (map[Extras.ACCOUNT_TYPE]) ?: "UNKNOWN"
  508 + Log.i(TAG, "调用信鸽SDK-->delAccount()----account=${account}, accountType=${accountType}")
  509 + XGPushManager.delAccount(context, account, getAccountType(accountType), object : XGIOperateCallback {
  510 + override fun onSuccess(p0: Any?, p1: Int) {
  511 + Log.i(TAG, "delAccount successful")
  512 + val paraDict = mapOf("code" to 0,"type" to "account", "msg" to "delAccount successful")
  513 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  514 + }
  515 +
  516 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  517 + Log.i(TAG, "delAccount failure")
  518 + val paraDict = mapOf("code" to p1,"type" to "account", "msg" to p2)
  519 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  520 + }
  521 + })
  522 + }
  523 +
  524 + /**
  525 + * 清除全部账号
  526 + */
  527 + fun delAllAccount(call: MethodCall, result: MethodChannel.Result?) {
  528 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  529 + Log.i(TAG, "调用信鸽SDK-->delAllAccount()")
  530 + XGPushManager.delAllAccount(context, object : XGIOperateCallback {
  531 + override fun onSuccess(p0: Any?, p1: Int) {
  532 + Log.i(TAG, "delAllAccount successful")
  533 + val paraDict = mapOf("code" to 0,"type" to "account", "msg" to "delAllAccount successful")
  534 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  535 + }
  536 +
  537 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  538 + Log.i(TAG, "delAllAccount failure")
  539 + val paraDict = mapOf("code" to p1,"type" to "account", "msg" to p2)
  540 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  541 + }
  542 + })
  543 + }
  544 +
  545 + /**
  546 + * 新增用户属性
  547 + */
  548 + fun upsertAttributes(call: MethodCall, result: MethodChannel.Result?) {
  549 + val map = call.arguments<Map<String, String>>()
  550 + val attributesMap = map[Extras.ATTRIBUTES] as HashMap<String, String>
  551 + Log.i(TAG, "调用信鸽SDK-->upsertAttributes()----->attributes=${attributesMap}")
  552 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  553 + XGPushManager.upsertAttributes(context, "upsertAttributes", attributesMap, object : XGIOperateCallback {
  554 + override fun onSuccess(p0: Any?, p1: Int) {
  555 + Log.i(TAG, "upsertAttributes successful")
  556 + val paraDict = mapOf("code" to 0,"type" to "attributes", "msg" to "upsertAttributes successful")
  557 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  558 + }
  559 +
  560 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  561 + Log.i(TAG, "upsertAttributes failure")
  562 + val paraDict = mapOf("code" to p1,"type" to "attributes", "msg" to p2)
  563 + toFlutterMethod(Extras.XG_PUSH_DID_BIND_WITH_IDENENTIFIER, paraDict)
  564 + }
  565 + })
  566 + }
  567 +
  568 + /**
  569 + * 删除用户属性
  570 + */
  571 + fun delAttributes(call: MethodCall, result: MethodChannel.Result?) {
  572 + val map = call.arguments<Map<String, List<String>>>()
  573 + val attributesList = HashSet<String>(map[Extras.ATTRIBUTES])
  574 + Log.i(TAG, "调用信鸽SDK-->delAttributes()----->attributes=${attributesList}")
  575 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  576 + XGPushManager.delAttributes(context, "delAttributes", attributesList, object : XGIOperateCallback {
  577 + override fun onSuccess(p0: Any?, p1: Int) {
  578 + Log.i(TAG, "delAttributes successful")
  579 + val paraDict = mapOf("code" to 0,"type" to "attributes", "msg" to "delAttributes successful")
  580 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  581 + }
  582 +
  583 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  584 + Log.i(TAG, "delAttributes failure")
  585 + val paraDict = mapOf("code" to p1,"type" to "attributes", "msg" to p2)
  586 + toFlutterMethod(Extras.XG_PUSH_DID_UNBIND_WITH_IDENENTIFIER, paraDict)
  587 + }
  588 + })
  589 + }
  590 +
  591 + /**
  592 + * 更新用户属性
  593 + */
  594 + fun clearAndAppendAttributes(call: MethodCall, result: MethodChannel.Result?) {
  595 + val map = call.arguments<Map<String, String>>()
  596 + val attributesMap = map[Extras.ATTRIBUTES] as HashMap<String, String>
  597 + Log.i(TAG, "调用信鸽SDK-->clearAndAppendAttributes()----->attributes=${attributesMap}")
  598 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  599 + XGPushManager.clearAndAppendAttributes(context, "clearAndAppendAttributes", attributesMap, object : XGIOperateCallback {
  600 + override fun onSuccess(p0: Any?, p1: Int) {
  601 + Log.i(TAG, "clearAndAppendAttributes successful")
  602 + val paraDict = mapOf("code" to 0,"type" to "attributes", "msg" to "clearAndAppendAttributes successful")
  603 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  604 + }
  605 +
  606 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  607 + Log.i(TAG, "clearAndAppendAttributes failure")
  608 + val paraDict = mapOf("code" to p1,"type" to "attributes", "msg" to p2)
  609 + toFlutterMethod(Extras.XG_PUSH_DID_UPDATED_WITH_IDENENTIFIER, paraDict)
  610 + }
  611 + })
  612 + }
  613 +
  614 + /**
  615 + * 清除全部用户属性
  616 + */
  617 + fun clearAttributes(call: MethodCall, result: MethodChannel.Result?) {
  618 + Log.i(TAG, "调用信鸽SDK-->clearAttributes()")
  619 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  620 + XGPushManager.clearAttributes(context, "clearAttributes", object : XGIOperateCallback {
  621 + override fun onSuccess(p0: Any?, p1: Int) {
  622 + Log.i(TAG, "clearAttributes successful")
  623 + val paraDict = mapOf("code" to 0,"type" to "attributes", "msg" to "clearAttributes successful")
  624 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  625 + }
  626 +
  627 + override fun onFail(p0: Any?, p1: Int, p2: String?) {
  628 + Log.i(TAG, "clearAttributes failure")
  629 + val paraDict = mapOf("code" to p1,"type" to "attributes", "msg" to p2)
  630 + toFlutterMethod(Extras.XG_PUSH_DID_CLEAR_WITH_IDENENTIFIER, paraDict)
  631 + }
  632 + })
  633 + }
  634 +
  635 + /**
  636 + * 开启其他推送 XGPushManager.registerPush 前,开启第三方推送
  637 + */
  638 + fun enableOtherPush(call: MethodCall, result: MethodChannel.Result?) {
  639 + Log.i(TAG, "调用信鸽SDK-->enableOtherPush()")
  640 + XGPushConfig.enableOtherPush(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, true)
  641 + }
  642 +
  643 + /**
  644 + * 开启其他推送 XGPushManager.registerPush 前,开启第三方推送
  645 + */
  646 + fun enableOtherPush2(call: MethodCall, result: MethodChannel.Result?) {
  647 + val map = call.arguments<HashMap<String, Any>>()
  648 + val enable = map["enable"] as Boolean
  649 + Log.i(TAG, "调用信鸽SDK-->enableOtherPush2()")
  650 + XGPushConfig.enableOtherPush(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, enable)
  651 + }
  652 +
  653 + /**
  654 + * 获取厂商推送 token XGPushManager.registerPush 成功后
  655 + */
  656 + fun getOtherPushToken(call: MethodCall?, result: MethodChannel.Result) {
  657 + val otherPushToken: String = (XGPushConfig.getOtherPushToken(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext))?:""
  658 + Log.i(TAG, "调用信鸽SDK-->getOtherPushToken()---otherPushToken=${otherPushToken}")
  659 + result.success(otherPushToken)
  660 + }
  661 +
  662 + /**
  663 + * 获取厂商推送品牌 XGPushManager.registerPush 成功后
  664 + */
  665 + fun getOtherPushType(call: MethodCall?, result: MethodChannel.Result) {
  666 + val otherPushType: String = (XGPushConfig.getOtherPushType(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext))?:""
  667 + Log.i(TAG, "调用信鸽SDK-->getOtherPushType()---otherPushType=${otherPushType}")
  668 + result.success(otherPushType)
  669 + }
  670 +
  671 + fun enablePullUpOtherApp(call: MethodCall, result: MethodChannel.Result) {
  672 + val map = call.arguments<HashMap<String, Any>>()
  673 + val enable = map["enable"] as Boolean
  674 + Log.i(TAG, "调用信鸽SDK-->enablePullUpOtherApp()")
  675 + XGPushConfig.enablePullUpOtherApp(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, enable)
  676 + }
  677 +
  678 + fun setBadgeNum(call: MethodCall, result: MethodChannel.Result?) {
  679 + val map = call.arguments<Map<String, Int>>()
  680 + val badgeNum = map[Extras.BADGE_NUM] as Int
  681 + Log.i(TAG, "调用信鸽SDK-->setBadgeNum()-----badgeNum=${badgeNum}")
  682 + XGPushConfig.setBadgeNum(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, badgeNum)
  683 + }
  684 +
  685 + fun resetBadgeNum(call: MethodCall, result: MethodChannel.Result?) {
  686 + Log.i(TAG, "调用信鸽SDK-->resetBadgeNum()")
  687 + XGPushConfig.resetBadgeNum(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext)
  688 + }
  689 +
  690 + fun cancelAllNotification(call: MethodCall, result: MethodChannel.Result?) {
  691 + Log.i(TAG, "调用信鸽SDK-->cancelAllNotification()")
  692 + XGPushManager.cancelAllNotifaction(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext)
  693 + }
  694 +
  695 + fun createNotificationChannel(call: MethodCall, result: MethodChannel.Result?) {
  696 + val map = call.arguments<Map<String, Int>>()
  697 + val channelId = map[Extras.CHANNEL_ID] as String
  698 + val channelName = map[Extras.CHANNEL_NAME] as String
  699 + if (map.size == 2) {
  700 + Log.i(TAG, "调用信鸽SDK-->createNotificationChannel(${channelId}, ${channelName})")
  701 + XGPushManager.createNotificationChannel(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext,
  702 + channelId, channelName, true, true, true, null)
  703 + } else {
  704 + val enableVibration = map[Extras.ENABLE_VIBRATION] as Boolean
  705 + val enableLights = map[Extras.ENABLE_LIGHTS] as Boolean
  706 + val enableSound = map[Extras.ENABLE_SOUND] as Boolean
  707 + val soundFileName = map[Extras.SOUND_FILE_NAME] as String
  708 +
  709 + val context = if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext
  710 + val soundFileId = context.getResources().getIdentifier(soundFileName, "raw", context.getPackageName())
  711 + if (soundFileId > 0) {
  712 + val soundUri = "android.resource://" + context.getPackageName() + "/" + soundFileId;
  713 + Log.i(TAG, "调用信鸽SDK-->createNotificationChannel(${channelId}, ${channelName}, ${enableVibration}, ${enableLights}, ${enableSound}, ${soundUri})")
  714 + XGPushManager.createNotificationChannel(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext,
  715 + channelId, channelName, enableVibration, enableLights, enableSound, Uri.parse(soundUri))
  716 + } else {
  717 + Log.i(TAG, "调用信鸽SDK-->createNotificationChannel(${channelId}, ${channelName}, ${enableVibration}, ${enableLights}, ${enableSound}, null)")
  718 + XGPushManager.createNotificationChannel(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext,
  719 + channelId, channelName, enableVibration, enableLights, enableSound, null)
  720 + }
  721 + }
  722 + }
  723 +
  724 +
  725 + /**
  726 + * 设置小米平台的APP_KEY
  727 + * 推荐有账号体系的App使用(此接口保留之前的账号,只做增加操作,一个token下最多只能有10个账号超过限制会自动顶掉之前绑定的账号)
  728 + *
  729 + * @param call String APP_KEY
  730 + * @param result 结果
  731 + */
  732 + fun setMiPushAppKey(call: MethodCall, result: MethodChannel.Result?) {
  733 + val map = call.arguments<Map<String, String>>()
  734 + val appKey = map[Extras.APP_KEY]
  735 + Log.i(TAG, "调用信鸽SDK-->setMiPushAppKey()-----key=${appKey}")
  736 + XGPushConfig.setMiPushAppKey(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appKey)
  737 + }
  738 +
  739 + /**
  740 + * 设置小米平台的APP_ID
  741 + *
  742 + * @param call String app_id
  743 + * @param result 结果
  744 + */
  745 + fun setMiPushAppId(call: MethodCall, result: MethodChannel.Result?) {
  746 + val map = call.arguments<Map<String, String>>()
  747 + val appId = map[Extras.APP_ID]
  748 + Log.i(TAG, "调用信鸽SDK-->setMiPushAppId()-----appId=${appId}")
  749 + XGPushConfig.setMiPushAppId(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appId)
  750 + }
  751 +
  752 +
  753 + /**
  754 + * 设置魅族平台的的APP_KEy
  755 + */
  756 + fun setMzPushAppKey(call: MethodCall, result: MethodChannel.Result?) {
  757 + val map = call.arguments<Map<String, String>>()
  758 + val appKey = map[Extras.APP_KEY]
  759 + Log.i(TAG, "调用信鸽SDK-->setMzPushAppKey()-----appKey=${appKey}")
  760 + XGPushConfig.setMzPushAppKey(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appKey)
  761 + }
  762 +
  763 + /**
  764 + * 设置魅族平台的的APP_KEy
  765 + */
  766 + fun setMzPushAppId(call: MethodCall, result: MethodChannel.Result?) {
  767 + val map = call.arguments<Map<String, String>>()
  768 + val appId = map[Extras.APP_ID]
  769 + Log.i(TAG, "调用信鸽SDK-->setMzPushAppId()-----appId=${appId}")
  770 + XGPushConfig.setMzPushAppId(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appId)
  771 + }
  772 +
  773 + /**
  774 + * 在调用腾讯移动推送 XGPushManager.registerPush前,调用以下代码:
  775 + * 在应用首次启动时弹出通知栏权限请求窗口,应用安装周期内,提示弹窗仅展示一次。需 TPNS-OPPO 依赖包版本在 1.1.5.1 及以上支持,系统 ColorOS 5.0 以上有效。
  776 + */
  777 + private fun enableOppoNotification(call: MethodCall, result: MethodChannel.Result) {
  778 + val map = call.arguments<Map<String, Any>>()
  779 + val isNotification = map["isNotification"] as Boolean
  780 + Log.i(TAG, "调用信鸽SDK-->enableOppoNotification()-----isNotification=${isNotification}")
  781 + XGPushConfig.enableOppoNotification(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, isNotification)
  782 + }
  783 +
  784 + /**
  785 + * 设置OPPO的key
  786 + *
  787 + * @param call String类型的APPKey
  788 + * @param result
  789 + */
  790 + private fun setOppoPushAppKey(call: MethodCall, result: MethodChannel.Result) {
  791 + val map = call.arguments<Map<String, String>>()
  792 + val appKey = map[Extras.APP_KEY]
  793 + Log.i(TAG, "调用信鸽SDK-->setOppoPushAppKey()-----appKey=${appKey}")
  794 + XGPushConfig.setOppoPushAppKey(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appKey)
  795 + }
  796 +
  797 + /**
  798 + * 设置OPPO的appID
  799 + *
  800 + * @param call String 类型发AppId
  801 + * @param result
  802 + */
  803 + private fun setOppoPushAppId(call: MethodCall, result: MethodChannel.Result) {
  804 + val map = call.arguments<Map<String, String>>()
  805 + val appId = map[Extras.APP_ID]
  806 + Log.i(TAG, "调用信鸽SDK-->setOppoPushAppId()-----appId=${appId}")
  807 + XGPushConfig.setOppoPushAppId(if (!isPluginBindingValid()) registrar.context() else mPluginBinding.applicationContext, appId)
  808 + }
  809 +
  810 + /**
  811 + * 判断是否为支持FCM手机
  812 + */
  813 + fun isFcmRom(call: MethodCall?, result: MethodChannel.Result?) { // boolean is
  814 + }
  815 +
  816 + /**
  817 + * 判断是否为谷歌手机
  818 + */
  819 + private fun isGoogleRom(call: MethodCall, result: MethodChannel.Result) {
  820 + result.success(DeviceInfoUtil.isGoogleRom())
  821 + }
  822 +
  823 + /**
  824 + * 判断是否为360手机
  825 + */
  826 + private fun is360Rom(call: MethodCall, result: MethodChannel.Result) {
  827 + Log.i(TAG, "is360Rom===" + DeviceInfoUtil.is360Rom())
  828 + result.success(DeviceInfoUtil.is360Rom())
  829 + }
  830 +
  831 + /**
  832 + * 判断是否为Vivo手机
  833 + */
  834 + private fun isVivoRom(call: MethodCall, result: MethodChannel.Result) {
  835 + Log.i(TAG, "isVivoRom===" + DeviceInfoUtil.isVivoRom())
  836 + result.success(DeviceInfoUtil.isVivoRom())
  837 + }
  838 +
  839 + /**
  840 + * 判断是否为Oppo手机
  841 + */
  842 + private fun isOppoRom(call: MethodCall, result: MethodChannel.Result) {
  843 + Log.i(TAG, "isOppoRom===" + DeviceInfoUtil.isOppoRom())
  844 + result.success(DeviceInfoUtil.isOppoRom())
  845 + }
  846 +
  847 + /**
  848 + * 判断是否为魅族手机
  849 + */
  850 + private fun isMeizuRom(call: MethodCall, result: MethodChannel.Result) {
  851 + Log.i(TAG, "isMeizuRom===" + DeviceInfoUtil.isMeizuRom())
  852 + result.success(DeviceInfoUtil.isMeizuRom())
  853 + }
  854 +
  855 + /**
  856 + * 判断是否为华为手机
  857 + */
  858 + private fun isEmuiRom(call: MethodCall, result: MethodChannel.Result) {
  859 + Log.i(TAG, "isEmuiRom===" + DeviceInfoUtil.isEmuiRom())
  860 + result.success(DeviceInfoUtil.isEmuiRom())
  861 + }
  862 +
  863 + /**
  864 + * 判断是否为小米手机
  865 + */
  866 + private fun isMiuiRom(call: MethodCall, result: MethodChannel.Result) {
  867 + Log.i(TAG, "isMiuiRom===" + DeviceInfoUtil.isMiuiRom())
  868 + result.success(DeviceInfoUtil.isMiuiRom())
  869 + }
  870 +
  871 +
  872 +
  873 + override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
  874 + val channel1 = MethodChannel(flutterPluginBinding.getFlutterEngine().getDartExecutor(), "tpns_flutter_plugin")
  875 + channel1.setMethodCallHandler(XgFlutterPlugin(flutterPluginBinding, channel1))
  876 +
  877 + Log.i("| XgpushpPlugin | Flutter | Android | ", "methodChannel onAttachedToEngine XgFlutterPlugin")
  878 + Log.i("| XgpushpPlugin | Flutter | Android | ", "onAttachedToEngine instance = " + instance)
  879 + XGMessageReceiver.sendHandlerMessage()
  880 + }
  881 +
  882 +
  883 + override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
  884 + }
  885 +}
  1 +version: v2.0
  2 +
  3 +stages:
  4 + - name: "stage1"
  5 + jobs:
  6 + job1:
  7 + runs-on:
  8 + pool-name: docker-on-devcloud #docker-on-devcloud、docker、local、agentless
  9 + container:
  10 + image: mirrors.tencent.com/ci/tlinux3_ci:2.1.0
  11 + needs:
  12 + jdk: "1.8.0_161"
  13 + steps:
  14 + - uses: syncLocalCode@latest
  15 + name: 同步文件到云端插件
  16 + with:
  17 + syncGitRepository: false
  18 + - uses: CodeccCheckAtomDebug@4.*
  19 + name: 腾讯代码分析
  20 + with:
  21 + beAutoLang: true
  22 + # languages: # 工程语言, 可取值:"C_CPP", "JAVA", "C_SHARP", "JS", "OC", "PYTHON", "PHP", "RUBY", "GOLANG", "SWIFT", "TYPESCRIPT", "KOTLIN", "LUA", "OTHERS"
  23 + # - "JAVA"
  24 + checkerSetType: "openScan" #openScan对应按开源治理要求配置规则集,epcScan对应按PCG EPC要求配置,normal对应自主配置规则集
  25 + toolScanType: "0" # 扫描方式。0是全量扫描,1是增量扫描。
  26 + fileCacheEnable: true # 由于IDE中代码可能没有上传Git,因此需要开启代码缓存,便于在CodeCC查看代码详情
  1 +## 通用 API 接口说明
  2 +
  3 +#### 1. 注册推送服务
  4 + /// iOS前台收到通知不希望展示时可将withInAppAlert参数置为false
  5 + /// android接入厂商通道时,请先参考 [厂商通道接入说明](vendor.md) 配置各厂商通道参数信息后,再调用此注册方法。
  6 +```dart
  7 + void startXg(String accessId, String accessKey, {bool withInAppAlert = true});
  8 +```
  9 +
  10 +#### 2. 注销推送服务
  11 +```dart
  12 + void stopXg();
  13 +```
  14 +
  15 +#### 3. 设置debug模式
  16 +```dart
  17 + void setEnableDebug(bool enableDebug);
  18 +```
  19 +
  20 +#### 4. 账号类型枚举
  21 + /// UNKNOWN 默认类型,当前只支持此类型的推送
  22 + /// CUSTOM 自定义
  23 + /// IDFA 广告唯一标识,iOS 专用,安卓侧默认为UNKNOWN类型
  24 + /// PHONE_NUMBER 手机号码
  25 + /// WX_OPEN_ID 微信 OPENID
  26 + /// QQ_OPEN_ID QQ OPENID
  27 + /// EMAIL 邮箱
  28 + /// SINA_WEIBO 新浪微博
  29 + /// ALIPAY 支付宝
  30 + /// TAOBAO 淘宝
  31 + /// DOUBAN 豆瓣
  32 + /// BAIDU 百度
  33 + /// JINGDONG 京东
  34 + /// IMEI 安卓手机标识,安卓专用,iOS默认为UNKNOWN类型
  35 +```dart
  36 + enum AccountType { UNKNOWN, CUSTOM, IDFA, PHONE_NUMBER, WX_OPEN_ID, QQ_OPEN_ID, EMAIL, SINA_WEIBO, ALIPAY, TAOBAO, DOUBAN, FACEBOOK, TWITTER, GOOGLE, BAIDU, JINGDONG, LINKEDIN, IMEI }
  37 +```
  38 +
  39 +#### 5. 设置账号
  40 + /// account 账号标识
  41 + /// accountType 账号类型枚举
  42 + /// note 同一账号类型对应一个唯一账号,覆盖操作,多账号体系请使用不同账号类型
  43 +```dart
  44 + void setAccount(String account, AccountType accountType);
  45 +```
  46 +
  47 +#### 6. 删除指定账号
  48 + /// account 账号标识
  49 + /// accountType 账号类型枚举
  50 +```dart
  51 + void deleteAccount(String account, AccountType accountType);
  52 +```
  53 +
  54 +#### 7. 删除所有账号
  55 +```dart
  56 + void cleanAccounts();
  57 +```
  58 +
  59 +#### 8. 追加标签
  60 + /// tags 标签字符串数组(标签字符串不允许有空格或者是tab字符)
  61 +```dart
  62 + void addTags(List<String> tags);
  63 +```
  64 +
  65 +#### 9. 覆盖标签(清除所有标签再追加)
  66 + /// tags 标签字符串数组(标签字符串不允许有空格或者是tab字符)
  67 +```dart
  68 + void setTags(List<String> tags);
  69 +```
  70 +
  71 +#### 10. 删除指定标签
  72 + /// tags 标签字符串数组(标签字符串不允许有空格或者是tab字符)
  73 +```dart
  74 + void deleteTags(List<String> tags);
  75 +```
  76 +
  77 +#### 11. 清除所有标签
  78 +```dart
  79 + void cleanTags();
  80 +```
  81 +
  82 +#### 12. 同步角标(同步角标值到TPNS,仅iOS)
  83 + /// badgeSum 角标值
  84 +```dart
  85 + void setBadge(int badgeSum);
  86 +```
  87 +
  88 +#### 13. 设置应用角标(同步到TPNS成功后用于设置应用角标数,仅iOS)
  89 + /// badgeSum 角标值
  90 +```dart
  91 + void setAppBadge(int badgeSum);
  92 +```
  93 +
  94 +#### 14. 获取 XgAndroidApi
  95 + /// 获取 XgAndroidApi 调用Android里的api接口
  96 +```dart
  97 + XgAndroidApi getXgAndroidApi();
  98 +```
  99 +
  100 +#### 15. 新增用户属性
  101 + /// attributes 类型为 Map 字典(k, v字符串不允许有空格或者是tab字符)
  102 +```dart
  103 + void upsertAttributes(Map<String, String> attributes);
  104 +```
  105 +
  106 +#### 16. 删除用户属性
  107 + /// attributes 类型为要删除属性 key 的字符串数组(字符串不允许有空格或者是tab字符)
  108 +```dart
  109 + void delAttributes(List<String> attributes);
  110 +```
  111 +
  112 +#### 17. 更新用户属性
  113 + /// attributes 类型为 Map 字典(k, v字符串不允许有空格或者是tab字符)
  114 +```dart
  115 + void clearAndAppendAttributes(Map<String, String> attributes);
  116 +```
  117 +
  118 +#### 18. 清除全部用户属性
  119 +```dart
  120 + void clearAttributes();
  121 +```
  122 +
  123 +
  124 +## 回调接口说明
  125 +
  126 +#### 1 静默消息(iOS)/透传消息(Android)回调
  127 +```dart
  128 + _onReceiveMessage 数据类型 Map<String, Object> para: iOS/Android返回不同的消息体,以双端返回kv为准
  129 +```
  130 +
  131 +#### 2 收到通知消息回调
  132 +```dart
  133 + _onReceiveNotificationResponse 数据类型 Map<String, Object> para: iOS/Android返回不同的消息体,以双端返回kv为准
  134 +```
  135 +
  136 +#### 3 通知点击回调
  137 +```dart
  138 + _xgPushClickAction 数据类型 Map<String, Object> para: iOS/Android返回不同的消息体,以双端返回kv为准
  139 +```
  140 +
  141 +#### 4 注册成功回调
  142 +```dart
  143 + _onRegisteredDone 数据类型 String para: 注册成功信息
  144 +```
  145 +
  146 +#### 5 注册失败回调
  147 +```dart
  148 + _onRegisteredDeviceToken 数据类型 String para: xgToken,注册失败如果有xgToken则返回
  149 +```
  150 +
  151 +#### 6 注销完成的回调
  152 +```dart
  153 + _unRegistered 数据类型 String para: 注销成功或者失败信息
  154 +```
  155 +
  156 +#### 7 绑定账号/标签/用户属性回调
  157 +**说明**V1.2.8开始返回类型由String->Map,新增code及type标识!
  158 +```dart
  159 + _xgPushDidBindWithIdentifier 数据类型 Map<String, Object> para:
  160 + key:
  161 + code:int类型,操作结果,0代表成功
  162 + type: String类型,操作类型,取值为account/tag/attributes
  163 + msg: String类型,提示信息
  164 +```
  165 +
  166 +#### 8 解绑账号/标签/用户属性回调
  167 +**说明**V1.2.8开始返回类型由String->Map,新增code及type标识!
  168 +```dart
  169 + _xgPushDidUnbindWithIdentifier 数据类型 Map<String, Object> para:
  170 + key:
  171 + code:int类型,操作结果,0代表成功
  172 + type: String类型,操作类型,取值为account/tag/attributes
  173 + msg: String类型,提示信息
  174 +```
  175 +
  176 +#### 9 更新标签/用户属性回调
  177 +**说明**V1.2.8开始返回类型由String->Map,新增code及type标识!
  178 +```dart
  179 + _xgPushDidUpdatedBindedIdentifier 数据类型 Map<String, Object> para:
  180 + key:
  181 + code:int类型,操作结果,0代表成功
  182 + type: String类型,操作类型,取值为tag/attributes
  183 + msg: String类型,提示信息
  184 +```
  185 +
  186 +#### 10 清除所有账号/标签/用户属性回调
  187 +**说明**V1.2.8开始返回类型由String->Map,新增code及type标识!
  188 +```dart
  189 + _xgPushDidClearAllIdentifiers 数据类型 Map<String, Object> para:
  190 + key:
  191 + code:int类型,操作结果,0代表成功
  192 + type: String类型,操作类型,取值为account/tag/attributes
  193 + msg: String类型,提示信息
  194 +```
  195 +
  196 +
  197 +
  198 +## 安卓端 XgAndroidApi 接口说明
  199 +
  200 +> 说明:XgAndroidApi 为针对安卓独立接口的内部再次封装,可以通过 `XgFlutterPlugin.xgApi` 直接访问,例如:
  201 +> ```dart
  202 +> // 调用示例:开启厂商其他推送接口
  203 +> XgFlutterPlugin.xgApi.enableOtherPush()
  204 +> ```
  205 +
  206 +#### 1. 开启其他推送
  207 +```dart
  208 + enableOtherPush();
  209 +```
  210 +
  211 +#### 2. 设置小米推送的APP_ID
  212 +```dart
  213 + setMiPushAppId({String appId});
  214 +```
  215 +
  216 +#### 3. 设置小米推送的APP_KEY
  217 +```dart
  218 + setMiPushAppKey({String appKey});
  219 +```
  220 +
  221 +#### 4. 设置魅族推送所需appID
  222 +```dart
  223 + setMzPushAppId({String appId});
  224 +```
  225 +
  226 +#### 5. 设置魅族推送所需appKey
  227 +```dart
  228 + setMzPushAppKey({String appKey});
  229 +```
  230 +
  231 +#### 6. 开启Oppo通知
  232 +```dart
  233 + enableOppoNotification();
  234 +```
  235 +
  236 +#### 7. 设置Oppo推送ID
  237 +```dart
  238 + setOppoPushAppId({String appId});
  239 +```
  240 +
  241 +#### 8. 设置Oppo推送Key
  242 +```dart
  243 + setOppoPushAppKey({String appKey});
  244 +```
  245 +
  246 +#### 9. 清空当前应用在通知栏的通知
  247 +```dart
  248 + cancelAllNotification();
  249 +```
  250 +
  251 +#### 10. 配置是否关闭拉起其他 App;填入 false 为不拉起,默认为 true
  252 +```dart
  253 + enablePullUpOtherApp({bool enable})
  254 +```
  255 +
  256 +#### 11. 安卓角标设置,支持华为、OPPO、vivo,其中 OPPO 需另外向厂商申请角标展示权限
  257 +```dart
  258 + setBadgeNum({int badgeNum})
  259 +```
  260 +
  261 +#### 12. 设置手机应用角标归0,支持华为、OPPO、vivo,其中 OPPO 需另外向厂商申请角标展示权限
  262 +```dart
  263 + resetBadgeNum()
  264 +```
  265 +
  1 +## 厂商通道接入说明
  2 +
  3 +>? TPNS 已封装各厂商推送通道 SDK,请参考下文引入对应厂商推送 SDK 依赖。
  4 +> 如您的工程同时接入其他离线推送产品遇到依赖冲突,可对对应冲突依赖筛选使用其一。
  5 +
  6 +### 1. 华为通道接入,可参考移动推送 TPNS [华为通道接入](https://cloud.tencent.com/document/product/548/45909)
  7 +#### 1.1 工程配置:
  8 +##### 1.1.1 在安卓项目级目录 build.gradle 文件,【buildscript】>【 repositories & dependencies】下分别添加华为仓库地址和 HMS gradle 插件依赖:
  9 +```
  10 +buildscript {
  11 + repositories {
  12 + google()
  13 + jcenter()
  14 + maven {url 'http://developer.huawei.com/repo/'} // 华为 maven 仓库地址
  15 + }
  16 + dependencies {
  17 + // 其他classpath配置
  18 + classpath 'com.huawei.agconnect:agcp:1.9.1.301' // 华为推送 gradle 插件依赖
  19 + }
  20 +}
  21 +```
  22 +##### 1.1.2 在安卓项目级目录 build.gradle 文件,【allprojects】>【repositories】下添加华为依赖仓库地址:
  23 +```
  24 +allprojects {
  25 + repositories {
  26 + google()
  27 + jcenter()
  28 + maven {url 'http://developer.huawei.com/repo/'} // 华为 maven 仓库地址
  29 + }
  30 +}
  31 +```
  32 +##### 1.1.3. 将从华为推送平台获取的应用配置文件 agconnect-services.json 拷贝到 app 模块目录下。
  33 + ![](https://main.qcloudimg.com/raw/338c87faaeb388f648835f17aeddc490.png)
  34 +##### 1.1.4. 在 app 模块下 build.gradle 文件添加以下配置:
  35 +```
  36 +// app 其他 gradle 插件
  37 +apply plugin: 'com.huawei.agconnect' // HMS SDK gradle 插件
  38 +android {
  39 + // app 配置内容
  40 +}
  41 +```
  42 +##### 1.1.5. 在 app 模块下 build.gradle 文件内导入华为推送相关依赖:
  43 +```
  44 +dependencies {
  45 + // ... 程序其他依赖
  46 +
  47 + // 华为推送 [VERSION] 为当前最新 SDK 版本号,版本号可在 SDK 下载页查看
  48 + // TPNS Android SDK 自 1.2.1.3 版本起正式支持华为推送 V5 版本,请使用 1.2.1.3 及以上版本的 TPNS 华为依赖以避免集成冲突问题。
  49 + implementation 'com.tencent.tpns:huawei:[VERSION]-release'
  50 +
  51 + // HMS Core Push 模块依赖包
  52 + implementation 'com.huawei.hms:push:6.12.0.300'
  53 +}
  54 +```
  55 +
  56 +#### 1.2 开启华为推送
  57 +在调用 `regPush()`注册信鸽推送之前调用启用三方通道接口以开启厂商推送:
  58 +
  59 +```dart
  60 + XgFlutterPlugin.xgApi.enableOtherPush();
  61 + XgFlutterPlugin.xgApi.regPush();
  62 +```
  63 +
  64 +#### 1.3 代码混淆
  65 +
  66 +```
  67 + -ignorewarnings
  68 + -keepattributes *Annotation*
  69 + -keepattributes Exceptions
  70 + -keepattributes InnerClasses
  71 + -keepattributes Signature
  72 + -keepattributes SourceFile,LineNumberTable
  73 + -keep class com.hianalytics.android.**{*;}
  74 + -keep class com.huawei.updatesdk.**{*;}
  75 + -keep class com.huawei.hms.**{*;}
  76 +```
  77 +
  78 +
  79 +
  80 +### 2. 小米通道接入,可参考移动推送 TPNS [小米通道接入](https://cloud.tencent.com/document/product/548/36654)
  81 +
  82 +#### 2.1 引入小米推送的依赖
  83 +
  84 +```
  85 + implementation 'com.tencent.tpns:xiaomi:[VERSION]-release' // 小米推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  86 +```
  87 +#### 2.2 开启小米推送
  88 +
  89 +```dart
  90 + // 设置小米 AppID 和 AppKey。
  91 + XgFlutterPlugin.xgApi.setMiPushAppId(appId:"APP_ID");
  92 + XgFlutterPlugin.xgApi.setMiPushAppKey(appKey: "APPKEY");
  93 +
  94 + // 打开第三方推送并注册
  95 + XgFlutterPlugin.xgApi.enableOtherPush();
  96 + XgFlutterPlugin.xgApi.regPush();
  97 +```
  98 +#### 2.3 代码混淆
  99 +
  100 +```
  101 + -keep class com.xiaomi.**{*;}
  102 + -keep public class * extends com.xiaomi.mipush.sdk.PushMessageReceiver
  103 +```
  104 +
  105 +
  106 +
  107 +
  108 +### 3. 魅族通道接入,可参考移动推送 TPNS [魅族通道接入](https://cloud.tencent.com/document/product/548/36655)
  109 +#### 3.1 引入魅族推送的依赖
  110 +
  111 +```
  112 + implementation 'com.tencent.tpns:meizu:[VERSION]-release' // 魅族推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  113 +```
  114 +#### 3.2 开启魅族推送
  115 +
  116 +```dart
  117 + /// 设置魅族 AppID 和 AppKey
  118 + XgFlutterPlugin.xgApi.setMzPushAppId(appId:"APP_ID");
  119 + XgFlutterPlugin.xgApi.setMzPushAppKey(appKey: "APPKEY");
  120 +
  121 + /// 打开第三方推送
  122 + XgFlutterPlugin.xgApi.enableOtherPush();
  123 + XgFlutterPlugin.xgApi.regPush();
  124 +```
  125 +
  126 +#### 3.3 代码混淆
  127 +
  128 +```
  129 + -dontwarn com.meizu.cloud.pushsdk.**
  130 + -keep class com.meizu.cloud.pushsdk.**{*;}
  131 +```
  132 +
  133 +
  134 +
  135 +### 4. vivo通道接入,可参考移动推送 TPNS [vivo通道接入](https://cloud.tencent.com/document/product/548/36657)
  136 +#### 4.1 在 App 模块下的 build.gradle 文件内
  137 +
  138 +```
  139 + android: {
  140 + defaultConfig {
  141 + manifestPlaceholders = [
  142 + ....
  143 + VIVO_APPID: "VIVO的APPID"
  144 + VIVO_APPKEY:"VIVO的APP_KEy",
  145 + .....
  146 + ]
  147 + }
  148 + }
  149 +```
  150 +
  151 +```
  152 + /// 引入 vivo 推送的依赖
  153 + implementation 'com.tencent.tpns:vivo:[VERSION]-release' // vivo 推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  154 +```
  155 +#### 4.2 启用 vivo 推送
  156 +
  157 +```dart
  158 + /// 打开第三方推送
  159 + XgFlutterPlugin.xgApi.enableOtherPush();
  160 + XgFlutterPlugin.xgApi.regPush();
  161 +```
  162 +#### 4.3代码混淆
  163 +
  164 +```
  165 + -dontwarn com.vivo.push.**
  166 + -keep class com.vivo.push.**{*; }
  167 + -keep class com.vivo.vms.**{*; }
  168 + -keep class com.tencent.android.vivopush.VivoPushMessageReceiver{*;}
  169 +```
  170 +
  171 +
  172 +
  173 +### 5. OPPO通道接入,可参考移动推送 TPNS [OPPO通道接入](https://cloud.tencent.com/document/product/548/36658)
  174 +
  175 +#### 5.1 引入 OPPO 推送的依赖
  176 +
  177 +```
  178 + implementation 'com.tencent.tpns:oppo:[VERSION]-release' // OPPO 推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  179 +```
  180 +#### 5.2 开启推送
  181 +
  182 +```dart
  183 + /// 设置OPPO AppKey 和 AppSecret
  184 + XgFlutterPlugin.xgApi.setOppoPushAppId(appId:"Oppo的AppKey");
  185 + XgFlutterPlugin.xgApi.setOppoPushAppKey(appKey: "Oppo的AppSecret");
  186 +
  187 + /// 打开第三方推送
  188 + XgFlutterPlugin.xgApi.enableOtherPush();
  189 + XgFlutterPlugin.xgApi.regPush();
  190 +```
  191 +#### 5.3 代码混淆
  192 +
  193 +```
  194 + -keep public class * extends android.app.Service
  195 + -keep class com.heytap.mcssdk.** {*;}
  196 + -keep class com.heytap.msp.push.** { *;}
  197 +```
  198 +
  199 +
  200 +
  201 +### 6. FCM通道接入,可参考移动推送 TPNS [FCM通道接入](https://cloud.tencent.com/document/product/548/36656)
  202 +
  203 +#### 6.1 添加 google-services.json 文件,请参考[FCM通道配置文件](https://cloud.tencent.com/document/product/548/36656#.E9.85.8D.E7.BD.AE.E5.86.85.E5.AE.B9)。
  204 +#### 6.2 在项目级的 build.gradle 文件中的 dependencies 节点中添加下面代码,集成谷歌 service
  205 +
  206 +```
  207 + classpath 'com.google.gms:google-services:4.2.0'
  208 +```
  209 +#### 6.3 在应用级的 build.gradle 文件中,添加依赖:
  210 +
  211 +```
  212 + implementation 'com.tencent.tpns:fcm:[VERSION]-release' // fcm 推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  213 + implementation 'com.google.firebase:firebase-messaging:17.6.0'
  214 +```
  215 +
  216 +  并在应用级的 build.gradle 文件末尾新增:
  217 +```
  218 + apply plugin: 'com.google.gms.google-services'
  219 +```
  220 +#### 6.4 启用 FCM 推送
  221 +
  222 +```dart
  223 + /// 打开第三方推送
  224 + XgFlutterPlugin.xgApi.enableOtherPush();
  225 + XgFlutterPlugin.xgApi.regPush();
  226 +```
  227 +
  228 +### 7. 荣耀通道接入,可参考移动推送 TPNS [荣耀通道接入](https://cloud.tencent.com/document/product/548/74465)
  229 +#### 7.1 在 App 模块下的 build.gradle 文件内
  230 +
  231 +```
  232 + android: {
  233 + defaultConfig {
  234 + manifestPlaceholders = [
  235 + ....
  236 + HONOR_APPID : "xxxx"
  237 + .....
  238 + ]
  239 + }
  240 + }
  241 +```
  242 +
  243 +```
  244 + /// 引入 vivo 推送的依赖
  245 + implementation 'com.tencent.tpns:honor:[VERSION]-release' // 荣耀 推送 [VERSION] 为当前SDK版本号,版本号可在SDK下载页查看
  246 +```
  247 +#### 7.2 启用 荣耀 推送
  248 +
  249 +```dart
  250 + /// 打开第三方推送
  251 + XgFlutterPlugin.xgApi.enableOtherPush();
  252 + XgFlutterPlugin.xgApi.regPush();
  253 +```
  254 +#### 7.3代码混淆
  255 +
  256 +```
  257 + -ignorewarnings
  258 + -keepattributes *Annotation*
  259 + -keepattributes Exceptions
  260 + -keepattributes InnerClasses
  261 + -keepattributes Signature
  262 + -keepattributes SourceFile,LineNumberTable
  263 +
  264 +
  265 + -keep class com.hihonor.push.framework.aidl.**{*;}
  266 + -keep class com.hihonor.push.sdk.**{*;}
  267 +
  268 +```
  269 +
  270 +## 厂商通道注册失败排查指南
  271 +如您的应用接入了厂商通道,但在应用运行日志中观察到如下类似日志:
  272 +
  273 +```
  274 +[OtherPushClient] handleUpdateToken other push token is : other push type: huawei
  275 +```
  276 +
  277 +表示您的应用注册该厂商通道失败。您可以通过获取厂商通道注册失败的返回码来进行问题定位和排查,详情参考 [厂商通道注册失败排查指南](https://cloud.tencent.com/document/product/548/45659)。
  1 +# Miscellaneous
  2 +*.class
  3 +*.log
  4 +*.pyc
  5 +*.swp
  6 +.DS_Store
  7 +.atom/
  8 +.buildlog/
  9 +.history
  10 +.svn/
  11 +
  12 +# IntelliJ related
  13 +*.iml
  14 +*.ipr
  15 +*.iws
  16 +.idea/
  17 +
  18 +# The .vscode folder contains launch configuration and tasks you configure in
  19 +# VS Code which you may wish to be included in version control, so this line
  20 +# is commented out by default.
  21 +#.vscode/
  22 +
  23 +# Flutter/Dart/Pub related
  24 +**/doc/api/
  25 +.dart_tool/
  26 +.flutter-plugins
  27 +.flutter-plugins-dependencies
  28 +.packages
  29 +.pub-cache/
  30 +.pub/
  31 +/build/
  32 +
  33 +# Web related
  34 +lib/generated_plugin_registrant.dart
  35 +
  36 +# Exceptions to above rules.
  37 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
  1 +# This file tracks properties of this Flutter project.
  2 +# Used by Flutter tool to assess capabilities and perform upgrades etc.
  3 +#
  4 +# This file should be version controlled.
  5 +
  6 +version:
  7 + revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  8 + channel: stable
  9 +
  10 +project_type: app
  11 +
  12 +# Tracks metadata for the flutter migrate command
  13 +migration:
  14 + platforms:
  15 + - platform: root
  16 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  17 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  18 + - platform: android
  19 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  20 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  21 + - platform: ios
  22 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  23 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  24 + - platform: linux
  25 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  26 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  27 + - platform: macos
  28 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  29 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  30 + - platform: web
  31 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  32 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  33 + - platform: windows
  34 + create_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  35 + base_revision: bcea432bce54a83306b3c00a7ad0ed98f777348d
  36 +
  37 + # User provided section
  38 +
  39 + # List of Local paths (relative to this file) that should be
  40 + # ignored by the migrate tool.
  41 + #
  42 + # Files that are not part of the templates will be ignored by default.
  43 + unmanaged_files:
  44 + - 'lib/main.dart'
  45 + - 'ios/Runner.xcodeproj/project.pbxproj'
  1 +# tpns_flutter_plugin
  2 +
  3 +## 安装
  4 +在工程 pubspec.yaml 中加入 dependencies
  5 +```
  6 + dependencies:
  7 + tpns_flutter_plugin:
  8 + git:
  9 + url: https://github.com/TencentCloud/TPNS-Flutter-Plugin
  10 + ref: V1.3.4
  11 +```
  12 +
  13 +
  14 +## 使用
  15 +
  16 +- 执行flutter pub get安装好插件后进入iOS文件目录(cd ios)执行:pod install安装依赖库
  17 +- 在 xcode8 之后需要点开推送选项: TARGETS -> Capabilities -> Push Notification 设为 on 状态
  18 +
  19 +```dart
  20 + import 'package:tpns_flutter_plugin/tpns_flutter_plugin.dart';
  21 +```
  22 +
  23 + 说明(接口使用参考/tpns_flutter_plugin/example/lib/main.dart和/tpns_flutter_plugin/example/lib/ios/homeTest.dart文件)
  24 +
  25 +
  1 +# This file configures the analyzer, which statically analyzes Dart code to
  2 +# check for errors, warnings, and lints.
  3 +#
  4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
  5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
  6 +# invoked from the command line by running `flutter analyze`.
  7 +
  8 +# The following line activates a set of recommended lints for Flutter apps,
  9 +# packages, and plugins designed to encourage good coding practices.
  10 +include: package:flutter_lints/flutter.yaml
  11 +
  12 +linter:
  13 + # The lint rules applied to this project can be customized in the
  14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  15 + # included above or to enable additional rules. A list of all available lints
  16 + # and their documentation is published at
  17 + # https://dart-lang.github.io/linter/lints/index.html.
  18 + #
  19 + # Instead of disabling a lint rule for the entire project in the
  20 + # section below, it can also be suppressed for a single line of code
  21 + # or a specific dart file by using the `// ignore: name_of_lint` and
  22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  23 + # producing the lint.
  24 + rules:
  25 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
  26 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
  27 +
  28 +# Additional information about this file can be found at
  29 +# https://dart.dev/guides/language/analysis-options
  1 +gradle-wrapper.jar
  2 +/.gradle
  3 +/captures/
  4 +/gradlew
  5 +/gradlew.bat
  6 +/local.properties
  7 +GeneratedPluginRegistrant.java
  8 +
  9 +# Remember to never publicly share your keystore.
  10 +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
  11 +key.properties
  12 +**/*.keystore
  13 +**/*.jks
  1 +def localProperties = new Properties()
  2 +def localPropertiesFile = rootProject.file('local.properties')
  3 +if (localPropertiesFile.exists()) {
  4 + localPropertiesFile.withReader('UTF-8') { reader ->
  5 + localProperties.load(reader)
  6 + }
  7 +}
  8 +
  9 +def flutterRoot = localProperties.getProperty('flutter.sdk')
  10 +if (flutterRoot == null) {
  11 + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
  12 +}
  13 +
  14 +def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
  15 +if (flutterVersionCode == null) {
  16 + flutterVersionCode = '1'
  17 +}
  18 +
  19 +def flutterVersionName = localProperties.getProperty('flutter.versionName')
  20 +if (flutterVersionName == null) {
  21 + flutterVersionName = '1.0'
  22 +}
  23 +
  24 +apply plugin: 'com.android.application'
  25 +apply plugin: 'kotlin-android'
  26 +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
  27 +
  28 +android {
  29 + compileSdkVersion flutter.compileSdkVersion
  30 + ndkVersion flutter.ndkVersion
  31 +
  32 + compileOptions {
  33 + sourceCompatibility JavaVersion.VERSION_1_8
  34 + targetCompatibility JavaVersion.VERSION_1_8
  35 + }
  36 +
  37 + kotlinOptions {
  38 + jvmTarget = '1.8'
  39 + }
  40 +
  41 + sourceSets {
  42 + main.java.srcDirs += 'src/main/kotlin'
  43 + }
  44 +
  45 + defaultConfig {
  46 + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
  47 + applicationId "com.tencent.example"
  48 + // You can update the following values to match your application needs.
  49 + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
  50 + minSdkVersion flutter.minSdkVersion
  51 + targetSdkVersion flutter.targetSdkVersion
  52 + versionCode flutterVersionCode.toInteger()
  53 + versionName flutterVersionName
  54 + manifestPlaceholders = [
  55 + XG_ACCESS_ID : "1500004343",
  56 + XG_ACCESS_KEY : "ANCVHDQ0DO3E",
  57 + ]
  58 + }
  59 +
  60 + buildTypes {
  61 + release {
  62 + // TODO: Add your own signing config for the release build.
  63 + // Signing with the debug keys for now, so `flutter run --release` works.
  64 + signingConfig signingConfigs.debug
  65 + }
  66 + }
  67 +}
  68 +
  69 +flutter {
  70 + source '../..'
  71 +}
  72 +
  73 +dependencies {
  74 + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  75 +}
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.tencent.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.tencent.example">
  3 + <application
  4 + android:label="example"
  5 + android:icon="@mipmap/ic_launcher">
  6 + <activity
  7 + android:name=".MainActivity"
  8 + android:exported="true"
  9 + android:launchMode="singleTop"
  10 + android:theme="@style/LaunchTheme"
  11 + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  12 + android:hardwareAccelerated="true"
  13 + android:windowSoftInputMode="adjustResize">
  14 + <!-- Specifies an Android theme to apply to this Activity as soon as
  15 + the Android process has started. This theme is visible to the user
  16 + while the Flutter UI initializes. After that, this theme continues
  17 + to determine the Window background behind the Flutter UI. -->
  18 + <meta-data
  19 + android:name="io.flutter.embedding.android.NormalTheme"
  20 + android:resource="@style/NormalTheme"
  21 + />
  22 + <intent-filter>
  23 + <action android:name="android.intent.action.MAIN"/>
  24 + <category android:name="android.intent.category.LAUNCHER"/>
  25 + </intent-filter>
  26 + </activity>
  27 + <!-- Don't delete the meta-data below.
  28 + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
  29 + <meta-data
  30 + android:name="flutterEmbedding"
  31 + android:value="2" />
  32 + </application>
  33 +</manifest>
  1 +package com.tencent.example
  2 +
  3 +import io.flutter.embedding.android.FlutterActivity
  4 +
  5 +class MainActivity: FlutterActivity() {
  6 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="?android:colorBackground" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="@android:color/white" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.tencent.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +buildscript {
  2 + ext.kotlin_version = '1.6.10'
  3 + repositories {
  4 + google()
  5 + mavenCentral()
  6 + }
  7 +
  8 + dependencies {
  9 + classpath 'com.android.tools.build:gradle:7.1.2'
  10 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  11 + }
  12 +}
  13 +
  14 +allprojects {
  15 + repositories {
  16 + google()
  17 + mavenCentral()
  18 + }
  19 +}
  20 +
  21 +rootProject.buildDir = '../build'
  22 +subprojects {
  23 + project.buildDir = "${rootProject.buildDir}/${project.name}"
  24 +}
  25 +subprojects {
  26 + project.evaluationDependsOn(':app')
  27 +}
  28 +
  29 +tasks.register("clean", Delete) {
  30 + delete rootProject.buildDir
  31 +}
  1 +org.gradle.jvmargs=-Xmx1536M
  2 +android.useAndroidX=true
  3 +android.enableJetifier=true
  1 +#Fri Jun 23 08:50:38 CEST 2017
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionPath=wrapper/dists
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
  6 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
  1 +include ':app'
  2 +
  3 +def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
  4 +def properties = new Properties()
  5 +
  6 +assert localPropertiesFile.exists()
  7 +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
  8 +
  9 +def flutterSdkPath = properties.getProperty("flutter.sdk")
  10 +assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
  11 +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
  1 +*.mode1v3
  2 +*.mode2v3
  3 +*.moved-aside
  4 +*.pbxuser
  5 +*.perspectivev3
  6 +**/*sync/
  7 +.sconsign.dblite
  8 +.tags*
  9 +**/.vagrant/
  10 +**/DerivedData/
  11 +Icon?
  12 +**/Pods/
  13 +**/.symlinks/
  14 +profile
  15 +xcuserdata
  16 +**/.generated/
  17 +Flutter/App.framework
  18 +Flutter/Flutter.framework
  19 +Flutter/Flutter.podspec
  20 +Flutter/Generated.xcconfig
  21 +Flutter/app.flx
  22 +Flutter/app.zip
  23 +Flutter/flutter_assets/
  24 +Flutter/flutter_export_environment.sh
  25 +ServiceDefinitions.json
  26 +Runner/GeneratedPluginRegistrant.*
  27 +
  28 +# Exceptions to above rules.
  29 +!default.mode1v3
  30 +!default.mode2v3
  31 +!default.pbxuser
  32 +!default.perspectivev3
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>App</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>io.flutter.flutter.app</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundleName</key>
  14 + <string>App</string>
  15 + <key>CFBundlePackageType</key>
  16 + <string>FMWK</string>
  17 + <key>CFBundleShortVersionString</key>
  18 + <string>1.0</string>
  19 + <key>CFBundleSignature</key>
  20 + <string>????</string>
  21 + <key>CFBundleVersion</key>
  22 + <string>1.0</string>
  23 + <key>MinimumOSVersion</key>
  24 + <string>12.0</string>
  25 +</dict>
  26 +</plist>
  1 +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
  2 +#include "Generated.xcconfig"
  1 +#include "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
  2 +#include "Generated.xcconfig"
  1 +# Uncomment this line to define a global platform for your project
  2 +# platform :ios, '12.0'
  3 +
  4 +# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
  5 +ENV['COCOAPODS_DISABLE_STATS'] = 'true'
  6 +
  7 +project 'Runner', {
  8 + 'Debug' => :debug,
  9 + 'Profile' => :release,
  10 + 'Release' => :release,
  11 +}
  12 +
  13 +def flutter_root
  14 + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  15 + unless File.exist?(generated_xcode_build_settings_path)
  16 + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  17 + end
  18 +
  19 + File.foreach(generated_xcode_build_settings_path) do |line|
  20 + matches = line.match(/FLUTTER_ROOT\=(.*)/)
  21 + return matches[1].strip if matches
  22 + end
  23 + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
  24 +end
  25 +
  26 +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
  27 +
  28 +flutter_ios_podfile_setup
  29 +
  30 +target 'Runner' do
  31 + use_frameworks!
  32 + use_modular_headers!
  33 +
  34 + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  35 +end
  36 +
  37 +post_install do |installer|
  38 + installer.pods_project.targets.each do |target|
  39 + flutter_additional_ios_build_settings(target)
  40 + end
  41 +end
  1 +PODS:
  2 + - Flutter (1.0.0)
  3 + - TPNS-iOS (1.4.0.5)
  4 + - tpns_flutter_plugin (1.3.4):
  5 + - Flutter
  6 + - TPNS-iOS (= 1.4.0.5)
  7 +
  8 +DEPENDENCIES:
  9 + - Flutter (from `Flutter`)
  10 + - tpns_flutter_plugin (from `.symlinks/plugins/tpns_flutter_plugin/ios`)
  11 +
  12 +SPEC REPOS:
  13 + trunk:
  14 + - TPNS-iOS
  15 +
  16 +EXTERNAL SOURCES:
  17 + Flutter:
  18 + :path: Flutter
  19 + tpns_flutter_plugin:
  20 + :path: ".symlinks/plugins/tpns_flutter_plugin/ios"
  21 +
  22 +SPEC CHECKSUMS:
  23 + Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
  24 + TPNS-iOS: 757b0439d967beb8c5d6be6a8e9ad23e11d1e36c
  25 + tpns_flutter_plugin: 54270cae525b4a255f9140b9b7f745724601646a
  26 +
  27 +PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011
  28 +
  29 +COCOAPODS: 1.16.2
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 54;
  7 + objects = {
  8 +
  9 +/* Begin PBXBuildFile section */
  10 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
  11 + 2DDE509E727BD43954A7C76A /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 46E5BF2F00BA5FE35FD91D82 /* Pods_Runner.framework */; };
  12 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
  13 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
  14 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
  15 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
  16 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
  17 +/* End PBXBuildFile section */
  18 +
  19 +/* Begin PBXCopyFilesBuildPhase section */
  20 + 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
  21 + isa = PBXCopyFilesBuildPhase;
  22 + buildActionMask = 2147483647;
  23 + dstPath = "";
  24 + dstSubfolderSpec = 10;
  25 + files = (
  26 + );
  27 + name = "Embed Frameworks";
  28 + runOnlyForDeploymentPostprocessing = 0;
  29 + };
  30 +/* End PBXCopyFilesBuildPhase section */
  31 +
  32 +/* Begin PBXFileReference section */
  33 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
  34 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
  35 + 1B1E0FCD23C4ADF20072DC3A /* Runner.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Runner.entitlements; sourceTree = "<group>"; };
  36 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
  37 + 46E5BF2F00BA5FE35FD91D82 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; };
  38 + 60F13BDE7DC0855DBCFC12F2 /* 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>"; };
  39 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
  40 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
  41 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
  42 + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
  43 + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
  44 + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
  45 + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  46 + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
  47 + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  48 + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
  49 + 9E01C11A453962BD60DABB7C /* 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>"; };
  50 + EEAD574267970C6F5031E634 /* 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>"; };
  51 +/* End PBXFileReference section */
  52 +
  53 +/* Begin PBXFrameworksBuildPhase section */
  54 + 97C146EB1CF9000F007C117D /* Frameworks */ = {
  55 + isa = PBXFrameworksBuildPhase;
  56 + buildActionMask = 2147483647;
  57 + files = (
  58 + 2DDE509E727BD43954A7C76A /* Pods_Runner.framework in Frameworks */,
  59 + );
  60 + runOnlyForDeploymentPostprocessing = 0;
  61 + };
  62 +/* End PBXFrameworksBuildPhase section */
  63 +
  64 +/* Begin PBXGroup section */
  65 + 0FD4F9FC8439C49779381BD0 /* Frameworks */ = {
  66 + isa = PBXGroup;
  67 + children = (
  68 + 46E5BF2F00BA5FE35FD91D82 /* Pods_Runner.framework */,
  69 + );
  70 + name = Frameworks;
  71 + sourceTree = "<group>";
  72 + };
  73 + 232F5FF2451FA860FA3BC0F4 /* Pods */ = {
  74 + isa = PBXGroup;
  75 + children = (
  76 + 60F13BDE7DC0855DBCFC12F2 /* Pods-Runner.debug.xcconfig */,
  77 + EEAD574267970C6F5031E634 /* Pods-Runner.release.xcconfig */,
  78 + 9E01C11A453962BD60DABB7C /* Pods-Runner.profile.xcconfig */,
  79 + );
  80 + path = Pods;
  81 + sourceTree = "<group>";
  82 + };
  83 + 9740EEB11CF90186004384FC /* Flutter */ = {
  84 + isa = PBXGroup;
  85 + children = (
  86 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
  87 + 9740EEB21CF90195004384FC /* Debug.xcconfig */,
  88 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
  89 + 9740EEB31CF90195004384FC /* Generated.xcconfig */,
  90 + );
  91 + name = Flutter;
  92 + sourceTree = "<group>";
  93 + };
  94 + 97C146E51CF9000F007C117D = {
  95 + isa = PBXGroup;
  96 + children = (
  97 + 9740EEB11CF90186004384FC /* Flutter */,
  98 + 97C146F01CF9000F007C117D /* Runner */,
  99 + 97C146EF1CF9000F007C117D /* Products */,
  100 + 232F5FF2451FA860FA3BC0F4 /* Pods */,
  101 + 0FD4F9FC8439C49779381BD0 /* Frameworks */,
  102 + );
  103 + sourceTree = "<group>";
  104 + };
  105 + 97C146EF1CF9000F007C117D /* Products */ = {
  106 + isa = PBXGroup;
  107 + children = (
  108 + 97C146EE1CF9000F007C117D /* Runner.app */,
  109 + );
  110 + name = Products;
  111 + sourceTree = "<group>";
  112 + };
  113 + 97C146F01CF9000F007C117D /* Runner */ = {
  114 + isa = PBXGroup;
  115 + children = (
  116 + 1B1E0FCD23C4ADF20072DC3A /* Runner.entitlements */,
  117 + 97C146FA1CF9000F007C117D /* Main.storyboard */,
  118 + 97C146FD1CF9000F007C117D /* Assets.xcassets */,
  119 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
  120 + 97C147021CF9000F007C117D /* Info.plist */,
  121 + 97C146F11CF9000F007C117D /* Supporting Files */,
  122 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
  123 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
  124 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
  125 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
  126 + );
  127 + path = Runner;
  128 + sourceTree = "<group>";
  129 + };
  130 + 97C146F11CF9000F007C117D /* Supporting Files */ = {
  131 + isa = PBXGroup;
  132 + children = (
  133 + );
  134 + name = "Supporting Files";
  135 + sourceTree = "<group>";
  136 + };
  137 +/* End PBXGroup section */
  138 +
  139 +/* Begin PBXNativeTarget section */
  140 + 97C146ED1CF9000F007C117D /* Runner */ = {
  141 + isa = PBXNativeTarget;
  142 + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
  143 + buildPhases = (
  144 + 2D231361BD2B90879FC56479 /* [CP] Check Pods Manifest.lock */,
  145 + 9740EEB61CF901F6004384FC /* Run Script */,
  146 + 97C146EA1CF9000F007C117D /* Sources */,
  147 + 97C146EB1CF9000F007C117D /* Frameworks */,
  148 + 97C146EC1CF9000F007C117D /* Resources */,
  149 + 9705A1C41CF9048500538489 /* Embed Frameworks */,
  150 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
  151 + CA9D2F060B4EAED2F2EA8812 /* [CP] Copy Pods Resources */,
  152 + );
  153 + buildRules = (
  154 + );
  155 + dependencies = (
  156 + );
  157 + name = Runner;
  158 + productName = Runner;
  159 + productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
  160 + productType = "com.apple.product-type.application";
  161 + };
  162 +/* End PBXNativeTarget section */
  163 +
  164 +/* Begin PBXProject section */
  165 + 97C146E61CF9000F007C117D /* Project object */ = {
  166 + isa = PBXProject;
  167 + attributes = {
  168 + LastUpgradeCheck = 1510;
  169 + ORGANIZATIONNAME = "The Chromium Authors";
  170 + TargetAttributes = {
  171 + 97C146ED1CF9000F007C117D = {
  172 + CreatedOnToolsVersion = 7.3.1;
  173 + DevelopmentTeam = 299MFJ63GP;
  174 + LastSwiftMigration = 1100;
  175 + ProvisioningStyle = Manual;
  176 + };
  177 + };
  178 + };
  179 + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
  180 + compatibilityVersion = "Xcode 3.2";
  181 + developmentRegion = en;
  182 + hasScannedForEncodings = 0;
  183 + knownRegions = (
  184 + en,
  185 + Base,
  186 + );
  187 + mainGroup = 97C146E51CF9000F007C117D;
  188 + productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
  189 + projectDirPath = "";
  190 + projectRoot = "";
  191 + targets = (
  192 + 97C146ED1CF9000F007C117D /* Runner */,
  193 + );
  194 + };
  195 +/* End PBXProject section */
  196 +
  197 +/* Begin PBXResourcesBuildPhase section */
  198 + 97C146EC1CF9000F007C117D /* Resources */ = {
  199 + isa = PBXResourcesBuildPhase;
  200 + buildActionMask = 2147483647;
  201 + files = (
  202 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
  203 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
  204 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
  205 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
  206 + );
  207 + runOnlyForDeploymentPostprocessing = 0;
  208 + };
  209 +/* End PBXResourcesBuildPhase section */
  210 +
  211 +/* Begin PBXShellScriptBuildPhase section */
  212 + 2D231361BD2B90879FC56479 /* [CP] Check Pods Manifest.lock */ = {
  213 + isa = PBXShellScriptBuildPhase;
  214 + buildActionMask = 2147483647;
  215 + files = (
  216 + );
  217 + inputFileListPaths = (
  218 + );
  219 + inputPaths = (
  220 + "${PODS_PODFILE_DIR_PATH}/Podfile.lock",
  221 + "${PODS_ROOT}/Manifest.lock",
  222 + );
  223 + name = "[CP] Check Pods Manifest.lock";
  224 + outputFileListPaths = (
  225 + );
  226 + outputPaths = (
  227 + "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt",
  228 + );
  229 + runOnlyForDeploymentPostprocessing = 0;
  230 + shellPath = /bin/sh;
  231 + shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n";
  232 + showEnvVarsInLog = 0;
  233 + };
  234 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
  235 + isa = PBXShellScriptBuildPhase;
  236 + alwaysOutOfDate = 1;
  237 + buildActionMask = 2147483647;
  238 + files = (
  239 + );
  240 + inputPaths = (
  241 + "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
  242 + );
  243 + name = "Thin Binary";
  244 + outputPaths = (
  245 + );
  246 + runOnlyForDeploymentPostprocessing = 0;
  247 + shellPath = /bin/sh;
  248 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
  249 + };
  250 + 9740EEB61CF901F6004384FC /* Run Script */ = {
  251 + isa = PBXShellScriptBuildPhase;
  252 + alwaysOutOfDate = 1;
  253 + buildActionMask = 2147483647;
  254 + files = (
  255 + );
  256 + inputPaths = (
  257 + );
  258 + name = "Run Script";
  259 + outputPaths = (
  260 + );
  261 + runOnlyForDeploymentPostprocessing = 0;
  262 + shellPath = /bin/sh;
  263 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
  264 + };
  265 + CA9D2F060B4EAED2F2EA8812 /* [CP] Copy Pods Resources */ = {
  266 + isa = PBXShellScriptBuildPhase;
  267 + buildActionMask = 2147483647;
  268 + files = (
  269 + );
  270 + inputPaths = (
  271 + "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh",
  272 + "${PODS_CONFIGURATION_BUILD_DIR}/TPNS-iOS/TPNS-iOS-Privacy.bundle",
  273 + );
  274 + name = "[CP] Copy Pods Resources";
  275 + outputPaths = (
  276 + "${TARGET_BUILD_DIR}/${UNLOCALIZED_RESOURCES_FOLDER_PATH}/TPNS-iOS-Privacy.bundle",
  277 + );
  278 + runOnlyForDeploymentPostprocessing = 0;
  279 + shellPath = /bin/sh;
  280 + shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-resources.sh\"\n";
  281 + showEnvVarsInLog = 0;
  282 + };
  283 +/* End PBXShellScriptBuildPhase section */
  284 +
  285 +/* Begin PBXSourcesBuildPhase section */
  286 + 97C146EA1CF9000F007C117D /* Sources */ = {
  287 + isa = PBXSourcesBuildPhase;
  288 + buildActionMask = 2147483647;
  289 + files = (
  290 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
  291 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
  292 + );
  293 + runOnlyForDeploymentPostprocessing = 0;
  294 + };
  295 +/* End PBXSourcesBuildPhase section */
  296 +
  297 +/* Begin PBXVariantGroup section */
  298 + 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
  299 + isa = PBXVariantGroup;
  300 + children = (
  301 + 97C146FB1CF9000F007C117D /* Base */,
  302 + );
  303 + name = Main.storyboard;
  304 + sourceTree = "<group>";
  305 + };
  306 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
  307 + isa = PBXVariantGroup;
  308 + children = (
  309 + 97C147001CF9000F007C117D /* Base */,
  310 + );
  311 + name = LaunchScreen.storyboard;
  312 + sourceTree = "<group>";
  313 + };
  314 +/* End PBXVariantGroup section */
  315 +
  316 +/* Begin XCBuildConfiguration section */
  317 + 249021D3217E4FDB00AE95B9 /* Profile */ = {
  318 + isa = XCBuildConfiguration;
  319 + buildSettings = {
  320 + ALWAYS_SEARCH_USER_PATHS = NO;
  321 + CLANG_ANALYZER_NONNULL = YES;
  322 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  323 + CLANG_CXX_LIBRARY = "libc++";
  324 + CLANG_ENABLE_MODULES = YES;
  325 + CLANG_ENABLE_OBJC_ARC = YES;
  326 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  327 + CLANG_WARN_BOOL_CONVERSION = YES;
  328 + CLANG_WARN_COMMA = YES;
  329 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  330 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  331 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  332 + CLANG_WARN_EMPTY_BODY = YES;
  333 + CLANG_WARN_ENUM_CONVERSION = YES;
  334 + CLANG_WARN_INFINITE_RECURSION = YES;
  335 + CLANG_WARN_INT_CONVERSION = YES;
  336 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  337 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  338 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  339 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  340 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  341 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  342 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  343 + CLANG_WARN_UNREACHABLE_CODE = YES;
  344 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  345 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  346 + COPY_PHASE_STRIP = NO;
  347 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  348 + ENABLE_NS_ASSERTIONS = NO;
  349 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  350 + GCC_C_LANGUAGE_STANDARD = gnu99;
  351 + GCC_NO_COMMON_BLOCKS = YES;
  352 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  353 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  354 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  355 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  356 + GCC_WARN_UNUSED_FUNCTION = YES;
  357 + GCC_WARN_UNUSED_VARIABLE = YES;
  358 + IPHONEOS_DEPLOYMENT_TARGET = 12.0;
  359 + MTL_ENABLE_DEBUG_INFO = NO;
  360 + SDKROOT = iphoneos;
  361 + SUPPORTED_PLATFORMS = iphoneos;
  362 + TARGETED_DEVICE_FAMILY = "1,2";
  363 + VALIDATE_PRODUCT = YES;
  364 + };
  365 + name = Profile;
  366 + };
  367 + 249021D4217E4FDB00AE95B9 /* Profile */ = {
  368 + isa = XCBuildConfiguration;
  369 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  370 + buildSettings = {
  371 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  372 + CLANG_ENABLE_MODULES = YES;
  373 + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
  374 + CODE_SIGN_IDENTITY = "Apple Development";
  375 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
  376 + CODE_SIGN_STYLE = Manual;
  377 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  378 + DEVELOPMENT_TEAM = "";
  379 + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 299MFJ63GP;
  380 + ENABLE_BITCODE = NO;
  381 + FRAMEWORK_SEARCH_PATHS = (
  382 + "$(inherited)",
  383 + "$(PROJECT_DIR)/Flutter",
  384 + );
  385 + INFOPLIST_FILE = Runner/Info.plist;
  386 + LD_RUNPATH_SEARCH_PATHS = (
  387 + "$(inherited)",
  388 + "@executable_path/Frameworks",
  389 + );
  390 + LIBRARY_SEARCH_PATHS = (
  391 + "$(inherited)",
  392 + "$(PROJECT_DIR)/Flutter",
  393 + );
  394 + NEW_SETTING = "";
  395 + PRODUCT_BUNDLE_IDENTIFIER = com.tencent.tpns;
  396 + PRODUCT_NAME = "$(TARGET_NAME)";
  397 + PROVISIONING_PROFILE_SPECIFIER = "";
  398 + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = com.tencent.tpns_dev;
  399 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  400 + SWIFT_VERSION = 5.0;
  401 + VERSIONING_SYSTEM = "apple-generic";
  402 + };
  403 + name = Profile;
  404 + };
  405 + 97C147031CF9000F007C117D /* Debug */ = {
  406 + isa = XCBuildConfiguration;
  407 + buildSettings = {
  408 + ALWAYS_SEARCH_USER_PATHS = NO;
  409 + CLANG_ANALYZER_NONNULL = YES;
  410 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  411 + CLANG_CXX_LIBRARY = "libc++";
  412 + CLANG_ENABLE_MODULES = YES;
  413 + CLANG_ENABLE_OBJC_ARC = YES;
  414 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  415 + CLANG_WARN_BOOL_CONVERSION = YES;
  416 + CLANG_WARN_COMMA = YES;
  417 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  418 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  419 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  420 + CLANG_WARN_EMPTY_BODY = YES;
  421 + CLANG_WARN_ENUM_CONVERSION = YES;
  422 + CLANG_WARN_INFINITE_RECURSION = YES;
  423 + CLANG_WARN_INT_CONVERSION = YES;
  424 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  425 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  426 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  427 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  428 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  429 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  430 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  431 + CLANG_WARN_UNREACHABLE_CODE = YES;
  432 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  433 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  434 + COPY_PHASE_STRIP = NO;
  435 + DEBUG_INFORMATION_FORMAT = dwarf;
  436 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  437 + ENABLE_TESTABILITY = YES;
  438 + GCC_C_LANGUAGE_STANDARD = gnu99;
  439 + GCC_DYNAMIC_NO_PIC = NO;
  440 + GCC_NO_COMMON_BLOCKS = YES;
  441 + GCC_OPTIMIZATION_LEVEL = 0;
  442 + GCC_PREPROCESSOR_DEFINITIONS = (
  443 + "DEBUG=1",
  444 + "$(inherited)",
  445 + );
  446 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  447 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  448 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  449 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  450 + GCC_WARN_UNUSED_FUNCTION = YES;
  451 + GCC_WARN_UNUSED_VARIABLE = YES;
  452 + IPHONEOS_DEPLOYMENT_TARGET = 12.0;
  453 + MTL_ENABLE_DEBUG_INFO = YES;
  454 + ONLY_ACTIVE_ARCH = YES;
  455 + SDKROOT = iphoneos;
  456 + TARGETED_DEVICE_FAMILY = "1,2";
  457 + };
  458 + name = Debug;
  459 + };
  460 + 97C147041CF9000F007C117D /* Release */ = {
  461 + isa = XCBuildConfiguration;
  462 + buildSettings = {
  463 + ALWAYS_SEARCH_USER_PATHS = NO;
  464 + CLANG_ANALYZER_NONNULL = YES;
  465 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  466 + CLANG_CXX_LIBRARY = "libc++";
  467 + CLANG_ENABLE_MODULES = YES;
  468 + CLANG_ENABLE_OBJC_ARC = YES;
  469 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  470 + CLANG_WARN_BOOL_CONVERSION = YES;
  471 + CLANG_WARN_COMMA = YES;
  472 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  473 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  474 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  475 + CLANG_WARN_EMPTY_BODY = YES;
  476 + CLANG_WARN_ENUM_CONVERSION = YES;
  477 + CLANG_WARN_INFINITE_RECURSION = YES;
  478 + CLANG_WARN_INT_CONVERSION = YES;
  479 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  480 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  481 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  482 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  483 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  484 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  485 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  486 + CLANG_WARN_UNREACHABLE_CODE = YES;
  487 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  488 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  489 + COPY_PHASE_STRIP = NO;
  490 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  491 + ENABLE_NS_ASSERTIONS = NO;
  492 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  493 + GCC_C_LANGUAGE_STANDARD = gnu99;
  494 + GCC_NO_COMMON_BLOCKS = YES;
  495 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  496 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  497 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  498 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  499 + GCC_WARN_UNUSED_FUNCTION = YES;
  500 + GCC_WARN_UNUSED_VARIABLE = YES;
  501 + IPHONEOS_DEPLOYMENT_TARGET = 12.0;
  502 + MTL_ENABLE_DEBUG_INFO = NO;
  503 + SDKROOT = iphoneos;
  504 + SUPPORTED_PLATFORMS = iphoneos;
  505 + SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
  506 + TARGETED_DEVICE_FAMILY = "1,2";
  507 + VALIDATE_PRODUCT = YES;
  508 + };
  509 + name = Release;
  510 + };
  511 + 97C147061CF9000F007C117D /* Debug */ = {
  512 + isa = XCBuildConfiguration;
  513 + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
  514 + buildSettings = {
  515 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  516 + CLANG_ENABLE_MODULES = YES;
  517 + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
  518 + CODE_SIGN_IDENTITY = "Apple Development";
  519 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "Apple Development";
  520 + CODE_SIGN_STYLE = Manual;
  521 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  522 + DEVELOPMENT_TEAM = "";
  523 + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 299MFJ63GP;
  524 + ENABLE_BITCODE = NO;
  525 + FRAMEWORK_SEARCH_PATHS = (
  526 + "$(inherited)",
  527 + "$(PROJECT_DIR)/Flutter",
  528 + );
  529 + INFOPLIST_FILE = Runner/Info.plist;
  530 + LD_RUNPATH_SEARCH_PATHS = (
  531 + "$(inherited)",
  532 + "@executable_path/Frameworks",
  533 + );
  534 + LIBRARY_SEARCH_PATHS = (
  535 + "$(inherited)",
  536 + "$(PROJECT_DIR)/Flutter",
  537 + );
  538 + NEW_SETTING = "";
  539 + PRODUCT_BUNDLE_IDENTIFIER = com.tencent.tpns;
  540 + PRODUCT_NAME = "$(TARGET_NAME)";
  541 + PROVISIONING_PROFILE_SPECIFIER = "";
  542 + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = com.tencent.tpns_dev;
  543 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  544 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  545 + SWIFT_VERSION = 5.0;
  546 + VERSIONING_SYSTEM = "apple-generic";
  547 + };
  548 + name = Debug;
  549 + };
  550 + 97C147071CF9000F007C117D /* Release */ = {
  551 + isa = XCBuildConfiguration;
  552 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  553 + buildSettings = {
  554 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  555 + CLANG_ENABLE_MODULES = YES;
  556 + CODE_SIGN_ENTITLEMENTS = Runner/Runner.entitlements;
  557 + CODE_SIGN_IDENTITY = "Apple Development";
  558 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  559 + CODE_SIGN_STYLE = Manual;
  560 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  561 + DEVELOPMENT_TEAM = "";
  562 + "DEVELOPMENT_TEAM[sdk=iphoneos*]" = 299MFJ63GP;
  563 + ENABLE_BITCODE = NO;
  564 + FRAMEWORK_SEARCH_PATHS = (
  565 + "$(inherited)",
  566 + "$(PROJECT_DIR)/Flutter",
  567 + );
  568 + INFOPLIST_FILE = Runner/Info.plist;
  569 + LD_RUNPATH_SEARCH_PATHS = (
  570 + "$(inherited)",
  571 + "@executable_path/Frameworks",
  572 + );
  573 + LIBRARY_SEARCH_PATHS = (
  574 + "$(inherited)",
  575 + "$(PROJECT_DIR)/Flutter",
  576 + );
  577 + NEW_SETTING = "";
  578 + PRODUCT_BUNDLE_IDENTIFIER = com.tencent.tpns;
  579 + PRODUCT_NAME = "$(TARGET_NAME)";
  580 + PROVISIONING_PROFILE_SPECIFIER = "";
  581 + "PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]" = com.tencent.tpns_dev;
  582 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  583 + SWIFT_VERSION = 5.0;
  584 + VERSIONING_SYSTEM = "apple-generic";
  585 + };
  586 + name = Release;
  587 + };
  588 +/* End XCBuildConfiguration section */
  589 +
  590 +/* Begin XCConfigurationList section */
  591 + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
  592 + isa = XCConfigurationList;
  593 + buildConfigurations = (
  594 + 97C147031CF9000F007C117D /* Debug */,
  595 + 97C147041CF9000F007C117D /* Release */,
  596 + 249021D3217E4FDB00AE95B9 /* Profile */,
  597 + );
  598 + defaultConfigurationIsVisible = 0;
  599 + defaultConfigurationName = Release;
  600 + };
  601 + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
  602 + isa = XCConfigurationList;
  603 + buildConfigurations = (
  604 + 97C147061CF9000F007C117D /* Debug */,
  605 + 97C147071CF9000F007C117D /* Release */,
  606 + 249021D4217E4FDB00AE95B9 /* Profile */,
  607 + );
  608 + defaultConfigurationIsVisible = 0;
  609 + defaultConfigurationName = Release;
  610 + };
  611 +/* End XCConfigurationList section */
  612 + };
  613 + rootObject = 97C146E61CF9000F007C117D /* Project object */;
  614 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "self:">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "1510"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  18 + BuildableName = "Runner.app"
  19 + BlueprintName = "Runner"
  20 + ReferencedContainer = "container:Runner.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <MacroExpansion>
  31 + <BuildableReference
  32 + BuildableIdentifier = "primary"
  33 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  34 + BuildableName = "Runner.app"
  35 + BlueprintName = "Runner"
  36 + ReferencedContainer = "container:Runner.xcodeproj">
  37 + </BuildableReference>
  38 + </MacroExpansion>
  39 + <Testables>
  40 + </Testables>
  41 + </TestAction>
  42 + <LaunchAction
  43 + buildConfiguration = "Release"
  44 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  45 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  46 + launchStyle = "0"
  47 + useCustomWorkingDirectory = "NO"
  48 + ignoresPersistentStateOnLaunch = "NO"
  49 + debugDocumentVersioning = "YES"
  50 + debugServiceExtension = "internal"
  51 + allowLocationSimulation = "YES">
  52 + <BuildableProductRunnable
  53 + runnableDebuggingMode = "0">
  54 + <BuildableReference
  55 + BuildableIdentifier = "primary"
  56 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  57 + BuildableName = "Runner.app"
  58 + BlueprintName = "Runner"
  59 + ReferencedContainer = "container:Runner.xcodeproj">
  60 + </BuildableReference>
  61 + </BuildableProductRunnable>
  62 + </LaunchAction>
  63 + <ProfileAction
  64 + buildConfiguration = "Profile"
  65 + shouldUseLaunchSchemeArgsEnv = "YES"
  66 + savedToolIdentifier = ""
  67 + useCustomWorkingDirectory = "NO"
  68 + debugDocumentVersioning = "YES">
  69 + <BuildableProductRunnable
  70 + runnableDebuggingMode = "0">
  71 + <BuildableReference
  72 + BuildableIdentifier = "primary"
  73 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  74 + BuildableName = "Runner.app"
  75 + BlueprintName = "Runner"
  76 + ReferencedContainer = "container:Runner.xcodeproj">
  77 + </BuildableReference>
  78 + </BuildableProductRunnable>
  79 + </ProfileAction>
  80 + <AnalyzeAction
  81 + buildConfiguration = "Debug">
  82 + </AnalyzeAction>
  83 + <ArchiveAction
  84 + buildConfiguration = "Release"
  85 + revealArchiveInOrganizer = "YES">
  86 + </ArchiveAction>
  87 +</Scheme>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "group:Runner.xcodeproj">
  6 + </FileRef>
  7 + <FileRef
  8 + location = "group:Pods/Pods.xcodeproj">
  9 + </FileRef>
  10 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +import UIKit
  2 +import Flutter
  3 +
  4 +@UIApplicationMain
  5 +@objc class AppDelegate: FlutterAppDelegate {
  6 + override func application(
  7 + _ application: UIApplication,
  8 + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  9 + ) -> Bool {
  10 + GeneratedPluginRegistrant.register(with: self)
  11 + return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  12 + }
  13 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "iphone",
  5 + "size" : "20x20",
  6 + "scale" : "2x"
  7 + },
  8 + {
  9 + "idiom" : "iphone",
  10 + "size" : "20x20",
  11 + "scale" : "3x"
  12 + },
  13 + {
  14 + "idiom" : "iphone",
  15 + "size" : "29x29",
  16 + "scale" : "1x"
  17 + },
  18 + {
  19 + "idiom" : "iphone",
  20 + "size" : "29x29",
  21 + "scale" : "2x"
  22 + },
  23 + {
  24 + "idiom" : "iphone",
  25 + "size" : "29x29",
  26 + "scale" : "3x"
  27 + },
  28 + {
  29 + "idiom" : "iphone",
  30 + "size" : "40x40",
  31 + "scale" : "2x"
  32 + },
  33 + {
  34 + "idiom" : "iphone",
  35 + "size" : "40x40",
  36 + "scale" : "3x"
  37 + },
  38 + {
  39 + "size" : "60x60",
  40 + "idiom" : "iphone",
  41 + "filename" : "xg-120.png",
  42 + "scale" : "2x"
  43 + },
  44 + {
  45 + "size" : "60x60",
  46 + "idiom" : "iphone",
  47 + "filename" : "xg-180.png",
  48 + "scale" : "3x"
  49 + },
  50 + {
  51 + "idiom" : "ipad",
  52 + "size" : "20x20",
  53 + "scale" : "1x"
  54 + },
  55 + {
  56 + "idiom" : "ipad",
  57 + "size" : "20x20",
  58 + "scale" : "2x"
  59 + },
  60 + {
  61 + "idiom" : "ipad",
  62 + "size" : "29x29",
  63 + "scale" : "1x"
  64 + },
  65 + {
  66 + "idiom" : "ipad",
  67 + "size" : "29x29",
  68 + "scale" : "2x"
  69 + },
  70 + {
  71 + "idiom" : "ipad",
  72 + "size" : "40x40",
  73 + "scale" : "1x"
  74 + },
  75 + {
  76 + "idiom" : "ipad",
  77 + "size" : "40x40",
  78 + "scale" : "2x"
  79 + },
  80 + {
  81 + "idiom" : "ipad",
  82 + "size" : "76x76",
  83 + "scale" : "1x"
  84 + },
  85 + {
  86 + "idiom" : "ipad",
  87 + "size" : "76x76",
  88 + "scale" : "2x"
  89 + },
  90 + {
  91 + "idiom" : "ipad",
  92 + "size" : "83.5x83.5",
  93 + "scale" : "2x"
  94 + },
  95 + {
  96 + "idiom" : "ios-marketing",
  97 + "size" : "1024x1024",
  98 + "scale" : "1x"
  99 + }
  100 + ],
  101 + "info" : {
  102 + "version" : 1,
  103 + "author" : "xcode"
  104 + }
  105 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "filename" : "LaunchImage.png",
  6 + "scale" : "1x"
  7 + },
  8 + {
  9 + "idiom" : "universal",
  10 + "filename" : "LaunchImage@2x.png",
  11 + "scale" : "2x"
  12 + },
  13 + {
  14 + "idiom" : "universal",
  15 + "filename" : "LaunchImage@3x.png",
  16 + "scale" : "3x"
  17 + }
  18 + ],
  19 + "info" : {
  20 + "version" : 1,
  21 + "author" : "xcode"
  22 + }
  23 +}
  1 +# Launch Screen Assets
  2 +
  3 +You can customize the launch screen with your own desired assets by replacing the image files in this directory.
  4 +
  5 +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--View Controller-->
  9 + <scene sceneID="EHf-IW-A2E">
  10 + <objects>
  11 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
  14 + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <subviews>
  19 + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
  20 + </imageView>
  21 + </subviews>
  22 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  23 + <constraints>
  24 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
  25 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
  26 + </constraints>
  27 + </view>
  28 + </viewController>
  29 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  30 + </objects>
  31 + <point key="canvasLocation" x="53" y="375"/>
  32 + </scene>
  33 + </scenes>
  34 + <resources>
  35 + <image name="LaunchImage" width="168" height="185"/>
  36 + </resources>
  37 +</document>
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--Flutter View Controller-->
  9 + <scene sceneID="tne-QT-ifu">
  10 + <objects>
  11 + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
  14 + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
  17 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  18 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  19 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  20 + </view>
  21 + </viewController>
  22 + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
  23 + </objects>
  24 + </scene>
  25 + </scenes>
  26 +</document>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>$(EXECUTABLE_NAME)</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundleName</key>
  14 + <string>tpns_flutter_demo</string>
  15 + <key>CFBundlePackageType</key>
  16 + <string>APPL</string>
  17 + <key>CFBundleShortVersionString</key>
  18 + <string>$(FLUTTER_BUILD_NAME)</string>
  19 + <key>CFBundleSignature</key>
  20 + <string>????</string>
  21 + <key>CFBundleVersion</key>
  22 + <string>$(FLUTTER_BUILD_NUMBER)</string>
  23 + <key>LSRequiresIPhoneOS</key>
  24 + <true/>
  25 + <key>UILaunchStoryboardName</key>
  26 + <string>LaunchScreen</string>
  27 + <key>UIMainStoryboardFile</key>
  28 + <string>Main</string>
  29 + <key>UISupportedInterfaceOrientations</key>
  30 + <array>
  31 + <string>UIInterfaceOrientationPortrait</string>
  32 + <string>UIInterfaceOrientationLandscapeLeft</string>
  33 + <string>UIInterfaceOrientationLandscapeRight</string>
  34 + </array>
  35 + <key>UISupportedInterfaceOrientations~ipad</key>
  36 + <array>
  37 + <string>UIInterfaceOrientationPortrait</string>
  38 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  39 + <string>UIInterfaceOrientationLandscapeLeft</string>
  40 + <string>UIInterfaceOrientationLandscapeRight</string>
  41 + </array>
  42 + <key>UIViewControllerBasedStatusBarAppearance</key>
  43 + <false/>
  44 + <key>CADisableMinimumFrameDurationOnPhone</key>
  45 + <true/>
  46 + <key>UIApplicationSupportsIndirectInputEvents</key>
  47 + <true/>
  48 +</dict>
  49 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>aps-environment</key>
  6 + <string>development</string>
  7 +</dict>
  8 +</plist>
  1 +library flutter_tableview;
  2 +
  3 +import 'package:flutter/material.dart';
  4 +
  5 +typedef int RowCountAtSection(int section);
  6 +typedef Widget ListViewFatherWidgetBuilder(
  7 + BuildContext context, Widget canScrollWidget);
  8 +typedef Widget SectionHeaderBuilder(BuildContext context, int section);
  9 +typedef Widget CellBuilder(BuildContext context, int section, int row);
  10 +typedef double CellHeight(BuildContext context, int section, int row);
  11 +typedef double SectionHeaderHeight(BuildContext context, int section);
  12 +
  13 +const String ErorrFlagBegin =
  14 + '\n\n\n====================FlutterTableView Error========================\n\n\n\n';
  15 +
  16 +const String ErorrFlagEnd =
  17 + '\n\n\n\n\n==================================================================\n\n\n\n.';
  18 +
  19 +class FlutterTableView extends StatefulWidget {
  20 + FlutterTableView({
  21 + required this.sectionCount,
  22 + required this.rowCountAtSection,
  23 + required this.sectionHeaderBuilder,
  24 + required this.cellBuilder,
  25 + required this.sectionHeaderHeight,
  26 + required this.cellHeight,
  27 + this.listViewFatherWidgetBuilder,
  28 + this.controller,
  29 + this.physics,
  30 + this.shrinkWrap = false,
  31 + this.padding = const EdgeInsets.all(0.0),
  32 + this.cacheExtent = 50.0,
  33 + this.backgroundColor = Colors.transparent,
  34 + }) : assert(
  35 + (sectionCount != null && sectionCount > 0),
  36 + '$ErorrFlagBegin sectionCount must > 0 and could not be null. $ErorrFlagEnd',
  37 + ),
  38 + assert(
  39 + (rowCountAtSection != null),
  40 + '$ErorrFlagBegin function rowCountAtSection could not be null. $ErorrFlagEnd',
  41 + ),
  42 + assert(
  43 + (sectionHeaderBuilder != null),
  44 + '$ErorrFlagBegin function sectionHeaderBuilder could not be null. $ErorrFlagEnd',
  45 + ),
  46 + assert(
  47 + (cellBuilder != null),
  48 + '$ErorrFlagBegin function cellBuilder could not be null. $ErorrFlagEnd',
  49 + ),
  50 + assert(
  51 + (sectionHeaderHeight != null),
  52 + '$ErorrFlagBegin function sectionHeaderHeight could not be null. $ErorrFlagEnd',
  53 + ),
  54 + assert(
  55 + (cellHeight != null),
  56 + '$ErorrFlagBegin function cellHeight could not be null. $ErorrFlagEnd',
  57 + );
  58 +
  59 + @override
  60 + _FlutterTableViewState createState() {
  61 + return _FlutterTableViewState();
  62 + }
  63 +
  64 + /// How many section.
  65 + final int sectionCount;
  66 +
  67 + /// How many item in each section.
  68 + final RowCountAtSection rowCountAtSection;
  69 +
  70 + /// You can through sectionHeaderBuilder create section header widget.
  71 + /// Each section has at most one headWidget.
  72 + /// In a special section, if you don't need section header widget, you can return null.
  73 + final SectionHeaderBuilder sectionHeaderBuilder;
  74 +
  75 + /// You can through cellBuilder create items.
  76 + final CellBuilder cellBuilder;
  77 +
  78 + /// return each item widget height.
  79 + final CellHeight cellHeight;
  80 +
  81 + /// return each section header widget height.
  82 + final SectionHeaderHeight sectionHeaderHeight;
  83 +
  84 + /// You can wrap a widget for listView
  85 + final ListViewFatherWidgetBuilder? listViewFatherWidgetBuilder;
  86 +
  87 + /// see ScrollView controller
  88 + final ScrollController? controller;
  89 +
  90 + /// see ScrollView physics
  91 + final ScrollPhysics? physics;
  92 +
  93 + /// see ScrollView shrinkWrap
  94 + final bool shrinkWrap;
  95 +
  96 + final EdgeInsetsGeometry padding;
  97 +
  98 + /// see ScrollView cacheExtent
  99 + final double cacheExtent;
  100 +
  101 + final Color backgroundColor;
  102 +}
  103 +
  104 +class _FlutterTableViewState extends State<FlutterTableView> {
  105 + ////////////////////////////////////////////////////////////////////
  106 + // variables
  107 + ////////////////////////////////////////////////////////////////////
  108 + SectionHeaderModel? currentHeaderModel;
  109 + int totalItemCount = 0;
  110 + List<SectionHeaderModel> sectionHeaderList = [];
  111 + List<int> sectionTotalWidgetCountList = [];
  112 + ScrollController? scrollController;
  113 + ListView? listView;
  114 + bool insideSetStateFlag = false;
  115 +
  116 + ////////////////////////////////////////////////////////////////////
  117 + // init function
  118 + ////////////////////////////////////////////////////////////////////
  119 + void _initBaseData() {
  120 + this.totalItemCount = 0;
  121 + this.sectionHeaderList.clear();
  122 + this.sectionTotalWidgetCountList.clear();
  123 +
  124 + double offsetY = 0;
  125 + for (int section = 0; section < widget.sectionCount; section++) {
  126 + int rowCount = widget.rowCountAtSection(section);
  127 + Widget sectionHeader = widget.sectionHeaderBuilder(context, section);
  128 + double sectionHeight;
  129 + if (sectionHeader != null) {
  130 + sectionHeight = this.widget.sectionHeaderHeight(context, section);
  131 + } else {
  132 + sectionHeight = 0;
  133 + }
  134 +
  135 + double sectionHeaderY = offsetY;
  136 +
  137 + offsetY += sectionHeight;
  138 +
  139 + int sectionWidgetCount = sectionHeader == null ? rowCount : rowCount + 1;
  140 + sectionTotalWidgetCountList.add(sectionWidgetCount);
  141 + this.totalItemCount += sectionWidgetCount;
  142 +
  143 + for (int row = 0; row < rowCount; row++) {
  144 + offsetY += this.widget.cellHeight(context, section, row);
  145 + }
  146 +
  147 + SectionHeaderModel model = SectionHeaderModel(
  148 + y: sectionHeaderY,
  149 + sectionMaxY: offsetY,
  150 + height: sectionHeight,
  151 + section: section,
  152 + headerWidget: sectionHeader,
  153 + );
  154 + sectionHeaderList.add(model);
  155 + }
  156 + }
  157 +
  158 + void _initScrollController() {
  159 + this.scrollController = this.widget.controller;
  160 + if (this.scrollController == null) {
  161 + this.scrollController = ScrollController();
  162 + }
  163 +
  164 + this.scrollController?.addListener(() {
  165 + double offsetY = this.scrollController?.offset ?? 0;
  166 +
  167 + if (offsetY <= 0.0) {
  168 + this._updateCurrentSectionHeaderModel(SectionHeaderModel(), 0);
  169 + } else {
  170 + int section = 0;
  171 + for (int i = 0; i < this.sectionHeaderList.length; i++) {
  172 + SectionHeaderModel model = this.sectionHeaderList[i];
  173 + if (offsetY >= (model?.y ?? 0) && offsetY <= (model?.sectionMaxY ?? 0)) {
  174 + section = i;
  175 + break;
  176 + }
  177 + }
  178 +
  179 + SectionHeaderModel model = this.sectionHeaderList[section];
  180 + double delta = (model.sectionMaxY ?? 0) - (this.scrollController?.offset ?? 0);
  181 + double topOffset;
  182 + if (delta >= (model?.height ?? 0)) {
  183 + topOffset = 0.0;
  184 + } else {
  185 + topOffset = delta - (model?.height ?? 0);
  186 + }
  187 + this._updateCurrentSectionHeaderModel(model, topOffset);
  188 + }
  189 + });
  190 + }
  191 +
  192 + ////////////////////////////////////////////////////////////////////
  193 + // create listView
  194 + ////////////////////////////////////////////////////////////////////
  195 + void _createListView() {
  196 + if(this.insideSetStateFlag == false) {
  197 + this._initBaseData();
  198 + }
  199 +
  200 + this.insideSetStateFlag = false;
  201 +
  202 + this.listView = ListView.builder(
  203 + controller: this.scrollController,
  204 + physics: this.widget.physics ?? AlwaysScrollableScrollPhysics(),
  205 + shrinkWrap: this.widget.shrinkWrap,
  206 + cacheExtent: this.widget.cacheExtent,
  207 + itemBuilder: (BuildContext context, int index) {
  208 + Widget? itemWidget;
  209 + RowSectionModel model = this._getRowSectionModel(index) ?? RowSectionModel(section: 0, row: 0, haveHeaderWidget: false);
  210 + double height;
  211 + if (model.row == 0 && (model.haveHeaderWidget ?? false)) {
  212 + itemWidget = this.sectionHeaderList[model.section ?? 0].headerWidget;
  213 + height = this.widget.sectionHeaderHeight(context, model.section ?? 0);
  214 + } else {
  215 + int row = (model.haveHeaderWidget ?? false) == false ? (model.row ?? 0) : (model.row ?? 0) - 1;
  216 + itemWidget = this.widget.cellBuilder(context, model.section ?? 0, row);
  217 + height = this.widget.cellHeight(context, model.section ?? 0, row);
  218 + }
  219 +
  220 + return ConstrainedBox(
  221 + constraints: BoxConstraints(
  222 + minHeight: height,
  223 + maxHeight: height,
  224 + ),
  225 + child: itemWidget,
  226 + );
  227 + },
  228 + itemCount: this.totalItemCount,
  229 + );
  230 + }
  231 +
  232 + ////////////////////////////////////////////////////////////////////
  233 + // tool function
  234 + ////////////////////////////////////////////////////////////////////
  235 + RowSectionModel? _getRowSectionModel(int index) {
  236 + int passCount = 0;
  237 + for (int section = 0;
  238 + section < this.sectionTotalWidgetCountList.length;
  239 + section++) {
  240 + int currentSectionWidgetCount = this.sectionTotalWidgetCountList[section];
  241 + if (index >= passCount && index < passCount + currentSectionWidgetCount) {
  242 + int row = index - passCount;
  243 + bool haveSectionHeaderWidget =
  244 + this.sectionHeaderList[section].headerWidget != null;
  245 + RowSectionModel model = RowSectionModel(
  246 + section: section,
  247 + row: row,
  248 + haveHeaderWidget: haveSectionHeaderWidget,
  249 + );
  250 +
  251 + return model;
  252 + }
  253 +
  254 + passCount += currentSectionWidgetCount;
  255 + }
  256 + return null;
  257 + }
  258 +
  259 + void _updateCurrentSectionHeaderModel(
  260 + SectionHeaderModel model, double topOffset) {
  261 + bool needSetState = false;
  262 + if (model == null) {
  263 + if (this.currentHeaderModel != null) {
  264 + this.currentHeaderModel = null;
  265 + needSetState = true;
  266 + }
  267 + } else if (this.currentHeaderModel == null) {
  268 + this.currentHeaderModel = model;
  269 + this.currentHeaderModel?.topOffset = topOffset;
  270 + needSetState = true;
  271 + } else {
  272 + if (model != this.currentHeaderModel) {
  273 + this.currentHeaderModel = model;
  274 +
  275 + needSetState = true;
  276 + } else if (model.topOffset != topOffset) {
  277 + needSetState = true;
  278 + }
  279 +
  280 + this.currentHeaderModel?.topOffset = topOffset;
  281 + }
  282 +
  283 + if (needSetState == true) {
  284 + this.insideSetStateFlag = true;
  285 + setState(() {});
  286 + }
  287 + }
  288 +
  289 + ////////////////////////////////////////////////////////////////////
  290 + // life cycle
  291 + ////////////////////////////////////////////////////////////////////
  292 +
  293 + @override
  294 + void dispose() {
  295 + super.dispose();
  296 +
  297 + if (this.widget.controller == null) {
  298 + this.scrollController?.dispose();
  299 + }
  300 + }
  301 +
  302 + @override
  303 + void initState() {
  304 + this._initScrollController();
  305 + super.initState();
  306 + }
  307 +
  308 + @override
  309 + Widget build(BuildContext context) {
  310 + this._createListView();
  311 + Widget? listViewFatherWidget;
  312 + if (this.widget.listViewFatherWidgetBuilder != null) {
  313 + listViewFatherWidget =
  314 + this.widget.listViewFatherWidgetBuilder!(context, this.listView ?? ListView());
  315 + }
  316 +
  317 + Widget? listViewWidget = listViewFatherWidget ?? this.listView;
  318 +
  319 + if (this.currentHeaderModel != null &&
  320 + this.currentHeaderModel?.headerWidget != null) {
  321 + return Container(
  322 + padding: this.widget.padding,
  323 + color: widget.backgroundColor,
  324 + child: Stack(
  325 + children: <Widget>[
  326 + Container(
  327 + color: Colors.transparent,
  328 + child: listViewWidget,
  329 + ),
  330 + Positioned(
  331 + top: this.currentHeaderModel?.topOffset,
  332 + left: 0.0,
  333 + right: 0.0,
  334 + height: this.currentHeaderModel?.height,
  335 + child: Container(
  336 + color: Colors.white,
  337 + child: this.currentHeaderModel?.headerWidget,
  338 + ),
  339 + ),
  340 + ],
  341 + ),
  342 + );
  343 + }
  344 + return Container(
  345 + padding: this.widget.padding,
  346 + color: this.widget.backgroundColor,
  347 + child: Stack(
  348 + children: [
  349 + Container(
  350 + color: Colors.transparent,
  351 + child: listViewWidget,
  352 + ),
  353 + ],
  354 + ),
  355 + );
  356 + }
  357 +}
  358 +
  359 +////////////////////////////////////////////////////////////////////
  360 +// model class
  361 +////////////////////////////////////////////////////////////////////
  362 +
  363 +class RowSectionModel {
  364 + RowSectionModel({
  365 + this.section,
  366 + this.row,
  367 + this.haveHeaderWidget,
  368 + });
  369 +
  370 + final int? section;
  371 + final int? row;
  372 + final bool? haveHeaderWidget;
  373 +}
  374 +
  375 +class SectionHeaderModel {
  376 + SectionHeaderModel({
  377 + this.y,
  378 + this.sectionMaxY,
  379 + this.height,
  380 + this.section,
  381 + this.headerWidget,
  382 + });
  383 +
  384 + final double? y;
  385 + final double? sectionMaxY;
  386 + final double? height;
  387 + final int? section;
  388 + final Widget? headerWidget;
  389 +
  390 + double? topOffset;
  391 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'flutter_tableview.dart';
  3 +import 'package:tpns_flutter_plugin/tpns_flutter_plugin.dart';
  4 +import 'package:rflutter_alert/rflutter_alert.dart';
  5 +
  6 +List<String> sectionTitleList = ['关于账号接口', '关于标签接口', '关于用户属性接口', '关于应用接口'];
  7 +List<List<String>> sectionList = [
  8 + ['设置账号', '解绑账号', '清除全部账号'],
  9 + ['绑定一个标签', '解绑一个标签', '更新标签', '清除全部标签'],
  10 + ['新增用户属性', '删除用户属性', '更新用户属性', '清除全部用户属性'],
  11 + ['注册推送服务', '注销推送服务', '设备推送标识', '上报当前角标数', 'SDK 版本']
  12 +];
  13 +
  14 +class HomeTest extends StatelessWidget {
  15 + @override
  16 + Widget build(BuildContext context) {
  17 + return Scaffold(
  18 + appBar: AppBar(
  19 + title: Text('TPNS Demo'),
  20 + ),
  21 + body: HomeTestBody(),
  22 + );
  23 + }
  24 +}
  25 +
  26 +class HomeTestBody extends StatefulWidget {
  27 + @override
  28 + HomeTestBodyState createState() => HomeTestBodyState();
  29 +}
  30 +
  31 +class HomeTestBodyState extends State<HomeTestBody> {
  32 + final XgFlutterPlugin tpush = new XgFlutterPlugin();
  33 + String inputStr = "flutter";
  34 +
  35 + // Get row count.
  36 + int _rowCountAtSection(int section) {
  37 + if (section < sectionList.length) {
  38 + return sectionList[section].length;
  39 + } else {
  40 + return 0;
  41 + }
  42 + }
  43 +
  44 + String _titleOfSection(int section) {
  45 + if (section < sectionTitleList.length) {
  46 + return sectionTitleList[section];
  47 + } else {
  48 + return 'null';
  49 + }
  50 + }
  51 +
  52 + String _titleOfRow(int section, int row) {
  53 + if (section < sectionList.length) {
  54 + List<String> tmpList = sectionList[section];
  55 + if (row < tmpList.length) {
  56 + return tmpList[row];
  57 + } else {
  58 + return 'null';
  59 + }
  60 + } else {
  61 + return 'null';
  62 + }
  63 + }
  64 +
  65 + void _showAlert(int section, int row) {
  66 + String title = sectionList[section][row];
  67 + Alert(
  68 + context: context,
  69 + title: title,
  70 + content: Column(
  71 + children: <Widget>[
  72 + TextField(
  73 + decoration: InputDecoration(
  74 + labelText: '请输入',
  75 + ),
  76 + onChanged: (text) {
  77 + inputStr = text;
  78 + },
  79 + ),
  80 + ],
  81 + ),
  82 + buttons: [
  83 + DialogButton(
  84 + onPressed: () {
  85 + Navigator.pop(context);
  86 + _doAction(section, row);
  87 + },
  88 + child: Text(
  89 + "确认",
  90 + style: TextStyle(color: Colors.white, fontSize: 20),
  91 + ),
  92 + )
  93 + ]).show();
  94 + }
  95 +
  96 + //信鸽api接口调用函数
  97 + void _doAction(int section, int row) {
  98 + if (section == 0) {
  99 + if (row == 0) {
  100 + tpush.setAccount(inputStr, AccountType.UNKNOWN);
  101 + } else if (row == 1) {
  102 + tpush.deleteAccount(inputStr, AccountType.UNKNOWN);
  103 + } else if (row == 2) {
  104 + tpush.cleanAccounts();
  105 + }
  106 + } else if (section == 1) {
  107 + if (row == 0) {
  108 + tpush.addTags([inputStr]);
  109 + } else if (row == 1) {
  110 + tpush.deleteTags([inputStr]);
  111 + } else if (row == 2) {
  112 + tpush.setTags([inputStr]);
  113 + } else if (row == 3) {
  114 + tpush.cleanTags();
  115 + }
  116 + } else if (section == 2) {
  117 + if (row == 0) {
  118 + Map<String, String> attributes = {'nickname': "testAttribute"};
  119 + tpush.upsertAttributes(attributes);
  120 + } else if (row == 1) {
  121 + List<String> delAttr = ['nickname'];
  122 + tpush.delAttributes(delAttr);
  123 + } else if (row == 2) {
  124 + Map<String, String> attributes = {'nickname': "testAttribute2"};
  125 + tpush.clearAndAppendAttributes(attributes);
  126 + } else if (row == 3) {
  127 + tpush.clearAttributes();
  128 + }
  129 + } else if (section == 3) {
  130 + if (row == 0) {
  131 + tpush.startXg("1600007893", "IX4BGYYG8L4L");
  132 + } else if (row == 1) {
  133 + tpush.stopXg();
  134 + } else if (row == 2) {
  135 + getXgToken();
  136 + } else if (row == 3) {
  137 + tpush.setBadge(int.parse(inputStr));
  138 + } else if (row == 4) {
  139 + getXgSdkVersion();
  140 + }
  141 + }
  142 + }
  143 +
  144 + // Section header widget builder.
  145 + Widget _sectionHeaderBuilder(BuildContext context, int section) {
  146 + return InkWell(
  147 + onTap: () {},
  148 + child: Container(
  149 + alignment: Alignment.centerLeft,
  150 + padding: EdgeInsets.only(left: 16.0),
  151 + color: Color.fromRGBO(220, 220, 220, 1),
  152 + height: 100,
  153 + child: Text(_titleOfSection(section)),
  154 + ),
  155 + );
  156 + }
  157 +
  158 + // cell item widget builder.
  159 + Widget _cellBuilder(BuildContext context, int section, int row) {
  160 + return InkWell(
  161 + onTap: () {
  162 + if ((section == 0 && row == 2) ||
  163 + (section == 1 && row == 3) ||
  164 + (section == 2) ||
  165 + (section == 3 && row != 3)) {
  166 + _doAction(section, row);
  167 + } else {
  168 + _showAlert(section, row);
  169 + }
  170 + },
  171 + child: Container(
  172 + padding: EdgeInsets.only(left: 16.0),
  173 + alignment: Alignment.centerLeft,
  174 + decoration: BoxDecoration(
  175 + border: Border(
  176 + bottom: BorderSide(
  177 + color: Color.fromRGBO(240, 240, 240, 1),
  178 + ))),
  179 + height: 50.0,
  180 + child: Text(_titleOfRow(section, row)),
  181 + ),
  182 + );
  183 + }
  184 +
  185 + // Each section header height;
  186 + double _sectionHeaderHeight(BuildContext context, int section) {
  187 + return 50.0;
  188 + }
  189 +
  190 + // Each cell item widget height.
  191 + double _cellHeight(BuildContext context, int section, int row) {
  192 + return 50.0;
  193 + }
  194 +
  195 + Future<void> getXgSdkVersion() async {
  196 + try {
  197 + String? sdkVersion = await XgFlutterPlugin.xgSdkVersion;
  198 + print('xgSdkVersion: $sdkVersion');
  199 + Alert(context: context, title: sdkVersion, desc: "", buttons: [
  200 + DialogButton(
  201 + onPressed: () {
  202 + Navigator.pop(context);
  203 + },
  204 + child: Text(
  205 + "确认",
  206 + style: TextStyle(color: Colors.white, fontSize: 20),
  207 + ),
  208 + )
  209 + ]).show();
  210 + } catch (e) {
  211 + print(e.toString());
  212 + }
  213 + }
  214 +
  215 + Future<void> getXgToken() async {
  216 + try {
  217 + String? xgToken = await XgFlutterPlugin.xgToken;
  218 + print('xgtoken: $xgToken');
  219 + Alert(context: context, title: xgToken, desc: "", buttons: [
  220 + DialogButton(
  221 + onPressed: () {
  222 + Navigator.pop(context);
  223 + },
  224 + child: Text(
  225 + "确认",
  226 + style: TextStyle(color: Colors.white, fontSize: 20),
  227 + ),
  228 + )
  229 + ]).show();
  230 + } catch (e) {
  231 + print(e.toString());
  232 + }
  233 + }
  234 +
  235 + @override
  236 + Widget build(BuildContext context) {
  237 + return Container(
  238 + //FlutterTableView
  239 + child: FlutterTableView(
  240 + sectionCount: sectionList.length,
  241 + rowCountAtSection: _rowCountAtSection,
  242 + sectionHeaderBuilder: _sectionHeaderBuilder,
  243 + cellBuilder: _cellBuilder,
  244 + sectionHeaderHeight: _sectionHeaderHeight,
  245 + cellHeight: _cellHeight,
  246 + ),
  247 + );
  248 + }
  249 +}
  1 +import 'package:flutter/material.dart';
  2 +import 'dart:async';
  3 +import 'package:rflutter_alert/rflutter_alert.dart';
  4 +import 'ios/homeTest.dart';
  5 +import 'package:tpns_flutter_plugin/tpns_flutter_plugin.dart';
  6 +import 'dart:io';
  7 +
  8 +void main() => runApp(new MaterialApp(
  9 + home: new MyApp(),
  10 + debugShowCheckedModeBanner: false,
  11 + ));
  12 +
  13 +class MyApp extends StatefulWidget {
  14 + @override
  15 + _MyAppState createState() => _MyAppState();
  16 +}
  17 +
  18 +class _MyAppState extends State<MyApp> {
  19 + final XgFlutterPlugin tpush = new XgFlutterPlugin();
  20 +
  21 + @override
  22 + void initState() {
  23 + super.initState();
  24 + initPlatformState();
  25 + }
  26 +
  27 + // Platform messages are asynchronous, so we initialize in an async method.
  28 + Future<void> initPlatformState() async {
  29 + // If the widget was removed from the tree while the asynchronous platform
  30 + // message was in flight, we want to discard the reply rather than calling
  31 + // setState to update our non-existent appearance.
  32 + if (!mounted) return;
  33 +
  34 + /// 开启DEBUG
  35 + tpush.setEnableDebug(true);
  36 +
  37 + /// 添加回调事件
  38 + tpush.addEventHandler(
  39 + /// TPNS注册失败会走此回调
  40 + onRegisteredDeviceToken: (String msg) async {
  41 + print("flutter onRegisteredDeviceToken: $msg");
  42 + },
  43 +
  44 + /// TPNS注册成功会走此回调
  45 + onRegisteredDone: (String msg) async {
  46 + print("flutter onRegisteredDone: $msg");
  47 + _showAlert("注册成功");
  48 + },
  49 + unRegistered: (String msg) async {
  50 + print("flutter unRegistered: $msg");
  51 + _showAlert(msg);
  52 + },
  53 + onReceiveNotificationResponse: (Map<String, dynamic> msg) async {
  54 + print("flutter onReceiveNotificationResponse $msg");
  55 + },
  56 + onReceiveMessage: (Map<String, dynamic> msg) async {
  57 + print("flutter onReceiveMessage $msg");
  58 + },
  59 + xgPushNetworkConnected: (String msg) async {
  60 + print("flutter xgPushNetworkConnected: $msg");
  61 +
  62 + /// 建议在此同步角标到TPNS后台
  63 + /// tpush.setBadge(0);
  64 + /// 同步到TPNS后台的同时,更新本地应用角标数
  65 + /// tpush.setAppBadge(0);
  66 + },
  67 + xgPushDidSetBadge: (String msg) async {
  68 + print("flutter xgPushDidSetBadge: $msg");
  69 + _showAlert(msg);
  70 + },
  71 +
  72 + /// V1.2.8开始返回类型由String->Map,新增code及type标识!
  73 + xgPushDidBindWithIdentifier: (Map<String, dynamic> result) async {
  74 + print("flutter xgPushDidBindWithIdentifier: $result");
  75 + _showAlert(result["msg"]);
  76 + },
  77 +
  78 + /// V1.2.8开始返回类型由String->Map,新增code及type标识!
  79 + xgPushDidUnbindWithIdentifier: (Map<String, dynamic> result) async {
  80 + print("flutter xgPushDidUnbindWithIdentifier: $result");
  81 + _showAlert(result["msg"]);
  82 + },
  83 +
  84 + /// V1.2.8开始返回类型由String->Map,新增code及type标识!
  85 + xgPushDidUpdatedBindedIdentifier: (Map<String, dynamic> result) async {
  86 + print("flutter xgPushDidUpdatedBindedIdentifier: $result");
  87 + _showAlert(result["msg"]);
  88 + },
  89 +
  90 + /// V1.2.8开始返回类型由String->Map,新增code及type标识!
  91 + xgPushDidClearAllIdentifiers: (Map<String, dynamic> result) async {
  92 + print("flutter xgPushDidClearAllIdentifiers: $result");
  93 + _showAlert(result["msg"]);
  94 + },
  95 + xgPushClickAction: (Map<String, dynamic> msg) async {
  96 + print("flutter xgPushClickAction $msg");
  97 + _showAlert("clickResponse");
  98 + },
  99 + );
  100 +
  101 + /// 如果您的应用非广州集群则需要在startXG之前调用此函数
  102 + /// 香港:tpns.hk.tencent.com
  103 + /// 新加坡:tpns.sgp.tencent.com
  104 + /// 上海:tpns.sh.tencent.com
  105 + // tpush.configureClusterDomainName("tpns.hk.tencent.com");
  106 +
  107 + /// 启动TPNS服务
  108 + /// 注意:为了不影响回调效果,建议在应用启动方法优先添加回调以及调用TPNS注册方法
  109 + if (Platform.isIOS) {
  110 + tpush.startXg("1600007893", "IX4BGYYG8L4L");
  111 + } else {
  112 + tpush.startXg("1500004343", "ANCVHDQ0DO3E");
  113 + }
  114 + }
  115 +
  116 + void _showAlert(String title) {
  117 + Alert(context: context, title: title, buttons: [
  118 + DialogButton(
  119 + onPressed: () {
  120 + Navigator.pop(context);
  121 + },
  122 + child: Text(
  123 + "确认",
  124 + style: TextStyle(color: Colors.white, fontSize: 20),
  125 + ),
  126 + )
  127 + ]).show();
  128 + }
  129 +
  130 + @override
  131 + Widget build(BuildContext context) {
  132 + return HomeTest();
  133 + }
  134 +}