Commit 3c100276c77746cfc42d1ee50a977f8710bca8b1

Authored by weixin_45529955
1 parent d97fba96

图标分层

Showing 100 changed files with 3382 additions and 4 deletions

Too many changes to show.

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

  1 +// This is a basic Flutter integration test.
  2 +//
  3 +// Since integration tests run in a full Flutter application, they can interact
  4 +// with the host side of a plugin implementation, unlike Dart unit tests.
  5 +//
  6 +// For more information about Flutter integration tests, please see
  7 +// https://docs.flutter.dev/cookbook/testing/integration/introduction
  8 +
  9 +
  10 +import 'package:flutter_test/flutter_test.dart';
  11 +import 'package:integration_test/integration_test.dart';
  12 +
  13 +import 'package:fluwx/fluwx.dart';
  14 +
  15 +void main() {
  16 + IntegrationTestWidgetsFlutterBinding.ensureInitialized();
  17 +
  18 + testWidgets('getPlatformVersion test', (WidgetTester tester) async {
  19 +
  20 + });
  21 +}
  1 +
  2 +
1 import 'dart:async'; 3 import 'dart:async';
2 import 'dart:convert'; 4 import 'dart:convert';
3 import 'dart:io'; 5 import 'dart:io';
@@ -8,10 +10,10 @@ import 'package:flutter/cupertino.dart'; @@ -8,10 +10,10 @@ import 'package:flutter/cupertino.dart';
8 import 'package:flutter/material.dart'; 10 import 'package:flutter/material.dart';
9 import 'package:flutter_screenutil/flutter_screenutil.dart'; 11 import 'package:flutter_screenutil/flutter_screenutil.dart';
10 import 'package:fluwx/fluwx.dart'; 12 import 'package:fluwx/fluwx.dart';
11 -import 'package:fluwx/fluwx.dart'; 13 +
12 import 'package:one_key/app.dart'; 14 import 'package:one_key/app.dart';
13 import 'package:one_key/constant/constant.dart'; 15 import 'package:one_key/constant/constant.dart';
14 -import 'package:one_key/models/checkbind_phone_model.dart'; 16 +
15 import 'package:one_key/models/store_info.dart'; 17 import 'package:one_key/models/store_info.dart';
16 import 'package:one_key/net/dio_util.dart'; 18 import 'package:one_key/net/dio_util.dart';
17 import 'package:one_key/provider/create_store_model.dart'; 19 import 'package:one_key/provider/create_store_model.dart';
@@ -178,7 +180,7 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver { @@ -178,7 +180,7 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver {
178 .authBy( 180 .authBy(
179 which: NormalAuth( 181 which: NormalAuth(
180 scope: 'snsapi_userinfo', 182 scope: 'snsapi_userinfo',
181 - // state: 'wechat_sdk_demo_test', 183 + state: 'wechat_sdk_demo_test',
182 )) 184 ))
183 .then((data) {}); 185 .then((data) {});
184 // } 186 // }
@@ -939,3 +941,4 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver { @@ -939,3 +941,4 @@ class LoginState extends State<LoginPage> with WidgetsBindingObserver {
939 )); 941 ));
940 } 942 }
941 } 943 }
  944 +
@@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
4 "debug": true, 4 "debug": true,
5 "versionCode": 1, 5 "versionCode": 1,
6 "versionName": "1.0.0", 6 "versionName": "1.0.0",
7 - "minAPIVersion": 50000012, 7 + "minAPIVersion": 50100018,
8 "targetAPIVersion": 60000020, 8 "targetAPIVersion": 60000020,
9 "apiReleaseType": "Release", 9 "apiReleaseType": "Release",
10 "targetMinorAPIVersion": 0, 10 "targetMinorAPIVersion": 0,
  1 +.DS_Store
  2 +.dart_tool/
  3 +
  4 +.packages
  5 +.pub/
  6 +pubspec.lock
  7 +
  8 +build/
  9 +/.idea
  1 +## 4.5.0
  2 +* Avoid using system to open on desktop platforms (Thanks to [@prateekmedia](https://github.com/prateekmedia), PR [#7](https://github.com/javaherisaber/open_filex/pull/7))
  3 +* Use dartPluginClass as default_package for desktop platforms (Thanks to [@sjordan2010](https://github.com/sjordan2010), PR [#16](https://github.com/javaherisaber/open_filex/pull/16))
  4 +* Update support for Android 14 (API 34) (Thanks to [@ShirishAryalKhalti](https://github.com/ShirishAryalKhalti), PR [#13](https://github.com/javaherisaber/open_filex/pull/13))
  5 +* Fix MissingPluginException for opening adding as flutter module (Thanks to [@joker-fu](https://github.com/joker-fu), PR [#11](https://github.com/javaherisaber/open_filex/pull/11))
  6 +* Allow open to run async on Desktop platforms (Thanks to [@lexxxel](https://github.com/lexxxel), PR [#15](https://github.com/javaherisaber/open_filex/pull/15))
  7 +
  8 +## 4.4.0
  9 +* Fix error when embedding Flutter app to a native iOS app (Add-to-app) (Thanks to [@nukeolay](https://github.com/nukeolay), PR [#10](https://github.com/javaherisaber/open_filex/pull/10))
  10 +
  11 +## 4.3.4
  12 +* Add namespace property to make compatible with gradle 8.0 (Thanks to [@kishormainali](https://github.com/kishormainali), PR [#9](https://github.com/javaherisaber/open_filex/pull/9))
  13 +
  14 +## 4.3.3
  15 +* Update README.md
  16 +
  17 +## 4.3.2
  18 +* Move plugin initializations to onAttachedToEngine() in Android (Thanks to [@DK070202](https://github.com/DK070202), mentioned at [#163](https://github.com/crazecoder/open_file/issues/163))
  19 +
  20 +## 4.3.1
  21 +* Update README.md
  22 +
  23 +## 4.3.0
  24 +* Replace JCenter with MavenCentral in Android build.gradle repositories (Thanks to [@BetterB0y](https://github.com/BetterB0y))
  25 +
  26 +## 4.2.2
  27 +* Update CHANGELOG.md
  28 +
  29 +## 4.2.1
  30 +* Update CHANGELOG.md
  31 +
  32 +## 4.2.0
  33 +* Upgrade support for Granular media permissions in Android 13 [Commit#261f446](https://github.com/javaherisaber/open_filex/commit/261f4463835eb293a059bc09030443d5093bcbd2) (Thanks to [@0975086498](https://github.com/0975086498))
  34 +* Remove usages of `REQUEST_INSTALL_PACKAGES` in Android plugin [PR#1](https://github.com/javaherisaber/open_filex/pull/1) (Thanks to [@thebeast1](https://github.com/thebeast1))
  35 +* Upgrade example project with latest version of flutter (3.3.5) and Android 13 [Commit#9d2027d](https://github.com/javaherisaber/open_filex/commit/9d2027d4063194c822bb81c7a74ff20aadb0f2ee)
  36 +
  37 +## 4.1.1
  38 +* Add filePaths instruction for Android in README.md
  39 +* Fix parse args not filtering commands properly
  40 +* Fix viewController is not recognized in iOS
  41 +
  42 +## 4.1.0
  43 +* Fixed Plugin lifecycle onDetachedFromActivity in Android
  44 +* Add getExternalFilesDir when checking if a path requires a permission
  45 +
  46 +## 4.0.1
  47 +* Update readme descriptions
  48 +
  49 +## 4.0.0
  50 +* Update ffi to 2.0.1
  51 +* Require Flutter 3.0.0+ and Dart 2.17.0+ (because of ffi 2.0.0+)
  52 +* Update example project with latest version of Flutter (3.0.5)
  53 +
  54 +## 3.4.0
  55 +* Fix podspec in ios not resolved
  56 +## 3.3.0
  57 +* Remove dangerous permission `REQUEST_INSTALL_PACKAGES` in Android
  58 +## 3.2.1
  59 +* Add command parser before create system call [#144](https://github.com/crazecoder/open_file/issues/144) (thanks to [@mludovico](https://github.com/mludovico))
  60 +* Fix startActivity() might have NPE issue with filePath on Android (thanks to [@AlexV525](https://github.com/AlexV525))
  61 +* Add error type return when file path is nil on iOS
  62 +## 3.2.0
  63 +* add csv/kml/gpx/torrent support on Android
  64 +* remove android:requestLegacyExternalStorage
  65 +* fix Deprecated API warning when build on Android
  66 +* delete uti, DocumentInteraction will be retrieved automatically on iOS (thanks to [@std-c](https://github.com/std-c))
  67 +* fix returns wrong reponse on Windows
  68 +## 3.1.0
  69 +* upgrade FFI 1.0.0 (thanks to [@mit-mit](https://github.com/mit-mit))
  70 +* add linuxByProcess parameter (thanks to [@mx1up](https://github.com/mx1up))
  71 +* Migrate to Dart null safety system (thanks to [@orevial](https://github.com/orevial))
  72 +## 3.0.3
  73 +* upgrade compileSdkVersion
  74 +## 3.0.2
  75 +* add storage compatibility mode for AndroidQ.
  76 +* fix [#106](https://github.com/crazecoder/open_file/issues/106) [#100](https://github.com/crazecoder/open_file/issues/100) [#74](https://github.com/crazecoder/open_file/issues/74)
  77 +* fix multiple file providers. (thanks to [@jawa0919](https://github.com/jawa0919))
  78 +* Take file extension in lowercase for comparison.(thanks to [@kluverua](https://github.com/kluverua))
  79 +* Fixed a typo in the error message for fileNotFound.(thanks to [@sebas642](https://github.com/sebas642))
  80 +## 3.0.1
  81 +* fix web parameter error
  82 +* Replace result value from String to OpenResult.
  83 +## 3.0.0
  84 +* updated to the v2 Android Plugin APIs
  85 +* Distinguish android errors (No APP found and others)
  86 +* add web support
  87 +* add pc support
  88 +## 2.1.1
  89 +* rollback 2.0.3
  90 +## 2.1.0-pre.1
  91 +* add web support(beta)
  92 +* add pc support(beta)
  93 +## 2.0.3
  94 +* change use FileProvider from Android M to Android N
  95 +## 2.0.2
  96 +* catch No Activity found to handle Intent exception
  97 +* Optimize request REQUEST_INSTALL_PACKAGES permission on Android O
  98 +## 2.0.1+2
  99 +* fix android M FLAG_GRANT_READ_URI_PERMISSION
  100 +## 2.0.1+1
  101 +* Fixed crash caused by third party plug-in request permissions
  102 +## 2.0.1
  103 +* migrate to androidx
  104 +## 1.3.0
  105 +* roll back support
  106 +## 1.2.3+1
  107 +* request READ_EXTERNAL_STORAGE when the file is not in the app directory
  108 +## 1.2.3
  109 +* Optimize permission request logic on android
  110 +## 1.2.2+2
  111 +* fix crash when requestPermission
  112 +## 1.2.2+1
  113 +* migrate to androidx
  114 +## 1.2.2
  115 +* ask for permission when needed
  116 +## 1.2.1
  117 +* fix somethings
  118 +## 1.2.0
  119 +* Add custom parameters,"type" android,"uti" iOS
  120 +## 1.1.1
  121 +* fix startActivity crash in android
  122 +## 1.1.0
  123 +* fix ios open file
  124 +## 1.0.7
  125 +* resolve conflict with other plugins about FileProvider and multi appcompat-v7 compile
  126 +## 1.0.6
  127 +* resolve conflict with image_provider plugin
  128 +## 1.0.5
  129 +* Just Support >=2.0.0-dev.28.0
  130 +## 1.0.4
  131 +* Just Support Dart2
  132 +## 1.0.3
  133 +* Just Support Dart2
  134 +## 1.0.2
  135 +* Ios Support added and support android 7.0 or above
  1 +## Committers列表
  2 +
  3 +### 以下是此项目的committer人员
  4 +不区分先后顺序
  5 +
  6 +- [zjzhu](https://gitee.com/appproject)
  7 +- [aibin](https://gitee.com/binai)
  8 +- [lihui](https://gitee.com/lihui868)
  9 +- [gxzmf](https://gitee.com/gxzmf)
  1 +Copyright 2018 crazecoder. All rights reserved.
  2 +
  3 +Redistribution and use in source and binary forms, with or without
  4 +modification, are permitted provided that the following conditions are
  5 +met:
  6 +
  7 + * Redistributions of source code must retain the above copyright
  8 + notice, this list of conditions and the following disclaimer.
  9 + * Redistributions in binary form must reproduce the above
  10 + copyright notice, this list of conditions and the following
  11 + disclaimer in the documentation and/or other materials provided
  12 + with the distribution.
  13 + * Neither the name of Google Inc. nor the names of its
  14 + contributors may be used to endorse or promote products derived
  15 + from this software without specific prior written permission.
  16 +
  17 +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  18 +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  19 +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  20 +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  21 +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  22 +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  23 +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  24 +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  25 +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  26 +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  27 +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!-- Copyright (c) 2021 Huawei Device Co., Ltd.
  3 +
  4 + Licensed under the Apache License, Version 2.0 (the "License");
  5 + you may not use this file except in compliance with the License.
  6 + You may obtain a copy of the License at
  7 +
  8 + http://www.apache.org/licenses/LICENSE-2.0
  9 +
  10 + Unless required by applicable law or agreed to in writing, software
  11 + distributed under the License is distributed on an "AS IS" BASIS,
  12 + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + See the License for the specific language governing permissions and
  14 + limitations under the License.
  15 +
  16 + This is the configuration file template for OpenHarmony OSS Audit Tool, please copy it to your project root dir and modify it refer to OpenHarmony/tools_oat/README.
  17 +
  18 +-->
  19 +
  20 +<configuration>
  21 + <oatconfig>
  22 + <licensefile></licensefile>
  23 + <policylist>
  24 + <policy
  25 + desc=""
  26 + name="projectPolicy">
  27 + <policyitem
  28 + desc=""
  29 + filefilter="copyrightPolicyFilter"
  30 + group="defaultGroup"
  31 + name="SwanLink (Jiangsu) Technology Development Co., LTD."
  32 + path=".*"
  33 + rule="may"
  34 + type="copyright"/>
  35 + <policyitem type="license" name="BSD-3-Clause" path=".*" filefilter="defaultPolicyFilter" desc="不影响兼容性"/>
  36 + <policyitem type="license" name="BSD 3-Clause License" path=".*" filefilter="defaultPolicyFilter" desc="不影响兼容性"/>
  37 + <policyitem type="license" name="BSD-2-Clause" path=".*" filefilter="defaultPolicyFilter" desc="不影响兼容性"/>
  38 + <policyitem type="license" name="BSD 2-Clause License" path=".*" filefilter="defaultPolicyFilter" desc="不影响兼容性"/>
  39 + <policyitem type="compatibility" name="BSD-3-Clause" path=".*" desc="不影响兼容性"/>
  40 + <policyitem type="compatibility" name="BSD-2-Clause" path=".*" desc="不影响兼容性"/>
  41 + <policyitem type="license" name="BSDStyleLicense" path=".*" filefilter="defaultPolicyFilter" desc="不影响兼容性"/>
  42 + </policy>
  43 + <policy name="projectPolicy" desc="">
  44 + <!--policyitem type="compatibility" name="GPL-2.0+" path=".*" desc="Process that runs independently, invoked by the X process."/-->
  45 + <policyitem type="compatibility" name="GPL-2.0+" path=".*" desc="Process that runs independently, invoked by the X process."/>
  46 + <policyitem type="compatibility" name="Apache-2.0" path=".*" desc="不影响兼容性"/>
  47 + <policyitem type="compatibility" name="BSDStyleLicense" path=".*" desc="不影响兼容性" />
  48 + <!--policyitem type="copyright" name="xxx" path=".*" rule="may" group="defaultGroup" filefilter="copyrightPolicyFilter" desc="Developed by X Company"/-->
  49 + </policy>
  50 + </policylist>
  51 + <filefilterlist>
  52 + <filefilter name="defaultFilter" desc="Files not to check">
  53 + <filteritem type="filename" name="*.iml|*.json|*.txt|*.json5|*.yaml|*.md|*.bat" desc="desc files"/>
  54 + <filteritem type="filename" name="*.png|*.ico|*.jpg|*.webp|*.ttf|*.enc|*.mp3" desc="app resource files"/>
  55 + <filteritem type="filename" name="*.so|*.har" desc="engine二进制文件,不影响兼容性"/>
  56 + <filteritem type="filename" name="*.tgz" desc="hvigor本地插件,不影响兼容性"/>
  57 + <filteritem type="filepath" name="android/*" desc="安卓目录,不影响兼容性"/>
  58 + <filteritem type="filepath" name="ios/*" desc="ios目录,不影响兼容性"/>
  59 + <filteritem type="filepath" name="example/android/*" desc="安卓目录,不影响兼容性"/>
  60 + <filteritem type="filepath" name="example/ios/*" desc="ios目录,不影响兼容性"/>
  61 + </filefilter>
  62 + <filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
  63 + <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  64 + <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  65 + <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
  66 + </filefilter>
  67 + <filefilter name="copyrightPolicyFilter" desc="Filters for copyright header policies">
  68 + <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  69 + <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  70 + <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
  71 + </filefilter>
  72 + <filefilter name="licenseFileNamePolicyFilter" desc="Filters for LICENSE file policies">
  73 + <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  74 + <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  75 + <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
  76 + </filefilter>
  77 + <filefilter name="readmeFileNamePolicyFilter" desc="Filters for README file policies">
  78 + <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  79 + <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  80 + <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
  81 + </filefilter>
  82 + <filefilter name="readmeOpenSourcefileNamePolicyFilter" desc="Filters for README.OpenSource file policies">
  83 + <!--filteritem type="filename" name="*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  84 + <!--filteritem type="filepath" name="abcdefg/.*.uvwxyz" desc="Describe the reason for filtering scan results"/-->
  85 + <!--filteritem type="filepath" name="projectroot/[a-zA-Z0-9]{20,}.sh" desc="Temp files"/-->
  86 + </filefilter>
  87 + <filefilter name="binaryFileTypePolicyFilter" desc="Filters for binary file policies">
  88 + <filteritem type="filename" name="*.iml|*.json|*.txt" desc="desc files"/>
  89 + <filteritem type='filepath' name="*/example/ohos/entry/libs/arm64-v8a/libc++_shared.so" desc='二进制文件,不影响兼容性'/>
  90 + <filteritem type='filepath' name="ohos/AppScope/resources/base/media/app_icon.png" desc='二进制文件,不影响兼容性'/>
  91 + </filefilter>
  92 +
  93 + </filefilterlist>
  94 + <licensematcherlist>
  95 + <!--licensematcher name="uvwxyz License" desc="If the scanning result is InvalidLicense, you can define matching rules here. Note that quotation marks must be escaped.">
  96 + <licensetext name="
  97 + uvwxyz license textA xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  98 + " desc=""/>
  99 + <licensetext name="
  100 + uvwxyz license textB xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  101 + " desc=""/>
  102 + </licensematcher-->
  103 + </licensematcherlist>
  104 + </oatconfig>
  105 +</configuration>
  1 +<p align="center">
  2 + <h1 align="center"> <code>open_filex</code> </h1>
  3 +</p>
  4 +
  5 +This project is based on [open_filex](https://pub.dev/packages/open_filex).
  6 +
  7 +## 1. Installation and Usage
  8 +
  9 +### 1.1 Installation
  10 +
  11 +Go to the project directory and add the following dependencies in pubspec.yaml
  12 +
  13 +<!-- tabs:start -->
  14 +
  15 +#### pubspec.yaml
  16 +
  17 +```yaml
  18 +...
  19 +
  20 +dependencies:
  21 + open_filex:
  22 + git:
  23 + url: https://gitcode.com/openharmony-sig/flutter_native_image.git
  24 +...
  25 +```
  26 +
  27 +Execute Command
  28 +
  29 +```bash
  30 +flutter pub get
  31 +```
  32 +
  33 +<!-- tabs:end -->
  34 +
  35 +### 1.2 Usage
  36 +
  37 +For use cases [ohos/example](./example/lib/main.dart).
  38 +
  39 +## 2. Constraints
  40 +
  41 +### 2.1 Compatibility
  42 +
  43 +This document is verified based on the following versions:
  44 +
  45 +1. Flutter: 3.7.12-ohos-1.1.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;
  46 +2. Flutter: 3.22.1-ohos-1.0.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;
  47 +
  48 +## 3. API
  49 +
  50 +> [!TIP] If the value of **ohos Support** is **yes**, it means that the ohos platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android.
  51 +
  52 +| Name | Description | Type | Input | Output | ohos Support |
  53 +| ---- | -------------- | -------- | ------------------------------------------- | ------------ | ------------ |
  54 +| open | Opening a file | function | String filePath,{String? type, String? uti} | Future<File> | yes |
  55 +
  56 +## 4. Properties
  57 +
  58 +> [!TIP] If the value of **ohos Support** is **yes**, it means that the ohos platform supports this property; **no** means the opposite; **partially** means some capabilities of this property are supported. The usage method is the same on different platforms and the effect is the same as that of iOS or Android.
  59 +
  60 +| Name | Description | Type | Input | Output | ohos Support |
  61 +| -------- | ----------------------------- | ------ | ----- | ------ | ------------ |
  62 +| fileName | Path to the file to be opened | String | / | / | yes |
  63 +| type | MIME type hint for the file | String | / | / | yes |
  64 +| uti | Uniform Type Identifier | String | / | / | yes |
  65 +
  66 +## 5. Known Issues
  67 +
  68 +## 6. Others
  69 +
  70 +## 7. License
  71 +
  72 +This project is licensed under [The BSD-3-Clause License](./LICENSE).
  1 +<p align="center">
  2 + <h1 align="center"> <code>open_filex</code> </h1>
  3 +</p>
  4 +
  5 +本项目基于 [open_filex](https://pub.dev/packages/open_filex) 开发。
  6 +
  7 +## 1. 安装与使用
  8 +
  9 +### 1.1 安装方式
  10 +
  11 +进入到工程目录并在 pubspec.yaml 中添加以下依赖:
  12 +
  13 +<!-- tabs:start -->
  14 +
  15 +#### pubspec.yaml
  16 +
  17 +```yaml
  18 +...
  19 +
  20 +dependencies:
  21 + open_filex:
  22 + git:
  23 + url: https://gitcode.com/openharmony-sig/flutter_native_image.git
  24 +...
  25 +```
  26 +
  27 +执行命令
  28 +
  29 +```bash
  30 +flutter pub get
  31 +```
  32 +
  33 +<!-- tabs:end -->
  34 +
  35 +### 1.2 使用案例
  36 +
  37 +使用案例详见 [example](./example/lib/main.dart)。
  38 +
  39 +## 2. 约束与限制
  40 +
  41 +### 2.1 兼容性
  42 +
  43 +在以下版本中已测试通过:
  44 +
  45 +1. Flutter: 3.7.12-ohos-1.1.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;
  46 +2. Flutter: 3.22.1-ohos-1.0.3; SDK: 5.0.0(12); IDE: DevEco Studio: 5.1.0.828; ROM: 5.1.0.130 SP8;
  47 +
  48 +## 3. API
  49 +
  50 +> [!TIP] "ohos Support"列为 yes 表示 ohos 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
  51 +
  52 +| Name | Description | Type | Input | Output | ohos Support |
  53 +| ---- | ----------- | -------- | ------------------------------------------- | ------------ | ------------ |
  54 +| open | 打开文件 | function | String filePath,{String? type, String? uti} | Future<File> | yes |
  55 +
  56 +## 4. 属性
  57 +
  58 +> [!TIP] "ohos Support"列为 yes 表示 ohos 平台支持该属性;no 则表示不支持;partially 表示部分支持。使用方法跨平台一致,效果对标 iOS 或 Android 的效果。
  59 +
  60 +| Name | Description | Type | Input | Output | ohos Support |
  61 +| -------- | -------------------- | ------ | ----- | ------ | ------------ |
  62 +| fileName | 要打开的文件路径 | String | / | / | yes |
  63 +| type | 文件的 MIME 类型提示 | String | / | / | yes |
  64 +| uti | 统一类型标识符 | String | / | / | yes |
  65 +
  66 +## 5. 遗留问题
  67 +
  68 +## 6. 其他
  69 +
  70 +## 7. 开源协议
  71 +
  72 +本项目基于 [The BSD-3-Clause License](./LICENSE),请自由地享受和参与开源。
  1 +[
  2 + {
  3 + "Name": "open_file",
  4 + "License": "BSD-3-Clause License",
  5 + "License File": "LICENSE",
  6 + "Version Number": "c44fa568964f4caa96c04687939df0b28c48eb29",
  7 + "Owner": "george.lihui@huawei.com",
  8 + "Upstream URL": "https://github.com/javaherisaber/open_file",
  9 + "Description": "A plug-in that can call native APP to open files with string result in flutter, support iOS(UTI) / android(intent) / PC(ffi) / web(dart:html)."
  10 + }
  11 +]
  1 +# open_filex
  2 +[![pub package](https://img.shields.io/pub/v/open_filex.svg)](https://pub.dev/packages/open_filex)
  3 +
  4 +A plug-in that can call native APP to open files with string result in flutter, support iOS(DocumentInteraction) / android(intent) / PC(ffi) / web(dart:html)
  5 +
  6 +## Notice
  7 +This package is a fork of [open_file](https://pub.dev/packages/open_file) to fix the following issues:
  8 +- Remove `REQUEST_INSTALL_PACKAGES` permission in Android to comply with GooglePlay publish policies
  9 +- Update [ffi](https://pub.dev/packages/ffi) to 2.0.1+
  10 +- Upgrade support for [granular media permissions](https://developer.android.com/about/versions/13/behavior-changes-13#granular-media-permissions) in Android 13
  11 +- Fix plugin lifecycle onDetachedFromActivity in Android
  12 +- Fix viewController is not recognized in iOS
  13 +- Fix parse args not filtering commands properly
  14 +- Replace JCenter with MavenCentral in Android build.gradle repositories (since JCenter becomes unreachable sometimes due to it's end of life)
  15 +- Compatibility with Gradle 8+
  16 +- iOS embedded flutter compatibility
  17 +
  18 +For full list of changes see [CHANGELOG](https://pub.dev/packages/open_filex/changelog)
  19 +
  20 +## Usage
  21 +
  22 +To use this plugin, add [open_filex](https://pub.dev/packages/open_filex/install) as a dependency in your pubspec.yaml file.
  23 +```yaml
  24 +dependencies:
  25 + open_filex: ^lastVersion
  26 +```
  27 +
  28 +## Example
  29 +```dart
  30 +import 'package:open_filex/open_filex.dart';
  31 +
  32 +OpenFilex.open("/sdcard/example.txt");
  33 +```
  34 +
  35 +## Support
  36 +### android
  37 +```
  38 +{
  39 + {".3gp", "video/3gpp"},
  40 + {".torrent","application/x-bittorrent"},
  41 + {".kml", "application/vnd.google-earth.kml+xml"},
  42 + {".gpx", "application/gpx+xml"},
  43 + {".csv", "application/vnd.ms-excel"},
  44 + {".apk", "application/vnd.android.package-archive"},
  45 + {".asf", "video/x-ms-asf"},
  46 + {".avi", "video/x-msvideo"},
  47 + {".bin", "application/octet-stream"},
  48 + {".bmp", "image/bmp"},
  49 + {".c", "text/plain"},
  50 + {".class", "application/octet-stream"},
  51 + {".conf", "text/plain"},
  52 + {".cpp", "text/plain"},
  53 + {".doc", "application/msword"},
  54 + {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
  55 + {".xls", "application/vnd.ms-excel"},
  56 + {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
  57 + {".exe", "application/octet-stream"},
  58 + {".gif", "image/gif"},
  59 + {".gtar", "application/x-gtar"},
  60 + {".gz", "application/x-gzip"},
  61 + {".h", "text/plain"},
  62 + {".htm", "text/html"},
  63 + {".html", "text/html"},
  64 + {".jar", "application/java-archive"},
  65 + {".java", "text/plain"},
  66 + {".jpeg", "image/jpeg"},
  67 + {".jpg", "image/jpeg"},
  68 + {".js", "application/x-javascript"},
  69 + {".log", "text/plain"},
  70 + {".m3u", "audio/x-mpegurl"},
  71 + {".m4a", "audio/mp4a-latm"},
  72 + {".m4b", "audio/mp4a-latm"},
  73 + {".m4p", "audio/mp4a-latm"},
  74 + {".m4u", "video/vnd.mpegurl"},
  75 + {".m4v", "video/x-m4v"},
  76 + {".mov", "video/quicktime"},
  77 + {".mp2", "audio/x-mpeg"},
  78 + {".mp3", "audio/x-mpeg"},
  79 + {".mp4", "video/mp4"},
  80 + {".mpc", "application/vnd.mpohun.certificate"},
  81 + {".mpe", "video/mpeg"},
  82 + {".mpeg", "video/mpeg"},
  83 + {".mpg", "video/mpeg"},
  84 + {".mpg4", "video/mp4"},
  85 + {".mpga", "audio/mpeg"},
  86 + {".msg", "application/vnd.ms-outlook"},
  87 + {".ogg", "audio/ogg"},
  88 + {".pdf", "application/pdf"},
  89 + {".png", "image/png"},
  90 + {".pps", "application/vnd.ms-powerpoint"},
  91 + {".ppt", "application/vnd.ms-powerpoint"},
  92 + {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
  93 + {".prop", "text/plain"},
  94 + {".rc", "text/plain"},
  95 + {".rmvb", "audio/x-pn-realaudio"},
  96 + {".rtf", "application/rtf"},
  97 + {".sh", "text/plain"},
  98 + {".tar", "application/x-tar"},
  99 + {".tgz", "application/x-compressed"},
  100 + {".txt", "text/plain"},
  101 + {".wav", "audio/x-wav"},
  102 + {".wma", "audio/x-ms-wma"},
  103 + {".wmv", "audio/x-ms-wmv"},
  104 + {".wps", "application/vnd.ms-works"},
  105 + {".xml", "text/plain"},
  106 + {".z", "application/x-compress"},
  107 + {".zip", "application/x-zip-compressed"},
  108 + {"", "*/*"}
  109 +}
  110 +
  111 +```
  112 +when Conflict with other plugins about FileProvider, add code below in your /android/app/src/main/AndroidManifest.xml
  113 +```xml
  114 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  115 + xmlns:tools="http://schemas.android.com/tools"
  116 + package="xxx.xxx.xxxxx">
  117 + <application>
  118 + ...
  119 + <provider
  120 + android:name="androidx.core.content.FileProvider"
  121 + android:authorities="${applicationId}.fileProvider"
  122 + android:exported="false"
  123 + android:grantUriPermissions="true"
  124 + tools:replace="android:authorities">
  125 + <meta-data
  126 + android:name="android.support.FILE_PROVIDER_PATHS"
  127 + android:resource="@xml/filepaths"
  128 + tools:replace="android:resource" />
  129 + </provider>
  130 + </application>
  131 +</manifest>
  132 +```
  133 +furthermore add code below in your `/android/app/src/main/res/xml/filepaths.xml`
  134 +```xml
  135 +<paths>
  136 + <external-path name="external-path" path="."/>
  137 + <external-cache-path name="external-cache-path" path="."/>
  138 + <external-files-path name="external-files-path" path="."/>
  139 + <files-path name="files_path" path="."/>
  140 + <cache-path name="cache-path" path="."/>
  141 + <root-path name="root" path="."/>
  142 +</paths>
  143 +```
  144 +
  145 +when Android dependency 'com.android.support:appcompat-v7' has different version for the compile error, add code below in your /android/build.gradle
  146 +```gradle
  147 +subprojects {
  148 + project.configurations.all {
  149 + resolutionStrategy.eachDependency { details ->
  150 + if (details.requested.group == 'com.android.support'
  151 + && !details.requested.name.contains('multidex') ) {
  152 + details.useVersion "27.1.1"
  153 + }
  154 + }
  155 + }
  156 +}
  157 +```
  158 +
  159 +
  160 +### IOS with UTI (DocumentInteraction Auto)
  161 +```
  162 +{
  163 + {".rtf", "public.rtf"},
  164 + {".txt", "public.plain-text"},
  165 + {".html", "public.html"},
  166 + {".htm", "public.html"},
  167 + {".xml", "public.xml"},
  168 + {".tar", "public.tar-archive"},
  169 + {".gz", "org.gnu.gnu-zip-archive"},
  170 + {".gzip", "org.gnu.gnu-zip-archive"},
  171 + {".tgz", "org.gnu.gnu-zip-tar-archive"},
  172 + {".jpg", "public.jpeg"},
  173 + {".jpeg", "public.jpeg"},
  174 + {".png", "public.png"},
  175 + {".avi", "public.avi"},
  176 + {".mpg", "public.mpeg"},
  177 + {".mpeg", "public.mpeg"},
  178 + {".mp4", "public.mpeg-4"},
  179 + {".3gpp", "public.3gpp"},
  180 + {".3gp", "public.3gpp"},
  181 + {".mp3", "public.mp3"},
  182 + {".zip", "com.pkware.zip-archive"},
  183 + {".gif", "com.compuserve.gif"},
  184 + {".bmp", "com.microsoft.bmp"},
  185 + {".ico", "com.microsoft.ico"},
  186 + {".doc", "com.microsoft.word.doc"},
  187 + {".xls", "com.microsoft.excel.xls"},
  188 + {".ppt", "com.microsoft.powerpoint.​ppt"},
  189 + {".wav", "com.microsoft.waveform-​audio"},
  190 + {".wm", "com.microsoft.windows-​media-wm"},
  191 + {".wmv", "com.microsoft.windows-​media-wmv"},
  192 + {".pdf", "com.adobe.pdf"}
  193 +}
  194 +```
  1 +# open_file
  2 +
  3 +原始仓来源:https://github.com/javaherisaber/open_file
  4 +
  5 +## 仓库简介
  6 +open_file是一个Flutter插件,旨在帮助开发者在Flutter应用中打开指定路径的文件。
  7 +该仓库为open_file库的Flutter鸿蒙化仓。
  8 +
  9 +## 引入背景简述
  10 +OpenHarmony北向生态发展过程中,已经适配Flutter的厂商在接入OpenHarmony过程中存在使用open_file的诉求。鉴于此OpenHarmony为支持北向生态伙伴快速接入鸿蒙、快速实现产品化而提供的open_file,本方案采用插件化的适配器模式实现open_file鸿蒙化版本的兼容。
  11 +
  12 +## 使用场景
  13 +本方案仅供应用厂商中已支持Flutter框架的设备在移植OpenHarmony系统过程中作为备选方案使用。
  14 +
  15 +## 使用文档
  16 +
  17 +适配OpenHarmony平台的使用指导请见:[Flutter使用指导文档](https://gitee.com/openharmony-sig/flutter_samples/blob/master/ohos/docs/07_plugin/ohos%E5%B9%B3%E5%8F%B0%E9%80%82%E9%85%8Dflutter%E4%B8%89%E6%96%B9%E5%BA%93%E6%8C%87%E5%AF%BC.md)
  18 +
  19 +## License
  20 +
  21 +BSD-3-Clause License
  22 +
  23 +见 [LICENSE](LICENSE)
  1 +# This file configures the analyzer, which statically analyzes Dart code to
  2 +# check for errors, warnings, and lints.
  3 +#
  4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
  5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
  6 +# invoked from the command line by running `flutter analyze`.
  7 +
  8 +# The following line activates a set of recommended lints for Flutter apps,
  9 +# packages, and plugins designed to encourage good coding practices.
  10 +include: package:flutter_lints/flutter.yaml
  11 +
  12 +linter:
  13 + # The lint rules applied to this project can be customized in the
  14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  15 + # included above or to enable additional rules. A list of all available lints
  16 + # and their documentation is published at
  17 + # https://dart-lang.github.io/linter/lints/index.html.
  18 + #
  19 + # Instead of disabling a lint rule for the entire project in the
  20 + # section below, it can also be suppressed for a single line of code
  21 + # or a specific dart file by using the `// ignore: name_of_lint` and
  22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  23 + # producing the lint.
  24 + rules:
  25 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
  26 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
  27 +
  28 +# Additional information about this file can be found at
  29 +# https://dart.dev/guides/language/analysis-options
  1 +*.iml
  2 +.gradle
  3 +/local.properties
  4 +/.idea/workspace.xml
  5 +/.idea/libraries
  6 +.DS_Store
  7 +/build
  8 +/captures
  1 +group 'com.crazecoder.openfile'
  2 +version '1.0-SNAPSHOT'
  3 +
  4 +buildscript {
  5 + repositories {
  6 + google()
  7 + mavenCentral()
  8 + }
  9 +
  10 + dependencies {
  11 + classpath 'com.android.tools.build:gradle:7.3.1'
  12 + }
  13 +}
  14 +
  15 +rootProject.allprojects {
  16 + repositories {
  17 + google()
  18 + mavenCentral()
  19 + }
  20 +}
  21 +
  22 +apply plugin: 'com.android.library'
  23 +
  24 +android {
  25 +
  26 + // conditional for compatibility with older gradle versions
  27 + if (project.android.hasProperty('namespace')) {
  28 + namespace "com.crazecoder.openfile"
  29 + }
  30 +
  31 + compileSdkVersion 34
  32 +
  33 + defaultConfig {
  34 + minSdkVersion 16
  35 + testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
  36 + }
  37 + lintOptions {
  38 + disable 'InvalidPackage'
  39 + }
  40 +}
  41 +dependencies {
  42 + implementation 'androidx.appcompat:appcompat:1.6.1'
  43 +}
  1 +## For more details on how to configure your build environment visit
  2 +# http://www.gradle.org/docs/current/userguide/build_environment.html
  3 +#
  4 +# Specifies the JVM arguments used for the daemon process.
  5 +# The setting is particularly useful for tweaking memory settings.
  6 +# Default value: -Xmx1024m -XX:MaxPermSize=256m
  7 +# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
  8 +#
  9 +# When configured, Gradle will run in incubating parallel mode.
  10 +# This option should only be used with decoupled projects. More details, visit
  11 +# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects
  12 +# org.gradle.parallel=true
  13 +#Sun Apr 11 14:45:15 CST 2021
  14 +android.enableJetifier=true
  15 +#android.enableR8=true
  16 +android.useAndroidX=true
  17 +org.gradle.jvmargs=-Xmx1536M
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + xmlns:tools="http://schemas.android.com/tools"
  3 + package="com.crazecoder.openfile">
  4 +
  5 + <uses-permission
  6 + android:name="android.permission.READ_EXTERNAL_STORAGE"
  7 + android:maxSdkVersion="32" />
  8 +
  9 + <uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
  10 + <uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
  11 + <uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
  12 +
  13 + <application>
  14 + <provider
  15 + android:name="com.crazecoder.openfile.FileProvider"
  16 + android:authorities="${applicationId}.fileProvider.com.crazecoder.openfile"
  17 + android:exported="false"
  18 + android:grantUriPermissions="true"
  19 + tools:replace="android:authorities">
  20 + <meta-data
  21 + android:name="android.support.FILE_PROVIDER_PATHS"
  22 + android:resource="@xml/filepaths"
  23 + />
  24 + </provider>
  25 + </application>
  26 +</manifest>
  1 +package com.crazecoder.openfile;
  2 +
  3 +public class FileProvider extends androidx.core.content.FileProvider {
  4 +}
  1 +package com.crazecoder.openfile;
  2 +
  3 +import android.Manifest;
  4 +import android.annotation.SuppressLint;
  5 +import android.app.Activity;
  6 +import android.content.ActivityNotFoundException;
  7 +import android.content.ContentResolver;
  8 +import android.content.Context;
  9 +import android.content.Intent;
  10 +import android.database.Cursor;
  11 +import android.net.Uri;
  12 +import android.os.Build;
  13 +import android.os.Environment;
  14 +import android.provider.MediaStore;
  15 +import android.provider.Settings;
  16 +import android.util.Log;
  17 +
  18 +import androidx.annotation.NonNull;
  19 +import androidx.annotation.Nullable;
  20 +import androidx.annotation.RequiresApi;
  21 +import androidx.core.content.FileProvider;
  22 +import androidx.core.app.ActivityCompat;
  23 +import androidx.core.content.ContextCompat;
  24 +import androidx.core.content.PermissionChecker;
  25 +
  26 +import com.crazecoder.openfile.utils.JsonUtil;
  27 +import com.crazecoder.openfile.utils.MapUtil;
  28 +
  29 +import io.flutter.embedding.engine.plugins.FlutterPlugin;
  30 +import io.flutter.embedding.engine.plugins.activity.ActivityAware;
  31 +import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
  32 +import io.flutter.plugin.common.MethodCall;
  33 +import io.flutter.plugin.common.MethodChannel;
  34 +import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
  35 +import io.flutter.plugin.common.MethodChannel.Result;
  36 +import io.flutter.plugin.common.PluginRegistry;
  37 +
  38 +import java.io.File;
  39 +import java.io.IOException;
  40 +import java.util.Map;
  41 +
  42 +
  43 +/**
  44 + * OpenFilePlugin
  45 + */
  46 +public class OpenFilePlugin implements MethodCallHandler
  47 + , FlutterPlugin
  48 + , ActivityAware
  49 + , PluginRegistry.RequestPermissionsResultListener
  50 + , PluginRegistry.ActivityResultListener {
  51 + /**
  52 + * Plugin registration.
  53 + */
  54 + private @Nullable
  55 + FlutterPluginBinding flutterPluginBinding;
  56 +
  57 + private Context context;
  58 + private Activity activity;
  59 + private MethodChannel channel;
  60 +
  61 +
  62 + private Result result;
  63 + private String filePath;
  64 + private String typeString;
  65 +
  66 + private boolean isResultSubmitted = false;
  67 +
  68 + private static final int REQUEST_CODE = 33432;
  69 + private static final int RESULT_CODE = 0x12;
  70 + private static final String TYPE_STRING_APK = "application/vnd.android.package-archive";
  71 +
  72 + @Deprecated
  73 + public static void registerWith(PluginRegistry.Registrar registrar) {
  74 + OpenFilePlugin plugin = new OpenFilePlugin();
  75 + plugin.activity = registrar.activity();
  76 + plugin.context = registrar.context();
  77 + plugin.channel = new MethodChannel(registrar.messenger(), "open_file");
  78 + plugin.channel.setMethodCallHandler(plugin);
  79 + registrar.addRequestPermissionsResultListener(plugin);
  80 + registrar.addActivityResultListener(plugin);
  81 + }
  82 +
  83 + private boolean hasPermission(String permission) {
  84 + return ContextCompat.checkSelfPermission(activity, permission) == PermissionChecker.PERMISSION_GRANTED;
  85 + }
  86 +
  87 + private void requestPermission(String permission) {
  88 + ActivityCompat.requestPermissions(activity, new String[]{permission}, REQUEST_CODE);
  89 + }
  90 +
  91 + @Override
  92 + @SuppressLint("NewApi")
  93 + public void onMethodCall(MethodCall call, @NonNull Result result) {
  94 + isResultSubmitted = false;
  95 + if (call.method.equals("open_file")) {
  96 + this.result = result;
  97 + filePath = call.argument("file_path");
  98 + if (call.hasArgument("type") && call.argument("type") != null) {
  99 + typeString = call.argument("type");
  100 + } else {
  101 + typeString = getFileType(filePath);
  102 + }
  103 + if (pathRequiresPermission()) {
  104 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R) {
  105 + if(!isFileAvailable()){
  106 + return;
  107 + }
  108 + if (!isMediaStorePath() && !Environment.isExternalStorageManager()) {
  109 + result(-3, "Permission denied: android.Manifest.permission.MANAGE_EXTERNAL_STORAGE");
  110 + return;
  111 + }
  112 + }
  113 + if (canStartActivityWithPermission()) {
  114 + startActivity();
  115 + } else if (Build.VERSION.SDK_INT < 33) {
  116 + requestPermission(Manifest.permission.READ_EXTERNAL_STORAGE);
  117 + } else if (typeString.startsWith("image")) {
  118 + requestPermission(Manifest.permission.READ_MEDIA_IMAGES);
  119 + } else if (typeString.startsWith("video")) {
  120 + requestPermission(Manifest.permission.READ_MEDIA_VIDEO);
  121 + } else if (typeString.startsWith("audio")) {
  122 + requestPermission(Manifest.permission.READ_MEDIA_AUDIO);
  123 + }
  124 + } else {
  125 + startActivity();
  126 + }
  127 + } else {
  128 + result.notImplemented();
  129 + isResultSubmitted = true;
  130 + }
  131 + }
  132 +
  133 + private boolean canStartActivityWithPermission() {
  134 + return (Build.VERSION.SDK_INT < 33 && hasPermission(Manifest.permission.READ_EXTERNAL_STORAGE)) ||
  135 + (Build.VERSION.SDK_INT >= 33 && typeString.startsWith("image") && hasPermission(Manifest.permission.READ_MEDIA_IMAGES)) ||
  136 + (Build.VERSION.SDK_INT >= 33 && typeString.startsWith("video") && hasPermission(Manifest.permission.READ_MEDIA_VIDEO)) ||
  137 + (Build.VERSION.SDK_INT >= 33 && typeString.startsWith("audio") && hasPermission(Manifest.permission.READ_MEDIA_AUDIO)) ||
  138 + (Build.VERSION.SDK_INT >= 33 && !(typeString.startsWith("image") || typeString.startsWith("video") || typeString.startsWith("audio")));
  139 + }
  140 +
  141 + private boolean isMediaStorePath(){
  142 + boolean isMediaStorePath = false;
  143 + String[] mediaStorePath = {"/DCIM/"
  144 + ,"/Pictures/"
  145 + ,"/Movies/"
  146 + ,"/Alarms/"
  147 + ,"/Audiobooks/"
  148 + ,"/Music/"
  149 + ,"/Notifications/"
  150 + ,"/Podcasts/"
  151 + ,"/Ringtones/"
  152 + ,"/Download/"};
  153 + for (String s : mediaStorePath) {
  154 + if (filePath.contains(s)) {
  155 + isMediaStorePath = true;
  156 + break;
  157 + }
  158 + }
  159 + return isMediaStorePath;
  160 + }
  161 +
  162 + private boolean pathRequiresPermission() {
  163 + if (Build.VERSION.SDK_INT < Build.VERSION_CODES.M) {
  164 + return false;
  165 + }
  166 +
  167 + try {
  168 + String appDirCanonicalPath = new File(context.getApplicationInfo().dataDir).getCanonicalPath();
  169 + String fileCanonicalPath = new File(filePath).getCanonicalPath();
  170 + String extCanonicalPath = context.getExternalFilesDir(null).getCanonicalPath();
  171 + return !(fileCanonicalPath.startsWith(appDirCanonicalPath) || fileCanonicalPath.startsWith(extCanonicalPath));
  172 + } catch (IOException e) {
  173 + e.printStackTrace();
  174 + return true;
  175 + }
  176 + }
  177 +
  178 + private boolean isFileAvailable(){
  179 + if (filePath == null) {
  180 + result(-4, "the file path cannot be null");
  181 + return false;
  182 + }
  183 +
  184 + File file = new File(filePath);
  185 + if (!file.exists()) {
  186 + result(-2, "the " + filePath + " file does not exists");
  187 + return false;
  188 + }
  189 + return true;
  190 + }
  191 +
  192 + private void startActivity() {
  193 + if(!isFileAvailable()){
  194 + return;
  195 + }
  196 + Intent intent = new Intent(Intent.ACTION_VIEW);
  197 + if (TYPE_STRING_APK.equals(typeString))
  198 + intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
  199 + else
  200 + intent.setFlags(Intent.FLAG_ACTIVITY_SINGLE_TOP);
  201 + intent.addCategory(Intent.CATEGORY_DEFAULT);
  202 + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
  203 + intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
  204 + String packageName = context.getPackageName();
  205 + Uri uri = FileProvider.getUriForFile(context, packageName + ".fileProvider.com.crazecoder.openfile", new File(filePath));
  206 + intent.setDataAndType(uri, typeString);
  207 + } else {
  208 + intent.setDataAndType(Uri.fromFile(new File(filePath)), typeString);
  209 + }
  210 + int type = 0;
  211 + String message = "done";
  212 + try {
  213 + activity.startActivity(intent);
  214 + } catch (ActivityNotFoundException e) {
  215 + type = -1;
  216 + message = "No APP found to open this file。";
  217 + } catch (Exception e) {
  218 + type = -4;
  219 + message = "File opened incorrectly。";
  220 + }
  221 + result(type, message);
  222 + }
  223 +
  224 + private String getFileType(String filePath) {
  225 + String[] fileStrs = filePath.split("\\.");
  226 + String fileTypeStr = fileStrs[fileStrs.length - 1].toLowerCase();
  227 + switch (fileTypeStr) {
  228 + case "3gp":
  229 + return "video/3gpp";
  230 + case "torrent":
  231 + return "application/x-bittorrent";
  232 + case "kml":
  233 + return "application/vnd.google-earth.kml+xml";
  234 + case "gpx":
  235 + return "application/gpx+xml";
  236 + case "apk":
  237 + return TYPE_STRING_APK;
  238 + case "asf":
  239 + return "video/x-ms-asf";
  240 + case "avi":
  241 + return "video/x-msvideo";
  242 + case "bin":
  243 + case "class":
  244 + case "exe":
  245 + return "application/octet-stream";
  246 + case "bmp":
  247 + return "image/bmp";
  248 + case "c":
  249 + return "text/plain";
  250 + case "conf":
  251 + return "text/plain";
  252 + case "cpp":
  253 + return "text/plain";
  254 + case "doc":
  255 + return "application/msword";
  256 + case "docx":
  257 + return "application/vnd.openxmlformats-officedocument.wordprocessingml.document";
  258 + case "xls":
  259 + case "csv":
  260 + return "application/vnd.ms-excel";
  261 + case "xlsx":
  262 + return "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet";
  263 + case "gif":
  264 + return "image/gif";
  265 + case "gtar":
  266 + return "application/x-gtar";
  267 + case "gz":
  268 + return "application/x-gzip";
  269 + case "h":
  270 + return "text/plain";
  271 + case "htm":
  272 + return "text/html";
  273 + case "html":
  274 + return "text/html";
  275 + case "jar":
  276 + return "application/java-archive";
  277 + case "java":
  278 + return "text/plain";
  279 + case "jpeg":
  280 + return "image/jpeg";
  281 + case "jpg":
  282 + return "image/jpeg";
  283 + case "js":
  284 + return "application/x-javascript";
  285 + case "log":
  286 + return "text/plain";
  287 + case "m3u":
  288 + return "audio/x-mpegurl";
  289 + case "m4a":
  290 + return "audio/mp4a-latm";
  291 + case "m4b":
  292 + return "audio/mp4a-latm";
  293 + case "m4p":
  294 + return "audio/mp4a-latm";
  295 + case "m4u":
  296 + return "video/vnd.mpegurl";
  297 + case "m4v":
  298 + return "video/x-m4v";
  299 + case "mov":
  300 + return "video/quicktime";
  301 + case "mp2":
  302 + return "audio/x-mpeg";
  303 + case "mp3":
  304 + return "audio/x-mpeg";
  305 + case "mp4":
  306 + return "video/mp4";
  307 + case "mpc":
  308 + return "application/vnd.mpohun.certificate";
  309 + case "mpe":
  310 + return "video/mpeg";
  311 + case "mpeg":
  312 + return "video/mpeg";
  313 + case "mpg":
  314 + return "video/mpeg";
  315 + case "mpg4":
  316 + return "video/mp4";
  317 + case "mpga":
  318 + return "audio/mpeg";
  319 + case "msg":
  320 + return "application/vnd.ms-outlook";
  321 + case "ogg":
  322 + return "audio/ogg";
  323 + case "pdf":
  324 + return "application/pdf";
  325 + case "png":
  326 + return "image/png";
  327 + case "pps":
  328 + return "application/vnd.ms-powerpoint";
  329 + case "ppt":
  330 + return "application/vnd.ms-powerpoint";
  331 + case "pptx":
  332 + return "application/vnd.openxmlformats-officedocument.presentationml.presentation";
  333 + case "prop":
  334 + return "text/plain";
  335 + case "rc":
  336 + return "text/plain";
  337 + case "rmvb":
  338 + return "audio/x-pn-realaudio";
  339 + case "rtf":
  340 + return "application/rtf";
  341 + case "sh":
  342 + return "text/plain";
  343 + case "tar":
  344 + return "application/x-tar";
  345 + case "tgz":
  346 + return "application/x-compressed";
  347 + case "txt":
  348 + return "text/plain";
  349 + case "wav":
  350 + return "audio/x-wav";
  351 + case "wma":
  352 + return "audio/x-ms-wma";
  353 + case "wmv":
  354 + return "audio/x-ms-wmv";
  355 + case "wps":
  356 + return "application/vnd.ms-works";
  357 + case "xml":
  358 + return "text/plain";
  359 + case "z":
  360 + return "application/x-compress";
  361 + case "zip":
  362 + return "application/x-zip-compressed";
  363 + default:
  364 + return "*/*";
  365 + }
  366 + }
  367 +
  368 + @RequiresApi(api = Build.VERSION_CODES.M)
  369 + @Override
  370 + public boolean onRequestPermissionsResult(int requestCode, String[] strings, int[] grantResults) {
  371 + if (requestCode != REQUEST_CODE) return false;
  372 + for (String string : strings) {
  373 + if (!hasPermission(string)) {
  374 + result(-3, "Permission denied: " + string);
  375 + return false;
  376 + }
  377 + }
  378 + startActivity();
  379 + return true;
  380 + }
  381 +
  382 + @RequiresApi(api = Build.VERSION_CODES.M)
  383 + @Override
  384 + public boolean onActivityResult(int requestCode, int resultCode, Intent intent) {
  385 + if (requestCode == RESULT_CODE) {
  386 + startActivity();
  387 + }
  388 + return false;
  389 + }
  390 +
  391 + private void result(int type, String message) {
  392 + if (result != null && !isResultSubmitted) {
  393 + Map<String, Object> map = MapUtil.createMap(type, message);
  394 + result.success(JsonUtil.toJson(map));
  395 + isResultSubmitted = true;
  396 + }
  397 + }
  398 +
  399 + @Override
  400 + public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
  401 + this.flutterPluginBinding = binding;
  402 + context = flutterPluginBinding.getApplicationContext();
  403 + setup();
  404 + }
  405 +
  406 + private void setup() {
  407 + channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "open_file");
  408 + channel.setMethodCallHandler(this);
  409 + }
  410 +
  411 + @Override
  412 + public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
  413 + if (channel == null) {
  414 + // Could be on too low of an SDK to have started listening originally.
  415 + return;
  416 + }
  417 +
  418 + channel.setMethodCallHandler(null);
  419 + channel = null;
  420 + this.flutterPluginBinding = null;
  421 + }
  422 +
  423 + @Override
  424 + public void onAttachedToActivity(ActivityPluginBinding binding) {
  425 + setup();
  426 + activity = binding.getActivity();
  427 + binding.addRequestPermissionsResultListener(this);
  428 + binding.addActivityResultListener(this);
  429 + }
  430 +
  431 + @Override
  432 + public void onDetachedFromActivityForConfigChanges() {
  433 + onDetachedFromActivity();
  434 + }
  435 +
  436 + @Override
  437 + public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding binding) {
  438 + onAttachedToActivity(binding);
  439 + }
  440 +
  441 + @Override
  442 + public void onDetachedFromActivity() {
  443 + if (channel == null) {
  444 + return;
  445 + }
  446 + channel.setMethodCallHandler(null);
  447 + channel = null;
  448 + activity = null;
  449 + }
  450 +}
  1 +package com.crazecoder.openfile.utils;
  2 +
  3 +import org.json.JSONException;
  4 +import org.json.JSONObject;
  5 +
  6 +import java.util.Map;
  7 +
  8 +/**
  9 + * Note of this class.
  10 + *
  11 + * @author crazecoder
  12 + * @since 2018/12/28
  13 + */
  14 +public class JsonUtil {
  15 + public static String toJson(Map<String, Object> map) {
  16 + JSONObject jsonObject = new JSONObject();
  17 + try {
  18 + for (Map.Entry<String, Object> entry : map.entrySet()) {
  19 + jsonObject.put(entry.getKey(), entry.getValue());
  20 + }
  21 + } catch (JSONException e) {
  22 + e.printStackTrace();
  23 + }
  24 + return jsonObject.toString();
  25 + }
  26 +}
  1 +package com.crazecoder.openfile.utils;
  2 +
  3 +import java.util.HashMap;
  4 +import java.util.Map;
  5 +
  6 +public class MapUtil {
  7 + public static Map<String, Object> createMap(int type, String message) {
  8 + Map<String, Object> map = new HashMap<String, Object>();
  9 + map.put("type", type);
  10 + map.put("message", message);
  11 + return map;
  12 + }
  13 +}
  1 +<paths>
  2 + <external-path
  3 + name="external-path"
  4 + path="."/>
  5 + <external-cache-path
  6 + name="external-cache-path"
  7 + path="."/>
  8 + <external-files-path
  9 + name="external-files-path"
  10 + path="."/>
  11 + <files-path
  12 + name="files_path"
  13 + path="."/>
  14 + <cache-path
  15 + name="cache-path"
  16 + path="."/>
  17 + <root-path
  18 + name="root"
  19 + path="."/>
  20 +</paths>
  21 +
  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
  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: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  8 + channel: stable
  9 +
  10 +project_type: app
  11 +
  12 +# Tracks metadata for the flutter migrate command
  13 +migration:
  14 + platforms:
  15 + - platform: root
  16 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  17 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  18 + - platform: android
  19 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  20 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  21 + - platform: ios
  22 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  23 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  24 + - platform: linux
  25 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  26 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  27 + - platform: macos
  28 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  29 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  30 + - platform: web
  31 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  32 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  33 + - platform: windows
  34 + create_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  35 + base_revision: fb57da5f945d02ef4f98dfd9409a72b7cce74268
  36 +
  37 + # User provided section
  38 +
  39 + # List of Local paths (relative to this file) that should be
  40 + # ignored by the migrate tool.
  41 + #
  42 + # Files that are not part of the templates will be ignored by default.
  43 + unmanaged_files:
  44 + - 'lib/main.dart'
  45 + - 'ios/Runner.xcodeproj/project.pbxproj'
  1 +# open_filex
  2 +
  3 +A plug-in that can open files for android
  4 +
  5 +## Usage
  6 +
  7 +To use this plugin, add [open_filex](https://pub.dev/packages/open_filex/install) as a dependency in your pubspec.yaml file.
  8 +
  9 +## How to test this example in emulator
  10 +Add a .png file to /Download folder and run the example project
  11 +
  12 +## Example
  13 +```
  14 +import 'package:open_filex/open_filex.dart';
  15 +
  16 +OpenFilex.open("/sdcard/text.txt");
  17 +```
  18 +
  19 +## Support
  20 +```
  21 +{
  22 + {".3gp", "video/3gpp"},
  23 + {".apk", "application/vnd.android.package-archive"},
  24 + {".asf", "video/x-ms-asf"},
  25 + {".avi", "video/x-msvideo"},
  26 + {".bin", "application/octet-stream"},
  27 + {".bmp", "image/bmp"},
  28 + {".c", "text/plain"},
  29 + {".class", "application/octet-stream"},
  30 + {".conf", "text/plain"},
  31 + {".cpp", "text/plain"},
  32 + {".doc", "application/msword"},
  33 + {".docx", "application/vnd.openxmlformats-officedocument.wordprocessingml.document"},
  34 + {".xls", "application/vnd.ms-excel"},
  35 + {".xlsx", "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"},
  36 + {".exe", "application/octet-stream"},
  37 + {".gif", "image/gif"},
  38 + {".gtar", "application/x-gtar"},
  39 + {".gz", "application/x-gzip"},
  40 + {".h", "text/plain"},
  41 + {".htm", "text/html"},
  42 + {".html", "text/html"},
  43 + {".jar", "application/java-archive"},
  44 + {".java", "text/plain"},
  45 + {".jpeg", "image/jpeg"},
  46 + {".jpg", "image/jpeg"},
  47 + {".js", "application/x-javascript"},
  48 + {".log", "text/plain"},
  49 + {".m3u", "audio/x-mpegurl"},
  50 + {".m4a", "audio/mp4a-latm"},
  51 + {".m4b", "audio/mp4a-latm"},
  52 + {".m4p", "audio/mp4a-latm"},
  53 + {".m4u", "video/vnd.mpegurl"},
  54 + {".m4v", "video/x-m4v"},
  55 + {".mov", "video/quicktime"},
  56 + {".mp2", "audio/x-mpeg"},
  57 + {".mp3", "audio/x-mpeg"},
  58 + {".mp4", "video/mp4"},
  59 + {".mpc", "application/vnd.mpohun.certificate"},
  60 + {".mpe", "video/mpeg"},
  61 + {".mpeg", "video/mpeg"},
  62 + {".mpg", "video/mpeg"},
  63 + {".mpg4", "video/mp4"},
  64 + {".mpga", "audio/mpeg"},
  65 + {".msg", "application/vnd.ms-outlook"},
  66 + {".ogg", "audio/ogg"},
  67 + {".pdf", "application/pdf"},
  68 + {".png", "image/png"},
  69 + {".pps", "application/vnd.ms-powerpoint"},
  70 + {".ppt", "application/vnd.ms-powerpoint"},
  71 + {".pptx", "application/vnd.openxmlformats-officedocument.presentationml.presentation"},
  72 + {".prop", "text/plain"},
  73 + {".rc", "text/plain"},
  74 + {".rmvb", "audio/x-pn-realaudio"},
  75 + {".rtf", "application/rtf"},
  76 + {".sh", "text/plain"},
  77 + {".tar", "application/x-tar"},
  78 + {".tgz", "application/x-compressed"},
  79 + {".txt", "text/plain"},
  80 + {".wav", "audio/x-wav"},
  81 + {".wma", "audio/x-ms-wma"},
  82 + {".wmv", "audio/x-ms-wmv"},
  83 + {".wps", "application/vnd.ms-works"},
  84 + {".xml", "text/plain"},
  85 + {".z", "application/x-compress"},
  86 + {".zip", "application/x-zip-compressed"},
  87 + {"", "*/*"}
  88 +};
  89 +```
  1 +# This file configures the analyzer, which statically analyzes Dart code to
  2 +# check for errors, warnings, and lints.
  3 +#
  4 +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
  5 +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
  6 +# invoked from the command line by running `flutter analyze`.
  7 +
  8 +# The following line activates a set of recommended lints for Flutter apps,
  9 +# packages, and plugins designed to encourage good coding practices.
  10 +include: package:flutter_lints/flutter.yaml
  11 +
  12 +linter:
  13 + # The lint rules applied to this project can be customized in the
  14 + # section below to disable rules from the `package:flutter_lints/flutter.yaml`
  15 + # included above or to enable additional rules. A list of all available lints
  16 + # and their documentation is published at
  17 + # https://dart-lang.github.io/linter/lints/index.html.
  18 + #
  19 + # Instead of disabling a lint rule for the entire project in the
  20 + # section below, it can also be suppressed for a single line of code
  21 + # or a specific dart file by using the `// ignore: name_of_lint` and
  22 + # `// ignore_for_file: name_of_lint` syntax on the line or in the file
  23 + # producing the lint.
  24 + rules:
  25 + # avoid_print: false # Uncomment to disable the `avoid_print` rule
  26 + # prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
  27 +
  28 +# Additional information about this file can be found at
  29 +# https://dart.dev/guides/language/analysis-options
  1 +gradle-wrapper.jar
  2 +/.gradle
  3 +/captures/
  4 +/gradlew
  5 +/gradlew.bat
  6 +/local.properties
  7 +GeneratedPluginRegistrant.java
  8 +
  9 +# Remember to never publicly share your keystore.
  10 +# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
  11 +key.properties
  12 +**/*.keystore
  13 +**/*.jks
  1 +def localProperties = new Properties()
  2 +def localPropertiesFile = rootProject.file('local.properties')
  3 +if (localPropertiesFile.exists()) {
  4 + localPropertiesFile.withReader('UTF-8') { reader ->
  5 + localProperties.load(reader)
  6 + }
  7 +}
  8 +
  9 +def flutterRoot = localProperties.getProperty('flutter.sdk')
  10 +if (flutterRoot == null) {
  11 + throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
  12 +}
  13 +
  14 +def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
  15 +if (flutterVersionCode == null) {
  16 + flutterVersionCode = '1'
  17 +}
  18 +
  19 +def flutterVersionName = localProperties.getProperty('flutter.versionName')
  20 +if (flutterVersionName == null) {
  21 + flutterVersionName = '1.0'
  22 +}
  23 +
  24 +apply plugin: 'com.android.application'
  25 +apply plugin: 'kotlin-android'
  26 +apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
  27 +
  28 +android {
  29 + compileSdkVersion 34
  30 + ndkVersion flutter.ndkVersion
  31 +
  32 + compileOptions {
  33 + sourceCompatibility JavaVersion.VERSION_1_8
  34 + targetCompatibility JavaVersion.VERSION_1_8
  35 + }
  36 +
  37 + kotlinOptions {
  38 + jvmTarget = '1.8'
  39 + }
  40 +
  41 + sourceSets {
  42 + main.java.srcDirs += 'src/main/kotlin'
  43 + }
  44 +
  45 + defaultConfig {
  46 + // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
  47 + applicationId "com.example.example"
  48 + // You can update the following values to match your application needs.
  49 + // For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-build-configuration.
  50 + minSdkVersion flutter.minSdkVersion
  51 + targetSdkVersion 34
  52 + versionCode flutterVersionCode.toInteger()
  53 + versionName flutterVersionName
  54 + }
  55 +
  56 + buildTypes {
  57 + release {
  58 + // TODO: Add your own signing config for the release build.
  59 + // Signing with the debug keys for now, so `flutter run --release` works.
  60 + signingConfig signingConfigs.debug
  61 + }
  62 + }
  63 +}
  64 +
  65 +flutter {
  66 + source '../..'
  67 +}
  68 +
  69 +dependencies {
  70 + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
  71 +}
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + flutter needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 + <application
  9 + android:label="example"
  10 + android:name="${applicationName}"
  11 + android:icon="@mipmap/ic_launcher">
  12 + <activity
  13 + android:name=".MainActivity"
  14 + android:exported="true"
  15 + android:launchMode="singleTop"
  16 + android:theme="@style/LaunchTheme"
  17 + android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
  18 + android:hardwareAccelerated="true"
  19 + android:windowSoftInputMode="adjustResize">
  20 + <!-- Specifies an Android theme to apply to this Activity as soon as
  21 + the Android process has started. This theme is visible to the user
  22 + while the Flutter UI initializes. After that, this theme continues
  23 + to determine the Window background behind the Flutter UI. -->
  24 + <meta-data
  25 + android:name="io.flutter.embedding.android.NormalTheme"
  26 + android:resource="@style/NormalTheme"
  27 + />
  28 + <intent-filter>
  29 + <action android:name="android.intent.action.MAIN"/>
  30 + <category android:name="android.intent.category.LAUNCHER"/>
  31 + </intent-filter>
  32 + </activity>
  33 + <!-- Don't delete the meta-data below.
  34 + This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
  35 + <meta-data
  36 + android:name="flutterEmbedding"
  37 + android:value="2" />
  38 + </application>
  39 +</manifest>
  1 +package com.example.example
  2 +
  3 +import io.flutter.embedding.android.FlutterActivity
  4 +
  5 +class MainActivity: FlutterActivity() {
  6 +}
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="?android:colorBackground" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<!-- Modify this file to customize your launch splash screen -->
  3 +<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
  4 + <item android:drawable="@android:color/white" />
  5 +
  6 + <!-- You can insert your own image assets here -->
  7 + <!-- <item>
  8 + <bitmap
  9 + android:gravity="center"
  10 + android:src="@mipmap/launch_image" />
  11 + </item> -->
  12 +</layer-list>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<?xml version="1.0" encoding="utf-8"?>
  2 +<resources>
  3 + <!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
  4 + <style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
  5 + <!-- Show a splash screen on the activity. Automatically removed when
  6 + the Flutter engine draws its first frame -->
  7 + <item name="android:windowBackground">@drawable/launch_background</item>
  8 + </style>
  9 + <!-- Theme applied to the Android Window as soon as the process has started.
  10 + This theme determines the color of the Android Window while your
  11 + Flutter UI initializes, as well as behind your Flutter UI while its
  12 + running.
  13 +
  14 + This Theme is only used starting with V2 of Flutter's Android embedding. -->
  15 + <style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
  16 + <item name="android:windowBackground">?android:colorBackground</item>
  17 + </style>
  18 +</resources>
  1 +<manifest xmlns:android="http://schemas.android.com/apk/res/android"
  2 + package="com.example.example">
  3 + <!-- The INTERNET permission is required for development. Specifically,
  4 + the Flutter tool needs it to communicate with the running application
  5 + to allow setting breakpoints, to provide hot reload, etc.
  6 + -->
  7 + <uses-permission android:name="android.permission.INTERNET"/>
  8 +</manifest>
  1 +buildscript {
  2 + ext.kotlin_version = '1.6.21'
  3 + repositories {
  4 + google()
  5 + mavenCentral()
  6 + maven { url "https://maven.google.com" }
  7 + }
  8 +
  9 + dependencies {
  10 + classpath 'com.android.tools.build:gradle:7.3.1'
  11 + classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
  12 + }
  13 +}
  14 +
  15 +allprojects {
  16 + repositories {
  17 + google()
  18 + mavenCentral()
  19 + maven { url "https://maven.google.com" }
  20 + }
  21 +}
  22 +
  23 +rootProject.buildDir = '../build'
  24 +subprojects {
  25 + project.buildDir = "${rootProject.buildDir}/${project.name}"
  26 +}
  27 +subprojects {
  28 + project.evaluationDependsOn(':app')
  29 +}
  30 +
  31 +tasks.register("clean", Delete) {
  32 + delete rootProject.buildDir
  33 +}
  1 +org.gradle.jvmargs=-Xmx1536M
  2 +android.useAndroidX=true
  3 +android.enableJetifier=true
  1 +#Fri Jun 23 08:50:38 CEST 2017
  2 +distributionBase=GRADLE_USER_HOME
  3 +distributionPath=wrapper/dists
  4 +zipStoreBase=GRADLE_USER_HOME
  5 +zipStorePath=wrapper/dists
  6 +distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip
  1 +include ':app'
  2 +
  3 +def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
  4 +def properties = new Properties()
  5 +
  6 +assert localPropertiesFile.exists()
  7 +localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
  8 +
  9 +def flutterSdkPath = properties.getProperty("flutter.sdk")
  10 +assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
  11 +apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
  1 +**/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
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>en</string>
  7 + <key>CFBundleExecutable</key>
  8 + <string>App</string>
  9 + <key>CFBundleIdentifier</key>
  10 + <string>io.flutter.flutter.app</string>
  11 + <key>CFBundleInfoDictionaryVersion</key>
  12 + <string>6.0</string>
  13 + <key>CFBundleName</key>
  14 + <string>App</string>
  15 + <key>CFBundlePackageType</key>
  16 + <string>FMWK</string>
  17 + <key>CFBundleShortVersionString</key>
  18 + <string>1.0</string>
  19 + <key>CFBundleSignature</key>
  20 + <string>????</string>
  21 + <key>CFBundleVersion</key>
  22 + <string>1.0</string>
  23 + <key>MinimumOSVersion</key>
  24 + <string>9.0</string>
  25 +</dict>
  26 +</plist>
  1 +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
  2 +#include "Generated.xcconfig"
  1 +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
  2 +#include "Generated.xcconfig"
  1 +# Uncomment this line to define a global platform for your project
  2 +# platform :ios, '12.0'
  3 +
  4 +# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
  5 +ENV['COCOAPODS_DISABLE_STATS'] = 'true'
  6 +
  7 +project 'Runner', {
  8 + 'Debug' => :debug,
  9 + 'Profile' => :release,
  10 + 'Release' => :release,
  11 +}
  12 +
  13 +def flutter_root
  14 + generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
  15 + unless File.exist?(generated_xcode_build_settings_path)
  16 + raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
  17 + end
  18 +
  19 + File.foreach(generated_xcode_build_settings_path) do |line|
  20 + matches = line.match(/FLUTTER_ROOT\=(.*)/)
  21 + return matches[1].strip if matches
  22 + end
  23 + raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
  24 +end
  25 +
  26 +require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
  27 +
  28 +flutter_ios_podfile_setup
  29 +
  30 +target 'Runner' do
  31 + use_frameworks!
  32 + use_modular_headers!
  33 +
  34 + flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
  35 + target 'RunnerTests' do
  36 + inherit! :search_paths
  37 + end
  38 +end
  39 +
  40 +post_install do |installer|
  41 + installer.pods_project.targets.each do |target|
  42 + flutter_additional_ios_build_settings(target)
  43 + end
  44 +end
  1 +// !$*UTF8*$!
  2 +{
  3 + archiveVersion = 1;
  4 + classes = {
  5 + };
  6 + objectVersion = 50;
  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 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
  13 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
  14 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
  15 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
  16 +/* End PBXBuildFile section */
  17 +
  18 +/* Begin PBXCopyFilesBuildPhase section */
  19 + 9705A1C41CF9048500538489 /* Embed Frameworks */ = {
  20 + isa = PBXCopyFilesBuildPhase;
  21 + buildActionMask = 2147483647;
  22 + dstPath = "";
  23 + dstSubfolderSpec = 10;
  24 + files = (
  25 + );
  26 + name = "Embed Frameworks";
  27 + runOnlyForDeploymentPostprocessing = 0;
  28 + };
  29 +/* End PBXCopyFilesBuildPhase section */
  30 +
  31 +/* Begin PBXFileReference section */
  32 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
  33 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
  34 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
  35 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
  36 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
  37 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
  38 + 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
  39 + 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
  40 + 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
  41 + 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
  42 + 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
  43 + 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
  44 + 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
  45 +/* End PBXFileReference section */
  46 +
  47 +/* Begin PBXFrameworksBuildPhase section */
  48 + 97C146EB1CF9000F007C117D /* Frameworks */ = {
  49 + isa = PBXFrameworksBuildPhase;
  50 + buildActionMask = 2147483647;
  51 + files = (
  52 + );
  53 + runOnlyForDeploymentPostprocessing = 0;
  54 + };
  55 +/* End PBXFrameworksBuildPhase section */
  56 +
  57 +/* Begin PBXGroup section */
  58 + 9740EEB11CF90186004384FC /* Flutter */ = {
  59 + isa = PBXGroup;
  60 + children = (
  61 + 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
  62 + 9740EEB21CF90195004384FC /* Debug.xcconfig */,
  63 + 7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
  64 + 9740EEB31CF90195004384FC /* Generated.xcconfig */,
  65 + );
  66 + name = Flutter;
  67 + sourceTree = "<group>";
  68 + };
  69 + 97C146E51CF9000F007C117D = {
  70 + isa = PBXGroup;
  71 + children = (
  72 + 9740EEB11CF90186004384FC /* Flutter */,
  73 + 97C146F01CF9000F007C117D /* Runner */,
  74 + 97C146EF1CF9000F007C117D /* Products */,
  75 + );
  76 + sourceTree = "<group>";
  77 + };
  78 + 97C146EF1CF9000F007C117D /* Products */ = {
  79 + isa = PBXGroup;
  80 + children = (
  81 + 97C146EE1CF9000F007C117D /* Runner.app */,
  82 + );
  83 + name = Products;
  84 + sourceTree = "<group>";
  85 + };
  86 + 97C146F01CF9000F007C117D /* Runner */ = {
  87 + isa = PBXGroup;
  88 + children = (
  89 + 97C146FA1CF9000F007C117D /* Main.storyboard */,
  90 + 97C146FD1CF9000F007C117D /* Assets.xcassets */,
  91 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
  92 + 97C147021CF9000F007C117D /* Info.plist */,
  93 + 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
  94 + 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
  95 + 74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
  96 + 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
  97 + );
  98 + path = Runner;
  99 + sourceTree = "<group>";
  100 + };
  101 +/* End PBXGroup section */
  102 +
  103 +/* Begin PBXNativeTarget section */
  104 + 97C146ED1CF9000F007C117D /* Runner */ = {
  105 + isa = PBXNativeTarget;
  106 + buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
  107 + buildPhases = (
  108 + 9740EEB61CF901F6004384FC /* Run Script */,
  109 + 97C146EA1CF9000F007C117D /* Sources */,
  110 + 97C146EB1CF9000F007C117D /* Frameworks */,
  111 + 97C146EC1CF9000F007C117D /* Resources */,
  112 + 9705A1C41CF9048500538489 /* Embed Frameworks */,
  113 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
  114 + );
  115 + buildRules = (
  116 + );
  117 + dependencies = (
  118 + );
  119 + name = Runner;
  120 + productName = Runner;
  121 + productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
  122 + productType = "com.apple.product-type.application";
  123 + };
  124 +/* End PBXNativeTarget section */
  125 +
  126 +/* Begin PBXProject section */
  127 + 97C146E61CF9000F007C117D /* Project object */ = {
  128 + isa = PBXProject;
  129 + attributes = {
  130 + LastUpgradeCheck = 1300;
  131 + ORGANIZATIONNAME = "";
  132 + TargetAttributes = {
  133 + 97C146ED1CF9000F007C117D = {
  134 + CreatedOnToolsVersion = 7.3.1;
  135 + LastSwiftMigration = 1100;
  136 + };
  137 + };
  138 + };
  139 + buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
  140 + compatibilityVersion = "Xcode 9.3";
  141 + developmentRegion = en;
  142 + hasScannedForEncodings = 0;
  143 + knownRegions = (
  144 + en,
  145 + Base,
  146 + );
  147 + mainGroup = 97C146E51CF9000F007C117D;
  148 + productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
  149 + projectDirPath = "";
  150 + projectRoot = "";
  151 + targets = (
  152 + 97C146ED1CF9000F007C117D /* Runner */,
  153 + );
  154 + };
  155 +/* End PBXProject section */
  156 +
  157 +/* Begin PBXResourcesBuildPhase section */
  158 + 97C146EC1CF9000F007C117D /* Resources */ = {
  159 + isa = PBXResourcesBuildPhase;
  160 + buildActionMask = 2147483647;
  161 + files = (
  162 + 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
  163 + 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
  164 + 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
  165 + 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
  166 + );
  167 + runOnlyForDeploymentPostprocessing = 0;
  168 + };
  169 +/* End PBXResourcesBuildPhase section */
  170 +
  171 +/* Begin PBXShellScriptBuildPhase section */
  172 + 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
  173 + isa = PBXShellScriptBuildPhase;
  174 + buildActionMask = 2147483647;
  175 + files = (
  176 + );
  177 + inputPaths = (
  178 + );
  179 + name = "Thin Binary";
  180 + outputPaths = (
  181 + );
  182 + runOnlyForDeploymentPostprocessing = 0;
  183 + shellPath = /bin/sh;
  184 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
  185 + };
  186 + 9740EEB61CF901F6004384FC /* Run Script */ = {
  187 + isa = PBXShellScriptBuildPhase;
  188 + buildActionMask = 2147483647;
  189 + files = (
  190 + );
  191 + inputPaths = (
  192 + );
  193 + name = "Run Script";
  194 + outputPaths = (
  195 + );
  196 + runOnlyForDeploymentPostprocessing = 0;
  197 + shellPath = /bin/sh;
  198 + shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
  199 + };
  200 +/* End PBXShellScriptBuildPhase section */
  201 +
  202 +/* Begin PBXSourcesBuildPhase section */
  203 + 97C146EA1CF9000F007C117D /* Sources */ = {
  204 + isa = PBXSourcesBuildPhase;
  205 + buildActionMask = 2147483647;
  206 + files = (
  207 + 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
  208 + 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
  209 + );
  210 + runOnlyForDeploymentPostprocessing = 0;
  211 + };
  212 +/* End PBXSourcesBuildPhase section */
  213 +
  214 +/* Begin PBXVariantGroup section */
  215 + 97C146FA1CF9000F007C117D /* Main.storyboard */ = {
  216 + isa = PBXVariantGroup;
  217 + children = (
  218 + 97C146FB1CF9000F007C117D /* Base */,
  219 + );
  220 + name = Main.storyboard;
  221 + sourceTree = "<group>";
  222 + };
  223 + 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
  224 + isa = PBXVariantGroup;
  225 + children = (
  226 + 97C147001CF9000F007C117D /* Base */,
  227 + );
  228 + name = LaunchScreen.storyboard;
  229 + sourceTree = "<group>";
  230 + };
  231 +/* End PBXVariantGroup section */
  232 +
  233 +/* Begin XCBuildConfiguration section */
  234 + 249021D3217E4FDB00AE95B9 /* Profile */ = {
  235 + isa = XCBuildConfiguration;
  236 + buildSettings = {
  237 + ALWAYS_SEARCH_USER_PATHS = NO;
  238 + CLANG_ANALYZER_NONNULL = YES;
  239 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  240 + CLANG_CXX_LIBRARY = "libc++";
  241 + CLANG_ENABLE_MODULES = YES;
  242 + CLANG_ENABLE_OBJC_ARC = YES;
  243 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  244 + CLANG_WARN_BOOL_CONVERSION = YES;
  245 + CLANG_WARN_COMMA = YES;
  246 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  247 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  248 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  249 + CLANG_WARN_EMPTY_BODY = YES;
  250 + CLANG_WARN_ENUM_CONVERSION = YES;
  251 + CLANG_WARN_INFINITE_RECURSION = YES;
  252 + CLANG_WARN_INT_CONVERSION = YES;
  253 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  254 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  255 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  256 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  257 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  258 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  259 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  260 + CLANG_WARN_UNREACHABLE_CODE = YES;
  261 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  262 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  263 + COPY_PHASE_STRIP = NO;
  264 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  265 + ENABLE_NS_ASSERTIONS = NO;
  266 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  267 + GCC_C_LANGUAGE_STANDARD = gnu99;
  268 + GCC_NO_COMMON_BLOCKS = YES;
  269 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  270 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  271 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  272 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  273 + GCC_WARN_UNUSED_FUNCTION = YES;
  274 + GCC_WARN_UNUSED_VARIABLE = YES;
  275 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
  276 + MTL_ENABLE_DEBUG_INFO = NO;
  277 + SDKROOT = iphoneos;
  278 + SUPPORTED_PLATFORMS = iphoneos;
  279 + TARGETED_DEVICE_FAMILY = "1,2";
  280 + VALIDATE_PRODUCT = YES;
  281 + };
  282 + name = Profile;
  283 + };
  284 + 249021D4217E4FDB00AE95B9 /* Profile */ = {
  285 + isa = XCBuildConfiguration;
  286 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  287 + buildSettings = {
  288 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  289 + CLANG_ENABLE_MODULES = YES;
  290 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  291 + ENABLE_BITCODE = NO;
  292 + INFOPLIST_FILE = Runner/Info.plist;
  293 + LD_RUNPATH_SEARCH_PATHS = (
  294 + "$(inherited)",
  295 + "@executable_path/Frameworks",
  296 + );
  297 + PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
  298 + PRODUCT_NAME = "$(TARGET_NAME)";
  299 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  300 + SWIFT_VERSION = 5.0;
  301 + VERSIONING_SYSTEM = "apple-generic";
  302 + };
  303 + name = Profile;
  304 + };
  305 + 97C147031CF9000F007C117D /* Debug */ = {
  306 + isa = XCBuildConfiguration;
  307 + buildSettings = {
  308 + ALWAYS_SEARCH_USER_PATHS = NO;
  309 + CLANG_ANALYZER_NONNULL = YES;
  310 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  311 + CLANG_CXX_LIBRARY = "libc++";
  312 + CLANG_ENABLE_MODULES = YES;
  313 + CLANG_ENABLE_OBJC_ARC = YES;
  314 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  315 + CLANG_WARN_BOOL_CONVERSION = YES;
  316 + CLANG_WARN_COMMA = YES;
  317 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  318 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  319 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  320 + CLANG_WARN_EMPTY_BODY = YES;
  321 + CLANG_WARN_ENUM_CONVERSION = YES;
  322 + CLANG_WARN_INFINITE_RECURSION = YES;
  323 + CLANG_WARN_INT_CONVERSION = YES;
  324 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  325 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  326 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  327 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  328 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  329 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  330 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  331 + CLANG_WARN_UNREACHABLE_CODE = YES;
  332 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  333 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  334 + COPY_PHASE_STRIP = NO;
  335 + DEBUG_INFORMATION_FORMAT = dwarf;
  336 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  337 + ENABLE_TESTABILITY = YES;
  338 + GCC_C_LANGUAGE_STANDARD = gnu99;
  339 + GCC_DYNAMIC_NO_PIC = NO;
  340 + GCC_NO_COMMON_BLOCKS = YES;
  341 + GCC_OPTIMIZATION_LEVEL = 0;
  342 + GCC_PREPROCESSOR_DEFINITIONS = (
  343 + "DEBUG=1",
  344 + "$(inherited)",
  345 + );
  346 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  347 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  348 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  349 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  350 + GCC_WARN_UNUSED_FUNCTION = YES;
  351 + GCC_WARN_UNUSED_VARIABLE = YES;
  352 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
  353 + MTL_ENABLE_DEBUG_INFO = YES;
  354 + ONLY_ACTIVE_ARCH = YES;
  355 + SDKROOT = iphoneos;
  356 + TARGETED_DEVICE_FAMILY = "1,2";
  357 + };
  358 + name = Debug;
  359 + };
  360 + 97C147041CF9000F007C117D /* Release */ = {
  361 + isa = XCBuildConfiguration;
  362 + buildSettings = {
  363 + ALWAYS_SEARCH_USER_PATHS = NO;
  364 + CLANG_ANALYZER_NONNULL = YES;
  365 + CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
  366 + CLANG_CXX_LIBRARY = "libc++";
  367 + CLANG_ENABLE_MODULES = YES;
  368 + CLANG_ENABLE_OBJC_ARC = YES;
  369 + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
  370 + CLANG_WARN_BOOL_CONVERSION = YES;
  371 + CLANG_WARN_COMMA = YES;
  372 + CLANG_WARN_CONSTANT_CONVERSION = YES;
  373 + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
  374 + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
  375 + CLANG_WARN_EMPTY_BODY = YES;
  376 + CLANG_WARN_ENUM_CONVERSION = YES;
  377 + CLANG_WARN_INFINITE_RECURSION = YES;
  378 + CLANG_WARN_INT_CONVERSION = YES;
  379 + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
  380 + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
  381 + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
  382 + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
  383 + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
  384 + CLANG_WARN_STRICT_PROTOTYPES = YES;
  385 + CLANG_WARN_SUSPICIOUS_MOVE = YES;
  386 + CLANG_WARN_UNREACHABLE_CODE = YES;
  387 + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
  388 + "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
  389 + COPY_PHASE_STRIP = NO;
  390 + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
  391 + ENABLE_NS_ASSERTIONS = NO;
  392 + ENABLE_STRICT_OBJC_MSGSEND = YES;
  393 + GCC_C_LANGUAGE_STANDARD = gnu99;
  394 + GCC_NO_COMMON_BLOCKS = YES;
  395 + GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
  396 + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
  397 + GCC_WARN_UNDECLARED_SELECTOR = YES;
  398 + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
  399 + GCC_WARN_UNUSED_FUNCTION = YES;
  400 + GCC_WARN_UNUSED_VARIABLE = YES;
  401 + IPHONEOS_DEPLOYMENT_TARGET = 9.0;
  402 + MTL_ENABLE_DEBUG_INFO = NO;
  403 + SDKROOT = iphoneos;
  404 + SUPPORTED_PLATFORMS = iphoneos;
  405 + SWIFT_COMPILATION_MODE = wholemodule;
  406 + SWIFT_OPTIMIZATION_LEVEL = "-O";
  407 + TARGETED_DEVICE_FAMILY = "1,2";
  408 + VALIDATE_PRODUCT = YES;
  409 + };
  410 + name = Release;
  411 + };
  412 + 97C147061CF9000F007C117D /* Debug */ = {
  413 + isa = XCBuildConfiguration;
  414 + baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
  415 + buildSettings = {
  416 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  417 + CLANG_ENABLE_MODULES = YES;
  418 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  419 + ENABLE_BITCODE = NO;
  420 + INFOPLIST_FILE = Runner/Info.plist;
  421 + LD_RUNPATH_SEARCH_PATHS = (
  422 + "$(inherited)",
  423 + "@executable_path/Frameworks",
  424 + );
  425 + PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
  426 + PRODUCT_NAME = "$(TARGET_NAME)";
  427 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  428 + SWIFT_OPTIMIZATION_LEVEL = "-Onone";
  429 + SWIFT_VERSION = 5.0;
  430 + VERSIONING_SYSTEM = "apple-generic";
  431 + };
  432 + name = Debug;
  433 + };
  434 + 97C147071CF9000F007C117D /* Release */ = {
  435 + isa = XCBuildConfiguration;
  436 + baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
  437 + buildSettings = {
  438 + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
  439 + CLANG_ENABLE_MODULES = YES;
  440 + CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
  441 + ENABLE_BITCODE = NO;
  442 + INFOPLIST_FILE = Runner/Info.plist;
  443 + LD_RUNPATH_SEARCH_PATHS = (
  444 + "$(inherited)",
  445 + "@executable_path/Frameworks",
  446 + );
  447 + PRODUCT_BUNDLE_IDENTIFIER = com.example.example;
  448 + PRODUCT_NAME = "$(TARGET_NAME)";
  449 + SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
  450 + SWIFT_VERSION = 5.0;
  451 + VERSIONING_SYSTEM = "apple-generic";
  452 + };
  453 + name = Release;
  454 + };
  455 +/* End XCBuildConfiguration section */
  456 +
  457 +/* Begin XCConfigurationList section */
  458 + 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
  459 + isa = XCConfigurationList;
  460 + buildConfigurations = (
  461 + 97C147031CF9000F007C117D /* Debug */,
  462 + 97C147041CF9000F007C117D /* Release */,
  463 + 249021D3217E4FDB00AE95B9 /* Profile */,
  464 + );
  465 + defaultConfigurationIsVisible = 0;
  466 + defaultConfigurationName = Release;
  467 + };
  468 + 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
  469 + isa = XCConfigurationList;
  470 + buildConfigurations = (
  471 + 97C147061CF9000F007C117D /* Debug */,
  472 + 97C147071CF9000F007C117D /* Release */,
  473 + 249021D4217E4FDB00AE95B9 /* Profile */,
  474 + );
  475 + defaultConfigurationIsVisible = 0;
  476 + defaultConfigurationName = Release;
  477 + };
  478 +/* End XCConfigurationList section */
  479 + };
  480 + rootObject = 97C146E61CF9000F007C117D /* Project object */;
  481 +}
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "self:">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Scheme
  3 + LastUpgradeVersion = "1300"
  4 + version = "1.3">
  5 + <BuildAction
  6 + parallelizeBuildables = "YES"
  7 + buildImplicitDependencies = "YES">
  8 + <BuildActionEntries>
  9 + <BuildActionEntry
  10 + buildForTesting = "YES"
  11 + buildForRunning = "YES"
  12 + buildForProfiling = "YES"
  13 + buildForArchiving = "YES"
  14 + buildForAnalyzing = "YES">
  15 + <BuildableReference
  16 + BuildableIdentifier = "primary"
  17 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  18 + BuildableName = "Runner.app"
  19 + BlueprintName = "Runner"
  20 + ReferencedContainer = "container:Runner.xcodeproj">
  21 + </BuildableReference>
  22 + </BuildActionEntry>
  23 + </BuildActionEntries>
  24 + </BuildAction>
  25 + <TestAction
  26 + buildConfiguration = "Debug"
  27 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  28 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  29 + shouldUseLaunchSchemeArgsEnv = "YES">
  30 + <MacroExpansion>
  31 + <BuildableReference
  32 + BuildableIdentifier = "primary"
  33 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  34 + BuildableName = "Runner.app"
  35 + BlueprintName = "Runner"
  36 + ReferencedContainer = "container:Runner.xcodeproj">
  37 + </BuildableReference>
  38 + </MacroExpansion>
  39 + <Testables>
  40 + </Testables>
  41 + </TestAction>
  42 + <LaunchAction
  43 + buildConfiguration = "Debug"
  44 + selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
  45 + selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
  46 + launchStyle = "0"
  47 + useCustomWorkingDirectory = "NO"
  48 + ignoresPersistentStateOnLaunch = "NO"
  49 + debugDocumentVersioning = "YES"
  50 + debugServiceExtension = "internal"
  51 + allowLocationSimulation = "YES">
  52 + <BuildableProductRunnable
  53 + runnableDebuggingMode = "0">
  54 + <BuildableReference
  55 + BuildableIdentifier = "primary"
  56 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  57 + BuildableName = "Runner.app"
  58 + BlueprintName = "Runner"
  59 + ReferencedContainer = "container:Runner.xcodeproj">
  60 + </BuildableReference>
  61 + </BuildableProductRunnable>
  62 + </LaunchAction>
  63 + <ProfileAction
  64 + buildConfiguration = "Profile"
  65 + shouldUseLaunchSchemeArgsEnv = "YES"
  66 + savedToolIdentifier = ""
  67 + useCustomWorkingDirectory = "NO"
  68 + debugDocumentVersioning = "YES">
  69 + <BuildableProductRunnable
  70 + runnableDebuggingMode = "0">
  71 + <BuildableReference
  72 + BuildableIdentifier = "primary"
  73 + BlueprintIdentifier = "97C146ED1CF9000F007C117D"
  74 + BuildableName = "Runner.app"
  75 + BlueprintName = "Runner"
  76 + ReferencedContainer = "container:Runner.xcodeproj">
  77 + </BuildableReference>
  78 + </BuildableProductRunnable>
  79 + </ProfileAction>
  80 + <AnalyzeAction
  81 + buildConfiguration = "Debug">
  82 + </AnalyzeAction>
  83 + <ArchiveAction
  84 + buildConfiguration = "Release"
  85 + revealArchiveInOrganizer = "YES">
  86 + </ArchiveAction>
  87 +</Scheme>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<Workspace
  3 + version = "1.0">
  4 + <FileRef
  5 + location = "group:Runner.xcodeproj">
  6 + </FileRef>
  7 +</Workspace>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>IDEDidComputeMac32BitWarning</key>
  6 + <true/>
  7 +</dict>
  8 +</plist>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>PreviewsEnabled</key>
  6 + <false/>
  7 +</dict>
  8 +</plist>
  1 +import UIKit
  2 +import Flutter
  3 +
  4 +@UIApplicationMain
  5 +@objc class AppDelegate: FlutterAppDelegate {
  6 + override func application(
  7 + _ application: UIApplication,
  8 + didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  9 + ) -> Bool {
  10 + GeneratedPluginRegistrant.register(with: self)
  11 + return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  12 + }
  13 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "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 +}
  1 +{
  2 + "images" : [
  3 + {
  4 + "idiom" : "universal",
  5 + "filename" : "LaunchImage.png",
  6 + "scale" : "1x"
  7 + },
  8 + {
  9 + "idiom" : "universal",
  10 + "filename" : "LaunchImage@2x.png",
  11 + "scale" : "2x"
  12 + },
  13 + {
  14 + "idiom" : "universal",
  15 + "filename" : "LaunchImage@3x.png",
  16 + "scale" : "3x"
  17 + }
  18 + ],
  19 + "info" : {
  20 + "version" : 1,
  21 + "author" : "xcode"
  22 + }
  23 +}
  1 +# Launch Screen Assets
  2 +
  3 +You can customize the launch screen with your own desired assets by replacing the image files in this directory.
  4 +
  5 +You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images.
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="12121" systemVersion="16G29" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="12089"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--View Controller-->
  9 + <scene sceneID="EHf-IW-A2E">
  10 + <objects>
  11 + <viewController id="01J-lp-oVM" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="Ydg-fD-yQy"/>
  14 + <viewControllerLayoutGuide type="bottom" id="xbc-2k-c8Z"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
  17 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  18 + <subviews>
  19 + <imageView opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" image="LaunchImage" translatesAutoresizingMaskIntoConstraints="NO" id="YRO-k0-Ey4">
  20 + </imageView>
  21 + </subviews>
  22 + <color key="backgroundColor" red="1" green="1" blue="1" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
  23 + <constraints>
  24 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerX" secondItem="Ze5-6b-2t3" secondAttribute="centerX" id="1a2-6s-vTC"/>
  25 + <constraint firstItem="YRO-k0-Ey4" firstAttribute="centerY" secondItem="Ze5-6b-2t3" secondAttribute="centerY" id="4X2-HB-R7a"/>
  26 + </constraints>
  27 + </view>
  28 + </viewController>
  29 + <placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>
  30 + </objects>
  31 + <point key="canvasLocation" x="53" y="375"/>
  32 + </scene>
  33 + </scenes>
  34 + <resources>
  35 + <image name="LaunchImage" width="168" height="185"/>
  36 + </resources>
  37 +</document>
  1 +<?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2 +<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="10117" systemVersion="15F34" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" initialViewController="BYZ-38-t0r">
  3 + <dependencies>
  4 + <deployment identifier="iOS"/>
  5 + <plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="10085"/>
  6 + </dependencies>
  7 + <scenes>
  8 + <!--Flutter View Controller-->
  9 + <scene sceneID="tne-QT-ifu">
  10 + <objects>
  11 + <viewController id="BYZ-38-t0r" customClass="FlutterViewController" sceneMemberID="viewController">
  12 + <layoutGuides>
  13 + <viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
  14 + <viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
  15 + </layoutGuides>
  16 + <view key="view" contentMode="scaleToFill" id="8bC-Xf-vdC">
  17 + <rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
  18 + <autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
  19 + <color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
  20 + </view>
  21 + </viewController>
  22 + <placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
  23 + </objects>
  24 + </scene>
  25 + </scenes>
  26 +</document>
  1 +<?xml version="1.0" encoding="UTF-8"?>
  2 +<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  3 +<plist version="1.0">
  4 +<dict>
  5 + <key>CFBundleDevelopmentRegion</key>
  6 + <string>$(DEVELOPMENT_LANGUAGE)</string>
  7 + <key>CFBundleDisplayName</key>
  8 + <string>Example</string>
  9 + <key>CFBundleExecutable</key>
  10 + <string>$(EXECUTABLE_NAME)</string>
  11 + <key>CFBundleIdentifier</key>
  12 + <string>$(PRODUCT_BUNDLE_IDENTIFIER)</string>
  13 + <key>CFBundleInfoDictionaryVersion</key>
  14 + <string>6.0</string>
  15 + <key>CFBundleName</key>
  16 + <string>example</string>
  17 + <key>CFBundlePackageType</key>
  18 + <string>APPL</string>
  19 + <key>CFBundleShortVersionString</key>
  20 + <string>$(FLUTTER_BUILD_NAME)</string>
  21 + <key>CFBundleSignature</key>
  22 + <string>????</string>
  23 + <key>CFBundleVersion</key>
  24 + <string>$(FLUTTER_BUILD_NUMBER)</string>
  25 + <key>LSRequiresIPhoneOS</key>
  26 + <true/>
  27 + <key>UILaunchStoryboardName</key>
  28 + <string>LaunchScreen</string>
  29 + <key>UIMainStoryboardFile</key>
  30 + <string>Main</string>
  31 + <key>UISupportedInterfaceOrientations</key>
  32 + <array>
  33 + <string>UIInterfaceOrientationPortrait</string>
  34 + <string>UIInterfaceOrientationLandscapeLeft</string>
  35 + <string>UIInterfaceOrientationLandscapeRight</string>
  36 + </array>
  37 + <key>UISupportedInterfaceOrientations~ipad</key>
  38 + <array>
  39 + <string>UIInterfaceOrientationPortrait</string>
  40 + <string>UIInterfaceOrientationPortraitUpsideDown</string>
  41 + <string>UIInterfaceOrientationLandscapeLeft</string>
  42 + <string>UIInterfaceOrientationLandscapeRight</string>
  43 + </array>
  44 + <key>UIViewControllerBasedStatusBarAppearance</key>
  45 + <false/>
  46 + <key>CADisableMinimumFrameDurationOnPhone</key>
  47 + <true/>
  48 +</dict>
  49 +</plist>
  1 +import 'dart:async';
  2 +import 'dart:io';
  3 +
  4 +import 'package:flutter/material.dart';
  5 +import 'package:open_filex/open_filex.dart';
  6 +import 'package:permission_handler/permission_handler.dart';
  7 +import 'package:flutter_document_picker/flutter_document_picker.dart';
  8 +
  9 +void main() => runApp(const MyApp());
  10 +
  11 +class MyApp extends StatefulWidget {
  12 + const MyApp({Key? key}) : super(key: key);
  13 +
  14 + @override
  15 + MyAppState createState() => MyAppState();
  16 +}
  17 +
  18 +class MyAppState extends State<MyApp> {
  19 + var _openResult = 'Unknown';
  20 +
  21 + Future<void> openFile() async {
  22 + if (Platform.isLinux) {
  23 + _openLinuxFile();
  24 + } else if (Platform.isAndroid) {
  25 + _openAndroidExternalImage();
  26 + } else if (Platform.isWindows) {
  27 + _openWindowsFile();
  28 + } else if (Platform.isMacOS) {
  29 + _openMacOsFile();
  30 + } else if (Platform.operatingSystem == 'ohos') {
  31 + _openOHOSFile();
  32 + }
  33 + }
  34 +
  35 + _openOHOSFile() async {
  36 + // OpenFilex.open 需要传入有权限访问的文件地址才能访问,比如应用沙箱路径下的文件
  37 + // 这里使用了其它三方库来自定义选取文件做功能展示
  38 + String? path = await FlutterDocumentPicker.openDocument();
  39 + if (path != null) {
  40 + String filePath = "file://com.crazecoder.openfile.example$path";
  41 + final result = await OpenFilex.open(filePath);
  42 + setState(() {
  43 + _openResult = "type=${result.type} message=${result.message}";
  44 + });
  45 + } else {
  46 + setState(() {
  47 + _openResult = "User canceled the picker";
  48 + });
  49 + }
  50 + }
  51 +
  52 + _openMacOsFile() async {
  53 + final result = await OpenFilex.open("/Downloads/flutter.png");
  54 + setState(() {
  55 + _openResult = "type=${result.type} message=${result.message}";
  56 + });
  57 + }
  58 +
  59 + _openWindowsFile() async {
  60 + final result = await OpenFilex.open("C:/Users/Lion/Downloads/flutter.png");
  61 + setState(() {
  62 + _openResult = "type=${result.type} message=${result.message}";
  63 + });
  64 + }
  65 +
  66 + _openLinuxFile() async {
  67 + final result = await OpenFilex.open("/home/mehdi/Downloads/flutter.jpg");
  68 + setState(() {
  69 + _openResult = "type=${result.type} message=${result.message}";
  70 + });
  71 + }
  72 +
  73 + // ignore: unused_element
  74 + _openIOSFile() async {
  75 + final result = await OpenFilex.open("some path in your iOS device");
  76 + setState(() {
  77 + _openResult = "type=${result.type} message=${result.message}";
  78 + });
  79 + }
  80 +
  81 + // ignore: unused_element
  82 + _openAndroidPrivateFile() async {
  83 + //open an app private storage file
  84 + final result = await OpenFilex.open(
  85 + "/data/data/YOUR_PACKAGE_NAME/cache/IMG20230610192318.jpg");
  86 + setState(() {
  87 + _openResult = "type=${result.type} message=${result.message}";
  88 + });
  89 + }
  90 +
  91 + // ignore: unused_element
  92 + _openAndroidOtherAppFile() async {
  93 + //open an external storage image file on android 13
  94 + if (await Permission.manageExternalStorage.request().isGranted) {
  95 + final result = await OpenFilex.open("/data/user/0/xxx/images/1.jpg");
  96 + setState(() {
  97 + _openResult = "type=${result.type} message=${result.message}";
  98 + });
  99 + }
  100 + }
  101 +
  102 + // ignore: unused_element
  103 + _openAndroidExternalImage() async {
  104 + //open an external storage image file on android 13
  105 + if (await Permission.photos.request().isGranted) {
  106 + final result = await OpenFilex.open("/sdcard/Download/flutter.png");
  107 + setState(() {
  108 + _openResult = "type=${result.type} message=${result.message}";
  109 + });
  110 + }
  111 + }
  112 +
  113 + // ignore: unused_element
  114 + _openAndroidExternalVideo() async {
  115 + //open an external storage video file on android 13
  116 + if (await Permission.videos.request().isGranted) {
  117 + final result = await OpenFilex.open("/sdcard/Download/R-C.mp4");
  118 + setState(() {
  119 + _openResult = "type=${result.type} message=${result.message}";
  120 + });
  121 + }
  122 + }
  123 +
  124 + // ignore: unused_element
  125 + _openAndroidExternalAudio() async {
  126 + //open an external storage audio file on android 13
  127 + if (await Permission.audio.request().isGranted) {
  128 + final result = await OpenFilex.open("/sdcard/Download/R-C.mp3");
  129 + setState(() {
  130 + _openResult = "type=${result.type} message=${result.message}";
  131 + });
  132 + }
  133 + }
  134 +
  135 + // ignore: unused_element
  136 + _openAndroidExternalFile() async {
  137 + //open an external storage file
  138 + if (await Permission.manageExternalStorage.request().isGranted) {
  139 + final result = await OpenFilex.open("/sdcard/Android/data/R-C.xml");
  140 + setState(() {
  141 + _openResult = "type=${result.type} message=${result.message}";
  142 + });
  143 + }
  144 + }
  145 +
  146 + @override
  147 + Widget build(BuildContext context) {
  148 + return MaterialApp(
  149 + home: Scaffold(
  150 + appBar: AppBar(
  151 + title: const Text('Plugin example app'),
  152 + ),
  153 + body: Center(
  154 + child: Column(
  155 + mainAxisAlignment: MainAxisAlignment.center,
  156 + children: <Widget>[
  157 + Text('open result: $_openResult\n'),
  158 + TextButton(
  159 + onPressed: openFile,
  160 + child: const Text('Tap to open file'),
  161 + ),
  162 + ],
  163 + ),
  164 + ),
  165 + ),
  166 + );
  167 + }
  168 +}
  1 +# Project-level configuration.
  2 +cmake_minimum_required(VERSION 3.10)
  3 +project(runner LANGUAGES CXX)
  4 +
  5 +# The name of the executable created for the application. Change this to change
  6 +# the on-disk name of your application.
  7 +set(BINARY_NAME "example")
  8 +# The unique GTK application identifier for this application. See:
  9 +# https://wiki.gnome.org/HowDoI/ChooseApplicationID
  10 +set(APPLICATION_ID "com.example.example")
  11 +
  12 +# Explicitly opt in to modern CMake behaviors to avoid warnings with recent
  13 +# versions of CMake.
  14 +cmake_policy(SET CMP0063 NEW)
  15 +
  16 +# Load bundled libraries from the lib/ directory relative to the binary.
  17 +set(CMAKE_INSTALL_RPATH "$ORIGIN/lib")
  18 +
  19 +# Root filesystem for cross-building.
  20 +if(FLUTTER_TARGET_PLATFORM_SYSROOT)
  21 + set(CMAKE_SYSROOT ${FLUTTER_TARGET_PLATFORM_SYSROOT})
  22 + set(CMAKE_FIND_ROOT_PATH ${CMAKE_SYSROOT})
  23 + set(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
  24 + set(CMAKE_FIND_ROOT_PATH_MODE_PACKAGE ONLY)
  25 + set(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
  26 + set(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
  27 +endif()
  28 +
  29 +# Define build configuration options.
  30 +if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
  31 + set(CMAKE_BUILD_TYPE "Debug" CACHE
  32 + STRING "Flutter build mode" FORCE)
  33 + set_property(CACHE CMAKE_BUILD_TYPE PROPERTY STRINGS
  34 + "Debug" "Profile" "Release")
  35 +endif()
  36 +
  37 +# Compilation settings that should be applied to most targets.
  38 +#
  39 +# Be cautious about adding new options here, as plugins use this function by
  40 +# default. In most cases, you should add new options to specific targets instead
  41 +# of modifying this function.
  42 +function(APPLY_STANDARD_SETTINGS TARGET)
  43 + target_compile_features(${TARGET} PUBLIC cxx_std_14)
  44 + target_compile_options(${TARGET} PRIVATE -Wall -Werror)
  45 + target_compile_options(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:-O3>")
  46 + target_compile_definitions(${TARGET} PRIVATE "$<$<NOT:$<CONFIG:Debug>>:NDEBUG>")
  47 +endfunction()
  48 +
  49 +# Flutter library and tool build rules.
  50 +set(FLUTTER_MANAGED_DIR "${CMAKE_CURRENT_SOURCE_DIR}/flutter")
  51 +add_subdirectory(${FLUTTER_MANAGED_DIR})
  52 +
  53 +# System-level dependencies.
  54 +find_package(PkgConfig REQUIRED)
  55 +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
  56 +
  57 +add_definitions(-DAPPLICATION_ID="${APPLICATION_ID}")
  58 +
  59 +# Define the application target. To change its name, change BINARY_NAME above,
  60 +# not the value here, or `flutter run` will no longer work.
  61 +#
  62 +# Any new source files that you add to the application should be added here.
  63 +add_executable(${BINARY_NAME}
  64 + "main.cc"
  65 + "my_application.cc"
  66 + "${FLUTTER_MANAGED_DIR}/generated_plugin_registrant.cc"
  67 +)
  68 +
  69 +# Apply the standard set of build settings. This can be removed for applications
  70 +# that need different build settings.
  71 +apply_standard_settings(${BINARY_NAME})
  72 +
  73 +# Add dependency libraries. Add any application-specific dependencies here.
  74 +target_link_libraries(${BINARY_NAME} PRIVATE flutter)
  75 +target_link_libraries(${BINARY_NAME} PRIVATE PkgConfig::GTK)
  76 +
  77 +# Run the Flutter tool portions of the build. This must not be removed.
  78 +add_dependencies(${BINARY_NAME} flutter_assemble)
  79 +
  80 +# Only the install-generated bundle's copy of the executable will launch
  81 +# correctly, since the resources must in the right relative locations. To avoid
  82 +# people trying to run the unbundled copy, put it in a subdirectory instead of
  83 +# the default top-level location.
  84 +set_target_properties(${BINARY_NAME}
  85 + PROPERTIES
  86 + RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/intermediates_do_not_run"
  87 +)
  88 +
  89 +# Generated plugin build rules, which manage building the plugins and adding
  90 +# them to the application.
  91 +include(flutter/generated_plugins.cmake)
  92 +
  93 +
  94 +# === Installation ===
  95 +# By default, "installing" just makes a relocatable bundle in the build
  96 +# directory.
  97 +set(BUILD_BUNDLE_DIR "${PROJECT_BINARY_DIR}/bundle")
  98 +if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
  99 + set(CMAKE_INSTALL_PREFIX "${BUILD_BUNDLE_DIR}" CACHE PATH "..." FORCE)
  100 +endif()
  101 +
  102 +# Start with a clean build bundle directory every time.
  103 +install(CODE "
  104 + file(REMOVE_RECURSE \"${BUILD_BUNDLE_DIR}/\")
  105 + " COMPONENT Runtime)
  106 +
  107 +set(INSTALL_BUNDLE_DATA_DIR "${CMAKE_INSTALL_PREFIX}/data")
  108 +set(INSTALL_BUNDLE_LIB_DIR "${CMAKE_INSTALL_PREFIX}/lib")
  109 +
  110 +install(TARGETS ${BINARY_NAME} RUNTIME DESTINATION "${CMAKE_INSTALL_PREFIX}"
  111 + COMPONENT Runtime)
  112 +
  113 +install(FILES "${FLUTTER_ICU_DATA_FILE}" DESTINATION "${INSTALL_BUNDLE_DATA_DIR}"
  114 + COMPONENT Runtime)
  115 +
  116 +install(FILES "${FLUTTER_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
  117 + COMPONENT Runtime)
  118 +
  119 +foreach(bundled_library ${PLUGIN_BUNDLED_LIBRARIES})
  120 + install(FILES "${bundled_library}"
  121 + DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
  122 + COMPONENT Runtime)
  123 +endforeach(bundled_library)
  124 +
  125 +# Fully re-copy the assets directory on each build to avoid having stale files
  126 +# from a previous install.
  127 +set(FLUTTER_ASSET_DIR_NAME "flutter_assets")
  128 +install(CODE "
  129 + file(REMOVE_RECURSE \"${INSTALL_BUNDLE_DATA_DIR}/${FLUTTER_ASSET_DIR_NAME}\")
  130 + " COMPONENT Runtime)
  131 +install(DIRECTORY "${PROJECT_BUILD_DIR}/${FLUTTER_ASSET_DIR_NAME}"
  132 + DESTINATION "${INSTALL_BUNDLE_DATA_DIR}" COMPONENT Runtime)
  133 +
  134 +# Install the AOT library on non-Debug builds only.
  135 +if(NOT CMAKE_BUILD_TYPE MATCHES "Debug")
  136 + install(FILES "${AOT_LIBRARY}" DESTINATION "${INSTALL_BUNDLE_LIB_DIR}"
  137 + COMPONENT Runtime)
  138 +endif()
  1 +# This file controls Flutter-level build steps. It should not be edited.
  2 +cmake_minimum_required(VERSION 3.10)
  3 +
  4 +set(EPHEMERAL_DIR "${CMAKE_CURRENT_SOURCE_DIR}/ephemeral")
  5 +
  6 +# Configuration provided via flutter tool.
  7 +include(${EPHEMERAL_DIR}/generated_config.cmake)
  8 +
  9 +# TODO: Move the rest of this into files in ephemeral. See
  10 +# https://github.com/flutter/flutter/issues/57146.
  11 +
  12 +# Serves the same purpose as list(TRANSFORM ... PREPEND ...),
  13 +# which isn't available in 3.10.
  14 +function(list_prepend LIST_NAME PREFIX)
  15 + set(NEW_LIST "")
  16 + foreach(element ${${LIST_NAME}})
  17 + list(APPEND NEW_LIST "${PREFIX}${element}")
  18 + endforeach(element)
  19 + set(${LIST_NAME} "${NEW_LIST}" PARENT_SCOPE)
  20 +endfunction()
  21 +
  22 +# === Flutter Library ===
  23 +# System-level dependencies.
  24 +find_package(PkgConfig REQUIRED)
  25 +pkg_check_modules(GTK REQUIRED IMPORTED_TARGET gtk+-3.0)
  26 +pkg_check_modules(GLIB REQUIRED IMPORTED_TARGET glib-2.0)
  27 +pkg_check_modules(GIO REQUIRED IMPORTED_TARGET gio-2.0)
  28 +
  29 +set(FLUTTER_LIBRARY "${EPHEMERAL_DIR}/libflutter_linux_gtk.so")
  30 +
  31 +# Published to parent scope for install step.
  32 +set(FLUTTER_LIBRARY ${FLUTTER_LIBRARY} PARENT_SCOPE)
  33 +set(FLUTTER_ICU_DATA_FILE "${EPHEMERAL_DIR}/icudtl.dat" PARENT_SCOPE)
  34 +set(PROJECT_BUILD_DIR "${PROJECT_DIR}/build/" PARENT_SCOPE)
  35 +set(AOT_LIBRARY "${PROJECT_DIR}/build/lib/libapp.so" PARENT_SCOPE)
  36 +
  37 +list(APPEND FLUTTER_LIBRARY_HEADERS
  38 + "fl_basic_message_channel.h"
  39 + "fl_binary_codec.h"
  40 + "fl_binary_messenger.h"
  41 + "fl_dart_project.h"
  42 + "fl_engine.h"
  43 + "fl_json_message_codec.h"
  44 + "fl_json_method_codec.h"
  45 + "fl_message_codec.h"
  46 + "fl_method_call.h"
  47 + "fl_method_channel.h"
  48 + "fl_method_codec.h"
  49 + "fl_method_response.h"
  50 + "fl_plugin_registrar.h"
  51 + "fl_plugin_registry.h"
  52 + "fl_standard_message_codec.h"
  53 + "fl_standard_method_codec.h"
  54 + "fl_string_codec.h"
  55 + "fl_value.h"
  56 + "fl_view.h"
  57 + "flutter_linux.h"
  58 +)
  59 +list_prepend(FLUTTER_LIBRARY_HEADERS "${EPHEMERAL_DIR}/flutter_linux/")
  60 +add_library(flutter INTERFACE)
  61 +target_include_directories(flutter INTERFACE
  62 + "${EPHEMERAL_DIR}"
  63 +)
  64 +target_link_libraries(flutter INTERFACE "${FLUTTER_LIBRARY}")
  65 +target_link_libraries(flutter INTERFACE
  66 + PkgConfig::GTK
  67 + PkgConfig::GLIB
  68 + PkgConfig::GIO
  69 +)
  70 +add_dependencies(flutter flutter_assemble)
  71 +
  72 +# === Flutter tool backend ===
  73 +# _phony_ is a non-existent file to force this command to run every time,
  74 +# since currently there's no way to get a full input/output list from the
  75 +# flutter tool.
  76 +add_custom_command(
  77 + OUTPUT ${FLUTTER_LIBRARY} ${FLUTTER_LIBRARY_HEADERS}
  78 + ${CMAKE_CURRENT_BINARY_DIR}/_phony_
  79 + COMMAND ${CMAKE_COMMAND} -E env
  80 + ${FLUTTER_TOOL_ENVIRONMENT}
  81 + "${FLUTTER_ROOT}/packages/flutter_tools/bin/tool_backend.sh"
  82 + ${FLUTTER_TARGET_PLATFORM} ${CMAKE_BUILD_TYPE}
  83 + VERBATIM
  84 +)
  85 +add_custom_target(flutter_assemble DEPENDS
  86 + "${FLUTTER_LIBRARY}"
  87 + ${FLUTTER_LIBRARY_HEADERS}
  88 +)
  1 +//
  2 +// Generated file. Do not edit.
  3 +//
  4 +
  5 +// clang-format off
  6 +
  7 +#include "generated_plugin_registrant.h"
  8 +
  9 +
  10 +void fl_register_plugins(FlPluginRegistry* registry) {
  11 +}
  1 +//
  2 +// Generated file. Do not edit.
  3 +//
  4 +
  5 +// clang-format off
  6 +
  7 +#ifndef GENERATED_PLUGIN_REGISTRANT_
  8 +#define GENERATED_PLUGIN_REGISTRANT_
  9 +
  10 +#include <flutter_linux/flutter_linux.h>
  11 +
  12 +// Registers Flutter plugins.
  13 +void fl_register_plugins(FlPluginRegistry* registry);
  14 +
  15 +#endif // GENERATED_PLUGIN_REGISTRANT_
  1 +#
  2 +# Generated file, do not edit.
  3 +#
  4 +
  5 +list(APPEND FLUTTER_PLUGIN_LIST
  6 +)
  7 +
  8 +list(APPEND FLUTTER_FFI_PLUGIN_LIST
  9 +)
  10 +
  11 +set(PLUGIN_BUNDLED_LIBRARIES)
  12 +
  13 +foreach(plugin ${FLUTTER_PLUGIN_LIST})
  14 + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${plugin}/linux plugins/${plugin})
  15 + target_link_libraries(${BINARY_NAME} PRIVATE ${plugin}_plugin)
  16 + list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
  17 + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
  18 +endforeach(plugin)
  19 +
  20 +foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
  21 + add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
  22 + list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
  23 +endforeach(ffi_plugin)
  1 +#include "my_application.h"
  2 +
  3 +int main(int argc, char** argv) {
  4 + g_autoptr(MyApplication) app = my_application_new();
  5 + return g_application_run(G_APPLICATION(app), argc, argv);
  6 +}
  1 +#include "my_application.h"
  2 +
  3 +#include <flutter_linux/flutter_linux.h>
  4 +#ifdef GDK_WINDOWING_X11
  5 +#include <gdk/gdkx.h>
  6 +#endif
  7 +
  8 +#include "flutter/generated_plugin_registrant.h"
  9 +
  10 +struct _MyApplication {
  11 + GtkApplication parent_instance;
  12 + char** dart_entrypoint_arguments;
  13 +};
  14 +
  15 +G_DEFINE_TYPE(MyApplication, my_application, GTK_TYPE_APPLICATION)
  16 +
  17 +// Implements GApplication::activate.
  18 +static void my_application_activate(GApplication* application) {
  19 + MyApplication* self = MY_APPLICATION(application);
  20 + GtkWindow* window =
  21 + GTK_WINDOW(gtk_application_window_new(GTK_APPLICATION(application)));
  22 +
  23 + // Use a header bar when running in GNOME as this is the common style used
  24 + // by applications and is the setup most users will be using (e.g. Ubuntu
  25 + // desktop).
  26 + // If running on X and not using GNOME then just use a traditional title bar
  27 + // in case the window manager does more exotic layout, e.g. tiling.
  28 + // If running on Wayland assume the header bar will work (may need changing
  29 + // if future cases occur).
  30 + gboolean use_header_bar = TRUE;
  31 +#ifdef GDK_WINDOWING_X11
  32 + GdkScreen* screen = gtk_window_get_screen(window);
  33 + if (GDK_IS_X11_SCREEN(screen)) {
  34 + const gchar* wm_name = gdk_x11_screen_get_window_manager_name(screen);
  35 + if (g_strcmp0(wm_name, "GNOME Shell") != 0) {
  36 + use_header_bar = FALSE;
  37 + }
  38 + }
  39 +#endif
  40 + if (use_header_bar) {
  41 + GtkHeaderBar* header_bar = GTK_HEADER_BAR(gtk_header_bar_new());
  42 + gtk_widget_show(GTK_WIDGET(header_bar));
  43 + gtk_header_bar_set_title(header_bar, "example");
  44 + gtk_header_bar_set_show_close_button(header_bar, TRUE);
  45 + gtk_window_set_titlebar(window, GTK_WIDGET(header_bar));
  46 + } else {
  47 + gtk_window_set_title(window, "example");
  48 + }
  49 +
  50 + gtk_window_set_default_size(window, 1280, 720);
  51 + gtk_widget_show(GTK_WIDGET(window));
  52 +
  53 + g_autoptr(FlDartProject) project = fl_dart_project_new();
  54 + fl_dart_project_set_dart_entrypoint_arguments(project, self->dart_entrypoint_arguments);
  55 +
  56 + FlView* view = fl_view_new(project);
  57 + gtk_widget_show(GTK_WIDGET(view));
  58 + gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(view));
  59 +
  60 + fl_register_plugins(FL_PLUGIN_REGISTRY(view));
  61 +
  62 + gtk_widget_grab_focus(GTK_WIDGET(view));
  63 +}
  64 +
  65 +// Implements GApplication::local_command_line.
  66 +static gboolean my_application_local_command_line(GApplication* application, gchar*** arguments, int* exit_status) {
  67 + MyApplication* self = MY_APPLICATION(application);
  68 + // Strip out the first argument as it is the binary name.
  69 + self->dart_entrypoint_arguments = g_strdupv(*arguments + 1);
  70 +
  71 + g_autoptr(GError) error = nullptr;
  72 + if (!g_application_register(application, nullptr, &error)) {
  73 + g_warning("Failed to register: %s", error->message);
  74 + *exit_status = 1;
  75 + return TRUE;
  76 + }
  77 +
  78 + g_application_activate(application);
  79 + *exit_status = 0;
  80 +
  81 + return TRUE;
  82 +}
  83 +
  84 +// Implements GObject::dispose.
  85 +static void my_application_dispose(GObject* object) {
  86 + MyApplication* self = MY_APPLICATION(object);
  87 + g_clear_pointer(&self->dart_entrypoint_arguments, g_strfreev);
  88 + G_OBJECT_CLASS(my_application_parent_class)->dispose(object);
  89 +}
  90 +
  91 +static void my_application_class_init(MyApplicationClass* klass) {
  92 + G_APPLICATION_CLASS(klass)->activate = my_application_activate;
  93 + G_APPLICATION_CLASS(klass)->local_command_line = my_application_local_command_line;
  94 + G_OBJECT_CLASS(klass)->dispose = my_application_dispose;
  95 +}
  96 +
  97 +static void my_application_init(MyApplication* self) {}
  98 +
  99 +MyApplication* my_application_new() {
  100 + return MY_APPLICATION(g_object_new(my_application_get_type(),
  101 + "application-id", APPLICATION_ID,
  102 + "flags", G_APPLICATION_NON_UNIQUE,
  103 + nullptr));
  104 +}
  1 +#ifndef FLUTTER_MY_APPLICATION_H_
  2 +#define FLUTTER_MY_APPLICATION_H_
  3 +
  4 +#include <gtk/gtk.h>
  5 +
  6 +G_DECLARE_FINAL_TYPE(MyApplication, my_application, MY, APPLICATION,
  7 + GtkApplication)
  8 +
  9 +/**
  10 + * my_application_new:
  11 + *
  12 + * Creates a new Flutter-based application.
  13 + *
  14 + * Returns: a new #MyApplication.
  15 + */
  16 +MyApplication* my_application_new();
  17 +
  18 +#endif // FLUTTER_MY_APPLICATION_H_
  1 +# Flutter-related
  2 +**/Flutter/ephemeral/
  3 +**/Pods/
  4 +
  5 +# Xcode-related
  6 +**/dgph
  7 +**/xcuserdata/
  1 +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
  2 +#include "ephemeral/Flutter-Generated.xcconfig"
  1 +#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
  2 +#include "ephemeral/Flutter-Generated.xcconfig"
  1 +//
  2 +// Generated file. Do not edit.
  3 +//
  4 +
  5 +import FlutterMacOS
  6 +import Foundation
  7 +
  8 +
  9 +func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
  10 +}