Commit 4a4d100b authored by Sarah Zakarias's avatar Sarah Zakarias Committed by GitHub

Add battery charging status to Platform Channel example (#9147)

parent af170c8e
......@@ -4,6 +4,8 @@
package com.example.platformchannel;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.ContextWrapper;
import android.content.Intent;
import android.content.IntentFilter;
......@@ -13,19 +15,41 @@ import android.os.Build.VERSION_CODES;
import android.os.Bundle;
import io.flutter.app.FlutterActivity;
import io.flutter.plugin.common.FlutterEventChannel;
import io.flutter.plugin.common.FlutterEventChannel.EventSink;
import io.flutter.plugin.common.FlutterEventChannel.StreamHandler;
import io.flutter.plugin.common.FlutterMethodChannel;
import io.flutter.plugin.common.FlutterMethodChannel.MethodCallHandler;
import io.flutter.plugin.common.FlutterMethodChannel.Response;
import io.flutter.plugin.common.MethodCall;
public class MainActivity extends FlutterActivity {
private static final String CHANNEL = "samples.flutter.io/battery";
private static final String BATTERY_CHANNEL = "samples.flutter.io/battery";
private static final String CHARGING_CHANNEL = "samples.flutter.io/charging";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
new FlutterMethodChannel(getFlutterView(), CHANNEL).setMethodCallHandler(
new FlutterEventChannel(getFlutterView(), CHARGING_CHANNEL).setStreamHandler(
new StreamHandler() {
private BroadcastReceiver chargingStateChangeReceiver;
@Override
public void onListen(Object arguments, EventSink events) {
chargingStateChangeReceiver = createChargingStateChangeReceiver(events);
registerReceiver(
chargingStateChangeReceiver, new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
}
@Override
public void onCancel(Object arguments) {
unregisterReceiver(chargingStateChangeReceiver);
chargingStateChangeReceiver = null;
}
}
);
new FlutterMethodChannel(getFlutterView(), BATTERY_CHANNEL).setMethodCallHandler(
new MethodCallHandler() {
@Override
public void onMethodCall(MethodCall call, Response response) {
......@@ -45,6 +69,23 @@ public class MainActivity extends FlutterActivity {
);
}
private BroadcastReceiver createChargingStateChangeReceiver(final EventSink events) {
return new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
int status = intent.getIntExtra(BatteryManager.EXTRA_STATUS, -1);
if (status == BatteryManager.BATTERY_STATUS_UNKNOWN) {
events.error("UNAVAILABLE", "Charging status unavailable", null);
} else {
boolean isCharging = status == BatteryManager.BATTERY_STATUS_CHARGING ||
status == BatteryManager.BATTERY_STATUS_FULL;
events.success(isCharging ? "charging" : "discharging");
}
}
};
}
private int getBatteryLevel() {
int batteryLevel = -1;
if (VERSION.SDK_INT >= VERSION_CODES.LOLLIPOP) {
......
......@@ -5,6 +5,6 @@
#import <Flutter/Flutter.h>
#import <UIKit/UIKit.h>
@interface AppDelegate : FlutterAppDelegate
@interface AppDelegate : FlutterAppDelegate<FlutterStreamHandler>
@end
......@@ -5,11 +5,16 @@
#import "AppDelegate.h"
#import <Flutter/Flutter.h>
@implementation AppDelegate
@implementation AppDelegate {
FlutterEventReceiver _eventReceiver;
}
- (BOOL)application:(UIApplication*)application
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions {
FlutterViewController* controller =
(FlutterViewController*)self.window.rootViewController;
FlutterMethodChannel* batteryChannel = [FlutterMethodChannel
methodChannelWithName:@"samples.flutter.io/battery"
binaryMessenger:controller];
......@@ -28,6 +33,11 @@
result(FlutterMethodNotImplemented);
}
}];
FlutterEventChannel* chargingChannel = [FlutterEventChannel
eventChannelWithName:@"samples.flutter.io/charging"
binaryMessenger:controller];
[chargingChannel setStreamHandler:self];
return YES;
}
......@@ -41,4 +51,41 @@
}
}
- (FlutterError*)onListenWithArguments:(id)arguments
eventReceiver:(FlutterEventReceiver)eventReceiver {
_eventReceiver = eventReceiver;
[[UIDevice currentDevice] setBatteryMonitoringEnabled:YES];
[[NSNotificationCenter defaultCenter]
addObserver:self
selector:@selector(onBatteryStateDidChange:)
name:UIDeviceBatteryStateDidChangeNotification
object:nil];
return nil;
}
- (void)onBatteryStateDidChange:(NSNotification*)notification {
if (!_eventReceiver) return;
UIDeviceBatteryState state = [[UIDevice currentDevice] batteryState];
switch (state) {
case UIDeviceBatteryStateFull:
case UIDeviceBatteryStateCharging:
_eventReceiver(@"charging");
break;
case UIDeviceBatteryStateUnplugged:
_eventReceiver(@"discharging");
break;
default:
_eventReceiver([FlutterError errorWithCode:@"UNAVAILABLE"
message:@"Charging status unavailable"
details:nil]);
break;
}
}
- (FlutterError*)onCancelWithArguments:(id)arguments {
[[NSNotificationCenter defaultCenter] removeObserver:self];
_eventReceiver = nil;
return nil;
}
@end
// Copyright 2016 The Chromium Authors. All rights reserved.
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
......@@ -13,36 +13,67 @@ class PlatformChannel extends StatefulWidget {
}
class _PlatformChannelState extends State<PlatformChannel> {
static const PlatformMethodChannel platform = const PlatformMethodChannel('samples.flutter.io/battery');
String _batteryLevel = '';
static const PlatformMethodChannel methodChannel =
const PlatformMethodChannel('samples.flutter.io/battery');
static const PlatformEventChannel eventChannel =
const PlatformEventChannel('samples.flutter.io/charging');
String _batteryLevel = 'Battery level: unknown.';
String _chargingStatus = 'Battery status: unknown.';
Future<Null> _getBatteryLevel() async {
String batteryLevel;
try {
final int result = await platform.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level at $result % .';
} on PlatformException catch (e) {
batteryLevel = "Failed to get battery level: '${e.message}'.";
final int result = await methodChannel.invokeMethod('getBatteryLevel');
batteryLevel = 'Battery level: $result%.';
} on PlatformException {
batteryLevel = "Failed to get battery level.";
}
setState(() {
_batteryLevel = batteryLevel;
});
}
@override
void initState() {
super.initState();
eventChannel.receiveBroadcastStream().listen(_onEvent, onError: _onError);
}
void _onEvent(String event) {
setState(() {
_chargingStatus =
"Battery status: ${event == 'charging' ? '' : 'dis'}charging.";
});
}
void _onError(PlatformException error) {
setState(() {
_chargingStatus = "Battery status: unknown.";
});
}
@override
Widget build(BuildContext context) {
return new Material(
child: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new RaisedButton(
child: new Text('Get Battery Level'),
onPressed: _getBatteryLevel,
),
new Text(_batteryLevel, key: new Key('Battery level label')),
],
),
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
new Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
new Text(_batteryLevel, key: new Key('Battery level label')),
new Padding(
padding: new EdgeInsets.all(16.0),
child: new RaisedButton(
child: new Text('Refresh'),
onPressed: _getBatteryLevel,
),
),
],
),
new Text(_chargingStatus),
],
),
);
}
......
......@@ -14,23 +14,24 @@ void main() {
});
tearDownAll(() async {
if (driver != null)
driver.close();
if (driver != null) driver.close();
});
test('tap on the button, verify result', () async {
final SerializableFinder batteryLevelLabel = find.byValueKey('Battery level label');
expect(batteryLevelLabel, isNotNull);
final SerializableFinder button = find.text('Get Battery Level');
await driver.waitFor(button);
await driver.tap(button);
String batteryLevel;
while(batteryLevel == null || batteryLevel.isEmpty) {
batteryLevel = await driver.getText(batteryLevelLabel);
}
expect(batteryLevel, isNotEmpty);
final SerializableFinder batteryLevelLabel =
find.byValueKey('Battery level label');
expect(batteryLevelLabel, isNotNull);
final SerializableFinder button = find.text('Refresh');
await driver.waitFor(button);
await driver.tap(button);
String batteryLevel;
while (batteryLevel == null || batteryLevel.contains('unknown')) {
batteryLevel = await driver.getText(batteryLevelLabel);
}
expect(batteryLevel.contains('%'), isTrue);
});
});
}
\ No newline at end of file
}
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="FileEditorManager">
<leaf>
<file leaf-file-name="main.dart" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/lib/main.dart">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="0">
<caret line="0" column="0" lean-forward="false" selection-start-line="0" selection-start-column="0" selection-end-line="0" selection-end-column="0" />
</state>
</provider>
</entry>
</file>
</leaf>
</component>
<component name="ToolWindowManager">
<editor active="true" />
<layout>
<window_info id="Project" active="false" anchor="left" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="true" show_stripe_button="true" weight="0.25" sideWeight="0.5" order="0" side_tool="false" content_ui="combo" />
</layout>
</component>
<component name="ProjectView">
<panes>
<pane id="ProjectPane">
<option name="show-excluded-files" value="false" />
</pane>
</panes>
</component>
</project>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment