Add battery charging status to Platform Channel example (#9147)
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
// 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 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);
|
||||
final SerializableFinder button = find.text('Refresh');
|
||||
await driver.waitFor(button);
|
||||
await driver.tap(button);
|
||||
|
||||
String batteryLevel;
|
||||
while(batteryLevel == null || batteryLevel.isEmpty) {
|
||||
batteryLevel = await driver.getText(batteryLevelLabel);
|
||||
}
|
||||
expect(batteryLevel, isNotEmpty);
|
||||
String batteryLevel;
|
||||
while (batteryLevel == null || batteryLevel.contains('unknown')) {
|
||||
batteryLevel = await driver.getText(batteryLevelLabel);
|
||||
}
|
||||
|
||||
expect(batteryLevel.contains('%'), isTrue);
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
29
examples/platform_channel_swift/.idea/workspace.xml
generated
29
examples/platform_channel_swift/.idea/workspace.xml
generated
@@ -1,29 +0,0 @@
|
||||
<?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>
|
||||
Reference in New Issue
Block a user