Flutter 安卓WebView拍照上傳圖片文件問題及InAppWebView使用

前言

最近項(xiàng)目中加了一個(gè)H5的鏈接谱醇,里面有拍照、選照片和文件步做,以前用的原生的WebView副渴,iOS功能還可以正常彈窗,安卓死活沒反應(yīng)全度,就換了一種方案煮剧,使用InAppWebView看看。

webview_flutter官方的webview插件将鸵,很多功能缺失勉盅,H5上傳圖片,文件,但官方的插件并不支持顶掉。

實(shí)現(xiàn)過(guò)程

新建了頁(yè)面草娜,創(chuàng)建InAppWebView,具體代碼如下:


import 'dart:collection';
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_screenutil/flutter_screenutil.dart';
import 'package:magic/assets/styles/app_color.dart';

import '../../../common/utils/routers/fluro_navigator.dart';
import '../../../common/widgets/reza_app_bar.dart';

class WebViewInAppScreen extends StatefulWidget {
  const WebViewInAppScreen({
    Key key,
    @required this.url,
    this.title,
    this.type,
    this.onWebProgress,
    this.onWebResourceError,
    this.onLoadFinished,
    this.onWebTitleLoaded,
    this.onWebViewCreated,
  }) : super(key: key);

  final String url;
  final String title;
  final String type;
  final Function(int progress) onWebProgress;
  final Function(String errorMessage) onWebResourceError;
  final Function(String url) onLoadFinished;
  final Function(String webTitle) onWebTitleLoaded;
  final Function(InAppWebViewController controller) onWebViewCreated;

  @override
  State<WebViewInAppScreen> createState() => _WebViewInAppScreenState();
}

class _WebViewInAppScreenState extends State<WebViewInAppScreen> {

  // GlobalKey可以獲取到對(duì)應(yīng)的Widget的State對(duì)象
  // 當(dāng)我們頁(yè)面內(nèi)容很多時(shí)痒筒,而需要改變的內(nèi)容只有很少的一部分且在樹的底層的時(shí)候宰闰,我們?nèi)绾稳?shí)現(xiàn)增量更新/通常情況下有兩種方式,第一種是通過(guò)方法的回調(diào)簿透,去實(shí)現(xiàn)數(shù)據(jù)更新移袍,第二種是通過(guò)GlobalKey
  final GlobalKey webViewKey = GlobalKey();

  InAppWebViewController webViewController;
  InAppWebViewOptions viewOptions = InAppWebViewOptions(
    useShouldOverrideUrlLoading: true,
    mediaPlaybackRequiresUserGesture: true,
    // applicationNameForUserAgent: "dface-yjxdh-webview",
  );

  // webview配置
  // InAppWebViewGroupOptions viewOptions = InAppWebViewGroupOptions(
  // // 跨平臺(tái)配置
  // crossPlatform: InAppWebViewOptions (
  //   useShouldOverrideUrlLoading: true,
  //   mediaPlaybackRequiresUserGesture: true,
  // ),
  // // android平臺(tái)配置
  //   android: AndroidInAppWebViewOptions(
  //     //支持HybridComposition
  //     useHybridComposition: true
  //   ),
  //   // ios 平臺(tái)配置
  //   ios: IOSInAppWebViewOptions(
  //     allowsInlineMediaPlayback: true,
  //   )
  // );

  @override
  void initState() {
    // TODO: implement initState
    super.initState();
  }

  @override
  void dispose() {
    // TODO: implement dispose
    webViewController?.clearCache();
    super.dispose();
  }

  // 設(shè)置頁(yè)面標(biāo)題
  void setWebPageTitle(data) {
    if (widget.onWebTitleLoaded != null) {
      widget.onWebTitleLoaded(data);
    }
  }

  // flutter調(diào)用H5方法
  void callJSMethod() {

  }

  //返回
  void back() async {
    bool canGoBack = await webViewController.canGoBack();
    if (canGoBack) {
      webViewController.goBack();
    } else {
      NavigatorUtils.goBack(context);
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      resizeToAvoidBottomInset: Platform.isIOS ? false : true,
      appBar: RezaAppBar(
        centerTitle: widget.title,
        isBack: true,
        isClose: true,
        onBack: () {
          back();
        },
      ),
      body: Column(
        children: <Widget>[
          Expanded(
            child: InAppWebView(
              key: webViewKey,
              initialUrlRequest: URLRequest(url: Uri.parse(widget.url)),
              initialOptions: InAppWebViewGroupOptions(
                crossPlatform: viewOptions,
              ),
              onWebViewCreated: (controller) {
                webViewController = controller;
                if (widget.onWebViewCreated != null) {
                  widget.onWebViewCreated(controller);
                }
              },
              onTitleChanged: (controller, title) {
                if (widget.onWebTitleLoaded != null) {
                  widget.onWebTitleLoaded(title);
                }
              },
              onLoadStart: (controller, url) {},
              shouldOverrideUrlLoading: (controller, navigationAction) async {
                // 允許路由替換
                return NavigationActionPolicy.ALLOW;
              },
              onLoadStop: (controller, url) async {
                // 加載完成
                widget.onLoadFinished(url.toString());
              },
              onProgressChanged: (controller, progress) {
                if (widget.onWebProgress != null) {
                  widget.onWebProgress(progress);
                }
              },
              onLoadError: (controller, Uri url, int code, String message) {
                if (widget.onWebResourceError != null) {
                  widget.onWebResourceError(message);
                }
              },
              onUpdateVisitedHistory: (controller, url, androidIsReload) {},
              onConsoleMessage: (controller, consoleMessage) {
                print(consoleMessage);
              },
            ),
          ),
        ],
      ),
    );
  }
}

運(yùn)行,頁(yè)面倒是加載出來(lái)了老充,但是一點(diǎn)擊拍照的按鈕就直接崩潰了葡盗,如下:

報(bào)錯(cuò)信息

下面一大堆日志,關(guān)鍵報(bào)錯(cuò)的原因:

Couldn't find meta-data for provider with authority com.foton.general.flutter_inappwebview.fileprovider

崩潰原因:
相機(jī)權(quán)限默認(rèn)是禁止的蚂维。直接跳轉(zhuǎn)到相冊(cè)戳粒。
開啟相機(jī)權(quán)限,閃退虫啥。
授權(quán)被拒絕后蔚约,無(wú)法再?gòu)棾鍪跈?quán)
無(wú)法直接跳轉(zhuǎn)到相機(jī)拍照

所以就百度一番,原來(lái)是沒加這個(gè):

 <provider
           android:name="androidx.core.content.FileProvider"
           android:authorities="${applicationId}.flutter_inappwebview.fileprovider"
           android:exported="false"
           android:grantUriPermissions="true"
           >
           <meta-data
               android:name="android.support.FILE_PROVIDER_PATHS"
               android:resource="@xml/provider_paths" />
       </provider>

要在project->app->android->app->src->mian里的 AndroidManifest.xml 的 application 中添加上面的代碼涂籽,添加以上代碼后苹祟,在相機(jī)權(quán)限開啟的情況下,能正常彈出選擇彈框了。

結(jié)果運(yùn)行直接報(bào)錯(cuò)树枫,下面的錯(cuò)誤:

image.png

倒是說(shuō)的聽明白的直焙,沒加tools:replace="android:authorities",建議就加上了:

添加的完整的配置參數(shù):

<provider
            android:name="androidx.core.content.FileProvider"
            android:authorities="${applicationId}.flutter_inappwebview.fileprovider"
            android:exported="false"
            android:grantUriPermissions="true"
            tools:replace="android:authorities"
            >
            <meta-data
                android:name="android.support.FILE_PROVIDER_PATHS"
                android:resource="@xml/jshare_file_provider_paths" />
        </provider>

完整的配置砂轻。

然后運(yùn)行就OK了奔誓,可以拍照,選文件相冊(cè)了搔涝,記錄一下踩坑歷程厨喂。

image.png
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市庄呈,隨后出現(xiàn)的幾起案子蜕煌,更是在濱河造成了極大的恐慌,老刑警劉巖诬留,帶你破解...
    沈念sama閱讀 211,639評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件斜纪,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡文兑,警方通過(guò)查閱死者的電腦和手機(jī)盒刚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)绿贞,“玉大人伪冰,你說(shuō)我怎么就攤上這事≌寥洌” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵靠柑,是天一觀的道長(zhǎng)寨辩。 經(jīng)常有香客問我,道長(zhǎng)歼冰,這世上最難降的妖魔是什么靡狞? 我笑而不...
    開封第一講書人閱讀 56,474評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮隔嫡,結(jié)果婚禮上甸怕,老公的妹妹穿的比我還像新娘。我一直安慰自己腮恩,他們只是感情好梢杭,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評(píng)論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著秸滴,像睡著了一般武契。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,816評(píng)論 1 290
  • 那天咒唆,我揣著相機(jī)與錄音届垫,去河邊找鬼。 笑死全释,一個(gè)胖子當(dāng)著我的面吹牛装处,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播浸船,決...
    沈念sama閱讀 38,957評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼妄迁,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了糟袁?” 一聲冷哼從身側(cè)響起判族,我...
    開封第一講書人閱讀 37,718評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎项戴,沒想到半個(gè)月后形帮,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體戳玫,經(jīng)...
    沈念sama閱讀 44,176評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡隅津,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了竞漾。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片仿耽。...
    茶點(diǎn)故事閱讀 38,646評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡合冀,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出项贺,到底是詐尸還是另有隱情君躺,我是刑警寧澤,帶...
    沈念sama閱讀 34,322評(píng)論 4 330
  • 正文 年R本政府宣布开缎,位于F島的核電站棕叫,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏奕删。R本人自食惡果不足惜俺泣,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望完残。 院中可真熱鬧伏钠,春花似錦、人聲如沸谨设。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)铝宵。三九已至打掘,卻和暖如春华畏,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背尊蚁。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工亡笑, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人横朋。 一個(gè)月前我還...
    沈念sama閱讀 46,358評(píng)論 2 360
  • 正文 我出身青樓仑乌,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親琴锭。 傳聞我的和親對(duì)象是個(gè)殘疾皇子晰甚,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容