Просмотр исходного кода

[new]增加Android端应用权限设置流程

zk 10 месяцев назад
Родитель
Сommit
90e06866f8
24 измененных файлов с 720 добавлено и 4 удалено
  1. 12 4
      lib/module/permission/permission_setting_controller.dart
  2. 29 0
      plugins/flutter_tool_android/.gitignore
  3. 30 0
      plugins/flutter_tool_android/.metadata
  4. 3 0
      plugins/flutter_tool_android/CHANGELOG.md
  5. 1 0
      plugins/flutter_tool_android/LICENSE
  6. 15 0
      plugins/flutter_tool_android/README.md
  7. 4 0
      plugins/flutter_tool_android/analysis_options.yaml
  8. 9 0
      plugins/flutter_tool_android/android/.gitignore
  9. 69 0
      plugins/flutter_tool_android/android/build.gradle
  10. BIN
      plugins/flutter_tool_android/android/gradle/wrapper/gradle-wrapper.jar
  11. 7 0
      plugins/flutter_tool_android/android/gradle/wrapper/gradle-wrapper.properties
  12. 1 0
      plugins/flutter_tool_android/android/settings.gradle
  13. 2 0
      plugins/flutter_tool_android/android/src/main/AndroidManifest.xml
  14. 57 0
      plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/FlutterToolAndroidPlugin.java
  15. 170 0
      plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BackgroundPermissionUtil.java
  16. 40 0
      plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BatteryUtil.java
  17. 73 0
      plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BrandUtil.java
  18. 29 0
      plugins/flutter_tool_android/android/src/test/java/com/atmob/flutter_tool_android/FlutterToolAndroidPluginTest.java
  19. 18 0
      plugins/flutter_tool_android/lib/flutter_tool_android.dart
  20. 29 0
      plugins/flutter_tool_android/lib/src/flutter_tool_android_method_channel.dart
  21. 41 0
      plugins/flutter_tool_android/lib/src/flutter_tool_android_platform_interface.dart
  22. 70 0
      plugins/flutter_tool_android/pubspec.yaml
  23. 7 0
      pubspec.lock
  24. 4 0
      pubspec.yaml

+ 12 - 4
lib/module/permission/permission_setting_controller.dart

@@ -1,12 +1,11 @@
 import 'dart:io';
 
+import 'package:flutter_tool_android/flutter_tool_android.dart';
 import 'package:get/get.dart';
 import 'package:injectable/injectable.dart';
 import 'package:location/base/base_controller.dart';
 import 'package:location/resource/string.gen.dart';
-import 'package:location/utils/app_info_util.dart';
 import 'package:location/utils/toast_util.dart';
-
 import '../../utils/permission_util.dart';
 
 @injectable
@@ -53,7 +52,16 @@ class PermissionSettingController extends BaseController {
     }
   }
 
-  void openBatterySetting() {}
+  void openBatterySetting() async {
+    bool isIgnore = await FlutterToolAndroid.isIgnoringBatteryOptimizations();
+    if (isIgnore) {
+      ToastUtil.show(StringName.permissionSettingSuccess);
+    } else {
+      FlutterToolAndroid.openBatteryOptimizationSettings();
+    }
+  }
 
-  void openBackgroundRunSetting() async {}
+  void openBackgroundRunSetting() async {
+    FlutterToolAndroid.openAppBackgroundSetting();
+  }
 }

+ 29 - 0
plugins/flutter_tool_android/.gitignore

@@ -0,0 +1,29 @@
+# Miscellaneous
+*.class
+*.log
+*.pyc
+*.swp
+.DS_Store
+.atom/
+.buildlog/
+.history
+.svn/
+migrate_working_dir/
+
+# 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
+# Libraries should not include pubspec.lock, per https://dart.dev/guides/libraries/private-files#pubspeclock.
+/pubspec.lock
+**/doc/api/
+.dart_tool/
+build/

+ 30 - 0
plugins/flutter_tool_android/.metadata

@@ -0,0 +1,30 @@
+# 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: "80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819"
+  channel: "stable"
+
+project_type: plugin
+
+# Tracks metadata for the flutter migrate command
+migration:
+  platforms:
+    - platform: root
+      create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+      base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+    - platform: android
+      create_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+      base_revision: 80c2e84975bbd28ecf5f8d4bd4ca5a2490bfc819
+
+  # 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'

+ 3 - 0
plugins/flutter_tool_android/CHANGELOG.md

@@ -0,0 +1,3 @@
+## 0.0.1
+
+* TODO: Describe initial release.

+ 1 - 0
plugins/flutter_tool_android/LICENSE

@@ -0,0 +1 @@
+TODO: Add your license here.

+ 15 - 0
plugins/flutter_tool_android/README.md

@@ -0,0 +1,15 @@
+# flutter_tool_android
+
+系统通用工具类-Android
+
+## Getting Started
+
+This project is a starting point for a Flutter
+[plug-in package](https://flutter.dev/to/develop-plugins),
+a specialized package that includes platform-specific implementation code for
+Android and/or iOS.
+
+For help getting started with Flutter development, view the
+[online documentation](https://docs.flutter.dev), which offers tutorials,
+samples, guidance on mobile development, and a full API reference.
+

+ 4 - 0
plugins/flutter_tool_android/analysis_options.yaml

@@ -0,0 +1,4 @@
+include: package:flutter_lints/flutter.yaml
+
+# Additional information about this file can be found at
+# https://dart.dev/guides/language/analysis-options

+ 9 - 0
plugins/flutter_tool_android/android/.gitignore

@@ -0,0 +1,9 @@
+*.iml
+.gradle
+/local.properties
+/.idea/workspace.xml
+/.idea/libraries
+.DS_Store
+/build
+/captures
+.cxx

+ 69 - 0
plugins/flutter_tool_android/android/build.gradle

@@ -0,0 +1,69 @@
+group = "com.atmob.flutter_tool_android"
+version = "1.0"
+
+buildscript {
+    repositories {
+        google()
+        mavenCentral()
+    }
+
+    dependencies {
+        classpath("com.android.tools.build:gradle:7.3.0")
+    }
+}
+
+rootProject.allprojects {
+    repositories {
+        google()
+        mavenCentral()
+    }
+}
+
+// 加载 local.properties 文件
+def localProperties = new Properties()
+def localPropertiesFile = rootProject.file('local.properties')
+if (localPropertiesFile.exists()) {
+    localPropertiesFile.withInputStream { stream ->
+        localProperties.load(stream)
+    }
+}
+
+// 读取变量
+def flutterSdk = localProperties.getProperty('flutter.sdk')
+
+apply plugin: "com.android.library"
+
+android {
+    if (project.android.hasProperty("namespace")) {
+        namespace = "com.atmob.flutter_tool_android"
+    }
+
+    compileSdk = 34
+
+    compileOptions {
+        sourceCompatibility = JavaVersion.VERSION_1_8
+        targetCompatibility = JavaVersion.VERSION_1_8
+    }
+
+    defaultConfig {
+        minSdk = 21
+    }
+
+    dependencies {
+        //flutter
+        compileOnly files("$flutterSdk/bin/cache/artifacts/engine/android-arm/flutter.jar")
+
+        //AndroidX
+        compileOnly "androidx.annotation:annotation:1.1.0"
+    }
+
+    testOptions {
+        unitTests.all {
+            testLogging {
+                events "passed", "skipped", "failed", "standardOut", "standardError"
+                outputs.upToDateWhen { false }
+                showStandardStreams = true
+            }
+        }
+    }
+}

BIN
plugins/flutter_tool_android/android/gradle/wrapper/gradle-wrapper.jar


+ 7 - 0
plugins/flutter_tool_android/android/gradle/wrapper/gradle-wrapper.properties

@@ -0,0 +1,7 @@
+distributionBase=GRADLE_USER_HOME
+distributionPath=wrapper/dists
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
+networkTimeout=10000
+validateDistributionUrl=true
+zipStoreBase=GRADLE_USER_HOME
+zipStorePath=wrapper/dists

+ 1 - 0
plugins/flutter_tool_android/android/settings.gradle

@@ -0,0 +1 @@
+rootProject.name = 'flutter_tool_android'

+ 2 - 0
plugins/flutter_tool_android/android/src/main/AndroidManifest.xml

@@ -0,0 +1,2 @@
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.atmob.flutter_tool_android"></manifest>

+ 57 - 0
plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/FlutterToolAndroidPlugin.java

@@ -0,0 +1,57 @@
+package com.atmob.flutter_tool_android;
+
+import android.content.Context;
+
+import androidx.annotation.NonNull;
+
+import com.atmob.flutter_tool_android.utils.BackgroundPermissionUtil;
+import com.atmob.flutter_tool_android.utils.BatteryUtil;
+
+import java.util.Objects;
+
+import io.flutter.embedding.engine.plugins.FlutterPlugin;
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
+import io.flutter.plugin.common.MethodChannel.Result;
+
+/**
+ * FlutterToolAndroidPlugin
+ */
+public class FlutterToolAndroidPlugin implements FlutterPlugin, MethodCallHandler {
+    /// The MethodChannel that will the communication between Flutter and native Android
+    ///
+    /// This local reference serves to register the plugin with the Flutter Engine and unregister it
+    /// when the Flutter Engine is detached from the Activity
+    private MethodChannel channel;
+
+    private Context context;
+
+    @Override
+    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
+        context = flutterPluginBinding.getApplicationContext();
+        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "flutter_tool_android");
+        channel.setMethodCallHandler(this);
+    }
+
+    @Override
+    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
+        String method = call.method;
+        if (Objects.equals(method, "isIgnoringBatteryOptimizations")) {
+            result.success(BatteryUtil.isIgnoringBatteryOptimizations(context));
+        } else if (Objects.equals(method, "openBatteryOptimizationSettings")) {
+            BatteryUtil.openBatteryOptimizationSettings(context);
+            result.success(null);
+        } else if(Objects.equals(method,"openAppBackgroundSetting")){
+            BackgroundPermissionUtil.requestBackgroundPermission(context);
+            result.success(null);
+        }else {
+            result.notImplemented();
+        }
+    }
+
+    @Override
+    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
+        channel.setMethodCallHandler(null);
+    }
+}

+ 170 - 0
plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BackgroundPermissionUtil.java

@@ -0,0 +1,170 @@
+package com.atmob.flutter_tool_android.utils;
+
+import android.app.Activity;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.provider.Settings;
+import android.text.TextUtils;
+
+public class BackgroundPermissionUtil {
+    public static void requestBackgroundPermission(Context context) {
+        try {
+            int brand = BrandUtil.getBrand();
+            switch (brand) {
+                case BrandUtil.HuaWei:
+                    handleHuaWei(context);
+                    break;
+                case BrandUtil.XiaoMi:
+                    handleXiaoMi(context);
+                    break;
+                case BrandUtil.Vivo:
+                    handleVivo(context);
+                    break;
+                case BrandUtil.Oppo:
+                    handleOppo(context);
+                    break;
+                case BrandUtil.Meizu:
+                    handleMeizu(context);
+                    break;
+                case BrandUtil.Samsung:
+                    handleSamsung(context);
+                    break;
+                case BrandUtil.Smartisan:
+                    handleSmartisan(context);
+                    break;
+                case BrandUtil.LEPHONE:
+                    handleLePhone(context);
+                    break;
+                default:
+                    throw new Exception("handle brand failed. brand = " + brand);
+            }
+        } catch (Exception e) {
+            e.printStackTrace();
+            openSetting(context);
+        }
+    }
+
+    private static void handleLePhone(Context activity) {
+        openTargetApp(activity, "com.letv.android.letvsafe",
+                "com.letv.android.letvsafe.AutobootManageActivity");
+    }
+
+    private static void handleSmartisan(Context context) {
+        openTargetApp(context, "com.smartisanos.security", null);
+    }
+
+    private static void handleSamsung(Context context) throws Exception {
+        try {
+            openTargetApp(context, "com.samsung.android.sm_cn", "com.samsung.android.sm.autorun.ui.AutoRunActivity");
+            return;
+        } catch (Exception e){
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.samsung.android.sm_cn", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.samsung.android.sm", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        throw new Exception("handle samsung failed.");
+    }
+
+    private static void handleMeizu(Context context) {
+        openTargetApp(context, "com.meizu.safe", "com.meizu.safe.permission.SmartBGActivity");
+    }
+
+    private static void handleOppo(Context context) throws Exception {
+        try {
+            openTargetApp(context, "com.coloros.phonemanager", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.oppo.safe", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.coloros.oppoguardelf", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.coloros.safecenter", null);
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        throw new Exception("handle oppo failed.");
+    }
+
+    private static void handleVivo(Context context) throws Exception {
+        openTargetApp(context, "com.iqoo.secure", null);
+    }
+
+    private static void handleXiaoMi(Context context) {
+        openTargetApp(context, "com.miui.securitycenter",
+                "com.miui.permcenter.autostart.AutoStartManagementActivity");
+    }
+
+    private static void handleHuaWei(Context context) throws Exception {
+        try {
+            openTargetApp(context, "com.hihonor.systemmanager", "com.hihonor.systemmanager.appcontrol.activity.StartupAppControlActivity");
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.huawei.systemmanager", "com.huawei.systemmanager.appcontrol.activity.StartupAppControlActivity");
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.huawei.systemmanager",
+                    "com.huawei.systemmanager.startupmgr.ui.StartupNormalAppListActivity");
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        try {
+            openTargetApp(context, "com.huawei.systemmanager",
+                    "com.huawei.systemmanager.optimize.bootstart.BootStartActivity");
+            return;
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+        throw new Exception("handle huawei failed.");
+    }
+
+    public static void openSetting(Context context) {
+        Intent intent = new Intent();
+        intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+        intent.setAction(Settings.ACTION_APPLICATION_DETAILS_SETTINGS);
+        intent.setData(Uri.fromParts("package", context.getPackageName(), null));
+        context.startActivity(intent);
+    }
+
+    public static void openTargetApp(Context context, String packageName, String activityName) {
+        Intent intent;
+        if (TextUtils.isEmpty(activityName)) {
+            intent = context.getPackageManager().getLaunchIntentForPackage(packageName);
+        } else {
+            intent = new Intent();
+            intent.setAction("android.intent.action.VIEW");
+            intent.setComponent(new ComponentName(packageName, activityName));
+        }
+        context.startActivity(intent);
+    }
+}

+ 40 - 0
plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BatteryUtil.java

@@ -0,0 +1,40 @@
+package com.atmob.flutter_tool_android.utils;
+
+import android.content.Context;
+import android.content.Intent;
+import android.net.Uri;
+import android.os.Build;
+import android.os.PowerManager;
+import android.provider.Settings;
+
+public class BatteryUtil {
+
+    private BatteryUtil() {
+    }
+
+
+    public static boolean isIgnoringBatteryOptimizations(Context context) {
+        boolean isIgnoring = true;
+        PowerManager powerManager = (PowerManager) context.getSystemService(Context.POWER_SERVICE);
+        if (powerManager != null) {
+            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
+                isIgnoring = powerManager.isIgnoringBatteryOptimizations(context.getPackageName());
+            }
+        }
+        return isIgnoring;
+    }
+
+    public static void openBatteryOptimizationSettings(Context context) {
+        if (android.os.Build.VERSION.SDK_INT < android.os.Build.VERSION_CODES.M) {
+            return;
+        }
+        try {
+            Intent intent = new Intent(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
+            intent.setData(Uri.parse("package:" + context.getPackageName()));
+            intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+            context.startActivity(intent);
+        } catch (Exception e) {
+            e.printStackTrace();
+        }
+    }
+}

+ 73 - 0
plugins/flutter_tool_android/android/src/main/java/com/atmob/flutter_tool_android/utils/BrandUtil.java

@@ -0,0 +1,73 @@
+package com.atmob.flutter_tool_android.utils;
+
+import android.os.Build;
+
+public class BrandUtil {
+    public static final int HuaWei = 1;
+    public static final int XiaoMi = 2;
+    public static final int Vivo = 3;
+    public static final int Oppo = 4;
+    public static final int Meizu = 5;
+    public static final int Samsung = 6;
+    public static final int Smartisan = 7;
+    public static final int Lenovo = 8;
+    public static final int ZTE = 9;
+    public static final int OnePlus = 10;
+    public static final int Google = 11;
+    public static final int Sony = 12;
+    public static final int LG = 13;
+    public static final int HTC = 14;
+    public static final int ASUS = 15;
+    public static final int GIONEE = 16;
+    public static final int MOTOROLA = 17;
+    public static final int NUBIA = 18;
+    public static final int SHARP = 19;
+    public static final int LEPHONE = 20;
+
+    public static int getBrand() {
+        String brand = Build.BRAND;
+        if (brand.equalsIgnoreCase("HUAWEI") || brand.equalsIgnoreCase("HONOR")) {
+            return HuaWei;
+        } else if (brand.equalsIgnoreCase("Xiaomi")) {
+            return XiaoMi;
+        } else if (brand.equalsIgnoreCase("vivo")) {
+            return Vivo;
+        } else if (brand.equalsIgnoreCase("OPPO")) {
+            return Oppo;
+        } else if (brand.equalsIgnoreCase("Meizu")) {
+            return Meizu;
+        } else if (brand.equalsIgnoreCase("samsung")) {
+            return Samsung;
+        } else if (brand.equalsIgnoreCase("smartisan")) {
+            return Smartisan;
+        } else if (brand.equalsIgnoreCase("Lenovo")) {
+            return Lenovo;
+        } else if (brand.equalsIgnoreCase("ZTE")) {
+            return ZTE;
+        } else if (brand.equalsIgnoreCase("OnePlus")) {
+            return OnePlus;
+        } else if (brand.equalsIgnoreCase("Google")) {
+            return Google;
+        } else if (brand.equalsIgnoreCase("Sony")) {
+            return Sony;
+        } else if (brand.equalsIgnoreCase("LG")) {
+            return LG;
+        } else if (brand.equalsIgnoreCase("HTC")) {
+            return HTC;
+        } else if (brand.equalsIgnoreCase("ASUS")) {
+            return ASUS;
+        } else if (brand.equalsIgnoreCase("GIONEE")) {
+            return GIONEE;
+        } else if (brand.equalsIgnoreCase("MOTOROLA")) {
+            return MOTOROLA;
+        } else if (brand.equalsIgnoreCase("NUBIA")) {
+            return NUBIA;
+        } else if (brand.equalsIgnoreCase("SHARP")) {
+            return SHARP;
+        } else if (brand.equalsIgnoreCase("LETV")) {
+            return LEPHONE;
+        } else {
+            return 0;
+        }
+    }
+}

+ 29 - 0
plugins/flutter_tool_android/android/src/test/java/com/atmob/flutter_tool_android/FlutterToolAndroidPluginTest.java

@@ -0,0 +1,29 @@
+package com.atmob.flutter_tool_android;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+import io.flutter.plugin.common.MethodCall;
+import io.flutter.plugin.common.MethodChannel;
+import org.junit.Test;
+
+/**
+ * This demonstrates a simple unit test of the Java portion of this plugin's implementation.
+ *
+ * Once you have built the plugin's example app, you can run these tests from the command
+ * line by running `./gradlew testDebugUnitTest` in the `example/android/` directory, or
+ * you can run them directly from IDEs that support JUnit such as Android Studio.
+ */
+
+public class FlutterToolAndroidPluginTest {
+  @Test
+  public void onMethodCall_getPlatformVersion_returnsExpectedValue() {
+    FlutterToolAndroidPlugin plugin = new FlutterToolAndroidPlugin();
+
+    final MethodCall call = new MethodCall("getPlatformVersion", null);
+    MethodChannel.Result mockResult = mock(MethodChannel.Result.class);
+    plugin.onMethodCall(call, mockResult);
+
+    verify(mockResult).success("Android " + android.os.Build.VERSION.RELEASE);
+  }
+}

+ 18 - 0
plugins/flutter_tool_android/lib/flutter_tool_android.dart

@@ -0,0 +1,18 @@
+import 'package:flutter_tool_android/src/flutter_tool_android_platform_interface.dart';
+
+class FlutterToolAndroid {
+  FlutterToolAndroid._();
+
+  static Future<bool> isIgnoringBatteryOptimizations() {
+    return FlutterToolAndroidPlatform.instance.isIgnoringBatteryOptimizations();
+  }
+
+  static Future<void> openBatteryOptimizationSettings() {
+    return FlutterToolAndroidPlatform.instance
+        .openBatteryOptimizationSettings();
+  }
+
+  static Future<void> openAppBackgroundSetting() {
+    return FlutterToolAndroidPlatform.instance.openAppBackgroundSetting();
+  }
+}

+ 29 - 0
plugins/flutter_tool_android/lib/src/flutter_tool_android_method_channel.dart

@@ -0,0 +1,29 @@
+import 'package:flutter/foundation.dart';
+import 'package:flutter/services.dart';
+
+import 'flutter_tool_android_platform_interface.dart';
+
+/// An implementation of [FlutterToolAndroidPlatform] that uses method channels.
+class MethodChannelFlutterToolAndroid extends FlutterToolAndroidPlatform {
+  /// The method channel used to interact with the native platform.
+  @visibleForTesting
+  final methodChannel = const MethodChannel('flutter_tool_android');
+
+  @override
+  Future<bool> isIgnoringBatteryOptimizations() async {
+    final isIgnore = await methodChannel
+        .invokeMethod<bool>('isIgnoringBatteryOptimizations');
+    return isIgnore == true;
+  }
+
+  @override
+  Future<void> openBatteryOptimizationSettings() async {
+    return await methodChannel
+        .invokeMethod<void>('openBatteryOptimizationSettings');
+  }
+
+  @override
+  Future<void> openAppBackgroundSetting() async {
+    return await methodChannel.invokeMethod<void>('openAppBackgroundSetting');
+  }
+}

+ 41 - 0
plugins/flutter_tool_android/lib/src/flutter_tool_android_platform_interface.dart

@@ -0,0 +1,41 @@
+import 'package:plugin_platform_interface/plugin_platform_interface.dart';
+
+import 'flutter_tool_android_method_channel.dart';
+
+abstract class FlutterToolAndroidPlatform extends PlatformInterface {
+  /// Constructs a FlutterToolAndroidPlatform.
+  FlutterToolAndroidPlatform() : super(token: _token);
+
+  static final Object _token = Object();
+
+  static FlutterToolAndroidPlatform _instance =
+      MethodChannelFlutterToolAndroid();
+
+  /// The default instance of [FlutterToolAndroidPlatform] to use.
+  ///
+  /// Defaults to [MethodChannelFlutterToolAndroid].
+  static FlutterToolAndroidPlatform get instance => _instance;
+
+  /// Platform-specific implementations should set this with their own
+  /// platform-specific class that extends [FlutterToolAndroidPlatform] when
+  /// they register themselves.
+  static set instance(FlutterToolAndroidPlatform instance) {
+    PlatformInterface.verifyToken(instance, _token);
+    _instance = instance;
+  }
+
+  Future<bool> isIgnoringBatteryOptimizations() {
+    throw UnimplementedError(
+        'isIgnoringBatteryOptimizations() has not been implemented.');
+  }
+
+  Future<void> openBatteryOptimizationSettings() {
+    throw UnimplementedError(
+        'openBatteryOptimizationSettings() has not been implemented.');
+  }
+
+  Future<void> openAppBackgroundSetting() {
+    throw UnimplementedError(
+        'openAppBackgroundSetting() has not been implemented.');
+  }
+}

+ 70 - 0
plugins/flutter_tool_android/pubspec.yaml

@@ -0,0 +1,70 @@
+name: flutter_tool_android
+description: "系统通用工具类-Android"
+version: 0.0.1
+homepage:
+
+environment:
+  sdk: ^3.5.0
+  flutter: '>=3.3.0'
+
+dependencies:
+  flutter:
+    sdk: flutter
+  plugin_platform_interface: ^2.0.2
+
+dev_dependencies:
+  flutter_test:
+    sdk: flutter
+  flutter_lints: ^4.0.0
+
+# For information on the generic Dart part of this file, see the
+# following page: https://dart.dev/tools/pub/pubspec
+
+# The following section is specific to Flutter packages.
+flutter:
+  # This section identifies this Flutter project as a plugin project.
+  # The 'pluginClass' specifies the class (in Java, Kotlin, Swift, Objective-C, etc.)
+  # which should be registered in the plugin registry. This is required for
+  # using method channels.
+  # The Android 'package' specifies package in which the registered class is.
+  # This is required for using method channels on Android.
+  # The 'ffiPlugin' specifies that native code should be built and bundled.
+  # This is required for using `dart:ffi`.
+  # All these are used by the tooling to maintain consistency when
+  # adding or updating assets for this project.
+  plugin:
+    platforms:
+      android:
+        package: com.atmob.flutter_tool_android
+        pluginClass: FlutterToolAndroidPlugin
+
+  # To add assets to your plugin package, add an assets section, like this:
+  # assets:
+  #   - images/a_dot_burr.jpeg
+  #   - images/a_dot_ham.jpeg
+  #
+  # For details regarding assets in packages, see
+  # https://flutter.dev/to/asset-from-package
+  #
+  # An image asset can refer to one or more resolution-specific "variants", see
+  # https://flutter.dev/to/resolution-aware-images
+
+  # To add custom fonts to your plugin package, add a fonts section here,
+  # in this "flutter" section. Each entry in this list should have a
+  # "family" key with the font family name, and a "fonts" key with a
+  # list giving the asset and other descriptors for the font. For
+  # example:
+  # fonts:
+  #   - family: Schyler
+  #     fonts:
+  #       - asset: fonts/Schyler-Regular.ttf
+  #       - asset: fonts/Schyler-Italic.ttf
+  #         style: italic
+  #   - family: Trajan Pro
+  #     fonts:
+  #       - asset: fonts/TrajanPro.ttf
+  #       - asset: fonts/TrajanPro_Bold.ttf
+  #         weight: 700
+  #
+  # For details regarding fonts in packages, see
+  # https://flutter.dev/to/font-from-package

+ 7 - 0
pubspec.lock

@@ -418,6 +418,13 @@ packages:
     description: flutter
     source: sdk
     version: "0.0.0"
+  flutter_tool_android:
+    dependency: "direct main"
+    description:
+      path: "plugins/flutter_tool_android"
+      relative: true
+    source: path
+    version: "0.0.1"
   flutter_web_plugins:
     dependency: transitive
     description: flutter

+ 4 - 0
pubspec.yaml

@@ -117,6 +117,10 @@ dependencies:
   agile_pay:
     path: plugins/agile_pay
 
+  #工具类-android
+  flutter_tool_android:
+    path: plugins/flutter_tool_android
+
   ######################地图########################
   flutter_map:
     path: plugins/map