我正在构建一个Flutter应用程序,它基本上是从云端获取数据.
现在我想激发一个隐式意图,这样用户就可以 Select 他们最喜欢的应用程序来处理负载.
我一直在寻找答案,我try 了以下几种途径:
- url_Launcher插件(如How to open an application from a Flutter app?中建议的那样)
- Android意图
- 共享插件
路#3真的不是我想要的,因为它使用的是平台的"共享"机制(即.在Twitter上发布/发送给联系人),而不是打开有效负载.
路由1和2有点奏效.以一种摇摇欲坠的、怪异的方式.我稍后会解释的.
下面是我的代码流程:
import 'package:url_launcher/url_launcher.dart';
// ...
// retrieve payload from internet and save it to an External Storage location
File payload = await getPayload();
String uriToShare = samplePayload.uri.toString();
// at this point uriToShare looks like: 'file:///storage/emulated/0/jpg_example.jpg'
uriToShare = uriToShare.replaceFirst("file://", "content://");
// launch url
if (await canLaunch(uriToShare)) {
await launch(uriToShare);
} else {
throw "Failed to launch $uriToShare";
上面的代码使用的是url_launcher
插件.如果我使用的是android_intent
插件,那么最后一行代码变成:
// fire intent
AndroidIntent intent = AndroidIntent(
action: "action_view",
data: uriToShare,
);
await intent.launch();
在将文件保存到外部目录之前,所有操作都可以正常工作(运行代码后,我可以确认文件是否存在)
当我试图共享URI时,事情变得很奇怪. 我已经在3部不同的手机上测试了这段代码.其中之一(三星Galaxy S9)会抛出以下异常:
I/io.flutter.plugins.androidintent.AndroidIntentPlugin(10312): Sending intent Intent { act=android.intent.action.VIEW dat=content:///storage/emulated/0/jpg_example.jpg }
E/MethodChannel#plugins.flutter.io/android_intent(10312): Failed to handle method call
E/MethodChannel#plugins.flutter.io/android_intent(10312): java.lang.SecurityException: Permission Denial: starting Intent { act=android.intent.action.VIEW dat=content:///storage/emulated/0/jpg_example.jpg cmp=com.google.android.gm/.browse.TrampolineActivity } from ProcessRecord{6da6f74 10312:com.safe.fmeexpress/u0a218} (pid=10312, uid=10218) requires com.google.android.gm.permission.READ_GMAIL
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.os.Parcel.readException(Parcel.java:1959)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.os.Parcel.readException(Parcel.java:1905)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.IActivityManager$Stub$Proxy.startActivity(IActivityManager.java:4886)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.Instrumentation.execStartActivity(Instrumentation.java:1617)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.Activity.startActivityForResult(Activity.java:4564)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.Activity.startActivityForResult(Activity.java:4522)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.Activity.startActivity(Activity.java:4883)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.Activity.startActivity(Activity.java:4851)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at io.flutter.plugins.androidintent.AndroidIntentPlugin.onMethodCall(AndroidIntentPlugin.java:141)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage(MethodChannel.java:191)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at io.flutter.view.FlutterNativeView.handlePlatformMessage(FlutterNativeView.java:152)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.os.MessageQueue.nativePollOnce(Native Method)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.os.MessageQueue.next(MessageQueue.java:325)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.os.Looper.loop(Looper.java:142)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at android.app.ActivityThread.main(ActivityThread.java:6938)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at java.lang.reflect.Method.invoke(Native Method)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at com.android.internal.os.Zygote$MethodAndArgsCaller.run(Zygote.java:327)
E/MethodChannel#plugins.flutter.io/android_intent(10312): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1374)
我不知道这个意图是怎么被cmp=com.google.android.gm/.browse.TrampolineActivity
度污染的
这一例外仅在Galaxy S9中出现. 另外两部手机没有给我带来这个问题. 他们确实启动了文件uri,有人问我如何打开这个文件,但没有提供任何图像处理应用程序(如Gallery、QuickPic或Google Photos).
为了澄清一下,url_launcher
和android_intent
路由都会产生完全相同的结果.
感觉我好像错过了一步.有人能指出我做错了什么吗?我是否必须开始使用平台渠道来完成此任务?
关于我为什么这么做的一些澄清:
- 将uri类型从file://转换为content://,因为我得到的是
android.os.FileUriExposedException
- 将临时文件存储在外部存储中,因为我现在还不想处理授予URI读取权限的问题.(我试过了,但
android_intent
目前还没有办法设置意向标志)