Skip to content

Commit 19f566b

Browse files
authored
[url_launcher] Update README to use code excerpts. (#6042)
1 parent 25cd6e1 commit 19f566b

File tree

12 files changed

+247
-21
lines changed

12 files changed

+247
-21
lines changed

packages/url_launcher/url_launcher/CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
## 6.1.5
2+
3+
* Migrates `README.md` examples to the [`code-excerpt` system](https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#readme-code).
4+
15
## 6.1.4
26

37
* Adopts new platform interface method for launching URLs.

packages/url_launcher/url_launcher/README.md

Lines changed: 43 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
<?code-excerpt path-base="excerpts/packages/url_launcher_example"?>
2+
13
# url_launcher
24

35
[![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher)
@@ -14,6 +16,7 @@ To use this plugin, add `url_launcher` as a [dependency in your pubspec.yaml fil
1416

1517
### Example
1618

19+
<?code-excerpt "basic.dart (basic-example)"?>
1720
``` dart
1821
import 'package:flutter/material.dart';
1922
import 'package:url_launcher/url_launcher.dart';
@@ -24,7 +27,7 @@ void main() => runApp(
2427
const MaterialApp(
2528
home: Material(
2629
child: Center(
27-
child: RaisedButton(
30+
child: ElevatedButton(
2831
onPressed: _launchUrl,
2932
child: Text('Show Flutter homepage'),
3033
),
@@ -33,8 +36,10 @@ void main() => runApp(
3336
),
3437
);
3538
36-
void _launchUrl() async {
37-
if (!await launchUrl(_url)) throw 'Could not launch $_url';
39+
Future<void> _launchUrl() async {
40+
if (!await launchUrl(_url)) {
41+
throw 'Could not launch $_url';
42+
}
3843
}
3944
```
4045

@@ -65,7 +70,10 @@ on Android 11 (API 30) or higher. A `<queries>`
6570
element must be added to your manifest as a child of the root element.
6671

6772
Example:
73+
74+
<?code-excerpt "../../android/app/src/main/AndroidManifest.xml (android-queries)" plaster="none"?>
6875
``` xml
76+
<!-- Provide required visibility configuration for API level 30 and above -->
6977
<queries>
7078
<!-- If your app checks for SMS support -->
7179
<intent>
@@ -133,22 +141,37 @@ due to [a bug](https://github.com/dart-lang/sdk/issues/43838) in the way `Uri`
133141
encodes query parameters. Using `queryParameters` will result in spaces being
134142
converted to `+` in many cases.
135143

144+
<?code-excerpt "encoding.dart (encode-query-parameters)"?>
136145
```dart
137146
String? encodeQueryParameters(Map<String, String> params) {
138147
return params.entries
139-
.map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
148+
.map((MapEntry<String, String> e) =>
149+
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
140150
.join('&');
141151
}
152+
// ···
153+
final Uri emailLaunchUri = Uri(
154+
scheme: 'mailto',
155+
156+
query: encodeQueryParameters(<String, String>{
157+
'subject': 'Example Subject & Symbols are allowed!',
158+
}),
159+
);
160+
161+
launchUrl(emailLaunchUri);
162+
```
142163

143-
final Uri emailLaunchUri = Uri(
144-
scheme: 'mailto',
145-
146-
query: encodeQueryParameters(<String, String>{
147-
'subject': 'Example Subject & Symbols are allowed!'
148-
}),
149-
);
164+
Encoding for `sms` is slightly different:
150165

151-
launchUrl(emailLaunchUri);
166+
<?code-excerpt "encoding.dart (sms)"?>
167+
```dart
168+
final Uri smsLaunchUri = Uri(
169+
scheme: 'sms',
170+
path: '0118 999 881 999 119 7253',
171+
queryParameters: <String, String>{
172+
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
173+
},
174+
);
152175
```
153176

154177
### URLs not handled by `Uri`
@@ -168,14 +191,17 @@ original APIs.
168191
We recommend checking first whether the directory or file exists before calling `launchUrl`.
169192

170193
Example:
194+
195+
<?code-excerpt "files.dart (file)"?>
171196
```dart
172-
var filePath = '/path/to/file';
197+
final String filePath = testFile.absolute.path;
173198
final Uri uri = Uri.file(filePath);
174199
175-
if (await File(uri.toFilePath()).exists()) {
176-
if (!await launchUrl(uri)) {
177-
throw 'Could not launch $uri';
178-
}
200+
if (!File(uri.toFilePath()).existsSync()) {
201+
throw '$uri does not exist!';
202+
}
203+
if (!await launchUrl(uri)) {
204+
throw 'Could not launch $uri';
179205
}
180206
```
181207

packages/url_launcher/url_launcher/example/android/app/src/main/AndroidManifest.xml

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,29 @@
77
-->
88
<uses-permission android:name="android.permission.INTERNET"/>
99

10+
<!--#docregion android-queries-->
1011
<!-- Provide required visibility configuration for API level 30 and above -->
1112
<queries>
13+
<!-- If your app checks for SMS support -->
1214
<intent>
1315
<action android:name="android.intent.action.VIEW" />
14-
<data android:scheme="https" />
16+
<data android:scheme="sms" />
1517
</intent>
18+
<!-- If your app checks for call support -->
1619
<intent>
1720
<action android:name="android.intent.action.VIEW" />
1821
<data android:scheme="tel" />
1922
</intent>
23+
<!--#enddocregion android-queries-->
24+
<!-- The "https" scheme is only required for integration tests of this package.
25+
It shouldn't be needed in most actual apps, or show up in the README! -->
2026
<intent>
2127
<action android:name="android.intent.action.VIEW" />
22-
<data android:scheme="sms" />
28+
<data android:scheme="https" />
2329
</intent>
30+
<!--#docregion android-queries-->
2431
</queries>
32+
<!--#enddocregion android-queries-->
2533

2634
<application
2735
android:icon="@mipmap/ic_launcher"
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
targets:
2+
$default:
3+
sources:
4+
include:
5+
- lib/**
6+
- android/app/src/main/**
7+
# Some default includes that aren't really used here but will prevent
8+
# false-negative warnings:
9+
- $package$
10+
- lib/$lib$
11+
exclude:
12+
- '**/.*/**'
13+
- '**/build/**'
14+
- 'android/app/src/main/res/**'
15+
builders:
16+
code_excerpter|code_excerpter:
17+
enabled: true
18+
generate_for:
19+
- '**/*.dart'
20+
- android/**/*.xml
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Run this example with: flutter run -t lib/basic.dart -d emulator
6+
7+
// This file is used to extract code samples for the README.md file.
8+
// Run update-excerpts if you modify this file.
9+
10+
// #docregion basic-example
11+
import 'package:flutter/material.dart';
12+
import 'package:url_launcher/url_launcher.dart';
13+
14+
final Uri _url = Uri.parse('https://flutter.dev');
15+
16+
void main() => runApp(
17+
const MaterialApp(
18+
home: Material(
19+
child: Center(
20+
child: ElevatedButton(
21+
onPressed: _launchUrl,
22+
child: Text('Show Flutter homepage'),
23+
),
24+
),
25+
),
26+
),
27+
);
28+
29+
Future<void> _launchUrl() async {
30+
if (!await launchUrl(_url)) {
31+
throw 'Could not launch $_url';
32+
}
33+
}
34+
// #enddocregion basic-example
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Run this example with: flutter run -t lib/encoding.dart -d emulator
6+
7+
// This file is used to extract code samples for the README.md file.
8+
// Run update-excerpts if you modify this file.
9+
10+
import 'package:flutter/material.dart';
11+
import 'package:url_launcher/url_launcher.dart';
12+
13+
/// Encode [params] so it produces a correct query string.
14+
/// Workaround for: https://github.com/dart-lang/sdk/issues/43838
15+
// #docregion encode-query-parameters
16+
String? encodeQueryParameters(Map<String, String> params) {
17+
return params.entries
18+
.map((MapEntry<String, String> e) =>
19+
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
20+
.join('&');
21+
}
22+
// #enddocregion encode-query-parameters
23+
24+
void main() => runApp(
25+
MaterialApp(
26+
home: Material(
27+
child: Column(
28+
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
29+
children: const <Widget>[
30+
ElevatedButton(
31+
onPressed: _composeMail,
32+
child: Text('Compose an email'),
33+
),
34+
ElevatedButton(
35+
onPressed: _composeSms,
36+
child: Text('Compose a SMS'),
37+
),
38+
],
39+
),
40+
),
41+
),
42+
);
43+
44+
void _composeMail() {
45+
// #docregion encode-query-parameters
46+
final Uri emailLaunchUri = Uri(
47+
scheme: 'mailto',
48+
49+
query: encodeQueryParameters(<String, String>{
50+
'subject': 'Example Subject & Symbols are allowed!',
51+
}),
52+
);
53+
54+
launchUrl(emailLaunchUri);
55+
// #enddocregion encode-query-parameters
56+
}
57+
58+
void _composeSms() {
59+
// #docregion sms
60+
final Uri smsLaunchUri = Uri(
61+
scheme: 'sms',
62+
path: '0118 999 881 999 119 7253',
63+
queryParameters: <String, String>{
64+
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
65+
},
66+
);
67+
// #enddocregion sms
68+
69+
launchUrl(smsLaunchUri);
70+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
// Copyright 2013 The Flutter Authors. All rights reserved.
2+
// Use of this source code is governed by a BSD-style license that can be
3+
// found in the LICENSE file.
4+
5+
// Run this example with: flutter run -t lib/files.dart -d linux
6+
7+
// This file is used to extract code samples for the README.md file.
8+
// Run update-excerpts if you modify this file.
9+
import 'dart:io';
10+
11+
import 'package:flutter/material.dart';
12+
import 'package:path/path.dart' as p;
13+
import 'package:url_launcher/url_launcher.dart';
14+
15+
void main() => runApp(
16+
const MaterialApp(
17+
home: Material(
18+
child: Center(
19+
child: ElevatedButton(
20+
onPressed: _openFile,
21+
child: Text('Open File'),
22+
),
23+
),
24+
),
25+
),
26+
);
27+
28+
Future<void> _openFile() async {
29+
// Prepare a file within tmp
30+
final String tempFilePath = p.joinAll(<String>[
31+
...p.split(Directory.systemTemp.path),
32+
'flutter_url_launcher_example.txt'
33+
]);
34+
final File testFile = File(tempFilePath);
35+
await testFile.writeAsString('Hello, world!');
36+
// #docregion file
37+
final String filePath = testFile.absolute.path;
38+
final Uri uri = Uri.file(filePath);
39+
40+
if (!File(uri.toFilePath()).existsSync()) {
41+
throw '$uri does not exist!';
42+
}
43+
if (!await launchUrl(uri)) {
44+
throw 'Could not launch $uri';
45+
}
46+
// #enddocregion file
47+
}

packages/url_launcher/url_launcher/example/linux/flutter/generated_plugins.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
66
url_launcher_linux
77
)
88

9+
list(APPEND FLUTTER_FFI_PLUGIN_LIST
10+
)
11+
912
set(PLUGIN_BUNDLED_LIBRARIES)
1013

1114
foreach(plugin ${FLUTTER_PLUGIN_LIST})
@@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
1417
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
1518
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
1619
endforeach(plugin)
20+
21+
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
22+
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
23+
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
24+
endforeach(ffi_plugin)

packages/url_launcher/url_launcher/example/pubspec.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ environment:
99
dependencies:
1010
flutter:
1111
sdk: flutter
12+
path: ^1.8.0
1213
url_launcher:
1314
# When depending on this package from a real application you should use:
1415
# url_launcher: ^x.y.z
@@ -18,6 +19,7 @@ dependencies:
1819
path: ../
1920

2021
dev_dependencies:
22+
build_runner: ^2.1.10
2123
flutter_driver:
2224
sdk: flutter
2325
integration_test:

packages/url_launcher/url_launcher/example/windows/flutter/generated_plugins.cmake

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
66
url_launcher_windows
77
)
88

9+
list(APPEND FLUTTER_FFI_PLUGIN_LIST
10+
)
11+
912
set(PLUGIN_BUNDLED_LIBRARIES)
1013

1114
foreach(plugin ${FLUTTER_PLUGIN_LIST})
@@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
1417
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
1518
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
1619
endforeach(plugin)
20+
21+
foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
22+
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
23+
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
24+
endforeach(ffi_plugin)

packages/url_launcher/url_launcher/pubspec.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
33
web, phone, SMS, and email schemes.
44
repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher
55
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
6-
version: 6.1.4
6+
version: 6.1.5
77

88
environment:
99
sdk: ">=2.14.0 <3.0.0"

0 commit comments

Comments
 (0)