├── .gitignore ├── .metadata ├── CHANGELOG.md ├── LICENSE ├── README-CN.md ├── README.md ├── android ├── .gitignore ├── build.gradle ├── settings.gradle └── src │ └── main │ ├── AndroidManifest.xml │ └── kotlin │ └── com │ └── azhon │ └── flutter_app_update │ └── FlutterAppUpdatePlugin.kt ├── example ├── .gitignore ├── README.md ├── android │ ├── .gitignore │ ├── app │ │ ├── build.gradle │ │ └── src │ │ │ ├── debug │ │ │ └── AndroidManifest.xml │ │ │ ├── main │ │ │ ├── AndroidManifest.xml │ │ │ ├── kotlin │ │ │ │ └── com │ │ │ │ │ └── azhon │ │ │ │ │ └── flutter_app_update_example │ │ │ │ │ └── MainActivity.kt │ │ │ └── res │ │ │ │ ├── drawable-v21 │ │ │ │ └── launch_background.xml │ │ │ │ ├── drawable │ │ │ │ └── launch_background.xml │ │ │ │ ├── mipmap-hdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-mdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ └── ic_launcher.png │ │ │ │ ├── values-night │ │ │ │ └── styles.xml │ │ │ │ └── values │ │ │ │ └── styles.xml │ │ │ └── profile │ │ │ └── AndroidManifest.xml │ ├── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ └── settings.gradle ├── img │ ├── en │ │ ├── img1.jpg │ │ ├── img2.jpg │ │ ├── img3.jpg │ │ └── img4.jpg │ ├── img1.png │ ├── img2.png │ ├── img3.png │ └── img4.png ├── ios │ ├── .gitignore │ ├── Flutter │ │ ├── AppFrameworkInfo.plist │ │ ├── Debug.xcconfig │ │ └── Release.xcconfig │ ├── Podfile │ ├── Podfile.lock │ ├── Runner.xcodeproj │ │ ├── project.pbxproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ │ └── WorkspaceSettings.xcsettings │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── IDEWorkspaceChecks.plist │ │ │ └── WorkspaceSettings.xcsettings │ └── Runner │ │ ├── AppDelegate.h │ │ ├── AppDelegate.m │ │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ ├── Contents.json │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ ├── Icon-App-20x20@1x.png │ │ │ ├── Icon-App-20x20@2x.png │ │ │ ├── Icon-App-20x20@3x.png │ │ │ ├── Icon-App-29x29@1x.png │ │ │ ├── Icon-App-29x29@2x.png │ │ │ ├── Icon-App-29x29@3x.png │ │ │ ├── Icon-App-40x40@1x.png │ │ │ ├── Icon-App-40x40@2x.png │ │ │ ├── Icon-App-40x40@3x.png │ │ │ ├── Icon-App-60x60@2x.png │ │ │ ├── Icon-App-60x60@3x.png │ │ │ ├── Icon-App-76x76@1x.png │ │ │ ├── Icon-App-76x76@2x.png │ │ │ └── Icon-App-83.5x83.5@2x.png │ │ └── LaunchImage.imageset │ │ │ ├── Contents.json │ │ │ ├── LaunchImage.png │ │ │ ├── LaunchImage@2x.png │ │ │ ├── LaunchImage@3x.png │ │ │ └── README.md │ │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ │ ├── Info.plist │ │ └── main.m ├── lib │ ├── generated │ │ ├── intl │ │ │ ├── messages_all.dart │ │ │ ├── messages_en.dart │ │ │ └── messages_zh.dart │ │ └── l10n.dart │ ├── l10n │ │ ├── intl_en.arb │ │ └── intl_zh.arb │ └── main.dart ├── pubspec.lock ├── pubspec.yaml └── test │ └── widget_test.dart ├── flutter_app_update.iml ├── ios ├── .gitignore ├── Assets │ └── .gitkeep ├── Classes │ ├── FlutterAppUpdatePlugin.h │ └── FlutterAppUpdatePlugin.m └── flutter_app_update.podspec ├── lib ├── azhon_app_update.dart ├── flutter_app_update.dart ├── result_model.dart └── update_model.dart ├── pubspec.lock ├── pubspec.yaml └── test └── flutter_app_update_test.dart /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | # Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock. 26 | /pubspec.lock 27 | **/doc/api/ 28 | .dart_tool/ 29 | .packages 30 | build/ 31 | analysis_options.yaml -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 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: ee4e09cce01d6f2d7f4baebd247fde02e5008851 8 | channel: stable 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 17 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 18 | - platform: android 19 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 20 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 21 | - platform: ios 22 | create_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 23 | base_revision: ee4e09cce01d6f2d7f4baebd247fde02e5008851 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 3.2.2 2 | add install apk method 3 | 4 | ## 3.2.1 5 | adapter iOS 18 openURL 6 | 7 | ## 3.2.0 8 | opt download listener 9 | 10 | ## 3.1.2 11 | update AppUpdate library to 4.3.6 12 | 13 | ## 3.1.1 14 | update AppUpdate library to 4.3.4 15 | upgrade AGP to 8.7 16 | 17 | ## 3.1.0 18 | support intl 19 | change default readme to english 20 | 21 | ## 3.0.4 22 | update AppUpdate library to 4.3.2 23 | 24 | ## 3.0.3 25 | update AppUpdate library to 4.3.1 26 | 27 | ## 3.0.2 28 | add export library file 29 | 30 | ## 3.0.0 31 | update AppUpdate library to 4.2.8 32 | opt the upgrade logic to ensure the consistency of android and ios 33 | 34 | ## 2.1.0 35 | update AppUpdate library to 4.2.7 36 | opt flutter mini sdk version 37 | 38 | ## 2.0.2 39 | update AppUpdate library to 4.2.5 40 | 41 | ## 2.0.1 42 | [Fix issues 5](https://github.com/azhon/flutter_app_update/issues/5) 43 | 44 | ## 2.0.0 45 | update AppUpdate library to 4.2.2 46 | 47 | ## 1.0.5 48 | update AppUpdate library to 4.0.0 49 | 50 | ## 1.0.2 51 | opt iOS upgrade dialog 52 | opt iOS download url 53 | 54 | ## 1.0.1 55 | update Flutter to Null-Safety 56 | 57 | ## 1.0.0 58 | update Flutter to Null-Safety 59 | 60 | ## 0.0.2 61 | update renderings 62 | 63 | ## 0.0.1 64 | publish package -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [yyyy] [name of copyright owner] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /README-CN.md: -------------------------------------------------------------------------------- 1 | ### 一、使用说明 2 | - Android这一侧的下载依赖[AppUpdate库](https://github.com/azhon/AppUpdate) 3 | - 添加依赖 [pub versions](https://pub.dev/packages/flutter_app_update) 4 | ```yaml 5 | dependencies: 6 | flutter_app_update: ^latest_version 7 | ``` 8 | 9 | - 创建`UpdateModel`设置下载地址 10 | 11 | ```dart 12 | UpdateModel model = UpdateModel( 13 | url, 14 | "flutterUpdate.apk", 15 | /// android res/mipmap 目录下的图片名称 16 | "ic_launcher", 17 | 'https://itunes.apple.com/cn/app/抖音/id1142110895', 18 | ); 19 | AzhonAppUpdate.update(model).then((value) => debugPrint('$value')); 20 | ``` 21 | 22 | - 监听下载过程 23 | 24 | ```dart 25 | @override 26 | void initState() { 27 | super.initState(); 28 | AzhonAppUpdate.listener((ResultModel model) { 29 | debugPrint('$model'); 30 | }); 31 | } 32 | ``` 33 | 34 | ### 三、效果图 35 | 36 |   37 |   38 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ### [Chinese Doc](https://github.com/azhon/flutter_app_update/blob/main/README-CN.md) 2 | 3 | ### 一、Introduce 4 | - Android update use [AppUpdate](https://github.com/azhon/AppUpdate) library 5 | - Add to pubspec.yaml [pub versions](https://pub.dev/packages/flutter_app_update) 6 | ```yaml 7 | dependencies: 8 | flutter_app_update: ^latest_version 9 | ``` 10 | 11 | - Create `UpdateModel` and set apk url 12 | 13 | ```dart 14 | UpdateModel model = UpdateModel( 15 | url, 16 | "flutterUpdate.apk", 17 | /// android res/mipmap icon name 18 | "ic_launcher", 19 | 'https://itunes.apple.com/cn/app/xxxx', 20 | ); 21 | AzhonAppUpdate.update(model).then((value) => debugPrint('$value')); 22 | ``` 23 | - Add listener 24 | 25 | ```dart 26 | @override 27 | void initState() { 28 | super.initState(); 29 | AzhonAppUpdate.listener((ResultModel model) { 30 | debugPrint('$model'); 31 | }); 32 | } 33 | ``` 34 | 35 | ### 三、Screenshot 36 | 37 |   38 |   39 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .gradle 3 | /local.properties 4 | /.idea/workspace.xml 5 | /.idea/libraries 6 | .DS_Store 7 | /build 8 | /captures 9 | .cxx 10 | -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.azhon.flutter_app_update' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = '1.8.22' 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath 'com.android.tools.build:gradle:8.1.0' 13 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 14 | } 15 | } 16 | 17 | rootProject.allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | compileSdk 34 29 | namespace 'com.azhon.flutter_app_update' 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = JavaVersion.VERSION_1_8 38 | } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | test.java.srcDirs += "src/test/kotlin" 43 | } 44 | 45 | defaultConfig { 46 | minSdkVersion 16 47 | } 48 | } 49 | 50 | dependencies { 51 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 52 | implementation 'io.github.azhon:appupdate:4.3.6' 53 | 54 | } 55 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'flutter_app_update' 2 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | -------------------------------------------------------------------------------- /android/src/main/kotlin/com/azhon/flutter_app_update/FlutterAppUpdatePlugin.kt: -------------------------------------------------------------------------------- 1 | package com.azhon.flutter_app_update 2 | 3 | import android.app.Activity 4 | import android.content.Context 5 | import android.text.TextUtils 6 | import androidx.annotation.NonNull 7 | import com.azhon.appupdate.config.Constant 8 | import com.azhon.appupdate.listener.OnButtonClickListener 9 | import com.azhon.appupdate.listener.OnDownloadListener 10 | import com.azhon.appupdate.manager.DownloadManager 11 | import com.azhon.appupdate.util.ApkUtil 12 | import io.flutter.embedding.engine.plugins.FlutterPlugin 13 | import io.flutter.embedding.engine.plugins.activity.ActivityAware 14 | import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding 15 | import io.flutter.plugin.common.EventChannel 16 | import io.flutter.plugin.common.MethodCall 17 | import io.flutter.plugin.common.MethodChannel 18 | import io.flutter.plugin.common.MethodChannel.MethodCallHandler 19 | import io.flutter.plugin.common.MethodChannel.Result 20 | import org.json.JSONObject 21 | import java.io.File 22 | 23 | 24 | class FlutterAppUpdatePlugin : FlutterPlugin, MethodCallHandler, ActivityAware, 25 | EventChannel.StreamHandler { 26 | 27 | private lateinit var channel: MethodChannel 28 | private lateinit var applicationContext: Context 29 | private lateinit var activity: Activity 30 | private var events: EventChannel.EventSink? = null 31 | private var manager: DownloadManager? = null 32 | 33 | override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) { 34 | channel = MethodChannel(flutterPluginBinding.binaryMessenger, "azhon_app_update") 35 | channel.setMethodCallHandler(this) 36 | val eventChannel = 37 | EventChannel(flutterPluginBinding.binaryMessenger, "azhon_app_update_listener") 38 | eventChannel.setStreamHandler(this) 39 | applicationContext = flutterPluginBinding.applicationContext 40 | } 41 | 42 | override fun onAttachedToActivity(binding: ActivityPluginBinding) { 43 | this.activity = binding.activity 44 | } 45 | 46 | override fun onListen(arguments: Any?, events: EventChannel.EventSink?) { 47 | if (events != null) { 48 | this.events = events 49 | } 50 | } 51 | 52 | override fun onCancel(arguments: Any?) { 53 | 54 | } 55 | 56 | override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) { 57 | when (call.method) { 58 | "getVersionCode" -> { 59 | getVersionCode(result) 60 | } 61 | 62 | "getVersionName" -> { 63 | getVersionName(result) 64 | } 65 | 66 | "update" -> { 67 | update(call, result) 68 | } 69 | 70 | "cancel" -> { 71 | cancel(result) 72 | } 73 | 74 | "install" -> { 75 | install(call, result) 76 | } 77 | 78 | else -> { 79 | result.notImplemented() 80 | } 81 | } 82 | } 83 | 84 | private fun getVersionCode(result: Result) { 85 | val versionCode = ApkUtil.getVersionCode(applicationContext) 86 | result.success(versionCode) 87 | } 88 | 89 | private fun getVersionName(result: Result) { 90 | val packageInfo = 91 | applicationContext.packageManager.getPackageInfo(applicationContext.packageName, 0) 92 | result.success(packageInfo.versionName) 93 | } 94 | 95 | private fun install(call: MethodCall, result: Result) { 96 | var authorities = call.argument("authorities") 97 | val path = call.argument("path") 98 | if (TextUtils.isEmpty(authorities)) { 99 | authorities = 100 | Constant.AUTHORITIES ?: "${applicationContext.packageName}.fileProvider" 101 | } 102 | ApkUtil.installApk(applicationContext, authorities!!, File(path!!)) 103 | result.success(true) 104 | } 105 | 106 | /** 107 | * 判断参数是否为空来设置 108 | */ 109 | private fun update(call: MethodCall, result: Result) { 110 | val model = call.argument>("model") 111 | //获取图标 112 | val smallIcon = applicationContext.resources.getIdentifier( 113 | model!!["smallIcon"] as String, "mipmap", applicationContext.packageName 114 | ) 115 | manager = DownloadManager.Builder(activity).run { 116 | apkName(model["apkName"] as String) 117 | apkUrl(model["apkUrl"] as String) 118 | smallIcon(smallIcon) 119 | showNotification(model["showNotification"] as Boolean) 120 | jumpInstallPage(model["jumpInstallPage"] as Boolean) 121 | showBgdToast(model["showBgdToast"] as Boolean) 122 | onDownloadListener(downloadListener) 123 | onButtonClickListener(buttonListener) 124 | if (notNull(model, "apkMD5")) { 125 | apkMD5(model["apkMD5"] as String) 126 | } 127 | build() 128 | } 129 | manager?.download() 130 | result.success(true) 131 | } 132 | 133 | private fun cancel(result: Result) { 134 | manager?.cancel() 135 | result.success(true) 136 | } 137 | 138 | //判断是否为空 139 | private fun notNull(model: HashMap, key: String): Boolean { 140 | if (model[key] is String) { 141 | return !TextUtils.isEmpty(model[key].toString()) 142 | } 143 | return model[key] != null 144 | } 145 | 146 | override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) { 147 | channel.setMethodCallHandler(null) 148 | } 149 | 150 | override fun onDetachedFromActivity() { 151 | 152 | } 153 | 154 | override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) { 155 | } 156 | 157 | override fun onDetachedFromActivityForConfigChanges() { 158 | } 159 | 160 | private val downloadListener: OnDownloadListener = object : OnDownloadListener { 161 | override fun start() { 162 | events?.success(json("start").toString()) 163 | } 164 | 165 | override fun downloading(max: Int, progress: Int) { 166 | val json = json("downloading") 167 | json.put("max", max) 168 | json.put("progress", progress) 169 | events?.success(json.toString()) 170 | } 171 | 172 | override fun done(apk: File) { 173 | manager = null 174 | val json = json("done") 175 | json.put("apk", apk.path) 176 | events?.success(json.toString()) 177 | } 178 | 179 | override fun cancel() { 180 | events?.success(json("cancel").toString()) 181 | } 182 | 183 | override fun error(e: Throwable) { 184 | val json = json("error") 185 | json.put("exception", e.message) 186 | events?.success(json.toString()) 187 | } 188 | } 189 | private val buttonListener: OnButtonClickListener = object : OnButtonClickListener { 190 | 191 | override fun onButtonClick(id: Int) { 192 | val json = json("onButtonClick") 193 | json.put("id", id) 194 | events?.success(json.toString()) 195 | } 196 | } 197 | 198 | private fun json(type: String): JSONObject { 199 | val json = JSONObject() 200 | json.put("type", type) 201 | return json 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | migrate_working_dir/ 12 | 13 | # IntelliJ related 14 | *.iml 15 | *.ipr 16 | *.iws 17 | .idea/ 18 | 19 | # The .vscode folder contains launch configuration and tasks you configure in 20 | # VS Code which you may wish to be included in version control, so this line 21 | # is commented out by default. 22 | #.vscode/ 23 | 24 | # Flutter/Dart/Pub related 25 | **/doc/api/ 26 | **/ios/Flutter/.last_build_id 27 | .dart_tool/ 28 | .flutter-plugins 29 | .flutter-plugins-dependencies 30 | .packages 31 | .pub-cache/ 32 | .pub/ 33 | /build/ 34 | 35 | # Web related 36 | lib/generated_plugin_registrant.dart 37 | 38 | # Symbolication related 39 | app.*.symbols 40 | 41 | # Obfuscation related 42 | app.*.map.json 43 | 44 | # Android Studio will place build artifacts here 45 | /android/app/debug 46 | /android/app/profile 47 | /android/app/release 48 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # flutter_app_update_example 2 | 3 | Demonstrates how to use the flutter_app_update plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) 13 | 14 | For help getting started with Flutter development, view the 15 | [online documentation](https://docs.flutter.dev/), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 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 14 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | id "dev.flutter.flutter-gradle-plugin" 5 | } 6 | def localProperties = new Properties() 7 | def localPropertiesFile = rootProject.file('local.properties') 8 | if (localPropertiesFile.exists()) { 9 | localPropertiesFile.withReader('UTF-8') { reader -> 10 | localProperties.load(reader) 11 | } 12 | } 13 | 14 | def flutterRoot = localProperties.getProperty('flutter.sdk') 15 | if (flutterRoot == null) { 16 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 17 | } 18 | 19 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 20 | if (flutterVersionCode == null) { 21 | flutterVersionCode = '1' 22 | } 23 | 24 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 25 | if (flutterVersionName == null) { 26 | flutterVersionName = '1.0' 27 | } 28 | 29 | android { 30 | compileSdk 34 31 | 32 | namespace 'com.azhon.flutter_app_update_example' 33 | 34 | compileOptions { 35 | sourceCompatibility JavaVersion.VERSION_1_8 36 | targetCompatibility JavaVersion.VERSION_1_8 37 | } 38 | 39 | kotlinOptions { 40 | jvmTarget = '1.8' 41 | } 42 | 43 | sourceSets { 44 | main.java.srcDirs += 'src/main/kotlin' 45 | } 46 | 47 | defaultConfig { 48 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 49 | applicationId "com.azhon.flutter_app_update_example" 50 | // You can update the following values to match your application needs. 51 | // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration. 52 | minSdk flutter.minSdkVersion 53 | targetSdk flutter.targetSdkVersion 54 | versionCode flutterVersionCode.toInteger() 55 | versionName flutterVersionName 56 | } 57 | 58 | buildTypes { 59 | release { 60 | // TODO: Add your own signing config for the release build. 61 | // Signing with the debug keys for now, so `flutter run --release` works. 62 | signingConfig signingConfigs.debug 63 | } 64 | } 65 | } 66 | 67 | flutter { 68 | source '../..' 69 | } 70 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 14 | 18 | 22 | 23 | 24 | 25 | 26 | 27 | 29 | 32 | 33 | 34 | -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/azhon/flutter_app_update_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.azhon.flutter_app_update_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = '../build' 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(':app') 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | zipStoreBase=GRADLE_USER_HOME 4 | zipStorePath=wrapper/dists 5 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-all.zip 6 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "8.1.0" apply false 22 | id "org.jetbrains.kotlin.android" version "1.8.22" apply false 23 | } 24 | 25 | include ":app" -------------------------------------------------------------------------------- /example/img/en/img1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/en/img1.jpg -------------------------------------------------------------------------------- /example/img/en/img2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/en/img2.jpg -------------------------------------------------------------------------------- /example/img/en/img3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/en/img3.jpg -------------------------------------------------------------------------------- /example/img/en/img4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/en/img4.jpg -------------------------------------------------------------------------------- /example/img/img1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/img1.png -------------------------------------------------------------------------------- /example/img/img2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/img2.png -------------------------------------------------------------------------------- /example/img/img3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/img3.png -------------------------------------------------------------------------------- /example/img/img4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/img/img4.png -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 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 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 32 | end 33 | 34 | post_install do |installer| 35 | installer.pods_project.targets.each do |target| 36 | flutter_additional_ios_build_settings(target) 37 | end 38 | end 39 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - flutter_app_update (0.0.1): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - flutter_app_update (from `.symlinks/plugins/flutter_app_update/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | flutter_app_update: 14 | :path: ".symlinks/plugins/flutter_app_update/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 18 | flutter_app_update: 65f61da626cb111d1b24674abc4b01728d7723bc 19 | 20 | PODFILE CHECKSUM: 1a782344d33c12ced0182eeab11e8668d253eb48 21 | 22 | COCOAPODS: 1.16.2 23 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 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 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */; }; 13 | 97C146F31CF9000F007C117D /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 97C146F21CF9000F007C117D /* main.m */; }; 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 | FAD957CC596A888838579A33 /* libPods-Runner.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 83A9F18151EF1271437E1C4B /* libPods-Runner.a */; }; 18 | /* End PBXBuildFile section */ 19 | 20 | /* Begin PBXCopyFilesBuildPhase section */ 21 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 22 | isa = PBXCopyFilesBuildPhase; 23 | buildActionMask = 2147483647; 24 | dstPath = ""; 25 | dstSubfolderSpec = 10; 26 | files = ( 27 | ); 28 | name = "Embed Frameworks"; 29 | runOnlyForDeploymentPostprocessing = 0; 30 | }; 31 | /* End PBXCopyFilesBuildPhase section */ 32 | 33 | /* Begin PBXFileReference section */ 34 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 35 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 36 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 37 | 41746ED35CDB6732FD1F1879 /* 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 = ""; }; 38 | 774FC60A385D8A8057B74195 /* 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 = ""; }; 39 | 781C00A8E92CAF7EDC184DBC /* 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 = ""; }; 40 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 41 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; 42 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; 43 | 83A9F18151EF1271437E1C4B /* libPods-Runner.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libPods-Runner.a"; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 45 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 46 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 47 | 97C146F21CF9000F007C117D /* main.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = ""; }; 48 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 49 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 50 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 51 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 52 | /* End PBXFileReference section */ 53 | 54 | /* Begin PBXFrameworksBuildPhase section */ 55 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 56 | isa = PBXFrameworksBuildPhase; 57 | buildActionMask = 2147483647; 58 | files = ( 59 | FAD957CC596A888838579A33 /* libPods-Runner.a in Frameworks */, 60 | ); 61 | runOnlyForDeploymentPostprocessing = 0; 62 | }; 63 | /* End PBXFrameworksBuildPhase section */ 64 | 65 | /* Begin PBXGroup section */ 66 | 57375FC3415ABEC2F8B03EC5 /* Pods */ = { 67 | isa = PBXGroup; 68 | children = ( 69 | 41746ED35CDB6732FD1F1879 /* Pods-Runner.debug.xcconfig */, 70 | 774FC60A385D8A8057B74195 /* Pods-Runner.release.xcconfig */, 71 | 781C00A8E92CAF7EDC184DBC /* Pods-Runner.profile.xcconfig */, 72 | ); 73 | path = Pods; 74 | sourceTree = ""; 75 | }; 76 | 9740EEB11CF90186004384FC /* Flutter */ = { 77 | isa = PBXGroup; 78 | children = ( 79 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 80 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 81 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 82 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 83 | ); 84 | name = Flutter; 85 | sourceTree = ""; 86 | }; 87 | 97C146E51CF9000F007C117D = { 88 | isa = PBXGroup; 89 | children = ( 90 | 9740EEB11CF90186004384FC /* Flutter */, 91 | 97C146F01CF9000F007C117D /* Runner */, 92 | 97C146EF1CF9000F007C117D /* Products */, 93 | 57375FC3415ABEC2F8B03EC5 /* Pods */, 94 | F91250E4C49863C1C48D2891 /* Frameworks */, 95 | ); 96 | sourceTree = ""; 97 | }; 98 | 97C146EF1CF9000F007C117D /* Products */ = { 99 | isa = PBXGroup; 100 | children = ( 101 | 97C146EE1CF9000F007C117D /* Runner.app */, 102 | ); 103 | name = Products; 104 | sourceTree = ""; 105 | }; 106 | 97C146F01CF9000F007C117D /* Runner */ = { 107 | isa = PBXGroup; 108 | children = ( 109 | 7AFFD8ED1D35381100E5BB4D /* AppDelegate.h */, 110 | 7AFFD8EE1D35381100E5BB4D /* AppDelegate.m */, 111 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 112 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 113 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 114 | 97C147021CF9000F007C117D /* Info.plist */, 115 | 97C146F11CF9000F007C117D /* Supporting Files */, 116 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 117 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 118 | ); 119 | path = Runner; 120 | sourceTree = ""; 121 | }; 122 | 97C146F11CF9000F007C117D /* Supporting Files */ = { 123 | isa = PBXGroup; 124 | children = ( 125 | 97C146F21CF9000F007C117D /* main.m */, 126 | ); 127 | name = "Supporting Files"; 128 | sourceTree = ""; 129 | }; 130 | F91250E4C49863C1C48D2891 /* Frameworks */ = { 131 | isa = PBXGroup; 132 | children = ( 133 | 83A9F18151EF1271437E1C4B /* libPods-Runner.a */, 134 | ); 135 | name = Frameworks; 136 | sourceTree = ""; 137 | }; 138 | /* End PBXGroup section */ 139 | 140 | /* Begin PBXNativeTarget section */ 141 | 97C146ED1CF9000F007C117D /* Runner */ = { 142 | isa = PBXNativeTarget; 143 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 144 | buildPhases = ( 145 | 4FFC66E873B494B29E273186 /* [CP] Check Pods Manifest.lock */, 146 | 9740EEB61CF901F6004384FC /* Run Script */, 147 | 97C146EA1CF9000F007C117D /* Sources */, 148 | 97C146EB1CF9000F007C117D /* Frameworks */, 149 | 97C146EC1CF9000F007C117D /* Resources */, 150 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 151 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 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 = ""; 170 | TargetAttributes = { 171 | 97C146ED1CF9000F007C117D = { 172 | CreatedOnToolsVersion = 7.3.1; 173 | }; 174 | }; 175 | }; 176 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 177 | compatibilityVersion = "Xcode 9.3"; 178 | developmentRegion = en; 179 | hasScannedForEncodings = 0; 180 | knownRegions = ( 181 | en, 182 | Base, 183 | ); 184 | mainGroup = 97C146E51CF9000F007C117D; 185 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 186 | projectDirPath = ""; 187 | projectRoot = ""; 188 | targets = ( 189 | 97C146ED1CF9000F007C117D /* Runner */, 190 | ); 191 | }; 192 | /* End PBXProject section */ 193 | 194 | /* Begin PBXResourcesBuildPhase section */ 195 | 97C146EC1CF9000F007C117D /* Resources */ = { 196 | isa = PBXResourcesBuildPhase; 197 | buildActionMask = 2147483647; 198 | files = ( 199 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 200 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 201 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 202 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 203 | ); 204 | runOnlyForDeploymentPostprocessing = 0; 205 | }; 206 | /* End PBXResourcesBuildPhase section */ 207 | 208 | /* Begin PBXShellScriptBuildPhase section */ 209 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 210 | isa = PBXShellScriptBuildPhase; 211 | alwaysOutOfDate = 1; 212 | buildActionMask = 2147483647; 213 | files = ( 214 | ); 215 | inputPaths = ( 216 | "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}", 217 | ); 218 | name = "Thin Binary"; 219 | outputPaths = ( 220 | ); 221 | runOnlyForDeploymentPostprocessing = 0; 222 | shellPath = /bin/sh; 223 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 224 | }; 225 | 4FFC66E873B494B29E273186 /* [CP] Check Pods Manifest.lock */ = { 226 | isa = PBXShellScriptBuildPhase; 227 | buildActionMask = 2147483647; 228 | files = ( 229 | ); 230 | inputFileListPaths = ( 231 | ); 232 | inputPaths = ( 233 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 234 | "${PODS_ROOT}/Manifest.lock", 235 | ); 236 | name = "[CP] Check Pods Manifest.lock"; 237 | outputFileListPaths = ( 238 | ); 239 | outputPaths = ( 240 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | shellPath = /bin/sh; 244 | 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"; 245 | showEnvVarsInLog = 0; 246 | }; 247 | 9740EEB61CF901F6004384FC /* Run Script */ = { 248 | isa = PBXShellScriptBuildPhase; 249 | alwaysOutOfDate = 1; 250 | buildActionMask = 2147483647; 251 | files = ( 252 | ); 253 | inputPaths = ( 254 | ); 255 | name = "Run Script"; 256 | outputPaths = ( 257 | ); 258 | runOnlyForDeploymentPostprocessing = 0; 259 | shellPath = /bin/sh; 260 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 261 | }; 262 | /* End PBXShellScriptBuildPhase section */ 263 | 264 | /* Begin PBXSourcesBuildPhase section */ 265 | 97C146EA1CF9000F007C117D /* Sources */ = { 266 | isa = PBXSourcesBuildPhase; 267 | buildActionMask = 2147483647; 268 | files = ( 269 | 978B8F6F1D3862AE00F588F7 /* AppDelegate.m in Sources */, 270 | 97C146F31CF9000F007C117D /* main.m in Sources */, 271 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 272 | ); 273 | runOnlyForDeploymentPostprocessing = 0; 274 | }; 275 | /* End PBXSourcesBuildPhase section */ 276 | 277 | /* Begin PBXVariantGroup section */ 278 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 279 | isa = PBXVariantGroup; 280 | children = ( 281 | 97C146FB1CF9000F007C117D /* Base */, 282 | ); 283 | name = Main.storyboard; 284 | sourceTree = ""; 285 | }; 286 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 287 | isa = PBXVariantGroup; 288 | children = ( 289 | 97C147001CF9000F007C117D /* Base */, 290 | ); 291 | name = LaunchScreen.storyboard; 292 | sourceTree = ""; 293 | }; 294 | /* End PBXVariantGroup section */ 295 | 296 | /* Begin XCBuildConfiguration section */ 297 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | ALWAYS_SEARCH_USER_PATHS = NO; 301 | CLANG_ANALYZER_NONNULL = YES; 302 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 303 | CLANG_CXX_LIBRARY = "libc++"; 304 | CLANG_ENABLE_MODULES = YES; 305 | CLANG_ENABLE_OBJC_ARC = YES; 306 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 307 | CLANG_WARN_BOOL_CONVERSION = YES; 308 | CLANG_WARN_COMMA = YES; 309 | CLANG_WARN_CONSTANT_CONVERSION = YES; 310 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 311 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 312 | CLANG_WARN_EMPTY_BODY = YES; 313 | CLANG_WARN_ENUM_CONVERSION = YES; 314 | CLANG_WARN_INFINITE_RECURSION = YES; 315 | CLANG_WARN_INT_CONVERSION = YES; 316 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 317 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 318 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 319 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 320 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 321 | CLANG_WARN_STRICT_PROTOTYPES = YES; 322 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 323 | CLANG_WARN_UNREACHABLE_CODE = YES; 324 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 325 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 326 | COPY_PHASE_STRIP = NO; 327 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 328 | ENABLE_NS_ASSERTIONS = NO; 329 | ENABLE_STRICT_OBJC_MSGSEND = YES; 330 | GCC_C_LANGUAGE_STANDARD = gnu99; 331 | GCC_NO_COMMON_BLOCKS = YES; 332 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 333 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 334 | GCC_WARN_UNDECLARED_SELECTOR = YES; 335 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 336 | GCC_WARN_UNUSED_FUNCTION = YES; 337 | GCC_WARN_UNUSED_VARIABLE = YES; 338 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 339 | MTL_ENABLE_DEBUG_INFO = NO; 340 | SDKROOT = iphoneos; 341 | SUPPORTED_PLATFORMS = iphoneos; 342 | TARGETED_DEVICE_FAMILY = "1,2"; 343 | VALIDATE_PRODUCT = YES; 344 | }; 345 | name = Profile; 346 | }; 347 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 348 | isa = XCBuildConfiguration; 349 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 350 | buildSettings = { 351 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 352 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 353 | DEVELOPMENT_TEAM = F8NXTFZ97Q; 354 | ENABLE_BITCODE = NO; 355 | INFOPLIST_FILE = Runner/Info.plist; 356 | LD_RUNPATH_SEARCH_PATHS = ( 357 | "$(inherited)", 358 | "@executable_path/Frameworks", 359 | ); 360 | PRODUCT_BUNDLE_IDENTIFIER = com.azhon.flutterAppUpdateExample; 361 | PRODUCT_NAME = "$(TARGET_NAME)"; 362 | VERSIONING_SYSTEM = "apple-generic"; 363 | }; 364 | name = Profile; 365 | }; 366 | 97C147031CF9000F007C117D /* Debug */ = { 367 | isa = XCBuildConfiguration; 368 | buildSettings = { 369 | ALWAYS_SEARCH_USER_PATHS = NO; 370 | CLANG_ANALYZER_NONNULL = YES; 371 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 372 | CLANG_CXX_LIBRARY = "libc++"; 373 | CLANG_ENABLE_MODULES = YES; 374 | CLANG_ENABLE_OBJC_ARC = YES; 375 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 376 | CLANG_WARN_BOOL_CONVERSION = YES; 377 | CLANG_WARN_COMMA = YES; 378 | CLANG_WARN_CONSTANT_CONVERSION = YES; 379 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 380 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 381 | CLANG_WARN_EMPTY_BODY = YES; 382 | CLANG_WARN_ENUM_CONVERSION = YES; 383 | CLANG_WARN_INFINITE_RECURSION = YES; 384 | CLANG_WARN_INT_CONVERSION = YES; 385 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 386 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 387 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 388 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 389 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 390 | CLANG_WARN_STRICT_PROTOTYPES = YES; 391 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 392 | CLANG_WARN_UNREACHABLE_CODE = YES; 393 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 394 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 395 | COPY_PHASE_STRIP = NO; 396 | DEBUG_INFORMATION_FORMAT = dwarf; 397 | ENABLE_STRICT_OBJC_MSGSEND = YES; 398 | ENABLE_TESTABILITY = YES; 399 | GCC_C_LANGUAGE_STANDARD = gnu99; 400 | GCC_DYNAMIC_NO_PIC = NO; 401 | GCC_NO_COMMON_BLOCKS = YES; 402 | GCC_OPTIMIZATION_LEVEL = 0; 403 | GCC_PREPROCESSOR_DEFINITIONS = ( 404 | "DEBUG=1", 405 | "$(inherited)", 406 | ); 407 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 408 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 409 | GCC_WARN_UNDECLARED_SELECTOR = YES; 410 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 411 | GCC_WARN_UNUSED_FUNCTION = YES; 412 | GCC_WARN_UNUSED_VARIABLE = YES; 413 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 414 | MTL_ENABLE_DEBUG_INFO = YES; 415 | ONLY_ACTIVE_ARCH = YES; 416 | SDKROOT = iphoneos; 417 | TARGETED_DEVICE_FAMILY = "1,2"; 418 | }; 419 | name = Debug; 420 | }; 421 | 97C147041CF9000F007C117D /* Release */ = { 422 | isa = XCBuildConfiguration; 423 | buildSettings = { 424 | ALWAYS_SEARCH_USER_PATHS = NO; 425 | CLANG_ANALYZER_NONNULL = YES; 426 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 427 | CLANG_CXX_LIBRARY = "libc++"; 428 | CLANG_ENABLE_MODULES = YES; 429 | CLANG_ENABLE_OBJC_ARC = YES; 430 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 431 | CLANG_WARN_BOOL_CONVERSION = YES; 432 | CLANG_WARN_COMMA = YES; 433 | CLANG_WARN_CONSTANT_CONVERSION = YES; 434 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 435 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 436 | CLANG_WARN_EMPTY_BODY = YES; 437 | CLANG_WARN_ENUM_CONVERSION = YES; 438 | CLANG_WARN_INFINITE_RECURSION = YES; 439 | CLANG_WARN_INT_CONVERSION = YES; 440 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 441 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 442 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 443 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 444 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 445 | CLANG_WARN_STRICT_PROTOTYPES = YES; 446 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 447 | CLANG_WARN_UNREACHABLE_CODE = YES; 448 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 449 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 450 | COPY_PHASE_STRIP = NO; 451 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 452 | ENABLE_NS_ASSERTIONS = NO; 453 | ENABLE_STRICT_OBJC_MSGSEND = YES; 454 | GCC_C_LANGUAGE_STANDARD = gnu99; 455 | GCC_NO_COMMON_BLOCKS = YES; 456 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 457 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 458 | GCC_WARN_UNDECLARED_SELECTOR = YES; 459 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 460 | GCC_WARN_UNUSED_FUNCTION = YES; 461 | GCC_WARN_UNUSED_VARIABLE = YES; 462 | IPHONEOS_DEPLOYMENT_TARGET = 12.0; 463 | MTL_ENABLE_DEBUG_INFO = NO; 464 | SDKROOT = iphoneos; 465 | SUPPORTED_PLATFORMS = iphoneos; 466 | TARGETED_DEVICE_FAMILY = "1,2"; 467 | VALIDATE_PRODUCT = YES; 468 | }; 469 | name = Release; 470 | }; 471 | 97C147061CF9000F007C117D /* Debug */ = { 472 | isa = XCBuildConfiguration; 473 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 474 | buildSettings = { 475 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 476 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 477 | DEVELOPMENT_TEAM = F8NXTFZ97Q; 478 | ENABLE_BITCODE = NO; 479 | INFOPLIST_FILE = Runner/Info.plist; 480 | LD_RUNPATH_SEARCH_PATHS = ( 481 | "$(inherited)", 482 | "@executable_path/Frameworks", 483 | ); 484 | PRODUCT_BUNDLE_IDENTIFIER = com.azhon.flutterAppUpdateExample; 485 | PRODUCT_NAME = "$(TARGET_NAME)"; 486 | VERSIONING_SYSTEM = "apple-generic"; 487 | }; 488 | name = Debug; 489 | }; 490 | 97C147071CF9000F007C117D /* Release */ = { 491 | isa = XCBuildConfiguration; 492 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 493 | buildSettings = { 494 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 495 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 496 | DEVELOPMENT_TEAM = F8NXTFZ97Q; 497 | ENABLE_BITCODE = NO; 498 | INFOPLIST_FILE = Runner/Info.plist; 499 | LD_RUNPATH_SEARCH_PATHS = ( 500 | "$(inherited)", 501 | "@executable_path/Frameworks", 502 | ); 503 | PRODUCT_BUNDLE_IDENTIFIER = com.azhon.flutterAppUpdateExample; 504 | PRODUCT_NAME = "$(TARGET_NAME)"; 505 | VERSIONING_SYSTEM = "apple-generic"; 506 | }; 507 | name = Release; 508 | }; 509 | /* End XCBuildConfiguration section */ 510 | 511 | /* Begin XCConfigurationList section */ 512 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 513 | isa = XCConfigurationList; 514 | buildConfigurations = ( 515 | 97C147031CF9000F007C117D /* Debug */, 516 | 97C147041CF9000F007C117D /* Release */, 517 | 249021D3217E4FDB00AE95B9 /* Profile */, 518 | ); 519 | defaultConfigurationIsVisible = 0; 520 | defaultConfigurationName = Release; 521 | }; 522 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 523 | isa = XCConfigurationList; 524 | buildConfigurations = ( 525 | 97C147061CF9000F007C117D /* Debug */, 526 | 97C147071CF9000F007C117D /* Release */, 527 | 249021D4217E4FDB00AE95B9 /* Profile */, 528 | ); 529 | defaultConfigurationIsVisible = 0; 530 | defaultConfigurationName = Release; 531 | }; 532 | /* End XCConfigurationList section */ 533 | }; 534 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 535 | } 536 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 37 | 38 | 39 | 40 | 41 | 42 | 52 | 54 | 60 | 61 | 62 | 63 | 69 | 71 | 77 | 78 | 79 | 80 | 82 | 83 | 86 | 87 | 88 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.h: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | 4 | @interface AppDelegate : FlutterAppDelegate 5 | 6 | @end 7 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.m: -------------------------------------------------------------------------------- 1 | #import "AppDelegate.h" 2 | #import "GeneratedPluginRegistrant.h" 3 | 4 | @implementation AppDelegate 5 | 6 | - (BOOL)application:(UIApplication *)application 7 | didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 8 | [GeneratedPluginRegistrant registerWithRegistry:self]; 9 | // Override point for customization after application launch. 10 | return [super application:application didFinishLaunchingWithOptions:launchOptions]; 11 | } 12 | 13 | @end 14 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 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 | } 24 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 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. -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleDisplayName 8 | Flutter App Update 9 | CFBundleExecutable 10 | $(EXECUTABLE_NAME) 11 | CFBundleIdentifier 12 | $(PRODUCT_BUNDLE_IDENTIFIER) 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | flutter_app_update_example 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | $(FLUTTER_BUILD_NAME) 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | $(FLUTTER_BUILD_NUMBER) 25 | LSRequiresIPhoneOS 26 | 27 | UILaunchStoryboardName 28 | LaunchScreen 29 | UIMainStoryboardFile 30 | Main 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | UIViewControllerBasedStatusBarAppearance 45 | 46 | CADisableMinimumFrameDurationOnPhone 47 | 48 | UIApplicationSupportsIndirectInputEvents 49 | 50 | 51 | 52 | -------------------------------------------------------------------------------- /example/ios/Runner/main.m: -------------------------------------------------------------------------------- 1 | #import 2 | #import 3 | #import "AppDelegate.h" 4 | 5 | int main(int argc, char* argv[]) { 6 | @autoreleasepool { 7 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class])); 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_all.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that looks up messages for specific locales by 3 | // delegating to the appropriate library. 4 | 5 | // Ignore issues from commonly used lints in this file. 6 | // ignore_for_file:implementation_imports, file_names, unnecessary_new 7 | // ignore_for_file:unnecessary_brace_in_string_interps, directives_ordering 8 | // ignore_for_file:argument_type_not_assignable, invalid_assignment 9 | // ignore_for_file:prefer_single_quotes, prefer_generic_function_type_aliases 10 | // ignore_for_file:comment_references 11 | 12 | import 'dart:async'; 13 | 14 | import 'package:flutter/foundation.dart'; 15 | import 'package:intl/intl.dart'; 16 | import 'package:intl/message_lookup_by_library.dart'; 17 | import 'package:intl/src/intl_helpers.dart'; 18 | 19 | import 'messages_en.dart' as messages_en; 20 | import 'messages_zh.dart' as messages_zh; 21 | 22 | typedef Future LibraryLoader(); 23 | Map _deferredLibraries = { 24 | 'en': () => new SynchronousFuture(null), 25 | 'zh': () => new SynchronousFuture(null), 26 | }; 27 | 28 | MessageLookupByLibrary? _findExact(String localeName) { 29 | switch (localeName) { 30 | case 'en': 31 | return messages_en.messages; 32 | case 'zh': 33 | return messages_zh.messages; 34 | default: 35 | return null; 36 | } 37 | } 38 | 39 | /// User programs should call this before using [localeName] for messages. 40 | Future initializeMessages(String localeName) { 41 | var availableLocale = Intl.verifiedLocale( 42 | localeName, (locale) => _deferredLibraries[locale] != null, 43 | onFailure: (_) => null); 44 | if (availableLocale == null) { 45 | return new SynchronousFuture(false); 46 | } 47 | var lib = _deferredLibraries[availableLocale]; 48 | lib == null ? new SynchronousFuture(false) : lib(); 49 | initializeInternalMessageLookup(() => new CompositeMessageLookup()); 50 | messageLookup.addLocale(availableLocale, _findGeneratedMessagesFor); 51 | return new SynchronousFuture(true); 52 | } 53 | 54 | bool _messagesExistFor(String locale) { 55 | try { 56 | return _findExact(locale) != null; 57 | } catch (e) { 58 | return false; 59 | } 60 | } 61 | 62 | MessageLookupByLibrary? _findGeneratedMessagesFor(String locale) { 63 | var actualLocale = 64 | Intl.verifiedLocale(locale, _messagesExistFor, onFailure: (_) => null); 65 | if (actualLocale == null) return null; 66 | return _findExact(actualLocale); 67 | } 68 | -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_en.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a en locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | // Ignore issues from commonly used lints in this file. 7 | // ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new 8 | // ignore_for_file:prefer_single_quotes,comment_references, directives_ordering 9 | // ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases 10 | // ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes 11 | // ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes 12 | 13 | import 'package:intl/intl.dart'; 14 | import 'package:intl/message_lookup_by_library.dart'; 15 | 16 | final messages = new MessageLookup(); 17 | 18 | typedef String MessageIfAbsent(String messageStr, List args); 19 | 20 | class MessageLookup extends MessageLookupByLibrary { 21 | String get localeName => 'en'; 22 | 23 | final messages = _notInlinedMessages(_notInlinedMessages); 24 | static Map _notInlinedMessages(_) => { 25 | "appTitle": MessageLookupByLibrary.simpleMessage( 26 | "A simple app update flutter package"), 27 | "cancel": MessageLookupByLibrary.simpleMessage("Cancel download"), 28 | "dialogCancel": MessageLookupByLibrary.simpleMessage("Cancel"), 29 | "dialogConfirm": MessageLookupByLibrary.simpleMessage("Upgrade"), 30 | "dialogContent": MessageLookupByLibrary.simpleMessage( 31 | "1.Support Android 4.1 and above\n2.Support for custom download process\n3.Support notification bar progress\n4.Support internationalization\n5.Use Kotlin Coroutines"), 32 | "dialogTitle": MessageLookupByLibrary.simpleMessage("New version"), 33 | "end": MessageLookupByLibrary.simpleMessage("end"), 34 | "forceUpgrade": MessageLookupByLibrary.simpleMessage("Force Upgrade"), 35 | "getCode": MessageLookupByLibrary.simpleMessage("Get VersionCode"), 36 | "getName": MessageLookupByLibrary.simpleMessage("Get VersionName"), 37 | "upgrade": MessageLookupByLibrary.simpleMessage("Upgrade"), 38 | "install": MessageLookupByLibrary.simpleMessage("Install Apk") 39 | }; 40 | } 41 | -------------------------------------------------------------------------------- /example/lib/generated/intl/messages_zh.dart: -------------------------------------------------------------------------------- 1 | // DO NOT EDIT. This is code generated via package:intl/generate_localized.dart 2 | // This is a library that provides messages for a zh locale. All the 3 | // messages from the main program should be duplicated here with the same 4 | // function name. 5 | 6 | // Ignore issues from commonly used lints in this file. 7 | // ignore_for_file:unnecessary_brace_in_string_interps, unnecessary_new 8 | // ignore_for_file:prefer_single_quotes,comment_references, directives_ordering 9 | // ignore_for_file:annotate_overrides,prefer_generic_function_type_aliases 10 | // ignore_for_file:unused_import, file_names, avoid_escaping_inner_quotes 11 | // ignore_for_file:unnecessary_string_interpolations, unnecessary_string_escapes 12 | 13 | import 'package:intl/intl.dart'; 14 | import 'package:intl/message_lookup_by_library.dart'; 15 | 16 | final messages = new MessageLookup(); 17 | 18 | typedef String MessageIfAbsent(String messageStr, List args); 19 | 20 | class MessageLookup extends MessageLookupByLibrary { 21 | String get localeName => 'zh'; 22 | 23 | final messages = _notInlinedMessages(_notInlinedMessages); 24 | static Map _notInlinedMessages(_) => { 25 | "appTitle": MessageLookupByLibrary.simpleMessage("一个简单好用的版本更新库"), 26 | "cancel": MessageLookupByLibrary.simpleMessage("取消下载"), 27 | "dialogCancel": MessageLookupByLibrary.simpleMessage("取消"), 28 | "dialogConfirm": MessageLookupByLibrary.simpleMessage("升级"), 29 | "dialogContent": MessageLookupByLibrary.simpleMessage( 30 | "1.支持Android4.1及以上版本\n2.支持自定义下载过程\n3.支持通知栏进度条展示\n4.支持文字国际化\n5.使用Kotlin协程重构"), 31 | "dialogTitle": MessageLookupByLibrary.simpleMessage("发现新版本"), 32 | "end": MessageLookupByLibrary.simpleMessage("结束"), 33 | "forceUpgrade": MessageLookupByLibrary.simpleMessage("强制更新"), 34 | "getCode": MessageLookupByLibrary.simpleMessage("获取VersionCode"), 35 | "getName": MessageLookupByLibrary.simpleMessage("获取VersionName"), 36 | "upgrade": MessageLookupByLibrary.simpleMessage("更新"), 37 | "install": MessageLookupByLibrary.simpleMessage("安装 Apk") 38 | }; 39 | } 40 | -------------------------------------------------------------------------------- /example/lib/generated/l10n.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | import 'package:flutter/material.dart'; 3 | import 'package:intl/intl.dart'; 4 | import 'intl/messages_all.dart'; 5 | 6 | // ************************************************************************** 7 | // Generator: Flutter Intl IDE plugin 8 | // Made by Localizely 9 | // ************************************************************************** 10 | 11 | // ignore_for_file: non_constant_identifier_names, lines_longer_than_80_chars 12 | // ignore_for_file: join_return_with_assignment, prefer_final_in_for_each 13 | // ignore_for_file: avoid_redundant_argument_values, avoid_escaping_inner_quotes 14 | 15 | class S { 16 | S(); 17 | 18 | static S? _current; 19 | 20 | static S get current { 21 | assert(_current != null, 22 | 'No instance of S was loaded. Try to initialize the S delegate before accessing S.current.'); 23 | return _current!; 24 | } 25 | 26 | static const AppLocalizationDelegate delegate = AppLocalizationDelegate(); 27 | 28 | static Future load(Locale locale) { 29 | final name = (locale.countryCode?.isEmpty ?? false) 30 | ? locale.languageCode 31 | : locale.toString(); 32 | final localeName = Intl.canonicalizedLocale(name); 33 | return initializeMessages(localeName).then((_) { 34 | Intl.defaultLocale = localeName; 35 | final instance = S(); 36 | S._current = instance; 37 | 38 | return instance; 39 | }); 40 | } 41 | 42 | static S of(BuildContext context) { 43 | final instance = S.maybeOf(context); 44 | assert(instance != null, 45 | 'No instance of S present in the widget tree. Did you add S.delegate in localizationsDelegates?'); 46 | return instance!; 47 | } 48 | 49 | static S? maybeOf(BuildContext context) { 50 | return Localizations.of(context, S); 51 | } 52 | 53 | /// `A simple app update flutter package` 54 | String get appTitle { 55 | return Intl.message( 56 | 'A simple app update flutter package', 57 | name: 'appTitle', 58 | desc: '', 59 | args: [], 60 | ); 61 | } 62 | 63 | /// `Upgrade` 64 | String get upgrade { 65 | return Intl.message( 66 | 'Upgrade', 67 | name: 'upgrade', 68 | desc: '', 69 | args: [], 70 | ); 71 | } 72 | 73 | /// `Force Upgrade` 74 | String get forceUpgrade { 75 | return Intl.message( 76 | 'Force Upgrade', 77 | name: 'forceUpgrade', 78 | desc: '', 79 | args: [], 80 | ); 81 | } 82 | 83 | /// `Cancel download` 84 | String get cancel { 85 | return Intl.message( 86 | 'Cancel download', 87 | name: 'cancel', 88 | desc: '', 89 | args: [], 90 | ); 91 | } 92 | 93 | /// `Get VersionCode` 94 | String get getCode { 95 | return Intl.message( 96 | 'Get VersionCode', 97 | name: 'getCode', 98 | desc: '', 99 | args: [], 100 | ); 101 | } 102 | 103 | /// `Get VersionName` 104 | String get getName { 105 | return Intl.message( 106 | 'Get VersionName', 107 | name: 'getName', 108 | desc: '', 109 | args: [], 110 | ); 111 | } 112 | 113 | /// `New version` 114 | String get dialogTitle { 115 | return Intl.message( 116 | 'New version', 117 | name: 'dialogTitle', 118 | desc: '', 119 | args: [], 120 | ); 121 | } 122 | 123 | /// `1.Support Android 4.1 and above\n2.Support for custom download process\n3.Support notification bar progress\n4.Support internationalization\n5.Use Kotlin Coroutines` 124 | String get dialogContent { 125 | return Intl.message( 126 | '1.Support Android 4.1 and above\n2.Support for custom download process\n3.Support notification bar progress\n4.Support internationalization\n5.Use Kotlin Coroutines', 127 | name: 'dialogContent', 128 | desc: '', 129 | args: [], 130 | ); 131 | } 132 | 133 | /// `Upgrade` 134 | String get dialogConfirm { 135 | return Intl.message( 136 | 'Upgrade', 137 | name: 'dialogConfirm', 138 | desc: '', 139 | args: [], 140 | ); 141 | } 142 | 143 | /// `Cancel` 144 | String get dialogCancel { 145 | return Intl.message( 146 | 'Cancel', 147 | name: 'dialogCancel', 148 | desc: '', 149 | args: [], 150 | ); 151 | } 152 | 153 | /// `end` 154 | String get end { 155 | return Intl.message( 156 | 'end', 157 | name: 'end', 158 | desc: '', 159 | args: [], 160 | ); 161 | } 162 | 163 | /// `install` 164 | String get install { 165 | return Intl.message( 166 | 'install', 167 | name: 'install', 168 | desc: '', 169 | args: [], 170 | ); 171 | } 172 | } 173 | 174 | class AppLocalizationDelegate extends LocalizationsDelegate { 175 | const AppLocalizationDelegate(); 176 | 177 | List get supportedLocales { 178 | return const [ 179 | Locale.fromSubtags(languageCode: 'en'), 180 | Locale.fromSubtags(languageCode: 'zh'), 181 | ]; 182 | } 183 | 184 | @override 185 | bool isSupported(Locale locale) => _isSupported(locale); 186 | @override 187 | Future load(Locale locale) => S.load(locale); 188 | @override 189 | bool shouldReload(AppLocalizationDelegate old) => false; 190 | 191 | bool _isSupported(Locale locale) { 192 | for (var supportedLocale in supportedLocales) { 193 | if (supportedLocale.languageCode == locale.languageCode) { 194 | return true; 195 | } 196 | } 197 | return false; 198 | } 199 | } 200 | -------------------------------------------------------------------------------- /example/lib/l10n/intl_en.arb: -------------------------------------------------------------------------------- 1 | { 2 | "appTitle": "A simple app update flutter package", 3 | "upgrade": "Upgrade", 4 | "forceUpgrade": "Force Upgrade", 5 | "cancel": "Cancel download", 6 | "getCode": "Get VersionCode", 7 | "getName": "Get VersionName", 8 | "dialogTitle": "New version", 9 | "dialogContent": "1.Support Android 4.1 and above\n2.Support for custom download process\n3.Support notification bar progress\n4.Support internationalization\n5.Use Kotlin Coroutines", 10 | "dialogConfirm": "Upgrade", 11 | "dialogCancel": "Cancel", 12 | "install": "Install Apk", 13 | "end": "end" 14 | } -------------------------------------------------------------------------------- /example/lib/l10n/intl_zh.arb: -------------------------------------------------------------------------------- 1 | { 2 | "appTitle": "一个简单好用的版本更新库", 3 | "upgrade": "更新", 4 | "forceUpgrade": "强制更新", 5 | "cancel": "取消下载", 6 | "getCode": "获取VersionCode", 7 | "getName": "获取VersionName", 8 | "dialogTitle": "发现新版本", 9 | "dialogContent": "1.支持Android4.1及以上版本\n2.支持自定义下载过程\n3.支持通知栏进度条展示\n4.支持文字国际化\n5.使用Kotlin协程重构", 10 | "dialogConfirm": "升级", 11 | "dialogCancel": "取消", 12 | "install": "安装 Apk", 13 | "end": "结束" 14 | } -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_app_update/flutter_app_update.dart'; 3 | import 'package:flutter_app_update/result_model.dart'; 4 | import 'package:flutter_app_update_example/generated/l10n.dart'; 5 | import 'package:flutter_localizations/flutter_localizations.dart'; 6 | 7 | void main() { 8 | WidgetsFlutterBinding.ensureInitialized(); 9 | runApp(const App()); 10 | } 11 | 12 | class App extends StatelessWidget { 13 | const App({Key? key}) : super(key: key); 14 | 15 | @override 16 | Widget build(BuildContext context) { 17 | return MaterialApp( 18 | theme: ThemeData(useMaterial3: false), 19 | localizationsDelegates: const [ 20 | S.delegate, 21 | GlobalMaterialLocalizations.delegate, 22 | GlobalCupertinoLocalizations.delegate, 23 | GlobalWidgetsLocalizations.delegate, 24 | ], 25 | supportedLocales: S.delegate.supportedLocales, 26 | home: Scaffold( 27 | appBar: AppBar( 28 | title: Builder( 29 | builder: (context) { 30 | return Text( 31 | S.of(context).appTitle, 32 | style: const TextStyle(fontSize: 16), 33 | ); 34 | }, 35 | ), 36 | ), 37 | body: const HomePage(), 38 | ), 39 | ); 40 | } 41 | } 42 | 43 | class HomePage extends StatefulWidget { 44 | const HomePage({Key? key}) : super(key: key); 45 | 46 | @override 47 | State createState() => _HomePageState(); 48 | } 49 | 50 | class _HomePageState extends State { 51 | String url = 52 | "https://imtt.dd.qq.com/16891/apk/FA48766BA12A41A1D619CB4B152889C6.apk?fsname=com.estrongs.android.pop_4.2.3.3_10089.apk&csr=1bbd"; 53 | 54 | @override 55 | void initState() { 56 | super.initState(); 57 | AzhonAppUpdate.listener((ResultModel model) { 58 | debugPrint('$model'); 59 | }); 60 | } 61 | 62 | @override 63 | Widget build(BuildContext context) { 64 | return Container( 65 | margin: const EdgeInsets.all(16), 66 | child: Column( 67 | mainAxisAlignment: MainAxisAlignment.center, 68 | children: [ 69 | _item(S.of(context).upgrade, () { 70 | _showUpdateDialog(false); 71 | }), 72 | _item(S.of(context).forceUpgrade, () { 73 | _showUpdateDialog(true); 74 | }), 75 | _item(S.of(context).cancel, () { 76 | AzhonAppUpdate.cancel.then((value) { 77 | debugPrint('cancel download status = $value'); 78 | }); 79 | }), 80 | const Divider(height: 10), 81 | _item(S.of(context).install, () { 82 | AzhonAppUpdate.install('Your apk path').then((value) { 83 | debugPrint('install status = $value'); 84 | }); 85 | }), 86 | const Divider(height: 10), 87 | _item(S.of(context).getCode, () { 88 | AzhonAppUpdate.getVersionCode.then((value) { 89 | debugPrint('versionCode result = $value'); 90 | }); 91 | }), 92 | _item(S.of(context).getName, () { 93 | AzhonAppUpdate.getVersionName.then((value) { 94 | debugPrint('versionName result = $value'); 95 | }); 96 | }), 97 | ], 98 | ), 99 | ); 100 | } 101 | 102 | _showUpdateDialog(bool forcedUpgrade) { 103 | showDialog( 104 | context: context, 105 | barrierDismissible: !forcedUpgrade, 106 | builder: (BuildContext context) { 107 | return WillPopScope( 108 | onWillPop: () => Future.value(!forcedUpgrade), 109 | child: AlertDialog( 110 | title: Text(S.of(context).dialogTitle), 111 | content: Text(S.of(context).dialogContent), 112 | actions: [ 113 | if (!forcedUpgrade) 114 | TextButton( 115 | child: Text(S.of(context).dialogCancel), 116 | onPressed: () => Navigator.of(context).pop(), 117 | ), 118 | TextButton( 119 | child: Text(S.of(context).dialogConfirm), 120 | onPressed: () { 121 | _appUpdate(); 122 | if (!forcedUpgrade) { 123 | Navigator.of(context).pop(); 124 | } 125 | }, 126 | ), 127 | ], 128 | ), 129 | ); 130 | }, 131 | ); 132 | } 133 | 134 | _appUpdate() { 135 | UpdateModel model = UpdateModel( 136 | url, 137 | "flutterUpdate.apk", 138 | "ic_launcher", 139 | 'https://itunes.apple.com/cn/app/抖音/id1142110895', 140 | ); 141 | AzhonAppUpdate.update(model); 142 | } 143 | 144 | Widget _item(String text, VoidCallback onPressed) { 145 | return SizedBox( 146 | width: double.infinity, 147 | child: TextButton( 148 | style: TextButton.styleFrom(backgroundColor: Colors.blue), 149 | child: Text(text, style: const TextStyle(color: Colors.white)), 150 | onPressed: () => onPressed.call(), 151 | ), 152 | ); 153 | } 154 | 155 | @override 156 | void dispose() { 157 | super.dispose(); 158 | AzhonAppUpdate.dispose(); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.18.0" 44 | cupertino_icons: 45 | dependency: "direct main" 46 | description: 47 | name: cupertino_icons 48 | sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.0.8" 52 | fake_async: 53 | dependency: transitive 54 | description: 55 | name: fake_async 56 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 57 | url: "https://pub.flutter-io.cn" 58 | source: hosted 59 | version: "1.3.1" 60 | flutter: 61 | dependency: "direct main" 62 | description: flutter 63 | source: sdk 64 | version: "0.0.0" 65 | flutter_app_update: 66 | dependency: "direct main" 67 | description: 68 | path: ".." 69 | relative: true 70 | source: path 71 | version: "3.2.1" 72 | flutter_lints: 73 | dependency: "direct dev" 74 | description: 75 | name: flutter_lints 76 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 77 | url: "https://pub.flutter-io.cn" 78 | source: hosted 79 | version: "2.0.3" 80 | flutter_localizations: 81 | dependency: "direct main" 82 | description: flutter 83 | source: sdk 84 | version: "0.0.0" 85 | flutter_test: 86 | dependency: "direct dev" 87 | description: flutter 88 | source: sdk 89 | version: "0.0.0" 90 | intl: 91 | dependency: transitive 92 | description: 93 | name: intl 94 | sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d" 95 | url: "https://pub.flutter-io.cn" 96 | source: hosted 97 | version: "0.18.1" 98 | lints: 99 | dependency: transitive 100 | description: 101 | name: lints 102 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 103 | url: "https://pub.flutter-io.cn" 104 | source: hosted 105 | version: "2.1.1" 106 | matcher: 107 | dependency: transitive 108 | description: 109 | name: matcher 110 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" 111 | url: "https://pub.flutter-io.cn" 112 | source: hosted 113 | version: "0.12.16" 114 | material_color_utilities: 115 | dependency: transitive 116 | description: 117 | name: material_color_utilities 118 | sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" 119 | url: "https://pub.flutter-io.cn" 120 | source: hosted 121 | version: "0.5.0" 122 | meta: 123 | dependency: transitive 124 | description: 125 | name: meta 126 | sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e 127 | url: "https://pub.flutter-io.cn" 128 | source: hosted 129 | version: "1.10.0" 130 | path: 131 | dependency: transitive 132 | description: 133 | name: path 134 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 135 | url: "https://pub.flutter-io.cn" 136 | source: hosted 137 | version: "1.8.3" 138 | sky_engine: 139 | dependency: transitive 140 | description: flutter 141 | source: sdk 142 | version: "0.0.99" 143 | source_span: 144 | dependency: transitive 145 | description: 146 | name: source_span 147 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 148 | url: "https://pub.flutter-io.cn" 149 | source: hosted 150 | version: "1.10.0" 151 | stack_trace: 152 | dependency: transitive 153 | description: 154 | name: stack_trace 155 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 156 | url: "https://pub.flutter-io.cn" 157 | source: hosted 158 | version: "1.11.1" 159 | stream_channel: 160 | dependency: transitive 161 | description: 162 | name: stream_channel 163 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 164 | url: "https://pub.flutter-io.cn" 165 | source: hosted 166 | version: "2.1.2" 167 | string_scanner: 168 | dependency: transitive 169 | description: 170 | name: string_scanner 171 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 172 | url: "https://pub.flutter-io.cn" 173 | source: hosted 174 | version: "1.2.0" 175 | term_glyph: 176 | dependency: transitive 177 | description: 178 | name: term_glyph 179 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 180 | url: "https://pub.flutter-io.cn" 181 | source: hosted 182 | version: "1.2.1" 183 | test_api: 184 | dependency: transitive 185 | description: 186 | name: test_api 187 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" 188 | url: "https://pub.flutter-io.cn" 189 | source: hosted 190 | version: "0.6.1" 191 | vector_math: 192 | dependency: transitive 193 | description: 194 | name: vector_math 195 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 196 | url: "https://pub.flutter-io.cn" 197 | source: hosted 198 | version: "2.1.4" 199 | web: 200 | dependency: transitive 201 | description: 202 | name: web 203 | sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 204 | url: "https://pub.flutter-io.cn" 205 | source: hosted 206 | version: "0.3.0" 207 | sdks: 208 | dart: ">=3.2.0-194.0.dev <4.0.0" 209 | flutter: ">=3.3.0" 210 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_app_update_example 2 | description: Demonstrates how to use the flutter_app_update plugin. 3 | version: 2.0.0+200 4 | 5 | # The following line prevents the package from being accidentally published to 6 | # pub.dev using `flutter pub publish`. This is preferred for private packages. 7 | publish_to: 'none' # Remove this line if you wish to publish to pub.dev 8 | 9 | environment: 10 | sdk: ">=2.17.0 <4.0.0" 11 | 12 | # Dependencies specify other packages that your package needs in order to work. 13 | # To automatically upgrade your package dependencies to the latest versions 14 | # consider running `flutter pub upgrade --major-versions`. Alternatively, 15 | # dependencies can be manually updated by changing the version numbers below to 16 | # the latest version available on pub.dev. To see which dependencies have newer 17 | # versions available, run `flutter pub outdated`. 18 | dependencies: 19 | flutter: 20 | sdk: flutter 21 | flutter_localizations: 22 | sdk: flutter 23 | flutter_app_update: 24 | # When depending on this package from a real application you should use: 25 | # flutter_app_update: ^x.y.z 26 | # See https://dart.dev/tools/pub/dependencies#version-constraints 27 | # The example app is bundled with the plugin so we use a path dependency on 28 | # the parent directory to use the current plugin's version. 29 | path: ../ 30 | 31 | # The following adds the Cupertino Icons font to your application. 32 | # Use with the CupertinoIcons class for iOS style icons. 33 | cupertino_icons: ^1.0.2 34 | 35 | dev_dependencies: 36 | flutter_test: 37 | sdk: flutter 38 | 39 | # The "flutter_lints" package below contains a set of recommended lints to 40 | # encourage good coding practices. The lint set provided by the package is 41 | # activated in the `analysis_options.yaml` file located at the root of your 42 | # package. See that file for information about deactivating specific lint 43 | # rules and activating additional ones. 44 | flutter_lints: ^2.0.0 45 | 46 | # For information on the generic Dart part of this file, see the 47 | # following page: https://dart.dev/tools/pub/pubspec 48 | 49 | # The following section is specific to Flutter packages. 50 | flutter_intl: 51 | enabled: true 52 | 53 | flutter: 54 | 55 | # The following line ensures that the Material Icons font is 56 | # included with your application, so that you can use the icons in 57 | # the material Icons class. 58 | uses-material-design: true 59 | 60 | # To add assets to your application, add an assets section, like this: 61 | # assets: 62 | # - images/a_dot_burr.jpeg 63 | # - images/a_dot_ham.jpeg 64 | 65 | # An image asset can refer to one or more resolution-specific "variants", see 66 | # https://flutter.dev/assets-and-images/#resolution-aware 67 | 68 | # For details regarding adding assets from package dependencies, see 69 | # https://flutter.dev/assets-and-images/#from-packages 70 | 71 | # To add custom fonts to your application, add a fonts section here, 72 | # in this "flutter" section. Each entry in this list should have a 73 | # "family" key with the font family name, and a "fonts" key with a 74 | # list giving the asset and other descriptors for the font. For 75 | # example: 76 | # fonts: 77 | # - family: Schyler 78 | # fonts: 79 | # - asset: fonts/Schyler-Regular.ttf 80 | # - asset: fonts/Schyler-Italic.ttf 81 | # style: italic 82 | # - family: Trajan Pro 83 | # fonts: 84 | # - asset: fonts/TrajanPro.ttf 85 | # - asset: fonts/TrajanPro_Bold.ttf 86 | # weight: 700 87 | # 88 | # For details regarding fonts from package dependencies, 89 | # see https://flutter.dev/custom-fonts/#from-packages 90 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility in the flutter_test package. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:flutter_app_update_example/main.dart'; 12 | 13 | void main() { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /flutter_app_update.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/azhon/flutter_app_update/9b2e0c35f367e4815f52fb743af134a31974fc61/ios/Assets/.gitkeep -------------------------------------------------------------------------------- /ios/Classes/FlutterAppUpdatePlugin.h: -------------------------------------------------------------------------------- 1 | #import 2 | 3 | @interface FlutterAppUpdatePlugin : NSObject 4 | @end 5 | -------------------------------------------------------------------------------- /ios/Classes/FlutterAppUpdatePlugin.m: -------------------------------------------------------------------------------- 1 | #import "FlutterAppUpdatePlugin.h" 2 | 3 | @implementation FlutterAppUpdatePlugin 4 | + (void)registerWithRegistrar:(NSObject*)registrar { 5 | 6 | FlutterMethodChannel* channel = [FlutterMethodChannel 7 | methodChannelWithName:@"azhon_app_update" 8 | binaryMessenger:[registrar messenger]]; 9 | FlutterAppUpdatePlugin* instance = [[FlutterAppUpdatePlugin alloc] init]; 10 | [registrar addMethodCallDelegate:instance channel:channel]; 11 | } 12 | 13 | - (void)handleMethodCall:(FlutterMethodCall*)call result:(FlutterResult)result { 14 | if ([call.method isEqualToString:@"getVersionCode"]){ 15 | NSString *versionCode = NSBundle.mainBundle.infoDictionary[@"CFBundleVersion"]; 16 | result(@([versionCode intValue])); 17 | } else if([call.method isEqualToString:@"getVersionName"]){ 18 | NSString *versionName = NSBundle.mainBundle.infoDictionary[@"CFBundleShortVersionString"]; 19 | result(versionName); 20 | }else if([call.method isEqualToString:@"update"]){ 21 | [self update:call.arguments]; 22 | }else if([call.method isEqualToString:@"cancel"]){ 23 | result(@(YES)); 24 | }else if([call.method isEqualToString:@"install"]){ 25 | result(@(YES)); 26 | } 27 | } 28 | #pragma 版本更新 29 | -(void)update:(id)arguments{ 30 | NSDictionary *model = arguments[@"model"]; 31 | NSString *iOSUrl= model[@"iOSUrl"]; 32 | //直接打开appStore 33 | [self openAppStore: iOSUrl]; 34 | } 35 | #pragma 打开AppStore 36 | -(void)openAppStore:(NSString *)iOSUrl{ 37 | NSString *encodeUrl = [iOSUrl stringByAddingPercentEncodingWithAllowedCharacters:[[NSCharacterSet characterSetWithCharactersInString:@""] invertedSet]]; 38 | NSURL *url = [NSURL URLWithString:encodeUrl]; 39 | if(![[UIApplication sharedApplication] canOpenURL:url]){ 40 | NSLog(@"Cannot open the url:%@",iOSUrl); 41 | return; 42 | } 43 | [[UIApplication sharedApplication] openURL:url options:@{} completionHandler:^(BOOL success) { 44 | if(success){ 45 | NSLog(@"Open url successfully:%@",iOSUrl); 46 | }else{ 47 | NSLog(@"Open url failed:%@",iOSUrl); 48 | } 49 | }]; 50 | } 51 | 52 | @end 53 | -------------------------------------------------------------------------------- /ios/flutter_app_update.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint flutter_app_update.podspec' to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'flutter_app_update' 7 | s.version = '0.0.1' 8 | s.summary = 'flutter 版本更新' 9 | s.description = <<-DESC 10 | flutter 版本更新 11 | DESC 12 | s.homepage = 'http://example.com' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Your Company' => 'email@example.com' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '8.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /lib/azhon_app_update.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | import 'dart:io'; 4 | 5 | import 'package:flutter/services.dart'; 6 | import 'package:flutter_app_update/result_model.dart'; 7 | import 'package:flutter_app_update/update_model.dart'; 8 | 9 | class AzhonAppUpdate { 10 | static const MethodChannel _channel = MethodChannel('azhon_app_update'); 11 | static const EventChannel _listenerChannel = 12 | EventChannel('azhon_app_update_listener'); 13 | static StreamSubscription? _listenerStream; 14 | 15 | ///获取应用的versionCode 16 | static Future get getVersionCode async { 17 | return await _channel.invokeMethod('getVersionCode'); 18 | } 19 | 20 | ///获取应用的versionName 21 | static Future get getVersionName async { 22 | return await _channel.invokeMethod('getVersionName'); 23 | } 24 | 25 | ///更新 26 | static Future update(UpdateModel model) async { 27 | return await _channel.invokeMethod('update', { 28 | 'model': model.toJson(), 29 | }); 30 | } 31 | 32 | ///安装应用 33 | static Future install(String apkPath, {String? authorities}) async { 34 | return await _channel.invokeMethod('install', { 35 | 'authorities': authorities, 36 | 'path': apkPath, 37 | }); 38 | } 39 | 40 | ///监听 41 | static listener(ValueChanged callback) { 42 | if (!Platform.isAndroid) return; 43 | _listenerStream = _listenerChannel.receiveBroadcastStream().listen((data) { 44 | callback.call(ResultModel.fromJson(jsonDecode(data))); 45 | }); 46 | } 47 | 48 | ///取消 49 | static Future get cancel async { 50 | return await _channel.invokeMethod('cancel'); 51 | } 52 | 53 | static dispose() { 54 | _listenerStream?.cancel(); 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /lib/flutter_app_update.dart: -------------------------------------------------------------------------------- 1 | export 'azhon_app_update.dart'; 2 | export 'update_model.dart'; 3 | -------------------------------------------------------------------------------- /lib/result_model.dart: -------------------------------------------------------------------------------- 1 | /// createTime: 2024/11/1 on 11:24 2 | /// desc: 3 | /// 4 | /// @author azhon 5 | class ResultModel { 6 | ResultType? type; 7 | int? max; 8 | int? progress; 9 | String? apk; 10 | String? exception; 11 | 12 | ResultModel({ 13 | required this.type, 14 | this.max, 15 | this.progress, 16 | this.apk, 17 | this.exception, 18 | }); 19 | 20 | ResultModel.fromJson(Map map) { 21 | type = ResultType.from(map['type']); 22 | max = map['max']; 23 | progress = map['progress']; 24 | apk = map['apk']; 25 | exception = map['exception']; 26 | } 27 | 28 | @override 29 | String toString() { 30 | return 'ResultModel{type: $type, max: $max, progress: $progress, apk: $apk, exception: $exception}'; 31 | } 32 | } 33 | 34 | enum ResultType { 35 | ///start download 36 | start('start'), 37 | 38 | ///downloading, [ResultModel.max],[ResultModel.progress] has extra 39 | downloading('downloading'), 40 | 41 | ///downloaded, [ResultModel.apk] has extra 42 | done('done'), 43 | 44 | ///cancel download 45 | cancel('cancel'), 46 | 47 | ///download error, [ResultModel.exception] has extra 48 | error('error'), 49 | ; 50 | 51 | final String value; 52 | 53 | const ResultType(this.value); 54 | 55 | static from(String value) { 56 | switch (value) { 57 | case 'start': 58 | return ResultType.start; 59 | case 'downloading': 60 | return ResultType.downloading; 61 | case 'done': 62 | return ResultType.done; 63 | case 'cancel': 64 | return ResultType.cancel; 65 | case 'error': 66 | return ResultType.error; 67 | } 68 | } 69 | } 70 | -------------------------------------------------------------------------------- /lib/update_model.dart: -------------------------------------------------------------------------------- 1 | class UpdateModel { 2 | ///Apk url 3 | final String apkUrl; 4 | 5 | ///Download apk name 6 | final String apkName; 7 | 8 | ///Notification small icon, here the name of the image in the mipmap, eg: ic_launcher.png then set ic_launcher 9 | final String smallIcon; 10 | 11 | ///iOS download url 12 | final String iOSUrl; 13 | 14 | ///New version md5 file verification (32-bit), verification for repeated downloads 15 | final String? apkMD5; 16 | 17 | ///Display progress notification 18 | final bool showNotification; 19 | 20 | ///Download completed and installation 21 | final bool jumpInstallPage; 22 | 23 | ///Show "Downloading new version in the background…" toast 24 | final bool showBgdToast; 25 | 26 | UpdateModel( 27 | this.apkUrl, 28 | this.apkName, 29 | this.smallIcon, 30 | this.iOSUrl, { 31 | this.apkMD5, 32 | this.showNotification = true, 33 | this.jumpInstallPage = true, 34 | this.showBgdToast = true, 35 | }); 36 | 37 | Map toJson() { 38 | final Map data = {}; 39 | data['apkUrl'] = apkUrl; 40 | data['apkName'] = apkName; 41 | data['smallIcon'] = smallIcon; 42 | data['iOSUrl'] = iOSUrl; 43 | data['apkMD5'] = apkMD5 ?? ''; 44 | data['showNotification'] = showNotification; 45 | data['jumpInstallPage'] = jumpInstallPage; 46 | data['showBgdToast'] = showBgdToast; 47 | return data; 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.flutter-io.cn" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.flutter-io.cn" 18 | source: hosted 19 | version: "2.1.1" 20 | characters: 21 | dependency: transitive 22 | description: 23 | name: characters 24 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 25 | url: "https://pub.flutter-io.cn" 26 | source: hosted 27 | version: "1.3.0" 28 | clock: 29 | dependency: transitive 30 | description: 31 | name: clock 32 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 33 | url: "https://pub.flutter-io.cn" 34 | source: hosted 35 | version: "1.1.1" 36 | collection: 37 | dependency: transitive 38 | description: 39 | name: collection 40 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 41 | url: "https://pub.flutter-io.cn" 42 | source: hosted 43 | version: "1.18.0" 44 | fake_async: 45 | dependency: transitive 46 | description: 47 | name: fake_async 48 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 49 | url: "https://pub.flutter-io.cn" 50 | source: hosted 51 | version: "1.3.1" 52 | flutter: 53 | dependency: "direct main" 54 | description: flutter 55 | source: sdk 56 | version: "0.0.0" 57 | flutter_lints: 58 | dependency: "direct dev" 59 | description: 60 | name: flutter_lints 61 | sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 62 | url: "https://pub.flutter-io.cn" 63 | source: hosted 64 | version: "2.0.3" 65 | flutter_test: 66 | dependency: "direct dev" 67 | description: flutter 68 | source: sdk 69 | version: "0.0.0" 70 | lints: 71 | dependency: transitive 72 | description: 73 | name: lints 74 | sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" 75 | url: "https://pub.flutter-io.cn" 76 | source: hosted 77 | version: "2.1.1" 78 | matcher: 79 | dependency: transitive 80 | description: 81 | name: matcher 82 | sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" 83 | url: "https://pub.flutter-io.cn" 84 | source: hosted 85 | version: "0.12.16" 86 | material_color_utilities: 87 | dependency: transitive 88 | description: 89 | name: material_color_utilities 90 | sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" 91 | url: "https://pub.flutter-io.cn" 92 | source: hosted 93 | version: "0.5.0" 94 | meta: 95 | dependency: transitive 96 | description: 97 | name: meta 98 | sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e 99 | url: "https://pub.flutter-io.cn" 100 | source: hosted 101 | version: "1.10.0" 102 | path: 103 | dependency: transitive 104 | description: 105 | name: path 106 | sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" 107 | url: "https://pub.flutter-io.cn" 108 | source: hosted 109 | version: "1.8.3" 110 | sky_engine: 111 | dependency: transitive 112 | description: flutter 113 | source: sdk 114 | version: "0.0.99" 115 | source_span: 116 | dependency: transitive 117 | description: 118 | name: source_span 119 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 120 | url: "https://pub.flutter-io.cn" 121 | source: hosted 122 | version: "1.10.0" 123 | stack_trace: 124 | dependency: transitive 125 | description: 126 | name: stack_trace 127 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 128 | url: "https://pub.flutter-io.cn" 129 | source: hosted 130 | version: "1.11.1" 131 | stream_channel: 132 | dependency: transitive 133 | description: 134 | name: stream_channel 135 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 136 | url: "https://pub.flutter-io.cn" 137 | source: hosted 138 | version: "2.1.2" 139 | string_scanner: 140 | dependency: transitive 141 | description: 142 | name: string_scanner 143 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 144 | url: "https://pub.flutter-io.cn" 145 | source: hosted 146 | version: "1.2.0" 147 | term_glyph: 148 | dependency: transitive 149 | description: 150 | name: term_glyph 151 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 152 | url: "https://pub.flutter-io.cn" 153 | source: hosted 154 | version: "1.2.1" 155 | test_api: 156 | dependency: transitive 157 | description: 158 | name: test_api 159 | sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" 160 | url: "https://pub.flutter-io.cn" 161 | source: hosted 162 | version: "0.6.1" 163 | vector_math: 164 | dependency: transitive 165 | description: 166 | name: vector_math 167 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 168 | url: "https://pub.flutter-io.cn" 169 | source: hosted 170 | version: "2.1.4" 171 | web: 172 | dependency: transitive 173 | description: 174 | name: web 175 | sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 176 | url: "https://pub.flutter-io.cn" 177 | source: hosted 178 | version: "0.3.0" 179 | sdks: 180 | dart: ">=3.2.0-194.0.dev <4.0.0" 181 | flutter: ">=3.3.0" 182 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_app_update 2 | description: A simple lightweight and customizable version update library for Flutter 3 | version: 3.2.2 4 | homepage: https://github.com/azhon/flutter_app_update 5 | 6 | environment: 7 | sdk: ">=2.17.0 <4.0.0" 8 | flutter: ">=3.3.0" 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | 14 | dev_dependencies: 15 | flutter_test: 16 | sdk: flutter 17 | flutter_lints: ^2.0.0 18 | 19 | # For information on the generic Dart part of this file, see the 20 | # following page: https://dart.dev/tools/pub/pubspec 21 | 22 | # The following section is specific to Flutter packages. 23 | flutter: 24 | # This section identifies this Flutter project as a plugin project. 25 | # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.) 26 | # which should be registered in the plugin registry. This is required for 27 | # using method channels. 28 | # The Android 'package' specifies package in which the registered class is. 29 | # This is required for using method channels on Android. 30 | # The 'ffiPlugin' specifies that native code should be built and bundled. 31 | # This is required for using `dart:ffi`. 32 | # All these are used by the tooling to maintain consistency when 33 | # adding or updating assets for this project. 34 | plugin: 35 | platforms: 36 | android: 37 | package: com.azhon.flutter_app_update 38 | pluginClass: FlutterAppUpdatePlugin 39 | ios: 40 | pluginClass: FlutterAppUpdatePlugin 41 | 42 | # To add assets to your plugin package, add an assets section, like this: 43 | # assets: 44 | # - images/a_dot_burr.jpeg 45 | # - images/a_dot_ham.jpeg 46 | # 47 | # For details regarding assets in packages, see 48 | # https://flutter.dev/assets-and-images/#from-packages 49 | # 50 | # An image asset can refer to one or more resolution-specific "variants", see 51 | # https://flutter.dev/assets-and-images/#resolution-aware 52 | 53 | # To add custom fonts to your plugin package, add a fonts section here, 54 | # in this "flutter" section. Each entry in this list should have a 55 | # "family" key with the font family name, and a "fonts" key with a 56 | # list giving the asset and other descriptors for the font. For 57 | # example: 58 | # fonts: 59 | # - family: Schyler 60 | # fonts: 61 | # - asset: fonts/Schyler-Regular.ttf 62 | # - asset: fonts/Schyler-Italic.ttf 63 | # style: italic 64 | # - family: Trajan Pro 65 | # fonts: 66 | # - asset: fonts/TrajanPro.ttf 67 | # - asset: fonts/TrajanPro_Bold.ttf 68 | # weight: 700 69 | # 70 | # For details regarding fonts in packages, see 71 | # https://flutter.dev/custom-fonts/#from-packages 72 | -------------------------------------------------------------------------------- /test/flutter_app_update_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | --------------------------------------------------------------------------------