i am facing flutter webview issue - android

I am new in a flutter. I m facing an issue in flutter_webview here is my code IDK what's wrong with it. I write this code with the help of StackOverflow and an official plugin. my HTML files working fine
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
class Licences extends StatefulWidget {
#override
_LicencesState createState() => _LicencesState();
}
class _LicencesState extends State<Licences> {
WebViewController webViewController;
String filePath = 'files/PrivacyPolicy.html';
loadHtml() async {
String data = await rootBundle.loadString(filePath);
webViewController.loadUrl(Uri.dataFromString(data,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString());
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('Open-Source Licences'),
),
body: Builder(builder: (BuildContext context) {
return WebView(
initialUrl: '',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController controller) {
webViewController = controller;
loadHtml();
},
);
}),
);
}
}

Related

'canGoBack' method isn't defined for flutter WebViewPlus

I'm trying to use ( canGoBack() ) method with (flutter webview plus) plugin but it isn't work!!
vs code said:
The method 'canGoBack' isn't defined for the type 'WebViewPlusController'.
Try correcting the name to the name of an existing method, or defining a method named 'canGoBack'.
this is my code:
//import 'dart:async';
import 'package:flutter/material.dart';
import 'package:webview_flutter_plus/webview_flutter_plus.dart';
class HomeScreen extends StatefulWidget {
const HomeScreen({Key? key}) : super(key: key);
#override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
late WebViewPlusController controller;
#override
Widget build(BuildContext context) => WillPopScope (
onWillPop: () async {
if (await controller.canGoBack() ) {
return false; }
},
child: SafeArea(
child: Scaffold(
// ignore: avoid_unnecessary_containers
body: Container(
child: WebViewPlus(
initialUrl: 'assets/index.html',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (controller) {
this.controller = controller;
},
),
),
),
),
);
}
how can I solve this problem?
I'm trying to use ( canGoBack() ) method with (flutter webview plus) plugin but it isn't work!!
To use the method canGoBack you have to access the WebViewPlusController's property webViewController, here an example:
if (await controller.webViewController.canGoBack()) {
return false;
}
More information in: https://pub.dev/documentation/webview_flutter_plus/latest/webview_flutter_plus/WebViewPlusController-class.html

How can i pull to refresh webview in flutter

I want to refresh webview page just when i swipe down the page. I found this code.
import 'dart:io';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:rivlus_webview_app/common_widgets/alert_dialog.dart';
class NewWebView extends StatefulWidget {
const NewWebView({Key? key}) : super(key: key);
#override
State<NewWebView> createState() => _NewWebViewState();
}
class _NewWebViewState extends State<NewWebView> {
WebViewController? _controller;
double progress = 0;
#override
Widget build(BuildContext context) {
return SafeArea(
child: WillPopScope(
onWillPop: () async {
final result = await const CommonAlertDialog(
title: 'Çıkış Yap',
content: 'Uygulamadan çıkış yapmak istediğinize emin misiniz?',
mainButtonText: 'Evet',
cancelButtonText: 'Vazgeç',
).show(context);
if (result == true) {
return exit(0);
} else {
return false;
}
},
child: WebView(
key: UniqueKey(),
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
},
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer()
..onDown = (DragDownDetails dragDownDetails) {
_controller!.getScrollY().then((value) {
if (value == 0 &&
dragDownDetails.globalPosition.direction < 1) {
_controller!.reload();
}
});
})),
),
),
);
}
}
This is work. But when I click on the top of the screen, it refreshes the page. I dont want this. I just want it to refresh the page when I pull the page down. How can I do that. Thanks.
Thanks for everyone. I solved this problem with inappwebview_flutter package.
I was facing this problem a lot while using web view the pull to refresh plugin is not working. Then I came across a solution that was very easy to use.
First declare a late variable of WebViewController:
late WebViewController webViewController;
Create WebView Widget and on it initialize webviewContoller in onWebViewCreated and use gestureRecognizers for pull to refresh:
WebView(
gestureNavigationEnabled: true,
initialUrl: 'yourwebsitelink',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated:
(WebViewController webViewController) {
this.webViewController = webViewController;
},
zoomEnabled: false,
gestureRecognizers: Set()
..add(Factory<VerticalDragGestureRecognizer>(
() => VerticalDragGestureRecognizer()
..onDown = (DragDownDetails dragDownDetails) {
webViewController
.getScrollY()
.then((value) {
if (value == 0 &&
dragDownDetails
.globalPosition.direction <
1) {
webViewController.reload();
}
});
}
),
),
)
Hope this will solve your issue. Don't forget to give thanks.
you can use this plugin pull_to_refresh for swipe refresh.
onRefresh method of SmartRefresher

fix net::err_unknown_url_scheme whatsapp link on flutter webview

Please I want to know how to launch WhatsApp in the Flutter webview app or launch WhatsApp from the browser in Flutter, have used many codes with no errors but they do not work.Am using mac m1
and vscode
import 'package:coinpaga/Connectivity_Provider.dart';
import 'package:coinpaga/services/local_notification_service.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'homepage.dart';
import 'package:hexcolor/hexcolor.dart';
import 'package:colorful_safe_area/colorful_safe_area.dart';
/// Receive message when app is in background solution for on
message
Future<void> backgroundHandler(RemoteMessage message)async{
print(message.data.toString());
print(message.notification!.title);
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
LocalNotificationServices.initialize();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(backgroundHandler);
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(
create: (context) => ConnectivityProvider(),
child: HomePage(),
)
],
child:MaterialApp(
title: 'coinpaga',
theme: ThemeData(
primarySwatch: Colors.blue,
),
debugShowCheckedModeBanner: false,
home: ColorfulSafeArea(
color: HexColor("#2e2a42"),
top: true,
bottom: false,
left: false,
right: false,
child: HomePage(),
)
),
);
}
}
Home.dart
import 'package:coinpaga/Connectivity_Provider.dart';
import 'package:coinpaga/no_internet.dart';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
import 'package:provider/provider.dart';
class HomePage extends StatefulWidget {
// ignore: unused_field
final _flutterwebview = FlutterWebviewPlugin();
HomePage({ Key? key }) : super(key: key);
#override
_HomePageState createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
#override
void initState() {
super.initState();
Provider.of<ConnectivityProvider>(context, listen:
false).startMonitoring();
}
#override
Widget build(BuildContext context) {
return pageUI();
}
#override
void dispose() {
_flutterwebview.dispose();
super.dispose();
}
}
Widget pageUI() {
return Consumer<ConnectivityProvider>(
builder: (context, model, child) {
return model.isOnline
? WebviewScaffold(
url: 'https://coinpaga.com',
withLocalStorage: true,
withJavascript: true,
scrollBar: false,
initialChild: Center(child: Text('Loading...')),
) : NoInternet();
},
);
}
// ignore: camel_case_types
class _flutterwebview {
static void dispose() {}
}
Please help me go through it.
String text = "Hello World !! Hey There";
String url = "https://wa.me/?text=${Uri.encodeFull(text)}";
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url),
mode: LaunchMode.externalApplication);
}
First, add url_launcher, then I use this code to launch whatsapp on flutter webview and works.
WebView(
initialUrl: getUrl(_url),
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) async {
if (request.url
.startsWith('https://api.whatsapp.com/send?phone')) {
print('blocking navigation to $request}');
List<String> urlSplitted = request.url.split("&text=");
String phone = "0123456789";
String message =
urlSplitted.last.toString().replaceAll("%20", " ");
await _launchURL(
"https://wa.me/$phone/?text=${Uri.parse(message)}");
return NavigationDecision.prevent;
}
print('allowing navigation to $request');
return NavigationDecision.navigate;
},
)
_launchURL(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
You can use url_launcher to launch URLs.
You can give https://api.whatsapp.com/send/?phone=(phone_number) URL to launch.
For the launching the WhatsApp Website use launch('https://api.whatsapp.com/send/?phone=(phone_number)')
Make sure you give your country code without (+).

Flutter webview intercept and add headers to all requests

Using the webview_flutter package i could load my website and add session cookies to the initial URL.
_controller.future.then((controller) {
_webViewController = controller;
Map<String, String> header = {'Cookie': 'ci_session=${widget.sessionId}'};
_webViewController.loadUrl('https://xxxx.com', headers: header);
});
In order to keep the session going i need to add the same header for all requests not just for the initial one.
Is there any way to intercept all requests and modify them by adding headers to them?
the closest thing i found was navigationDelegate but it only returns a NavigationDecision which isn't useful in my case.
You can use my plugin flutter_inappwebview, which is a Flutter plugin that allows you to add inline WebViews or open an in-app browser window and has a lot of events, methods, and options to control WebViews.
If you need to add custom headers for each request, you can use the shouldOverrideUrlLoading event (you need to enable it using useShouldOverrideUrlLoading: true option).
Instead, if you need to add cookies to your WebView, you can just use the CookieManager class (CookieManager.setCookie method to set a cookie).
Here is an example that set a cookie (named ci_session) in your WebView and also set a custom header (named My-Custom-Header) for each request:
import 'dart:async';
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewController webView;
CookieManager _cookieManager = CookieManager.instance();
#override
void initState() {
super.initState();
_cookieManager.setCookie(
url: "https://github.com/",
name: "ci_session",
value: "54th5hfdcfg34",
domain: ".github.com",
isSecure: true,
);
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('InAppWebView Example'),
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: InAppWebView(
initialUrl: "https://github.com/",
initialHeaders: {'My-Custom-Header': 'custom_value=564hgf34'},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useShouldOverrideUrlLoading: true
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {},
onLoadStop: (InAppWebViewController controller, String url) async {
List<Cookie> cookies = await _cookieManager.getCookies(url: url);
cookies.forEach((cookie) {
print(cookie.name + " " + cookie.value);
});
},
shouldOverrideUrlLoading: (controller, shouldOverrideUrlLoadingRequest) async {
print("URL: ${shouldOverrideUrlLoadingRequest.url}");
if (Platform.isAndroid || shouldOverrideUrlLoadingRequest.iosWKNavigationType == IOSWKNavigationType.LINK_ACTIVATED) {
controller.loadUrl(url: shouldOverrideUrlLoadingRequest.url, headers: {
'My-Custom-Header': 'custom_value=564hgf34'
});
return ShouldOverrideUrlLoadingAction.CANCEL;
}
return ShouldOverrideUrlLoadingAction.ALLOW;
},
))
])),
),
);
}
}
in flutter_webview case
onWebViewCreated: (WebViewController webViewController) {
this.webViewController = webViewController;
},
onPageStarted: (url) {
webViewController.loadUrl(url, headers: headers);
},
use this

Flutter Webview change webpage is not available

I wanna change the "Webpage not available", in my WebView application, if the user doesn't have internet.
I read the documentation, and try some another puglins
import 'package:webview_flutter/webview_flutter.dart';
[...]
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: const WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
),
);
}
}
You can try my plugin flutter_inappwebview. It has events to manage errors while the WebView is loading an url (onLoadError event) and when it receives HTTP errors, such as 403, 404, etc (onLoadHttpError event).
Full example with working code that loads a custom error page if the user doesn't have internet connection:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
Future main() async {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
}
#override
void dispose() {
super.dispose();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: InAppWebViewPage()
);
}
}
class InAppWebViewPage extends StatefulWidget {
#override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController webView;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("InAppWebView")
),
body: Container(
child: Column(children: <Widget>[
Expanded(
child: Container(
child: InAppWebView(
initialUrl: "https://flutter.dev/",
initialHeaders: {},
initialOptions: InAppWebViewWidgetOptions(
inAppWebViewOptions: InAppWebViewOptions(
debuggingEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
onLoadError: (InAppWebViewController controller, String url, int code, String message) async {
print("error $url: $code, $message");
var tRexHtml = await controller.getTRexRunnerHtml();
var tRexCss = await controller.getTRexRunnerCss();
controller.loadData(data: """
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0,maximum-scale=1.0, user-scalable=no">
<style>$tRexCss</style>
</head>
<body>
$tRexHtml
<p>
URL $url failed to load.
</p>
<p>
Error: $code, $message
</p>
</body>
</html>
""");
},
onLoadHttpError: (InAppWebViewController controller, String url, int statusCode, String description) async {
print("HTTP error $url: $statusCode, $description");
},
),
),
),
]))
);
}
}
The result is:
This example loads directly an html source, but you can load an html file from the assets folder or an url.
Just for fun: my plugin includes the javascript and css code of the Google Chrome t-rex game!
Just Add onWebResourceError method to your Webview.
WebView(
onWebResourceError: (WebResourceError webviewerrr) {
print("Handle your Error Page here");
},
initialUrl: "your url"
javascriptMode: JavascriptMode.unrestricted,
onPageFinished: (String url) {
print('Page finished loading:');
},
);

Categories

Resources