mirror of
https://github.com/flutter/samples.git
synced 2025-11-08 22:09:06 +00:00
[platform_channels] Migrate to sound null safety (#803)
This commit is contained in:
@@ -32,6 +32,8 @@ class AccelerometerStreamHandler(sManager: SensorManager, s: Sensor) : EventChan
|
|||||||
if (sensorEvent != null) {
|
if (sensorEvent != null) {
|
||||||
val axisValues = listOf(sensorEvent.values[0], sensorEvent.values[1], sensorEvent.values[2])
|
val axisValues = listOf(sensorEvent.values[0], sensorEvent.values[1], sensorEvent.values[2])
|
||||||
eventSink.success(axisValues)
|
eventSink.success(axisValues)
|
||||||
|
} else {
|
||||||
|
eventSink.error("DATA_UNAVAILABLE", "Cannot get accelerometer data", null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,6 @@
|
|||||||
<Workspace
|
<Workspace
|
||||||
version = "1.0">
|
version = "1.0">
|
||||||
<FileRef
|
<FileRef
|
||||||
location = "group:Runner.xcodeproj">
|
location = "self:">
|
||||||
</FileRef>
|
</FileRef>
|
||||||
</Workspace>
|
</Workspace>
|
||||||
|
|||||||
@@ -39,9 +39,7 @@ class DemoInfo {
|
|||||||
final String demoTitle;
|
final String demoTitle;
|
||||||
final String demoRoute;
|
final String demoRoute;
|
||||||
|
|
||||||
DemoInfo(this.demoTitle, this.demoRoute)
|
DemoInfo(this.demoTitle, this.demoRoute);
|
||||||
: assert(demoTitle != null),
|
|
||||||
assert(demoRoute != null);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
List<DemoInfo> demoList = [
|
List<DemoInfo> demoList = [
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class _AddPetDetailsState extends State<AddPetDetails> {
|
|||||||
groupValue: petType,
|
groupValue: petType,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
petType = value;
|
petType = value!;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
@@ -74,7 +74,7 @@ class _AddPetDetailsState extends State<AddPetDetails> {
|
|||||||
groupValue: petType,
|
groupValue: petType,
|
||||||
onChanged: (value) {
|
onChanged: (value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
petType = value;
|
petType = value!;
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -14,16 +14,16 @@ class Counter {
|
|||||||
static MethodChannel methodChannel = const MethodChannel('methodChannelDemo');
|
static MethodChannel methodChannel = const MethodChannel('methodChannelDemo');
|
||||||
|
|
||||||
/// This method is responsible to increment and return the value of count.
|
/// This method is responsible to increment and return the value of count.
|
||||||
static Future<int> increment({int counterValue}) async {
|
static Future<int> increment({required int counterValue}) async {
|
||||||
final result = await methodChannel
|
final result = await methodChannel
|
||||||
.invokeMethod<int>('increment', {'count': counterValue});
|
.invokeMethod<int>('increment', {'count': counterValue});
|
||||||
return result;
|
return result!;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// This method is responsible to decrement and return the value of count.
|
/// This method is responsible to decrement and return the value of count.
|
||||||
static Future<int> decrement({int counterValue}) async {
|
static Future<int> decrement({required int counterValue}) async {
|
||||||
final result = await methodChannel
|
final result = await methodChannel
|
||||||
.invokeMethod<int>('decrement', {'count': counterValue});
|
.invokeMethod<int>('decrement', {'count': counterValue});
|
||||||
return result;
|
return result!;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,21 +26,21 @@ class EventChannelDemo extends StatelessWidget {
|
|||||||
stream: Accelerometer.readings,
|
stream: Accelerometer.readings,
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.hasError) {
|
if (snapshot.hasError) {
|
||||||
return Text((snapshot.error as PlatformException).message);
|
return Text((snapshot.error as PlatformException).message!);
|
||||||
} else if (snapshot.hasData) {
|
} else if (snapshot.hasData) {
|
||||||
return Column(
|
return Column(
|
||||||
mainAxisAlignment: MainAxisAlignment.center,
|
mainAxisAlignment: MainAxisAlignment.center,
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
'x axis: ' + snapshot.data.x.toStringAsFixed(3),
|
'x axis: ' + snapshot.data!.x.toStringAsFixed(3),
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'y axis: ' + snapshot.data.y.toStringAsFixed(3),
|
'y axis: ' + snapshot.data!.y.toStringAsFixed(3),
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'z axis: ' + snapshot.data.z.toStringAsFixed(3),
|
'z axis: ' + snapshot.data!.z.toStringAsFixed(3),
|
||||||
style: textStyle,
|
style: textStyle,
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ class PlatformImageFetcher {
|
|||||||
|
|
||||||
/// Method responsible for providing the platform image.
|
/// Method responsible for providing the platform image.
|
||||||
static Future<Uint8List> getImage() async {
|
static Future<Uint8List> getImage() async {
|
||||||
final reply = await _basicMessageChannel.send('getImage') as Uint8List;
|
final reply = await _basicMessageChannel.send('getImage') as Uint8List?;
|
||||||
if (reply == null) {
|
if (reply == null) {
|
||||||
throw PlatformException(
|
throw PlatformException(
|
||||||
code: 'Error',
|
code: 'Error',
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
// found in the LICENSE file.
|
// found in the LICENSE file.
|
||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter/services.dart';
|
||||||
import 'package:platform_channels/src/counter_method_channel.dart';
|
import 'package:platform_channels/src/counter_method_channel.dart';
|
||||||
|
|
||||||
/// The widget demonstrates how to use [MethodChannel] to invoke platform methods.
|
/// The widget demonstrates how to use [MethodChannel] to invoke platform methods.
|
||||||
@@ -45,7 +46,7 @@ class _MethodChannelDemoState extends State<MethodChannelDemo> {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorMessage(
|
showErrorMessage(
|
||||||
context,
|
context,
|
||||||
error.message as String,
|
(error as PlatformException).message!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -63,7 +64,7 @@ class _MethodChannelDemoState extends State<MethodChannelDemo> {
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
showErrorMessage(
|
showErrorMessage(
|
||||||
context,
|
context,
|
||||||
error.message as String,
|
(error as PlatformException).message!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class PetListMessageChannel {
|
|||||||
/// A model class that provides [petList] which is received from platform.
|
/// A model class that provides [petList] which is received from platform.
|
||||||
class PetListModel {
|
class PetListModel {
|
||||||
PetListModel({
|
PetListModel({
|
||||||
this.petList,
|
required this.petList,
|
||||||
});
|
});
|
||||||
|
|
||||||
final List<PetDetails> petList;
|
final List<PetDetails> petList;
|
||||||
@@ -65,8 +65,8 @@ class PetListModel {
|
|||||||
/// A simple model that provides pet details like [petType] and [breed] of pet.
|
/// A simple model that provides pet details like [petType] and [breed] of pet.
|
||||||
class PetDetails {
|
class PetDetails {
|
||||||
PetDetails({
|
PetDetails({
|
||||||
this.petType,
|
required this.petType,
|
||||||
this.breed,
|
required this.breed,
|
||||||
});
|
});
|
||||||
|
|
||||||
final String petType;
|
final String petType;
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ class PetListScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PetListScreenState extends State<PetListScreen> {
|
class _PetListScreenState extends State<PetListScreen> {
|
||||||
PetListModel petListModel;
|
PetListModel petListModel = PetListModel(petList: []);
|
||||||
final scaffoldKey = GlobalKey<ScaffoldState>();
|
final scaffoldKey = GlobalKey<ScaffoldState>();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -22,7 +22,7 @@ class _PetListScreenState extends State<PetListScreen> {
|
|||||||
super.initState();
|
super.initState();
|
||||||
// Receives a string of json object from the platform and converts it
|
// Receives a string of json object from the platform and converts it
|
||||||
// to PetModel.
|
// to PetModel.
|
||||||
const BasicMessageChannel('stringCodecDemo', StringCodec())
|
const BasicMessageChannel<String?>('stringCodecDemo', StringCodec())
|
||||||
.setMessageHandler((message) async {
|
.setMessageHandler((message) async {
|
||||||
if (message == null) {
|
if (message == null) {
|
||||||
showSnackBar('An error occurred while adding pet details.', context);
|
showSnackBar('An error occurred while adding pet details.', context);
|
||||||
@@ -31,7 +31,7 @@ class _PetListScreenState extends State<PetListScreen> {
|
|||||||
petListModel = PetListModel.fromJson(message);
|
petListModel = PetListModel.fromJson(message);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
return;
|
return null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ class _PetListScreenState extends State<PetListScreen> {
|
|||||||
Navigator.pushNamed(context, '/addPetDetails');
|
Navigator.pushNamed(context, '/addPetDetails');
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
body: petListModel?.petList?.isEmpty ?? true
|
body: petListModel.petList.isEmpty
|
||||||
? const Center(child: Text('Enter Pet Details'))
|
? const Center(child: Text('Enter Pet Details'))
|
||||||
: BuildPetList(petListModel.petList),
|
: BuildPetList(petListModel.petList),
|
||||||
);
|
);
|
||||||
@@ -79,7 +79,7 @@ class BuildPetList extends StatelessWidget {
|
|||||||
await PetListMessageChannel.removePet(index);
|
await PetListMessageChannel.removePet(index);
|
||||||
showSnackBar('Removed successfully!', context);
|
showSnackBar('Removed successfully!', context);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
showSnackBar(error.message.toString(), context);
|
showSnackBar((error as PlatformException).message!, context);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ class PlatformImageDemo extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _PlatformImageDemoState extends State<PlatformImageDemo> {
|
class _PlatformImageDemoState extends State<PlatformImageDemo> {
|
||||||
Future<Uint8List> imageData;
|
Future<Uint8List>? imageData;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
@@ -41,12 +41,14 @@ class _PlatformImageDemoState extends State<PlatformImageDemo> {
|
|||||||
return const Placeholder();
|
return const Placeholder();
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return Center(
|
return Center(
|
||||||
child: Text(snapshot.error.toString()),
|
child: Text(
|
||||||
|
(snapshot.error as PlatformException).message!,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else if (snapshot.connectionState ==
|
} else if (snapshot.connectionState ==
|
||||||
ConnectionState.done) {
|
ConnectionState.done) {
|
||||||
return Image.memory(
|
return Image.memory(
|
||||||
snapshot.data,
|
snapshot.data!,
|
||||||
fit: BoxFit.fill,
|
fit: BoxFit.fill,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ packages:
|
|||||||
name: async
|
name: async
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "2.6.1"
|
version: "2.5.0"
|
||||||
boolean_selector:
|
boolean_selector:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -113,7 +113,7 @@ packages:
|
|||||||
name: source_span
|
name: source_span
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "1.8.1"
|
version: "1.8.0"
|
||||||
stack_trace:
|
stack_trace:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
@@ -148,7 +148,7 @@ packages:
|
|||||||
name: test_api
|
name: test_api
|
||||||
url: "https://pub.dartlang.org"
|
url: "https://pub.dartlang.org"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.3.0"
|
version: "0.2.19"
|
||||||
typed_data:
|
typed_data:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -4,13 +4,13 @@ description: A new Flutter project.
|
|||||||
version: 1.0.0+1
|
version: 1.0.0+1
|
||||||
|
|
||||||
environment:
|
environment:
|
||||||
sdk: ">=2.7.0 <3.0.0"
|
sdk: ">=2.12.0 <3.0.0"
|
||||||
|
|
||||||
dependencies:
|
dependencies:
|
||||||
flutter:
|
flutter:
|
||||||
sdk: flutter
|
sdk: flutter
|
||||||
|
|
||||||
cupertino_icons: ^1.0.0
|
cupertino_icons: ^1.0.3
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -19,8 +19,8 @@ void main() {
|
|||||||
// calls the BinaryMessenger.setMessageHandler registered for the EventChannel
|
// calls the BinaryMessenger.setMessageHandler registered for the EventChannel
|
||||||
// and add the incoming message to the StreamController used by the EventChannel
|
// and add the incoming message to the StreamController used by the EventChannel
|
||||||
// after decoding the message with codec used by the EventChannel.
|
// after decoding the message with codec used by the EventChannel.
|
||||||
void emitValues(ByteData event) {
|
void emitValues(ByteData? event) {
|
||||||
ServicesBinding.instance.defaultBinaryMessenger.handlePlatformMessage(
|
ServicesBinding.instance?.defaultBinaryMessenger.handlePlatformMessage(
|
||||||
'eventChannelDemo',
|
'eventChannelDemo',
|
||||||
event,
|
event,
|
||||||
(reply) {},
|
(reply) {},
|
||||||
@@ -29,7 +29,7 @@ void main() {
|
|||||||
|
|
||||||
// Register a mock for EventChannel. EventChannel under the hood uses
|
// Register a mock for EventChannel. EventChannel under the hood uses
|
||||||
// MethodChannel to listen and cancel the created stream.
|
// MethodChannel to listen and cancel the created stream.
|
||||||
ServicesBinding.instance.defaultBinaryMessenger
|
ServicesBinding.instance?.defaultBinaryMessenger
|
||||||
.setMockMessageHandler('eventChannelDemo', (message) async {
|
.setMockMessageHandler('eventChannelDemo', (message) async {
|
||||||
// Decode the message into MethodCallHandler.
|
// Decode the message into MethodCallHandler.
|
||||||
final methodCall = standardMethod.decodeMethodCall(message);
|
final methodCall = standardMethod.decodeMethodCall(message);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import 'package:platform_channels/src/pet_list_screen.dart';
|
|||||||
void main() {
|
void main() {
|
||||||
group('PetListScreen tests', () {
|
group('PetListScreen tests', () {
|
||||||
const basicMessageChannel =
|
const basicMessageChannel =
|
||||||
BasicMessageChannel('stringCodecDemo', StringCodec());
|
BasicMessageChannel<String?>('stringCodecDemo', StringCodec());
|
||||||
|
|
||||||
var petList = [
|
var petList = [
|
||||||
{
|
{
|
||||||
@@ -22,21 +22,21 @@ void main() {
|
|||||||
}
|
}
|
||||||
];
|
];
|
||||||
|
|
||||||
PetListModel petListModel;
|
PetListModel? petListModel;
|
||||||
|
|
||||||
setUpAll(() {
|
setUpAll(() {
|
||||||
// Mock for the pet list received from the platform.
|
// Mock for the pet list received from the platform.
|
||||||
basicMessageChannel.setMockMessageHandler((message) async {
|
basicMessageChannel.setMockMessageHandler((message) async {
|
||||||
petListModel = PetListModel.fromJson(message);
|
petListModel = PetListModel.fromJson(message!);
|
||||||
return;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
// Mock for the index received from the Dart to delete the pet details,
|
// Mock for the index received from the Dart to delete the pet details,
|
||||||
// and send the updated pet list back to Dart.
|
// and send the updated pet list back to Dart.
|
||||||
const BasicMessageChannel('binaryCodecDemo', BinaryCodec())
|
const BasicMessageChannel<ByteData?>('binaryCodecDemo', BinaryCodec())
|
||||||
.setMockMessageHandler((message) async {
|
.setMockMessageHandler((message) async {
|
||||||
// Convert the ByteData to String.
|
// Convert the ByteData to String.
|
||||||
final index = utf8.decoder.convert(message.buffer
|
final index = utf8.decoder.convert(message!.buffer
|
||||||
.asUint8List(message.offsetInBytes, message.lengthInBytes));
|
.asUint8List(message.offsetInBytes, message.lengthInBytes));
|
||||||
|
|
||||||
// Remove the pet details at the given index.
|
// Remove the pet details at the given index.
|
||||||
@@ -45,7 +45,8 @@ void main() {
|
|||||||
// Send the updated petList back.
|
// Send the updated petList back.
|
||||||
final map = {'petList': petList};
|
final map = {'petList': petList};
|
||||||
await basicMessageChannel.send(json.encode(map));
|
await basicMessageChannel.send(json.encode(map));
|
||||||
return;
|
|
||||||
|
return null;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -60,7 +61,7 @@ void main() {
|
|||||||
basicMessageChannel.send(json.encode(map));
|
basicMessageChannel.send(json.encode(map));
|
||||||
|
|
||||||
// Get the details of first pet.
|
// Get the details of first pet.
|
||||||
final petDetails = petListModel.petList.first;
|
final petDetails = petListModel!.petList.first;
|
||||||
expect(petDetails.petType, 'Dog');
|
expect(petDetails.petType, 'Dog');
|
||||||
expect(petDetails.breed, 'Pug');
|
expect(petDetails.breed, 'Pug');
|
||||||
});
|
});
|
||||||
@@ -68,7 +69,7 @@ void main() {
|
|||||||
testWidgets('BuildPetList test', (tester) async {
|
testWidgets('BuildPetList test', (tester) async {
|
||||||
await tester.pumpWidget(MaterialApp(
|
await tester.pumpWidget(MaterialApp(
|
||||||
home: Scaffold(
|
home: Scaffold(
|
||||||
body: BuildPetList(petListModel.petList),
|
body: BuildPetList(petListModel!.petList),
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
|
|
||||||
@@ -77,7 +78,7 @@ void main() {
|
|||||||
|
|
||||||
// Delete the pet details.
|
// Delete the pet details.
|
||||||
await tester.tap(find.byIcon(Icons.delete).first);
|
await tester.tap(find.byIcon(Icons.delete).first);
|
||||||
expect(petListModel.petList, isEmpty);
|
expect(petListModel!.petList, isEmpty);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user