mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
[federated_plugin_sample] modify the sample to expose battery API instead of geolocation API (#526)
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
# federated_plugin
|
# federated_plugin
|
||||||
|
|
||||||
A Flutter plugin sample that shows how to implement a federated plugin to fetch the device location on different platforms.
|
A Flutter plugin sample that shows how to implement a federated plugin to retrieve current battery level on different platforms.
|
||||||
|
|
||||||
This sample is currently being built. Not all platforms and functionality are in place.
|
This sample is currently being built. Not all platforms and functionality are in place.
|
||||||
|
|
||||||
|
|||||||
@@ -40,5 +40,4 @@ android {
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version"
|
||||||
implementation 'com.google.android.gms:play-services-location:17.0.0'
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
package="dev.flutter.federated_plugin">
|
package="dev.flutter.federated_plugin">
|
||||||
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
|
|
||||||
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
|
|
||||||
</manifest>
|
</manifest>
|
||||||
|
|||||||
@@ -4,109 +4,55 @@
|
|||||||
|
|
||||||
package dev.flutter.federated_plugin
|
package dev.flutter.federated_plugin
|
||||||
|
|
||||||
import android.Manifest
|
|
||||||
import android.app.Activity
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.PackageManager
|
import android.content.Intent
|
||||||
|
import android.content.IntentFilter
|
||||||
|
import android.os.BatteryManager
|
||||||
|
import android.os.Build
|
||||||
import androidx.annotation.NonNull
|
import androidx.annotation.NonNull
|
||||||
import androidx.core.app.ActivityCompat.requestPermissions
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import com.google.android.gms.location.LocationServices.getFusedLocationProviderClient
|
|
||||||
|
|
||||||
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
import io.flutter.embedding.engine.plugins.FlutterPlugin
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityAware
|
|
||||||
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding
|
|
||||||
import io.flutter.plugin.common.MethodCall
|
import io.flutter.plugin.common.MethodCall
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
import io.flutter.plugin.common.MethodChannel.MethodCallHandler
|
||||||
import io.flutter.plugin.common.MethodChannel.Result
|
import io.flutter.plugin.common.MethodChannel.Result
|
||||||
import io.flutter.plugin.common.PluginRegistry
|
|
||||||
|
|
||||||
|
class FederatedPlugin : FlutterPlugin, MethodCallHandler {
|
||||||
class FederatedPlugin : FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.RequestPermissionsResultListener {
|
|
||||||
private lateinit var channel: MethodChannel
|
private lateinit var channel: MethodChannel
|
||||||
private lateinit var context: Context
|
private var context: Context? = null
|
||||||
private lateinit var activity: Activity
|
|
||||||
private lateinit var result: Result
|
|
||||||
private val REQUEST_CODE = 1001
|
|
||||||
|
|
||||||
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onAttachedToEngine(@NonNull flutterPluginBinding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "location")
|
channel = MethodChannel(flutterPluginBinding.binaryMessenger, "battery")
|
||||||
channel.setMethodCallHandler(this)
|
channel.setMethodCallHandler(this)
|
||||||
context = flutterPluginBinding.applicationContext
|
context = flutterPluginBinding.applicationContext
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
override fun onMethodCall(@NonNull call: MethodCall, @NonNull result: Result) {
|
||||||
this.result = result
|
if (call.method == "getBatteryLevel") {
|
||||||
if (call.method == "getLocation") {
|
val batteryLevel: Int
|
||||||
// Check for the runtime permission if SDK version is greater than 23. If permissions
|
|
||||||
// are granted, send the location data back to Dart. If permissions are not granted,
|
batteryLevel = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
|
||||||
// request for the runtime permissions.
|
val batteryManager = context?.getSystemService(Context.BATTERY_SERVICE) as BatteryManager
|
||||||
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.LOLLIPOP && !checkPermissions()) {
|
batteryManager.getIntProperty(BatteryManager.BATTERY_PROPERTY_CAPACITY)
|
||||||
requestPermissions(activity, arrayOf(
|
|
||||||
Manifest.permission.ACCESS_FINE_LOCATION,
|
|
||||||
Manifest.permission.ACCESS_COARSE_LOCATION
|
|
||||||
), REQUEST_CODE)
|
|
||||||
} else {
|
} else {
|
||||||
provideLocation()
|
val intent = IntentFilter(Intent.ACTION_BATTERY_CHANGED).let { intentFilter ->
|
||||||
|
context?.registerReceiver(null, intentFilter)
|
||||||
|
}
|
||||||
|
intent!!.getIntExtra(BatteryManager.EXTRA_LEVEL, -1) * 100 / intent.getIntExtra(BatteryManager.EXTRA_SCALE, -1)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (batteryLevel < 0) {
|
||||||
|
result.error("STATUS_UNAVAILABLE", "Not able to determine battery level.", null)
|
||||||
|
} else {
|
||||||
|
result.success(batteryLevel)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
result.notImplemented()
|
result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Method to fetch and send the last known location of the device to Dart.
|
|
||||||
private fun provideLocation() {
|
|
||||||
getFusedLocationProviderClient(context).lastLocation
|
|
||||||
.addOnSuccessListener { location ->
|
|
||||||
if (location != null) {
|
|
||||||
result.success(listOf(location.longitude, location.latitude))
|
|
||||||
} else {
|
|
||||||
result.error("NOT_DETERMINED", "Not able to determine location", null)
|
|
||||||
}
|
|
||||||
}.addOnFailureListener { exception ->
|
|
||||||
result.error("Error", exception.message, null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Method to check permissions to access the location data.
|
|
||||||
private fun checkPermissions(): Boolean {
|
|
||||||
val fineLocationPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_FINE_LOCATION)
|
|
||||||
val coarseLocationPermission = ContextCompat.checkSelfPermission(context, Manifest.permission.ACCESS_COARSE_LOCATION)
|
|
||||||
|
|
||||||
return fineLocationPermission == PackageManager.PERMISSION_GRANTED &&
|
|
||||||
coarseLocationPermission == PackageManager.PERMISSION_GRANTED
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
override fun onDetachedFromEngine(@NonNull binding: FlutterPlugin.FlutterPluginBinding) {
|
||||||
channel.setMethodCallHandler(null)
|
channel.setMethodCallHandler(null)
|
||||||
}
|
context = null
|
||||||
|
|
||||||
override fun onDetachedFromActivity() {}
|
|
||||||
|
|
||||||
override fun onReattachedToActivityForConfigChanges(binding: ActivityPluginBinding) {
|
|
||||||
activity = binding.activity
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onAttachedToActivity(binding: ActivityPluginBinding) {
|
|
||||||
activity = binding.activity
|
|
||||||
binding.addRequestPermissionsResultListener(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun onDetachedFromActivityForConfigChanges() {}
|
|
||||||
|
|
||||||
// Callback for the result after requesting for runtime permissions. If permissions
|
|
||||||
// are granted, send the location data, or send an error back to Dart if permissions
|
|
||||||
// are not granted.
|
|
||||||
override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>?, grantResults: IntArray): Boolean {
|
|
||||||
if (requestCode == REQUEST_CODE && grantResults.isNotEmpty()) {
|
|
||||||
if (grantResults[0] == PackageManager.PERMISSION_GRANTED && grantResults[1] == PackageManager.PERMISSION_GRANTED) {
|
|
||||||
provideLocation()
|
|
||||||
} else {
|
|
||||||
result.error("PERMISSION_DENIED", "Permission denied from User", null)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,15 +18,15 @@ class MyApp extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Demonstrates how to use the getLocation method from federated_plugin to access
|
/// Demonstrates how to use the getBatteryLevel method from federated_plugin to retrieve
|
||||||
/// location data.
|
/// current battery level of device.
|
||||||
class HomePage extends StatefulWidget {
|
class HomePage extends StatefulWidget {
|
||||||
@override
|
@override
|
||||||
_HomePageState createState() => _HomePageState();
|
_HomePageState createState() => _HomePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
class _HomePageState extends State<HomePage> {
|
class _HomePageState extends State<HomePage> {
|
||||||
Location location;
|
int batteryLevel;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -40,21 +40,20 @@ class _HomePageState extends State<HomePage> {
|
|||||||
child: Column(
|
child: Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
location == null
|
batteryLevel == null
|
||||||
? SizedBox.shrink()
|
? SizedBox.shrink()
|
||||||
: Text(
|
: Text(
|
||||||
'Latitude: ${location.latitude}\n'
|
'Battery Level: $batteryLevel',
|
||||||
'Longitude: ${location.longitude}',
|
|
||||||
style: Theme.of(context).textTheme.headline5,
|
style: Theme.of(context).textTheme.headline5,
|
||||||
),
|
),
|
||||||
SizedBox(height: 16),
|
SizedBox(height: 16),
|
||||||
RaisedButton(
|
RaisedButton(
|
||||||
child: Text('Get Location'),
|
child: Text('Get Battery Level'),
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
try {
|
try {
|
||||||
final result = await getLocation();
|
final result = await getBatteryLevel();
|
||||||
setState(() {
|
setState(() {
|
||||||
location = result;
|
batteryLevel = result;
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
Scaffold.of(context).showSnackBar(
|
Scaffold.of(context).showSnackBar(
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:federated_plugin/federated_plugin.dart';
|
|
||||||
import 'package:federated_plugin_example/main.dart';
|
import 'package:federated_plugin_example/main.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
@@ -10,27 +9,23 @@ import 'package:flutter_test/flutter_test.dart';
|
|||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
group('federated plugin demo tests', () {
|
group('federated plugin demo tests', () {
|
||||||
final location = Location(latitude: 131.0, longitude: 221.0);
|
final batteryLevel = 45;
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
MethodChannel('location').setMockMethodCallHandler((call) async {
|
MethodChannel('battery').setMockMethodCallHandler((call) async {
|
||||||
if (call.method == 'getLocation') {
|
if (call.method == 'getBatteryLevel') {
|
||||||
return [location.longitude, location.latitude];
|
return batteryLevel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('get location from platform', (tester) async {
|
testWidgets('get current battery level from platform', (tester) async {
|
||||||
await tester.pumpWidget(MyApp());
|
await tester.pumpWidget(MyApp());
|
||||||
|
|
||||||
// Tap button to get location from platform.
|
// Tap button to retrieve current battery level from platform.
|
||||||
await tester.tap(find.byType(RaisedButton));
|
await tester.tap(find.byType(RaisedButton));
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
|
|
||||||
expect(
|
expect(find.text('Battery Level: $batteryLevel'), findsOneWidget);
|
||||||
find.text('Latitude: ${location.latitude}\n'
|
|
||||||
'Longitude: ${location.longitude}'),
|
|
||||||
findsOneWidget,
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,12 +5,10 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
||||||
import 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
export 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
|
|
||||||
/// Returns [Location] to provide latitude and longitude.
|
/// Returns the current battery level of device.
|
||||||
///
|
///
|
||||||
/// It uses [FederatedPluginInterface] interface to provide location.
|
/// It uses [FederatedPluginInterface] interface to provide current battery level.
|
||||||
Future<Location> getLocation() async {
|
Future<int> getBatteryLevel() async {
|
||||||
return await FederatedPluginInterface.instance.getLocation();
|
return await FederatedPluginInterface.instance.getBatteryLevel();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,17 +10,16 @@ void main() {
|
|||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
group('Federated Plugin Test', () {
|
group('Federated Plugin Test', () {
|
||||||
final location = Location(latitude: 131.0, longitude: 221.0);
|
final batteryLevel = 34;
|
||||||
MethodChannel('location').setMockMethodCallHandler((call) async {
|
MethodChannel('battery').setMockMethodCallHandler((call) async {
|
||||||
if (call.method == 'getLocation') {
|
if (call.method == 'getBatteryLevel') {
|
||||||
return [location.longitude, location.latitude];
|
return batteryLevel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getLocation method test', () async {
|
test('getBatteryLevel method test', () async {
|
||||||
final result = await getLocation();
|
final result = await getBatteryLevel();
|
||||||
expect(result.longitude, location.longitude);
|
expect(result, batteryLevel);
|
||||||
expect(result.latitude, location.latitude);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
// Copyright 2020 The Flutter team. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
|
// found in the LICENSE file.
|
||||||
|
|
||||||
|
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
|
|
||||||
|
/// Implements [FederatedPluginInterface] using [MethodChannel] to fetch
|
||||||
|
/// battery level from platform.
|
||||||
|
class BatteryMethodChannel extends FederatedPluginInterface {
|
||||||
|
static const MethodChannel _methodChannel = MethodChannel('battery');
|
||||||
|
|
||||||
|
@override
|
||||||
|
Future<int> getBatteryLevel() async {
|
||||||
|
return await _methodChannel.invokeMethod<int>('getBatteryLevel');
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:federated_plugin_platform_interface/location_method_channel.dart';
|
import 'package:federated_plugin_platform_interface/battery_method_channel.dart';
|
||||||
import 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
import 'package:plugin_platform_interface/plugin_platform_interface.dart';
|
||||||
|
|
||||||
/// Interface which allows all the platform plugins to implement the same
|
/// Interface which allows all the platform plugins to implement the same
|
||||||
@@ -12,11 +11,11 @@ abstract class FederatedPluginInterface extends PlatformInterface {
|
|||||||
FederatedPluginInterface() : super(token: _object);
|
FederatedPluginInterface() : super(token: _object);
|
||||||
|
|
||||||
static FederatedPluginInterface _federatedPluginInterface =
|
static FederatedPluginInterface _federatedPluginInterface =
|
||||||
LocationMethodChannel();
|
BatteryMethodChannel();
|
||||||
|
|
||||||
static final Object _object = Object();
|
static final Object _object = Object();
|
||||||
|
|
||||||
/// Provides instance of [LocationMethodChannel] to invoke platform calls.
|
/// Provides instance of [BatteryMethodChannel] to invoke platform calls.
|
||||||
static FederatedPluginInterface get instance => _federatedPluginInterface;
|
static FederatedPluginInterface get instance => _federatedPluginInterface;
|
||||||
|
|
||||||
static set instance(FederatedPluginInterface instance) {
|
static set instance(FederatedPluginInterface instance) {
|
||||||
@@ -24,8 +23,8 @@ abstract class FederatedPluginInterface extends PlatformInterface {
|
|||||||
_federatedPluginInterface = instance;
|
_federatedPluginInterface = instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns [Location] to provide latitude and longitude.
|
/// Returns the current battery level of device.
|
||||||
Future<Location> getLocation() async {
|
Future<int> getBatteryLevel() async {
|
||||||
throw UnimplementedError('getLocation() has not been implemented.');
|
throw UnimplementedError('getBatteryLevel() has not been implemented.');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
// Copyright 2020 The Flutter team. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
|
||||||
import 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
|
||||||
|
|
||||||
/// Implements [FederatedPluginInterface] using [MethodChannel] to fetch
|
|
||||||
/// location from platform.
|
|
||||||
class LocationMethodChannel extends FederatedPluginInterface {
|
|
||||||
static const MethodChannel _methodChannel = MethodChannel('location');
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<Location> getLocation() async {
|
|
||||||
final result =
|
|
||||||
await _methodChannel.invokeMethod<List<dynamic>>('getLocation');
|
|
||||||
|
|
||||||
return Location(
|
|
||||||
longitude: result.first as double,
|
|
||||||
latitude: result.last as double,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
// Copyright 2020 The Flutter team. All rights reserved.
|
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
|
||||||
// found in the LICENSE file.
|
|
||||||
|
|
||||||
/// Model to hold the incoming latitude and longitude values from platform.
|
|
||||||
class Location {
|
|
||||||
final double latitude;
|
|
||||||
final double longitude;
|
|
||||||
|
|
||||||
Location({this.latitude, this.longitude});
|
|
||||||
}
|
|
||||||
@@ -2,8 +2,7 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:federated_plugin_platform_interface/location_method_channel.dart';
|
import 'package:federated_plugin_platform_interface/battery_method_channel.dart';
|
||||||
import 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
|
|
||||||
@@ -11,18 +10,17 @@ void main() {
|
|||||||
TestWidgetsFlutterBinding.ensureInitialized();
|
TestWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
group('MethodChannel test', () {
|
group('MethodChannel test', () {
|
||||||
final location = Location(latitude: 1.0, longitude: 2.0);
|
final batteryLevel = 89;
|
||||||
MethodChannel('location').setMockMethodCallHandler((call) async {
|
MethodChannel('battery').setMockMethodCallHandler((call) async {
|
||||||
if (call.method == 'getLocation') {
|
if (call.method == 'getBatteryLevel') {
|
||||||
return [location.longitude, location.latitude];
|
return batteryLevel;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
test('getLocation method test', () async {
|
test('getBatteryLevel method test', () async {
|
||||||
final locationMethodChannel = LocationMethodChannel();
|
final locationMethodChannel = BatteryMethodChannel();
|
||||||
final result = await locationMethodChannel.getLocation();
|
final result = await locationMethodChannel.getBatteryLevel();
|
||||||
expect(result.longitude, location.longitude);
|
expect(result, batteryLevel);
|
||||||
expect(result.latitude, result.latitude);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,9 @@ build/
|
|||||||
**/ios/ServiceDefinitions.json
|
**/ios/ServiceDefinitions.json
|
||||||
**/ios/Runner/GeneratedPluginRegistrant.*
|
**/ios/Runner/GeneratedPluginRegistrant.*
|
||||||
|
|
||||||
|
# Web related
|
||||||
|
lib/generated_plugin_registrant.dart
|
||||||
|
|
||||||
# Exceptions to above rules.
|
# Exceptions to above rules.
|
||||||
!**/ios/**/default.mode1v3
|
!**/ios/**/default.mode1v3
|
||||||
!**/ios/**/default.mode2v3
|
!**/ios/**/default.mode2v3
|
||||||
|
|||||||
@@ -5,17 +5,17 @@
|
|||||||
import 'dart:html' as html;
|
import 'dart:html' as html;
|
||||||
|
|
||||||
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
import 'package:federated_plugin_platform_interface/federated_plugin_platform_interface.dart';
|
||||||
import 'package:federated_plugin_platform_interface/location_model.dart';
|
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
import 'package:flutter_web_plugins/flutter_web_plugins.dart';
|
||||||
|
|
||||||
/// Web Implementation of [FederatedPluginInterface] to provide location.
|
/// Web Implementation of [FederatedPluginInterface] to retrieve current battery
|
||||||
|
/// level of device.
|
||||||
class FederatedPlugin extends FederatedPluginInterface {
|
class FederatedPlugin extends FederatedPluginInterface {
|
||||||
final html.Geolocation _geolocation;
|
final html.Navigator _navigator;
|
||||||
|
|
||||||
/// Constructor to override the geolocation object for testing purpose.
|
/// Constructor to override the navigator object for testing purpose.
|
||||||
FederatedPlugin({html.Geolocation geolocation})
|
FederatedPlugin({html.Navigator navigator})
|
||||||
: _geolocation = geolocation ?? html.window.navigator.geolocation;
|
: _navigator = navigator ?? html.window.navigator;
|
||||||
|
|
||||||
/// Method to register the plugin which sets [FederatedPlugin] to be the default
|
/// Method to register the plugin which sets [FederatedPlugin] to be the default
|
||||||
/// instance of [FederatedPluginInterface].
|
/// instance of [FederatedPluginInterface].
|
||||||
@@ -23,21 +23,20 @@ class FederatedPlugin extends FederatedPluginInterface {
|
|||||||
FederatedPluginInterface.instance = FederatedPlugin();
|
FederatedPluginInterface.instance = FederatedPlugin();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns [Location] to provide latitude and longitude.
|
/// Returns the current battery level of device.
|
||||||
///
|
///
|
||||||
/// If any error, it's assume that user has denied the permission forever.
|
/// If any error, it's assume that the BatteryManager API is not supported by
|
||||||
|
/// browser.
|
||||||
@override
|
@override
|
||||||
Future<Location> getLocation() async {
|
Future<int> getBatteryLevel() async {
|
||||||
try {
|
try {
|
||||||
final geoPosition = await _geolocation.getCurrentPosition();
|
final battery = await _navigator.getBattery() as html.BatteryManager;
|
||||||
return Location(
|
// The battery level retrieved is in range of 0.0 to 1.0.
|
||||||
longitude: geoPosition.coords.longitude.toDouble(),
|
return battery.level * 100 as int;
|
||||||
latitude: geoPosition.coords.latitude.toDouble(),
|
|
||||||
);
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'PERMISSION_DENIED',
|
code: 'STATUS_UNAVAILABLE',
|
||||||
message: 'Permission denied from User',
|
message: 'The plugin is not supported by the browser.',
|
||||||
details: null,
|
details: null,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: federated_plugin_web
|
name: federated_plugin_web
|
||||||
description: Web implementation of federated_plugin to provide location.
|
description: Web implementation of federated_plugin to retrieve current battery level.
|
||||||
version: 0.0.1
|
version: 0.0.1
|
||||||
homepage:
|
homepage:
|
||||||
publish_to: none
|
publish_to: none
|
||||||
|
|||||||
@@ -9,45 +9,35 @@ import 'package:federated_plugin_web/federated_plugin_web.dart';
|
|||||||
import 'package:flutter_test/flutter_test.dart';
|
import 'package:flutter_test/flutter_test.dart';
|
||||||
import 'package:mockito/mockito.dart';
|
import 'package:mockito/mockito.dart';
|
||||||
|
|
||||||
const kLatitude = 4;
|
const kBatteryLevel = 0.49;
|
||||||
const kLongitude = 3;
|
|
||||||
|
|
||||||
class GeoLocationMock extends Mock implements Geolocation {}
|
class NavigatorMock extends Mock implements Navigator {}
|
||||||
|
|
||||||
class GeoPositionMock extends Mock implements Geoposition {
|
class BatteryManagerMock extends Mock implements BatteryManager {
|
||||||
@override
|
@override
|
||||||
Coordinates get coords => MockCoordinates();
|
num get level => kBatteryLevel;
|
||||||
}
|
|
||||||
|
|
||||||
class MockCoordinates extends Mock implements Coordinates {
|
|
||||||
@override
|
|
||||||
num get latitude => kLatitude;
|
|
||||||
|
|
||||||
@override
|
|
||||||
num get longitude => kLongitude;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
E2EWidgetsFlutterBinding.ensureInitialized();
|
E2EWidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
group('FederatedPlugin test', () {
|
group('FederatedPlugin test', () {
|
||||||
final geoLocationMock = GeoLocationMock();
|
final navigatorMock = NavigatorMock();
|
||||||
|
|
||||||
setUp(() {
|
setUp(() {
|
||||||
when(geoLocationMock.getCurrentPosition())
|
when(navigatorMock.getBattery())
|
||||||
.thenAnswer((realInvocation) async => GeoPositionMock());
|
.thenAnswer((realInvocation) async => BatteryManagerMock());
|
||||||
});
|
});
|
||||||
|
|
||||||
testWidgets('getLocation Method', (tester) async {
|
testWidgets('getBatteryLevel Method', (tester) async {
|
||||||
final federatedPlugin = FederatedPlugin(geolocation: geoLocationMock);
|
final federatedPlugin = FederatedPlugin(navigator: navigatorMock);
|
||||||
final location = await federatedPlugin.getLocation();
|
final batteryLevel = await federatedPlugin.getBatteryLevel();
|
||||||
|
|
||||||
// Verify that getCurrentPosition was called.
|
// Verify that getBattery was called.
|
||||||
verify(geoLocationMock.getCurrentPosition());
|
verify(navigatorMock.getBattery());
|
||||||
|
|
||||||
// Verify the values of Location.longitude and Location.latitude.
|
// Verify the battery level.
|
||||||
expect(location.longitude, kLongitude);
|
expect(batteryLevel, kBatteryLevel * 100);
|
||||||
expect(location.latitude, kLatitude);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user