Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[url_launcher] Update README to use code excerpts. #6042

Merged
merged 10 commits into from Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/url_launcher/url_launcher/CHANGELOG.md
@@ -1,3 +1,7 @@
## 6.1.5

* Migrates `README.md` examples to the [`code-excerpt` system](https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#readme-code).

## 6.1.4

* Adopts new platform interface method for launching URLs.
Expand Down
60 changes: 43 additions & 17 deletions packages/url_launcher/url_launcher/README.md
@@ -1,3 +1,5 @@
<?code-excerpt path-base="excerpts/packages/url_launcher_example"?>

# url_launcher

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

### Example

<?code-excerpt "basic.dart (basic-example)"?>
``` dart
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
Expand All @@ -24,7 +27,7 @@ void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: RaisedButton(
child: ElevatedButton(
onPressed: _launchUrl,
child: Text('Show Flutter homepage'),
),
Expand All @@ -33,8 +36,10 @@ void main() => runApp(
),
);

void _launchUrl() async {
if (!await launchUrl(_url)) throw 'Could not launch $_url';
Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw 'Could not launch $_url';
}
}
```

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

Example:

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

<?code-excerpt "encoding.dart (encode-query-parameters)"?>
```dart
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
// ···
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'smith@example.com',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!',
}),
);

launchUrl(emailLaunchUri);
```

final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'smith@example.com',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!'
}),
);
Encoding for `sms` is slightly different:

launchUrl(emailLaunchUri);
<?code-excerpt "encoding.dart (sms)"?>
```dart
final Uri smsLaunchUri = Uri(
scheme: 'sms',
path: '0118 999 881 999 119 7253',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤣

I was about to ask why this wasn't using some obviously fake number (like 123456789) when I realized what it was 🙂

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried to find a cool "555" number, but ended up going for the easy to remember 0118 999 881 999 119 725... 3

(Turns out I'm almost 7 years late, yikes!)

queryParameters: <String, String>{
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
},
);
```

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

Example:

<?code-excerpt "files.dart (file)"?>
```dart
var filePath = '/path/to/file';
final String filePath = testFile.absolute.path;
final Uri uri = Uri.file(filePath);

if (await File(uri.toFilePath()).exists()) {
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
if (!File(uri.toFilePath()).existsSync()) {
throw '$uri does not exist!';
}
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
```

Expand Down
Expand Up @@ -7,21 +7,29 @@
-->
<uses-permission android:name="android.permission.INTERNET"/>

<!--#docregion android-queries-->
<!-- Provide required visibility configuration for API level 30 and above -->
<queries>
<!-- If your app checks for SMS support -->
<intent>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's probably worth adding a comment saying this is only here for integration tests, and shouldn't be needed in most actual apps, so it doesn't confuse anyone else in the future.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed; I've added a comment to the https scheme bit of the XML, in addition to excluding it from the relevant docregion.

<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<!--#enddocregion android-queries-->
<!-- The "https" scheme is only required for integration tests of this package.
It shouldn't be needed in most actual apps, or show up in the README! -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
<data android:scheme="https" />
</intent>
<!--#docregion android-queries-->
</queries>
<!--#enddocregion android-queries-->

<application
android:icon="@mipmap/ic_launcher"
Expand Down
20 changes: 20 additions & 0 deletions packages/url_launcher/url_launcher/example/build.excerpt.yaml
@@ -0,0 +1,20 @@
targets:
$default:
sources:
include:
- lib/**
- android/app/src/main/**
# Some default includes that aren't really used here but will prevent
# false-negative warnings:
- $package$
- lib/$lib$
exclude:
- '**/.*/**'
- '**/build/**'
- 'android/app/src/main/res/**'
builders:
code_excerpter|code_excerpter:
enabled: true
generate_for:
- '**/*.dart'
- android/**/*.xml
34 changes: 34 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/basic.dart
@@ -0,0 +1,34 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/basic.dart -d emulator

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.

// #docregion basic-example
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

final Uri _url = Uri.parse('https://flutter.dev');

void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: _launchUrl,
child: Text('Show Flutter homepage'),
),
),
),
),
);

Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw 'Could not launch $_url';
}
}
// #enddocregion basic-example
70 changes: 70 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/encoding.dart
@@ -0,0 +1,70 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/encoding.dart -d emulator

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

/// Encode [params] so it produces a correct query string.
/// Workaround for: https://github.com/dart-lang/sdk/issues/43838
// #docregion encode-query-parameters
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
// #enddocregion encode-query-parameters

void main() => runApp(
MaterialApp(
home: Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const <Widget>[
ElevatedButton(
onPressed: _composeMail,
child: Text('Compose an email'),
),
ElevatedButton(
onPressed: _composeSms,
child: Text('Compose a SMS'),
),
],
),
),
),
);

void _composeMail() {
// #docregion encode-query-parameters
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: 'smith@example.com',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!',
}),
);

launchUrl(emailLaunchUri);
// #enddocregion encode-query-parameters
}

void _composeSms() {
// #docregion sms
final Uri smsLaunchUri = Uri(
scheme: 'sms',
path: '0118 999 881 999 119 7253',
queryParameters: <String, String>{
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
},
);
// #enddocregion sms

launchUrl(smsLaunchUri);
}
47 changes: 47 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/files.dart
@@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/files.dart -d linux

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: _openFile,
child: Text('Open File'),
),
),
),
),
);

Future<void> _openFile() async {
// Prepare a file within tmp
final String tempFilePath = p.joinAll(<String>[
...p.split(Directory.systemTemp.path),
'flutter_url_launcher_example.txt'
]);
final File testFile = File(tempFilePath);
await testFile.writeAsString('Hello, world!');
// #docregion file
final String filePath = testFile.absolute.path;
final Uri uri = Uri.file(filePath);

if (!File(uri.toFilePath()).existsSync()) {
throw '$uri does not exist!';
}
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
// #enddocregion file
}
Expand Up @@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
)

set(PLUGIN_BUNDLED_LIBRARIES)

foreach(plugin ${FLUTTER_PLUGIN_LIST})
Expand All @@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
2 changes: 2 additions & 0 deletions packages/url_launcher/url_launcher/example/pubspec.yaml
Expand Up @@ -9,6 +9,7 @@ environment:
dependencies:
flutter:
sdk: flutter
path: ^1.8.1
url_launcher:
# When depending on this package from a real application you should use:
# url_launcher: ^x.y.z
Expand All @@ -18,6 +19,7 @@ dependencies:
path: ../

dev_dependencies:
build_runner: ^2.1.10
flutter_driver:
sdk: flutter
integration_test:
Expand Down
Expand Up @@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
)

set(PLUGIN_BUNDLED_LIBRARIES)

foreach(plugin ${FLUTTER_PLUGIN_LIST})
Expand All @@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
2 changes: 1 addition & 1 deletion packages/url_launcher/url_launcher/pubspec.yaml
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
web, phone, SMS, and email schemes.
repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 6.1.4
version: 6.1.5

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down