Bird
Raised Fist0
Fluttermobile~20 mins

Platform channels (MethodChannel) in Flutter - Mini App: Build & Ship

Choose your learning style10 modes available
Build: Battery Level Screen
This screen shows the current battery level of the device by communicating with native platform code using MethodChannel.
Target UI
-------------------------
| Battery Level Screen   |
|-----------------------|
|                       |
|  Battery Level: ?%    |
|                       |
|  [Get Battery Level]   |
|                       |
-------------------------
Display a text showing 'Battery Level: ?%' initially.
Add a button labeled 'Get Battery Level'.
When the button is tapped, use MethodChannel to call native code to get battery level.
Update the text with the received battery level percentage.
Handle errors by showing 'Failed to get battery level.'
Starter Code
Flutter
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BatteryLevelScreen extends StatefulWidget {
  @override
  State<BatteryLevelScreen> createState() => _BatteryLevelScreenState();
}

class _BatteryLevelScreenState extends State<BatteryLevelScreen> {
  static const platform = MethodChannel('samples.flutter.dev/battery');

  String _batteryLevel = 'Battery Level: ?%';

  Future<void> _getBatteryLevel() async {
    // TODO: Call native code using platform.invokeMethod
    // and update _batteryLevel with the result or error
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Battery Level Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_batteryLevel, style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getBatteryLevel,
              child: const Text('Get Battery Level'),
            ),
          ],
        ),
      ),
    );
  }
}
Task 1
Task 2
Task 3
Solution
Flutter
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';

class BatteryLevelScreen extends StatefulWidget {
  @override
  State<BatteryLevelScreen> createState() => _BatteryLevelScreenState();
}

class _BatteryLevelScreenState extends State<BatteryLevelScreen> {
  static const platform = MethodChannel('samples.flutter.dev/battery');

  String _batteryLevel = 'Battery Level: ?%';

  Future<void> _getBatteryLevel() async {
    String batteryLevel;
    try {
      final int result = await platform.invokeMethod('getBatteryLevel');
      batteryLevel = 'Battery Level: $result%';
    } on PlatformException {
      batteryLevel = 'Failed to get battery level.';
    }

    if (!mounted) return;

    setState(() {
      _batteryLevel = batteryLevel;
    });
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Battery Level Screen')),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(_batteryLevel, style: const TextStyle(fontSize: 24)),
            const SizedBox(height: 20),
            ElevatedButton(
              onPressed: _getBatteryLevel,
              child: const Text('Get Battery Level'),
            ),
          ],
        ),
      ),
    );
  }
}

This app uses a MethodChannel to communicate with native platform code to get the battery level.

We define a channel named samples.flutter.dev/battery. When the user taps the button, _getBatteryLevel calls invokeMethod('getBatteryLevel') which asks the native code for the battery percentage.

If successful, it updates the text to show the battery level. If it fails, it shows an error message.

This example teaches how Flutter apps can talk to native code to access device features not directly available in Flutter.

Final Result
Completed Screen
-------------------------
| Battery Level Screen   |
|-----------------------|
|                       |
|  Battery Level: 76%   |
|                       |
|  [Get Battery Level]   |
|                       |
-------------------------
User taps 'Get Battery Level' button.
App calls native code via MethodChannel.
Battery level number updates in the text.
If error occurs, text shows 'Failed to get battery level.'
Stretch Goal
Add a loading indicator while the battery level is being fetched.
💡 Hint
Use a boolean state variable to track loading and show CircularProgressIndicator instead of the button text during loading.

Practice

(1/5)
1. What is the main purpose of MethodChannel in Flutter?
easy
A. To manage app navigation
B. To communicate between Flutter and native platform code
C. To create UI widgets in Flutter
D. To handle Flutter animations

Solution

  1. Step 1: Understand Flutter and native code interaction

    Flutter apps sometimes need to use features only available in native code like Android or iOS.
  2. Step 2: Role of MethodChannel

    MethodChannel is the way Flutter sends messages to native code and gets results back.
  3. Final Answer:

    To communicate between Flutter and native platform code -> Option B
  4. Quick Check:

    MethodChannel = Flutter-native communication [OK]
Hint: MethodChannel connects Flutter with native code [OK]
Common Mistakes:
  • Thinking MethodChannel creates UI widgets
  • Confusing MethodChannel with navigation or animation
  • Assuming MethodChannel runs only in Flutter without native code
2. Which of the following is the correct way to create a MethodChannel in Flutter?
easy
A. var channel = new MethodChannel();
B. MethodChannel channel = MethodChannel();
C. MethodChannel channel = MethodChannel('com.example.channel');
D. var channel = MethodChannel.create('channel');

Solution

  1. Step 1: Check MethodChannel constructor usage

    The constructor requires a string name to identify the channel, e.g., 'com.example.channel'.
  2. Step 2: Validate options

    MethodChannel channel = MethodChannel('com.example.channel'); correctly uses MethodChannel('com.example.channel'). Options A, C, and D are invalid syntax or missing required parameters.
  3. Final Answer:

    MethodChannel channel = MethodChannel('com.example.channel'); -> Option C
  4. Quick Check:

    MethodChannel needs a channel name string [OK]
Hint: MethodChannel constructor needs a channel name string [OK]
Common Mistakes:
  • Omitting the channel name string
  • Using 'new' keyword unnecessarily
  • Calling non-existent create() method
3. Given this Flutter code snippet, what will be printed if the native side returns the string "Hello from native"?
final channel = MethodChannel('com.example.channel');
String message = await channel.invokeMethod('greet');
print(message);
medium
A. null
B. Empty string
C. An error message
D. "Hello from native"

Solution

  1. Step 1: Understand invokeMethod behavior

    The invokeMethod sends a message to native code and waits for a response.
  2. Step 2: Native returns "Hello from native" string

    The returned string is assigned to message and printed.
  3. Final Answer:

    "Hello from native" -> Option D
  4. Quick Check:

    invokeMethod returns native response string [OK]
Hint: invokeMethod returns native response awaited as result [OK]
Common Mistakes:
  • Assuming invokeMethod returns null if native responds
  • Expecting invokeMethod to print automatically
  • Ignoring await causing Future object print
4. What is wrong with this Flutter code snippet for calling native code?
final channel = MethodChannel('com.example.channel');
channel.invokeMethod('getData');
print('Data received');
medium
A. invokeMethod is not awaited, so print runs before data arrives
B. MethodChannel name is invalid
C. invokeMethod requires a callback parameter
D. print statement syntax is incorrect

Solution

  1. Step 1: Check asynchronous call usage

    invokeMethod returns a Future and should be awaited to get the result before proceeding.
  2. Step 2: Analyze print timing

    Without await, print('Data received') runs immediately, before native response arrives.
  3. Final Answer:

    invokeMethod is not awaited, so print runs before data arrives -> Option A
  4. Quick Check:

    Always await invokeMethod for native response [OK]
Hint: Always await invokeMethod to get native result before next code [OK]
Common Mistakes:
  • Not awaiting invokeMethod causing timing issues
  • Thinking MethodChannel name is invalid without reason
  • Expecting invokeMethod to take a callback parameter
5. You want to send a message from Flutter to native Android code to get battery level. Which steps are needed to implement this using MethodChannel? Choose the correct sequence.
hard
A. 1. Create MethodChannel in Flutter with a name 2. Call invokeMethod('getBatteryLevel') 3. In Android native code, set MethodCallHandler on same channel name 4. Handle 'getBatteryLevel' method and return battery level 5. Flutter receives battery level response
B. 1. Create MethodChannel in Flutter with a name 2. Directly access Android battery API from Flutter 3. No native code needed 4. Flutter gets battery level
C. 1. Create MethodChannel in Flutter 2. Call invokeMethod without method name 3. Android native code listens on different channel name 4. Return battery level
D. 1. Use Flutter plugin battery package 2. No need to write native code or MethodChannel 3. Flutter gets battery level

Solution

  1. Step 1: Setup MethodChannel in Flutter

    Create a channel with a unique name to communicate with native code.
  2. Step 2: Call invokeMethod with method name

    Flutter sends 'getBatteryLevel' request to native side.
  3. Step 3: Setup native Android MethodCallHandler

    Native code listens on the same channel name and handles method calls.
  4. Step 4: Native code returns battery level

    Native side gets battery info and sends it back.
  5. Step 5: Flutter receives and uses battery level

    Flutter awaits response and uses the data.
  6. Final Answer:

    1. Create MethodChannel in Flutter with a name 2. Call invokeMethod('getBatteryLevel') 3. In Android native code, set MethodCallHandler on same channel name 4. Handle 'getBatteryLevel' method and return battery level 5. Flutter receives battery level response -> Option A
  7. Quick Check:

    Flutter-native communication needs matching channel and method handling [OK]
Hint: Match channel name and method handler on both sides [OK]
Common Mistakes:
  • Skipping native code setup for MethodCallHandler
  • Calling invokeMethod without method name
  • Using different channel names on Flutter and native sides
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard