Giter Club home page Giter Club logo

flutter-setting-app's Introduction

Settings

This guide describes how to write custom platform-specific code.

Some platform-specific functionality is available through existing packages.

  • Scope: Android(Kotlin) and iOS(Swift 5)

  • Feature: open setting screen.

iOS/Swift 5

Open Settings screen

Simulator.Screen.Recording.-.iPhone.SE.3rd.generation.-.2022-04-19.at.22.49.47.mp4

Android/Kotlin

Open Settings screen

Flutter Channel

Create channel

All channel names used in a single app must be unique; prefix the channel name with a unique ‘domain prefix’, for example:

  1. Define App Id

This is application Id(Android) or bundle Id (iOS)

static const String appID = "com.example";
  1. Define Feature Name
featureName= "settings";
  1. Define Channel
final String channelName= "$appID/$featureName";

static const MethodChannel platform = MethodChannel(channelName);

Invoke a method on the method channel

Create method name

  1. Define method name
static const String methodOpenAppSettingScreen = "openAppSettingScreen";
  1. Define method invoke

invoke a method on the method channel, specifying the concrete method to call using the String identifier openAppSettingScreen.

The call might fail—for example if the platform does not support the platform API (such as when running in a simulator)—so wrap the invokeMethod call in a try-catch statement.

Future<bool> openAppSettingScreen({final Function? onError}) async {
    try {
      final bool result =
          await platform.invokeMethod(methodOpenAppSettingScreen);
      return result;
    } on PlatformException catch (e) {
      if (kDebugMode) {
        print(e.toString());
      }
      return false;
    }
  }

The method await platform.invokeMethod(methodOpenAppSettingScreen) return data type bool.

When you calling platform-specific iOS and Android code using platform channels, you must return same data type.

Check the table shows how Dart values are received on the platform side and vice versa:

  • Flutter(Dart): bool
  • Android(Kotlin) : Boolean
  • iOS(Swift): Bool

Add an Android(Kotlin) platform-specific implementation

  1. Create configure Flutter Engine
  • open file MainActivity.kt
  • create method configureFlutterEngine

Screen Shot 2022-04-19 at 21 23 23

class MainActivity: FlutterActivity() {

    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
    }
}
  • Add channel name and method name

The channel name and method name are must be same value as Flutter channel

    companion object {
        private const val APP_ID: String = "com.example"
        private const val FEATURE_NAME: String = "settings"
        private const val CHANNEL_NAME: String = "$APP_ID/$FEATURE_NAME"
        private const val METHOD_OPEN_APP_SETTING_SCREEN: String = "openAppSettingScreen"
    }
  • Implement open setting screen
    fun openSettingScreen(): Boolean {
        val intentSetting = Intent(Settings.ACTION_APPLICATION_DETAILS_SETTINGS).apply {
            data = Uri.fromParts("package", packageName, null)
        }
        return try {
            startActivity(intentSetting)
            true
        } catch (e: Exception) {
            false
        }
    }

Remember method openSettingScreen will return Boolean type.

  • Detect channel name on method configureFlutterEngine
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME).setMethodCallHandler {
                call, result ->
            if (call.method == METHOD_OPEN_APP_SETTING_SCREEN) {
                // TODO
                return@setMethodCallHandler
            }
        }
    }
  • Implement method and handle result
    override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
        super.configureFlutterEngine(flutterEngine)
        MethodChannel(flutterEngine.dartExecutor.binaryMessenger, CHANNEL_NAME).setMethodCallHandler {
                call, result ->
            if (call.method == METHOD_OPEN_APP_SETTING_SCREEN) {
                result.success(openSettingScreen())
                return@setMethodCallHandler
            }
        }
    }

Add an iOS platform-specific implementation

  1. Create configure Flutter Engine
  • open file AppDelegate.swift on Xcode
@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)
  }

  • define controller
@UIApplicationMain
@objc class AppDelegate: FlutterAppDelegate {
  override func application(
    _ application: UIApplication,
    didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
  ) -> Bool {
    let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
    
    GeneratedPluginRegistrant.register(with: self)
    return super.application(application, didFinishLaunchingWithOptions: launchOptions)
  }
}
  • Add channel name and method name

The channel name and method name are must be same value as Flutter channel

    let appID = "com.example"
    let featureName = "settings"
    let methodOpenAppSettingScreen = "openAppSettingScreen"
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channelName = "\(self.appID)/\(self.featureName)"
        
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
  • Implement open setting screen
    
    private func openSettingScreen() -> Bool {
        if let url = URL(string:UIApplication.openSettingsURLString) {
            if UIApplication.shared.canOpenURL(url) {
                if #available(iOS 10.0, *) {
                    do {
                        try  UIApplication.shared.open(url, options: [:], completionHandler: nil)
                        return true
                    } catch {
                        return false
                    }
                    
                }
                return UIApplication.shared.openURL(url)
                
            }
        }
        
        return false
    }

Remember method openSettingScreen will return Bool type.

  • Find Flutter channel on method application and detect method name
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channelName = "\(self.appID)/\(self.featureName)"
        
        let settingChannel = FlutterMethodChannel(name: channelName,
                                                  binaryMessenger: controller.binaryMessenger)
        settingChannel.setMethodCallHandler({
            (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            if (call.method == self.methodOpenAppSettingScreen) {
                // TODO
            }
            
        })
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
  • Implement method and handle result
    
    override func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        let controller : FlutterViewController = window?.rootViewController as! FlutterViewController
        let channelName = "\(self.appID)/\(self.featureName)"
        
        let settingChannel = FlutterMethodChannel(name: channelName,
                                                  binaryMessenger: controller.binaryMessenger)
        settingChannel.setMethodCallHandler({
            (call: FlutterMethodCall, result: @escaping FlutterResult) -> Void in
            if (call.method == self.methodOpenAppSettingScreen) {
                result(self.openSettingScreen())
            }
            
        })
        
        GeneratedPluginRegistrant.register(with: self)
        return super.application(application, didFinishLaunchingWithOptions: launchOptions)
    }
    

Apply Channel Method

Future<void> _onSetting() async {
    final SettingChannel settingChannel = SettingChannel();
    await settingChannel.openAppSettingScreen();
}

Source code

https://github.com/ttpho/flutter-setting-app/blob/main/settings/lib/main.dart

flutter-setting-app's People

Contributors

ttpho avatar

Stargazers

 avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.