Browse Source

增加多Flavor打包;

maqiang 7 months ago
parent
commit
73229f56e3

+ 5 - 25
README.md

@@ -15,28 +15,8 @@ For help getting started with Flutter development, view the
15
 [online documentation](https://docs.flutter.dev/), which offers tutorials,
15
 [online documentation](https://docs.flutter.dev/), which offers tutorials,
16
 samples, guidance on mobile development, and a full API reference.
16
 samples, guidance on mobile development, and a full API reference.
17
 
17
 
18
-### 2024.03.14 app改动点:
19
-1. 扦样任务单状态新增:待领取, 检测机构收到扦样任务通知时,所有扦样人员都能看到所有任务单据,在app待扦样页面进行任务领取.√
20
-现在的开始扦样按钮改成任务领取,点击任务领取以后扦样任务单状态改成待扦样,列表页按钮变成开始扦样,点击扦样进行正常操作。√
21
-2. 扦样人员变成多选,后端提供人员接口,选择扦样人员;√
22
-3. 温度、湿度字段去掉,新增字段:天气情况:晴天/阴天/雨天,单选;√
23
-4. 扦样时间默认给当前时间;√
24
-5. 灾害污染情况给默认值:否;√
25
-6. 点击经纬度获取,自动代入省市县乡镇村;√
26
-7. 列表页显示字段修改:扦样任务单号/状态/检验指标/样品等级/采样品种;√
27
-
28
-### 2024.04.18 app改动点:
29
-1. 收获环节<扦样任务单列表>的筛选页面及功能.
30
-2. 扦样单列表:
31
-   1. <扦样人员>字段未显示的问题.√
32
-   2. <检验指标>和<扦样地区>位置互换.√
33
-   3. <检验指标>和<样品等级>为空时不展示.√
34
-3. 扦样单详情:
35
-   1. 扦样单位、监测类别、样品编号都去掉.√
36
-   2. 高德定位结果填入乡镇和村.√
37
-   3. 用药情况删除改为长按弹框确认删除.√
38
-   4. 用药情况的施药时间字段有数据时下拉箭头不显示.√
39
-   5. 下拉箭头颜色都改为高亮文本颜色.√
40
-4. 新增内容:
41
-   1. 电子签名:点击扦样单提交时跳出签名弹窗,根据扦样人数签名,按钮:重写、上一位、下一位、提交。
42
-   2. 电子签名图片上传接口:/infra/file/upload
18
+## App编译打包
19
+打包分为两个环境, 对应不同的后端服务器.
20
+Android打包方式如下:
21
+- 测试环境:flutter build apk --flavor develop --release
22
+- 生产环境:flutter build apk --flavor product --release

+ 28 - 7
android/app/build.gradle

@@ -34,7 +34,7 @@ android {
34
 
34
 
35
     sourceSets {
35
     sourceSets {
36
         main {
36
         main {
37
-            jniLibs.srcDirs = ['jniLibs']
37
+            jniLibs.srcDirs = ['libs']
38
         }
38
         }
39
     }
39
     }
40
 
40
 
@@ -46,6 +46,10 @@ android {
46
         targetSdkVersion flutter.targetSdkVersion
46
         targetSdkVersion flutter.targetSdkVersion
47
         versionCode flutterVersionCode.toInteger()
47
         versionCode flutterVersionCode.toInteger()
48
         versionName flutterVersionName
48
         versionName flutterVersionName
49
+
50
+//        ndk {
51
+//            abiFilters 'armeabi-v7a', 'arm64-v8a', 'x86_64'
52
+//        }
49
     }
53
     }
50
 
54
 
51
     println "targetSdkVersion: ${flutter.targetSdkVersion}"
55
     println "targetSdkVersion: ${flutter.targetSdkVersion}"
@@ -67,34 +71,51 @@ android {
67
         release {
71
         release {
68
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
72
             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
69
             signingConfig signingConfigs.release
73
             signingConfig signingConfigs.release
70
-            manifestPlaceholders = [APP_NAME: "国粮质检"]
74
+
71
             shrinkResources false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
75
             shrinkResources false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
72
             minifyEnabled false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
76
             minifyEnabled false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
73
         }
77
         }
74
         profile {
78
         profile {
75
             signingConfig signingConfigs.release
79
             signingConfig signingConfigs.release
76
-            manifestPlaceholders = [APP_NAME: "国粮质检-测试"]
77
-            applicationIdSuffix ".debug"
78
             shrinkResources false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
80
             shrinkResources false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
79
             minifyEnabled false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
81
             minifyEnabled false // 重要,打印机有so库,fix bug: https://github.com/flutter/flutter/issues/47527
80
         }
82
         }
81
         debug {
83
         debug {
82
             signingConfig signingConfigs.release
84
             signingConfig signingConfigs.release
83
-            manifestPlaceholders = [APP_NAME: "国粮质检-测试"]
84
-            applicationIdSuffix ".debug"
85
         }
85
         }
86
     }
86
     }
87
     android.applicationVariants.all {
87
     android.applicationVariants.all {
88
         def buildType = it.buildType.name
88
         def buildType = it.buildType.name
89
+        def flavor = it.productFlavors[0].name
89
         def outputFile
90
         def outputFile
90
         it.outputs.each {
91
         it.outputs.each {
91
             outputFile = it.outputFile
92
             outputFile = it.outputFile
92
             // 名称_环境_版本名称_版本号.apk
93
             // 名称_环境_版本名称_版本号.apk
93
             // lszlgl_release_0.0.2_2.apk
94
             // lszlgl_release_0.0.2_2.apk
94
-            it.outputFileName = "lszlgl_${buildType}_${defaultConfig.versionName}_${defaultConfig.versionCode}.apk"
95
+            it.outputFileName = "lszlgl_${flavor}_${defaultConfig.versionName}_${defaultConfig.versionCode}.apk"
95
         }
96
         }
96
     }
97
     }
97
 
98
 
99
+    // 多渠道配置
100
+    flavorDimensions "default"
101
+
102
+    productFlavors {
103
+        develop {
104
+            dimension "default"
105
+            manifestPlaceholders = [APP_NAME: "国粮质检-测试"]
106
+            applicationIdSuffix ".debug"
107
+        }
108
+        product {
109
+            dimension "default"
110
+            manifestPlaceholders = [APP_NAME: "国粮质检"]
111
+        }
112
+    }
113
+
114
+    lintOptions {
115
+        checkReleaseBuilds false
116
+        abortOnError false
117
+    }
118
+
98
     dependencies {
119
     dependencies {
99
         implementation fileTree(include: ['*.jar'], dir: 'libs')
120
         implementation fileTree(include: ['*.jar'], dir: 'libs')
100
         implementation 'com.amap.api:location:5.6.0'
121
         implementation 'com.amap.api:location:5.6.0'

android/app/jniLibs/arm64-v8a/libConfigFileINI.so → android/app/libs/arm64-v8a/libConfigFileINI.so


android/app/jniLibs/arm64-v8a/libLabelPrinterSDK.so → android/app/libs/arm64-v8a/libLabelPrinterSDK.so


android/app/jniLibs/arm64-v8a/libSimpleLogModule.so → android/app/libs/arm64-v8a/libSimpleLogModule.so


android/app/jniLibs/arm64-v8a/libc++_shared.so → android/app/libs/arm64-v8a/libc++_shared.so


android/app/jniLibs/armeabi-v7a/libConfigFileINI.so → android/app/libs/armeabi-v7a/libConfigFileINI.so


android/app/jniLibs/armeabi-v7a/libLabelPrinterSDK.so → android/app/libs/armeabi-v7a/libLabelPrinterSDK.so


android/app/jniLibs/armeabi-v7a/libSimpleLogModule.so → android/app/libs/armeabi-v7a/libSimpleLogModule.so


android/app/jniLibs/armeabi-v7a/libc++_shared.so → android/app/libs/armeabi-v7a/libc++_shared.so


android/app/jniLibs/x86/libConfigFileINI.so → android/app/libs/x86/libConfigFileINI.so


android/app/jniLibs/x86/libLabelPrinterSDK.so → android/app/libs/x86/libLabelPrinterSDK.so


android/app/jniLibs/x86/libSimpleLogModule.so → android/app/libs/x86/libSimpleLogModule.so


android/app/jniLibs/x86/libc++_shared.so → android/app/libs/x86/libc++_shared.so


android/app/jniLibs/x86_64/libConfigFileINI.so → android/app/libs/x86_64/libConfigFileINI.so


android/app/jniLibs/x86_64/libLabelPrinterSDK.so → android/app/libs/x86_64/libLabelPrinterSDK.so


android/app/jniLibs/x86_64/libSimpleLogModule.so → android/app/libs/x86_64/libSimpleLogModule.so


android/app/jniLibs/x86_64/libc++_shared.so → android/app/libs/x86_64/libc++_shared.so


+ 2 - 0
android/app/src/main/java/com/szls/lszlgl/MainActivity.java

@@ -8,6 +8,7 @@ import io.flutter.embedding.android.FlutterActivity;
8
 import io.flutter.embedding.engine.FlutterEngine;
8
 import io.flutter.embedding.engine.FlutterEngine;
9
 import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
9
 import io.flutter.embedding.engine.plugins.util.GeneratedPluginRegister;
10
 import io.flutter.plugins.BluetoothPlugin;
10
 import io.flutter.plugins.BluetoothPlugin;
11
+import io.flutter.plugins.FlavorPlugin;
11
 
12
 
12
 public class MainActivity extends FlutterActivity {
13
 public class MainActivity extends FlutterActivity {
13
 
14
 
@@ -23,5 +24,6 @@ public class MainActivity extends FlutterActivity {
23
 
24
 
24
         //插件实例的注册,就是自己写个类,然后实现Flutter提供的FlutterPlugin接口
25
         //插件实例的注册,就是自己写个类,然后实现Flutter提供的FlutterPlugin接口
25
         flutterEngine.getPlugins().add(new BluetoothPlugin(this));
26
         flutterEngine.getPlugins().add(new BluetoothPlugin(this));
27
+        flutterEngine.getPlugins().add(new FlavorPlugin());
26
     }
28
     }
27
 }
29
 }

+ 53 - 0
android/app/src/main/java/io/flutter/plugins/FlavorPlugin.java

@@ -0,0 +1,53 @@
1
+package io.flutter.plugins;
2
+
3
+
4
+import androidx.annotation.NonNull;
5
+
6
+import com.szls.lszlgl.BuildConfig;
7
+
8
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
9
+import io.flutter.plugin.common.MethodCall;
10
+import io.flutter.plugin.common.MethodChannel;
11
+
12
+public class FlavorPlugin implements FlutterPlugin, MethodChannel.MethodCallHandler {
13
+
14
+    private MethodChannel mChannel;
15
+
16
+    public FlavorPlugin() {
17
+    }
18
+
19
+    @Override
20
+    public void onAttachedToEngine(@NonNull FlutterPluginBinding binding) {
21
+        mChannel = new MethodChannel(binding.getBinaryMessenger(), "plugin_flavor");
22
+        mChannel.setMethodCallHandler(this);
23
+    }
24
+
25
+    @Override
26
+    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
27
+        mChannel.setMethodCallHandler(null);
28
+        mChannel = null;
29
+    }
30
+
31
+    @Override
32
+    public void onMethodCall(@NonNull MethodCall call, @NonNull MethodChannel.Result result) {
33
+        switch (call.method) {
34
+            case "getPlatformVersion":
35
+                result.success("Android " + android.os.Build.VERSION.RELEASE);
36
+                break;
37
+            case "flavor":
38
+                getFlavor(result);
39
+                break;
40
+            default:
41
+                result.notImplemented();
42
+                break;
43
+        }
44
+    }
45
+
46
+    /**
47
+     * 获取Flavor
48
+     */
49
+    private void getFlavor(MethodChannel.Result result) {
50
+        result.success(BuildConfig.FLAVOR);
51
+    }
52
+
53
+}

+ 43 - 0
lib/config/app_config.dart

@@ -0,0 +1,43 @@
1
+import 'package:lszlgl/plugin/flavor_plugin.dart';
2
+import 'package:package_info_plus/package_info_plus.dart';
3
+
4
+import '../network/my_api.dart';
5
+
6
+enum AppEnvironment {
7
+  /// 开发环境
8
+  develop,
9
+
10
+  /// 生产环境
11
+  product,
12
+}
13
+
14
+class AppConfig {
15
+  AppConfig._();
16
+
17
+  /// 环境信息
18
+  static late AppEnvironment env;
19
+
20
+  /// 包信息
21
+  static late PackageInfo packageInfo;
22
+
23
+  static Future<void> init() async {
24
+    packageInfo = await PackageInfo.fromPlatform();
25
+
26
+    env = await _initEnv();
27
+
28
+    /// 初始化网络请求
29
+    MyApi.init(env);
30
+  }
31
+
32
+  /// 初始化环境
33
+  static Future<AppEnvironment> _initEnv() async {
34
+    // 获取flavor
35
+    var name = await FlavorPlugin.instance.getFlavor();
36
+    // 转为环境数据
37
+    return switch (name) {
38
+      'develop' => AppEnvironment.develop,
39
+      'product' => AppEnvironment.product,
40
+      _ => AppEnvironment.product,
41
+    };
42
+  }
43
+}

+ 6 - 7
lib/main.dart

@@ -1,8 +1,4 @@
1
 import 'dart:async';
1
 import 'dart:async';
2
-import 'dart:io';
3
-import 'package:drift/drift.dart' as drift;
4
-import 'package:drift/native.dart';
5
-import 'package:flutter/foundation.dart';
6
 import 'package:flutter/material.dart';
2
 import 'package:flutter/material.dart';
7
 import 'package:flutter/services.dart';
3
 import 'package:flutter/services.dart';
8
 import 'package:flutter_localizations/flutter_localizations.dart';
4
 import 'package:flutter_localizations/flutter_localizations.dart';
@@ -12,6 +8,8 @@ import 'package:lszlgl/config/colors.dart';
12
 import 'package:lszlgl/drfit/database.dart';
8
 import 'package:lszlgl/drfit/database.dart';
13
 import 'package:lszlgl/router/my_navigator.dart';
9
 import 'package:lszlgl/router/my_navigator.dart';
14
 
10
 
11
+import 'config/app_config.dart';
12
+
15
 late Logger logger;
13
 late Logger logger;
16
 late MyDatabase database;
14
 late MyDatabase database;
17
 
15
 
@@ -24,8 +22,9 @@ void main() async {
24
       DeviceOrientation.portraitUp,
22
       DeviceOrientation.portraitUp,
25
       DeviceOrientation.portraitDown,
23
       DeviceOrientation.portraitDown,
26
     ]);
24
     ]);
27
-
28
-    runApp(const MyApp());
25
+    AppConfig.init().then((value) {
26
+      runApp(const MyApp());
27
+    });
29
     database = MyDatabase();
28
     database = MyDatabase();
30
   });
29
   });
31
 }
30
 }
@@ -66,7 +65,7 @@ class MyApp extends StatelessWidget {
66
   Widget build(BuildContext context) {
65
   Widget build(BuildContext context) {
67
     var theme = Theme.of(context);
66
     var theme = Theme.of(context);
68
     return MaterialApp(
67
     return MaterialApp(
69
-      title: '粮食质量管理${kReleaseMode ? '' : '-测试'}',
68
+      title: AppConfig.packageInfo.appName,
70
       theme: ThemeData(
69
       theme: ThemeData(
71
         colorScheme: ColorScheme.fromSeed(
70
         colorScheme: ColorScheme.fromSeed(
72
           seedColor: Colors.blue,
71
           seedColor: Colors.blue,

+ 17 - 8
lib/network/my_api.dart

@@ -1,21 +1,30 @@
1
 import 'package:dio/dio.dart';
1
 import 'package:dio/dio.dart';
2
-import 'package:flutter/foundation.dart';
2
+import 'package:lszlgl/config/app_config.dart';
3
 
3
 
4
 import 'api.dart';
4
 import 'api.dart';
5
 
5
 
6
 class MyApi {
6
 class MyApi {
7
   MyApi._();
7
   MyApi._();
8
 
8
 
9
+  /// 生产url
9
   static String productUrl = 'http://121.36.17.6:49099';
10
   static String productUrl = 'http://121.36.17.6:49099';
11
+
12
+  /// 测试url
10
   static String testUrl = 'http://121.36.17.6:19090';
13
   static String testUrl = 'http://121.36.17.6:19090';
11
 
14
 
12
-  static Api get({Dio? dio, String? baseUrl}) {
15
+  static late String globalUrl;
13
 
16
 
14
-    if (kReleaseMode) {
15
-      baseUrl ??= productUrl;
16
-    } else {
17
-      baseUrl ??= testUrl;
18
-    }
19
-    return Api(dio: dio, baseUrl: baseUrl);
17
+  static void init(AppEnvironment env) {
18
+    globalUrl = switch (env) {
19
+      AppEnvironment.develop => testUrl,
20
+      AppEnvironment.product => productUrl,
21
+    };
22
+  }
23
+
24
+  static Api get({Dio? dio, String? baseUrl}) {
25
+    return Api(
26
+      dio: dio,
27
+      baseUrl: baseUrl ?? globalUrl,
28
+    );
20
   }
29
   }
21
 }
30
 }

+ 2 - 9
lib/page/user_center/setting_page.dart

@@ -1,9 +1,9 @@
1
 import 'package:flutter/material.dart';
1
 import 'package:flutter/material.dart';
2
 import 'package:lszlgl/base/base_state.dart';
2
 import 'package:lszlgl/base/base_state.dart';
3
+import 'package:lszlgl/config/app_config.dart';
3
 import 'package:lszlgl/service/upgrade_service.dart';
4
 import 'package:lszlgl/service/upgrade_service.dart';
4
 import 'package:lszlgl/widget/button.dart';
5
 import 'package:lszlgl/widget/button.dart';
5
 import 'package:lszlgl/widget/card_item.dart';
6
 import 'package:lszlgl/widget/card_item.dart';
6
-import 'package:package_info_plus/package_info_plus.dart';
7
 
7
 
8
 /// 设置
8
 /// 设置
9
 class SettingPage extends StatefulWidget {
9
 class SettingPage extends StatefulWidget {
@@ -16,7 +16,6 @@ class SettingPage extends StatefulWidget {
16
 class _SettingPageState extends BaseState<SettingPage> {
16
 class _SettingPageState extends BaseState<SettingPage> {
17
   bool sound = true;
17
   bool sound = true;
18
   bool shake = true;
18
   bool shake = true;
19
-  String version = '';
20
 
19
 
21
   void onSave() {
20
   void onSave() {
22
     MyNavigator.showToast('保存成功');
21
     MyNavigator.showToast('保存成功');
@@ -30,12 +29,6 @@ class _SettingPageState extends BaseState<SettingPage> {
30
   @override
29
   @override
31
   void initState() {
30
   void initState() {
32
     super.initState();
31
     super.initState();
33
-
34
-    PackageInfo.fromPlatform().then((packageInfo) {
35
-      setState(() {
36
-        version = packageInfo.version;
37
-      });
38
-    });
39
   }
32
   }
40
 
33
 
41
   @override
34
   @override
@@ -79,7 +72,7 @@ class _SettingPageState extends BaseState<SettingPage> {
79
             rightChild: buildSwitch(shake, (value) => setState(() => shake = value)),
72
             rightChild: buildSwitch(shake, (value) => setState(() => shake = value)),
80
             bottomLine: true,
73
             bottomLine: true,
81
           ),
74
           ),
82
-          CardItemWidget('版本信息', rightText: 'V$version', onTap: onVersionTap),
75
+          CardItemWidget('版本信息', rightText: 'V${AppConfig.packageInfo.version}', onTap: onVersionTap),
83
         ],
76
         ],
84
       ),
77
       ),
85
     );
78
     );

+ 21 - 0
lib/plugin/flavor_plugin.dart

@@ -0,0 +1,21 @@
1
+import 'dart:async';
2
+
3
+import 'package:flutter/services.dart';
4
+
5
+class FlavorPlugin {
6
+  FlavorPlugin._();
7
+
8
+  static FlavorPlugin? _instance;
9
+
10
+  static FlavorPlugin get instance => _instance ??= FlavorPlugin._();
11
+
12
+  final MethodChannel _channel = const MethodChannel('plugin_flavor');
13
+
14
+  Future<String?> get platformVersion async {
15
+    final String? version = await _channel.invokeMethod('getPlatformVersion');
16
+    return version;
17
+  }
18
+
19
+  /// 获取Flavor
20
+  Future<String?> getFlavor() => _channel.invokeMethod('flavor');
21
+}

+ 2 - 2
lib/service/upgrade_service.dart

@@ -2,7 +2,7 @@ import 'dart:io';
2
 
2
 
3
 import 'package:dio/dio.dart';
3
 import 'package:dio/dio.dart';
4
 import 'package:install_plugin/install_plugin.dart';
4
 import 'package:install_plugin/install_plugin.dart';
5
-import 'package:package_info_plus/package_info_plus.dart';
5
+import 'package:lszlgl/config/app_config.dart';
6
 import 'package:path_provider/path_provider.dart';
6
 import 'package:path_provider/path_provider.dart';
7
 import 'package:permission_handler/permission_handler.dart';
7
 import 'package:permission_handler/permission_handler.dart';
8
 
8
 
@@ -70,7 +70,7 @@ class UpgradeService {
70
         // 获取线上版本 lszlgl_release_0.0.2_2.apk
70
         // 获取线上版本 lszlgl_release_0.0.2_2.apk
71
         List<String> nameSplit = UpgradeService.getName(path).split('_');
71
         List<String> nameSplit = UpgradeService.getName(path).split('_');
72
         int onlineCode = int.parse(nameSplit[nameSplit.length - 1].split('.').first);
72
         int onlineCode = int.parse(nameSplit[nameSplit.length - 1].split('.').first);
73
-        int localCode = int.parse((await PackageInfo.fromPlatform()).buildNumber);
73
+        int localCode = int.parse(AppConfig.packageInfo.buildNumber);
74
         logger.d('versionUpgrade:localCode:$localCode onlineCode:$onlineCode');
74
         logger.d('versionUpgrade:localCode:$localCode onlineCode:$onlineCode');
75
         if (localCode >= onlineCode) {
75
         if (localCode >= onlineCode) {
76
           if (showLoading) MyNavigator.showToast('已是最新版本');
76
           if (showLoading) MyNavigator.showToast('已是最新版本');