我正在尝试使用该url_launcher
插件通过链接打开 youtube 视频,但该canLaunch
功能不断抛出错误。我只能通过完全删除该canLaunch
功能来绕过此错误,但无法弄清楚出了什么问题。
代码不起作用:
_goToVideo(YoutubeVideoData video) async {
if (await canLaunch(video.url)) {
await launch(video.url);
} else {
throw 'Could not launch ${video.url}';
}
}
Run Code Online (Sandbox Code Playgroud)
代码工作:
_goToVideo(YoutubeVideoData video) async {
await launch(video.url);
}
Run Code Online (Sandbox Code Playgroud)
我不太确定为什么我不能使用自述文件示例中canLaunch
所写的方法
错误:
E/flutter (12574): [ERROR:flutter/lib/ui/ui_dart_state.cc(166)] Unhandled Exception: Could not launch https://www.youtube.com/watch?v=-3g5WlqJtIo
E/flutter (12574): #0 _goToVideo (package:esfandapp/widgets/newsList/videoCard.dart:71:5)
E/flutter (12574): <asynchronous suspension>
E/flutter (12574): #1 VideoCard.build.<anonymous closure> (package:esfandapp/widgets/newsList/videoCard.dart:13:20)
E/flutter (12574): #2 _InkResponseState._handleTap (package:flutter/src/material/ink_well.dart:992:19)
E/flutter (12574): #3 _InkResponseState.build.<anonymous closure> (package:flutter/src/material/ink_well.dart:1098:38)
E/flutter (12574): #4 GestureRecognizer.invokeCallback (package:flutter/src/gestures/recognizer.dart:184:24)
E/flutter (12574): #5 TapGestureRecognizer.handleTapUp (package:flutter/src/gestures/tap.dart:524:11)
E/flutter (12574): #6 BaseTapGestureRecognizer._checkUp (package:flutter/src/gestures/tap.dart:284:5)
E/flutter (12574): #7 BaseTapGestureRecognizer.acceptGesture (package:flutter/src/gestures/tap.dart:256:7)
E/flutter (12574): #8 GestureArenaManager.sweep (package:flutter/src/gestures/arena.dart:158:27)
E/flutter (12574): #9 GestureBinding.handleEvent (package:flutter/src/gestures/binding.dart:224:20)
E/flutter (12574): #10 GestureBinding.dispatchEvent (package:flutter/src/gestures/binding.dart:200:22)
E/flutter (12574): #11 GestureBinding._handlePointerEvent (package:flutter/src/gestures/binding.dart:158:7)
E/flutter (12574): #12 GestureBinding._flushPointerEventQueue (package:flutter/src/gestures/binding.dart:104:7)
E/flutter (12574): #13 GestureBinding._handlePointerDataPacket (package:flutter/src/gestures/binding.dart:88:7)
E/flutter (12574): #14 _rootRunUnary (dart:async/zone.dart:1206:13)
E/flutter (12574): #15 _CustomZone.runUnary (dart:async/zone.dart:1100:19)
E/flutter (12574): #16 _CustomZone.runUnaryGuarded (dart:async/zone.dart:1005:7)
E/flutter (12574): #17 _invoke1 (dart:ui/hooks.dart:267:10)
E/flutter (12574): #18 _dispatchPointerDataPacket (dart:ui/hooks.dart:176:5)
Run Code Online (Sandbox Code Playgroud)
使用函数的小部件:
class VideoCard extends StatelessWidget {
final YoutubeVideoData video;
VideoCard({this.video});
@override
Widget build(BuildContext context) {
return InkWell(
onTap: () => _goToVideo(video),
child: Container(
child: Card(
child: Container(
child: Column(
children: [
Align(
child: Padding(
child: Text(
video.title,
style: TextStyle(
fontFamily: 'Roboto Condensed',
fontSize: 16,
),
),
padding: EdgeInsets.fromLTRB(15, 0, 15, 10),
),
alignment: Alignment.centerLeft,
),
Container(
child: Image.network(video.thumbnails[1], fit: BoxFit.cover,),
width: MediaQuery.of(context).size.width,
),
Align(
child: Container(
child: Text(
video.date.toString() + "",
style: TextStyle(
fontFamily: 'Roboto Condensed',
fontSize: 14,
fontWeight: FontWeight.w300,
),
),
padding: EdgeInsets.fromLTRB(15, 5, 15, 0),
),
alignment: Alignment.centerLeft,
),
],
),
width: MediaQuery.of(context).size.width - 32,
padding: EdgeInsets.symmetric(
horizontal: 0,
vertical: 10,
),
alignment: Alignment.center,
),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(25))),
),
),
);
}
}
Run Code Online (Sandbox Code Playgroud)
Joh*_*y B 41
从 API30 (Android 11) 开始,您的 Android 应用程序必须列出它与之交互的所有应用程序。
你可以加:
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
Run Code Online (Sandbox Code Playgroud)
在您的 android 清单中绕过它或专门列出它们。
更多信息:https : //developer.android.com/about/versions/11/privacy/package-visibility
Wes*_*324 30
就我个人而言,我不喜欢使用 QUERY_ALL_PACKAGES 权限似乎带来的不确定性(因为 Google 可能会在未来停止让人们使用它)。出于这个原因,我做了一些调查,发现将以下内容添加到我的 AndroidManifest.xml 允许我的应用程序在 API 30 上打开浏览器、电话应用程序和电子邮件应用程序:
<manifest>
<!-- Nest within the manifest element, not the application element-->
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
</queries>
<application>
....
</application>
</manifest>
Run Code Online (Sandbox Code Playgroud)
要在 iOS 上使用相同的功能,可能需要将以下内容添加到您的 info.plist 文件中:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>https</string>
<string>http</string>
<string>tel</string>
<string>mailto</string>
</array>
Run Code Online (Sandbox Code Playgroud)
只是想分享,以防它帮助别人。
即使在尝试接受的答案之后,如果它不适合您,请尝试以下代码。
前期步骤:按照建议的已接受答案进行操作。
之前在AndroidManifest.xml中添加以下标签<application/>
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES"/>
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.DIAL" />
<data android:scheme="tel" />
</intent>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
</queries>
Run Code Online (Sandbox Code Playgroud)
现在我已经做了什么
创建一个方法:
Future<void> _makeSocialMediaRequest(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
Run Code Online (Sandbox Code Playgroud)
并通过以下方式调用它:
//FOR EMAIL
final Uri _emailLaunchUri = Uri(
scheme: 'mailto',
path: 'pratik13butani@gmail.com',
queryParameters: {'subject': 'Pratik Butani'});
_makeSocialMediaRequest(_emailLaunchUri.toString());
//FOR PHONE NUMBER:
final Uri _phoneLaunchUri =
Uri(scheme: 'tel', path: postOffice.mobileNo);
_makeSocialMediaRequest(_phoneLaunchUri.toString());
//FOR ANY URL.. YOU CAN PASS DIRECT URL..
_makeSocialMediaRequest("http://pratikbutani.com");
Run Code Online (Sandbox Code Playgroud)
它对我有用。希望它也对你有用。谢谢。
小智 7
兄弟只放了'!' 在“if (!await canLaunch(url))”之前使用这个 -->
if (!await canLaunch(url)){
await launch(
url,
forceSafariVC: false,
forceWebView: false,
headers: <String, String>{'my_header_key': 'my_header_value'},
);
} else {
throw 'Could not launch $url';
}
Run Code Online (Sandbox Code Playgroud)