在 iOS 上从 flutter 应用程序打开 youtube 应用程序
Open the youtube app from flutter app on iOS
我基本上想在按下按钮时从我的应用程序打开特定的 YouTube 视频。如果用户设备上安装了 youtube 应用程序,则应在 youtube 应用程序中打开视频(而不是在浏览器或单独的网络视图中)。
我为此使用了 url_launcher
包,它在 android 上运行良好。但是在 iOS 上,即使安装了 youtube 应用程序也不会打开,而是打开一个单独的网站 window,其中相应的 youtube url 显示为网页。
我想,我可以像这样覆盖这种行为:
_launchURL() async {
if (Platform.isIOS) {
if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
}
}
} else {
const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
但是没用。如果您想知道,我使用以下导入:
import 'dart:io' show Platform;
import 'package:url_launcher/url_launcher.dart';
我很确定,youtube://
URL-方案有效(启动 YouTube 应用程序),因为我在第三方应用程序(Launch Center Pro 和 Pythonista)上对其进行了测试。
我无法测试的最后一件事是 Platform.isIOS
在我的 IPhone 上是否真的正确。
是否有从 flutter 打开 YouTube 应用程序的有效方法?
我修好了。我必须设置 forceSafariVC: false
,因为它在默认情况下为真,这会导致 url 在应用程序内的一种网络视图中打开。
_launchURL() async {
if (Platform.isIOS) {
if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw', forceSafariVC: false);
} else {
if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
}
}
} else {
const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
这实际上记录在 url_launcher
文档中,但有些隐藏...
您不必拥有所有 if/else 子句。最重要的是要考虑设备是否有 YouTube 应用程序,无论 O.S ( 并且记得将你的功能定义为 Future 因为异步 ):
Future<void> _launchYoutubeVideo(String _youtubeUrl) async {
if (_youtubeUrl != null && _youtubeUrl.isNotEmpty) {
if (await canLaunch(_youtubeUrl)) {
final bool _nativeAppLaunchSucceeded = await launch(
_youtubeUrl,
forceSafariVC: false,
universalLinksOnly: true,
);
if (!_nativeAppLaunchSucceeded) {
await launch(_youtubeUrl, forceSafariVC: true);
}
}
}
}
这里要强调的是避免几个if/else si属性universalLinksOnly设置为true。
我已经解决了这个问题。您可以试试下面的代码:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() => runApp(const HomePage());
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
);
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<void>? _launched;
@override
Widget build(BuildContext context) {
const String toLaunch = 'https://www.youtube.com/watch?v=WcZ8lTRTNM0';
return Scaffold(
appBar: AppBar(title: const Text('Flutter Demo')),
body: Center(
child: ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInBrowser(toLaunch);
}),
child: const Text('Launch in browser'),
),
), );
}
Future<void> _launchInBrowser(String url) async {
if (!await launch(
url,
forceSafariVC: true,
forceWebView: false,
headers: <String, String>{'my_header_key': 'my_header_value'},
)) {
throw 'Could not launch $url';
}
}
}
我基本上想在按下按钮时从我的应用程序打开特定的 YouTube 视频。如果用户设备上安装了 youtube 应用程序,则应在 youtube 应用程序中打开视频(而不是在浏览器或单独的网络视图中)。
我为此使用了 url_launcher
包,它在 android 上运行良好。但是在 iOS 上,即使安装了 youtube 应用程序也不会打开,而是打开一个单独的网站 window,其中相应的 youtube url 显示为网页。
我想,我可以像这样覆盖这种行为:
_launchURL() async {
if (Platform.isIOS) {
if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
}
}
} else {
const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
}
但是没用。如果您想知道,我使用以下导入:
import 'dart:io' show Platform;
import 'package:url_launcher/url_launcher.dart';
我很确定,youtube://
URL-方案有效(启动 YouTube 应用程序),因为我在第三方应用程序(Launch Center Pro 和 Pythonista)上对其进行了测试。
我无法测试的最后一件事是 Platform.isIOS
在我的 IPhone 上是否真的正确。
是否有从 flutter 打开 YouTube 应用程序的有效方法?
我修好了。我必须设置 forceSafariVC: false
,因为它在默认情况下为真,这会导致 url 在应用程序内的一种网络视图中打开。
_launchURL() async {
if (Platform.isIOS) {
if (await canLaunch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('youtube://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw', forceSafariVC: false);
} else {
if (await canLaunch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw')) {
await launch('https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw');
} else {
throw 'Could not launch https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
}
}
} else {
const url = 'https://www.youtube.com/channel/UCwXdFgeE9KYzlDdR7TG9cMw';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
这实际上记录在 url_launcher
文档中,但有些隐藏...
您不必拥有所有 if/else 子句。最重要的是要考虑设备是否有 YouTube 应用程序,无论 O.S ( 并且记得将你的功能定义为 Future 因为异步 ):
Future<void> _launchYoutubeVideo(String _youtubeUrl) async {
if (_youtubeUrl != null && _youtubeUrl.isNotEmpty) {
if (await canLaunch(_youtubeUrl)) {
final bool _nativeAppLaunchSucceeded = await launch(
_youtubeUrl,
forceSafariVC: false,
universalLinksOnly: true,
);
if (!_nativeAppLaunchSucceeded) {
await launch(_youtubeUrl, forceSafariVC: true);
}
}
}
}
这里要强调的是避免几个if/else si属性universalLinksOnly设置为true。
我已经解决了这个问题。您可以试试下面的代码:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() => runApp(const HomePage());
class HomePage extends StatelessWidget {
const HomePage({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return const MaterialApp(
debugShowCheckedModeBanner: false,
home: MyApp(),
);
}
}
class MyApp extends StatefulWidget {
const MyApp({Key? key}) : super(key: key);
@override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
Future<void>? _launched;
@override
Widget build(BuildContext context) {
const String toLaunch = 'https://www.youtube.com/watch?v=WcZ8lTRTNM0';
return Scaffold(
appBar: AppBar(title: const Text('Flutter Demo')),
body: Center(
child: ElevatedButton(
onPressed: () => setState(() {
_launched = _launchInBrowser(toLaunch);
}),
child: const Text('Launch in browser'),
),
), );
}
Future<void> _launchInBrowser(String url) async {
if (!await launch(
url,
forceSafariVC: true,
forceWebView: false,
headers: <String, String>{'my_header_key': 'my_header_value'},
)) {
throw 'Could not launch $url';
}
}
}