Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Android FlutterBoostFragment无法触发onActivityForResult #2038

Closed
koukoucai opened this issue May 13, 2024 · 2 comments
Closed

[Bug]: Android FlutterBoostFragment无法触发onActivityForResult #2038

koukoucai opened this issue May 13, 2024 · 2 comments
Labels
Not a problem with boost Maybe it not a problem with boost

Comments

@koukoucai
Copy link

请描述遇到的问题,以及您所期望的正确的结果

Android端 FlutterBoostFragment 内使用flutter_inappwebview 加载h5页面 input标签 选择相册后无法回调

请说明如何操作会遇到上述问题

项目工程:Flutter boost下面的example工程 新增 flutter_inappwebview: 5.8.0
open flutter fragment page 新增一个FlutterBoostFragment 新增一个InAppWebViewExampleScreen 加载https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_file 弹出图片选择后选择图片后展示
使用FlutterBoostActivity 作为容器新增InAppWebViewExampleScreen 加载该h5页面可以。

请问是什么原因

在下面填入关键复现代码

import 'dart:collection';
// import 'dart:convert';
import 'dart:io';
// import 'dart:typed_data';

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


class InAppWebViewExampleScreen extends StatefulWidget {
  @override
  _InAppWebViewExampleScreenState createState() =>
      new _InAppWebViewExampleScreenState();
}

class _InAppWebViewExampleScreenState extends State<InAppWebViewExampleScreen> {
  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController? webViewController;
  InAppWebViewGroupOptions options = InAppWebViewGroupOptions(
      crossPlatform: InAppWebViewOptions(
          // useShouldOverrideUrlLoading: true,
          // mediaPlaybackRequiresUserGesture: false
          javaScriptEnabled: true,
          disableHorizontalScroll: true,
      ),

      android: AndroidInAppWebViewOptions(
        useHybridComposition: true,
      ),
      ios: IOSInAppWebViewOptions(
        allowsInlineMediaPlayback: true,
      ));

  late PullToRefreshController pullToRefreshController;
  late ContextMenu contextMenu;
  String url = "";
  double progress = 0;
  final urlController = TextEditingController();

  @override
  void initState() {
    super.initState();

    contextMenu = ContextMenu(
        menuItems: [
          ContextMenuItem(
              androidId: 1,
              iosId: "1",
              title: "Special",
              action: () async {
                print("Menu item Special clicked!");
                print(await webViewController?.getSelectedText());
                await webViewController?.clearFocus();
              })
        ],
        options: ContextMenuOptions(hideDefaultSystemContextMenuItems: false),
        onCreateContextMenu: (hitTestResult) async {
          print("onCreateContextMenu");
          print(hitTestResult.extra);
          print(await webViewController?.getSelectedText());
        },
        onHideContextMenu: () {
          print("onHideContextMenu");
        },
        onContextMenuActionItemClicked: (contextMenuItemClicked) async {
          var id = (Platform.isAndroid)
              ? contextMenuItemClicked.androidId
              : contextMenuItemClicked.iosId;
          print("onContextMenuActionItemClicked: " +
              id.toString() +
              " " +
              contextMenuItemClicked.title);
        });

    pullToRefreshController = PullToRefreshController(
      options: PullToRefreshOptions(
        color: Colors.blue,
      ),
      onRefresh: () async {
        if (Platform.isAndroid) {
          webViewController?.reload();
        } else if (Platform.isIOS) {
          webViewController?.loadUrl(
              urlRequest: URLRequest(url: await webViewController?.getUrl()));
        }
      },
    );
  }

  @override
  void dispose() {
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
        appBar: AppBar(title: Text("InAppWebView")),
        // drawer: myDrawer(context: context),
        body: SafeArea(
            child: Column(children: <Widget>[
          TextField(
            decoration: InputDecoration(prefixIcon: Icon(Icons.search)),
            controller: urlController,
            keyboardType: TextInputType.url,
            onSubmitted: (value) {
              var url = Uri.parse(value);
              if (url.scheme.isEmpty) {
                url = Uri.parse("https://www.google.com/search?q=" + value);
              }
              webViewController?.loadUrl(urlRequest: URLRequest(url: url));
            },
          ),
          Expanded(
            child: Stack(
              children: [
                InAppWebView(
                  key: webViewKey,
                  // contextMenu: contextMenu,
                  initialUrlRequest:
                      // URLRequest(url: Uri.parse("https://github.com/flutter")),
                      URLRequest(url: Uri.parse("https://www.w3schools.com/tags/tryit.asp?filename=tryhtml5_input_type_file")),
                    
                  // initialFile: "assets/index.html",
                  initialUserScripts: UnmodifiableListView<UserScript>([]),
                  initialOptions: options,
                  pullToRefreshController: pullToRefreshController,
                  onWebViewCreated: (controller) {
                    webViewController = controller;
                  },
                  onLoadStart: (controller, url) {
                    setState(() {
                      this.url = url.toString();
                      urlController.text = this.url;
                    });
                  },
                  androidOnPermissionRequest:
                      (controller, origin, resources) async {
                    return PermissionRequestResponse(
                        resources: resources,
                        action: PermissionRequestResponseAction.GRANT);
                  },
                  shouldOverrideUrlLoading:
                      (controller, navigationAction) async {
                    var uri = navigationAction.request.url!;

                    if (![
                      "http",
                      "https",
                      "file",
                      "chrome",
                      "data",
                      "javascript",
                      "about"
                    ].contains(uri.scheme)) {
                      if (await canLaunchUrl(uri)) {
                        // Launch the App
                        await launchUrl(
                          uri,
                        );
                        // and cancel the request
                        return NavigationActionPolicy.CANCEL;
                      }
                    }

                    return NavigationActionPolicy.ALLOW;
                  },
                  onLoadStop: (controller, url) async {
                    pullToRefreshController.endRefreshing();
                    setState(() {
                      this.url = url.toString();
                      urlController.text = this.url;
                    });
                  },
                  onLoadError: (controller, url, code, message) {
                    pullToRefreshController.endRefreshing();
                  },
                  onProgressChanged: (controller, progress) {
                    if (progress == 100) {
                      pullToRefreshController.endRefreshing();
                    }
                    setState(() {
                      this.progress = progress / 100;
                      urlController.text = this.url;
                    });
                  },
                  onUpdateVisitedHistory: (controller, url, androidIsReload) {
                    setState(() {
                      this.url = url.toString();
                      urlController.text = this.url;
                    });
                  },
                  onConsoleMessage: (controller, consoleMessage) {
                    print(consoleMessage);
                  },
                ),
                progress < 1.0
                    ? LinearProgressIndicator(value: progress)
                    : Container(),
              ],
            ),
          ),
          ButtonBar(
            alignment: MainAxisAlignment.center,
            children: <Widget>[
              ElevatedButton(
                child: Icon(Icons.arrow_back),
                onPressed: () {
                  webViewController?.goBack();
                },
              ),
              ElevatedButton(
                child: Icon(Icons.arrow_forward),
                onPressed: () {
                  webViewController?.goForward();
                },
              ),
              ElevatedButton(
                child: Icon(Icons.refresh),
                onPressed: () {
                  webViewController?.reload();
                },
              ),
            ],
          ),
        ])));
  }
}

复现的平台

Both

Flutter SDK版本

3.7.9

FlutterBoost版本

main主分支

是否延迟初始化FlutterBoost

No

解决方案

@joechan-cq
Copy link
Collaborator

根据flutter_inappwebview源码中的InAppWebViewChromeClient类,可以看到打开图片选择时所用的activity,是TabMainActivity,也就是FlutterBoostFragment所在的容器Activity并不是FlutterActivity,所以无法触发inAppWebview中依赖FlutterEngineConnectionRegistry的onActivityResultFlutterEngineActivityPluginBinding的onActivityResult,也就无法把结果传回到Flutter

这个只能说是flutter_inappwebview并不适配FlutterBoost。如果要得到正确的结果,可以尝试的一种方案是在FlutterBoostFragment的容器Activity中自行把Activity收到的onActivityResult的结果转发给RegistryPluginBindingonActivityResult。另一种方案修改InAppWebViewChromeClient中的跳转方式,使用FlutterBoostFragmentstartActivityForResult进行跳转,或者使用Activity Result API做类似处理。

@joechan-cq joechan-cq added the Not a problem with boost Maybe it not a problem with boost label May 15, 2024
@koukoucai
Copy link
Author

根据flutter_inappwebview源码中的InAppWebViewChromeClient类,可以看到打开图片选择时所用的activity,是TabMainActivity,也就是FlutterBoostFragment所在的容器Activity并不是FlutterActivity,所以无法触发inAppWebview中依赖FlutterEngineConnectionRegistry的onActivityResultFlutterEngineActivityPluginBinding的onActivityResult,也就无法把结果传回到Flutter

这个只能说是flutter_inappwebview并不适配FlutterBoost。如果要得到正确的结果,可以尝试的一种方案是在FlutterBoostFragment的容器Activity中自行把Activity收到的onActivityResult的结果转发给RegistryPluginBindingonActivityResult。另一种方案修改InAppWebViewChromeClient中的跳转方式,使用FlutterBoostFragmentstartActivityForResult进行跳转,或者使用Activity Result API做类似处理。

感谢解答

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Not a problem with boost Maybe it not a problem with boost
Projects
None yet
Development

No branches or pull requests

2 participants