How to get final url from webview flutter - flutter

I am making Downloader app which has a Webview where user can browse when there is the video playing he can download by click float button .but the problem is that it has only initial URL I want final URL to send it to my API to download that video.How to get Final Url in webview
import 'dart:html';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main(){
runApp(myapp());
}
class myapp extends StatefulWidget {
#override
_myappState createState() => _myappState();
}
final Completer<WebViewController> _controller = Completer<WebViewController>();
class _myappState extends State<myapp> {
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: Scaffold(
appBar: AppBar(
title: new Text('Fb Video Downloader'),
backgroundColor: Colors.blueAccent,
),
body: Column(
children: <Widget>[
new Text(''),
WebView(
initialUrl: "https://example.com",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webcontroller){
_controller.complete(webcontroller);
},
),
],
),
),
);
}
}`

Looking at the documentation for WebViewController it seems like it has a method called currentUrl() that probably will give you the result you're looking for.
currentUrl = await _yourWebController.currentUrl()

Related

How to make device back button to go to the previous page in flutter webview

I have some simple code here that just displays a webpage. I want to make it so that, pressing the device back button takes you to the previous page on the webview. I tried looking for solutions online but was unable to integrate any of them into my code. Kindly help me out.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
MyAppState createState() => MyAppState();
}
class MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
if (Platform.isAndroid) WebView.platform = SurfaceAndroidWebView();
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Mobile App",
home: Scaffold(
body: SafeArea(
child: WebView(
initialUrl: 'https://flutter.dev',
javascriptMode: JavascriptMode.unrestricted,
))),
debugShowCheckedModeBanner: false,
);
}
}
Wrap Scaffold with this widget
WillPopScope(
onWillPop: controller.onBackPressedHandler,
child: Scaffold( ... )
Future<bool> onBackPressedHandler() {
return Future.value(false);} //return false disables default functionality
you can control back button functionality in onBackPressedHandler function.
For your case you should put this line of code inside it
webviewController.goBack();

Flutter / webview_flutter too big to fit screen

I am running flutter 1.17.1, using webview_flutter: ^0.3.21
dependencies added to pubspec.yaml and added this to the end of info.plist
<key>io.flutter.embedded_views_preview</key>
<string>YES</string>
Problem: Webpage loaded into webview is too big to fit mobile phone screen.
screenshot
Here is the code with the webview:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class WebViewContainer extends StatefulWidget {
final url;
WebViewContainer(this.url);
#override
createState() => _WebViewContainerState(this.url);
}
class _WebViewContainerState extends State<WebViewContainer> {
var _url;
final _key = UniqueKey();
_WebViewContainerState(this._url);
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
Expanded(
child: WebView(
key: _key,
javascriptMode: JavascriptMode.unrestricted,
initialUrl: _url))
],
));
}
}
Link to the full app:
https://github.com/bi-samson/mreader
I've tried a minimal repro with the url "https://www.businessinsider.jp/" and the latest version of webview_flutter, this is the output:
Minimal repro:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
visualDensity: VisualDensity.adaptivePlatformDensity,
),
home: MyHomePage(title: 'Flutter Demo Home Page'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Completer<WebViewController> _controller =
Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: WebView(
initialUrl: "https://www.businessinsider.jp/",
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
javascriptMode: JavascriptMode.unrestricted,
),
);
}
}
It seems that the issue doesn't occur in the latest version.
Use InAppWebView instead of WebView.
This will add a line like this to your package's pubspec.yaml:
dependencies:
flutter_inappwebview: ^5.3.2
Here is a code example:
return InAppWebView(
initialOptions: InAppWebViewGroupOptions(
android: AndroidInAppWebViewOptions(
useHybridComposition: true,
textZoom: 100 * 2 // it makes 2 times bigger
)
),
onWebViewCreated: (InAppWebViewController controller) {
webViewController = controller;
controller.loadData(data: widget.html, mimeType: "text/html");
},
);
If you want to make it smaller, you just need to divide it as below:
textZoom: 100 / 2 // it makes 2 times smaller

Flutter webview showing blank screen

I am trying to use WebView() on my flutter app. After I wrote the code there are not any errors, however, when running the debug mode on my simulator the page is blank. The AppBar is there and the text is on it also, but the body is a blank screen.
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
class Audio extends StatefulWidget {
#override
_AudioState createState() => _AudioState();
}
class _AudioState extends State<Audio> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Audio"),
),
body: WebView(
key: UniqueKey(),
initialUrl: "http://google.com",
javascriptMode: JavascriptMode.unrestricted
),
);
}
}
This is pretty much an intended behavior. It seems that the initialUrl you've provided is an insecure HTTP connection.
The documentation "Insecure HTTP connections are disabled by default on iOS and Android" explains everything about this:
Starting with Android API
28
and iOS
9,
these platforms disable insecure HTTP connections by default.
With this change Flutter also disables insecure connections on mobile
platforms. Other platforms (desktop, web, etc) are not affected.
You can override this behavior by following the platform-specific
guidelines to define a domain-specific network policy. See the
migration guide below for details.
Much like the platforms, the application can still open insecure
socket connections. Flutter does not enforce any policy at socket
level; you would be responsible for securing the connection.
Here are the sample scenarios:
Scenario 1:
Using "http://google.com"
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(Audio());
}
class Audio extends StatefulWidget {
#override
_AudioState createState() => _AudioState();
}
class _AudioState extends State<Audio> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Audio"),
),
body: WebView(
key: UniqueKey(),
initialUrl: "http://google.com",
javascriptMode: JavascriptMode.unrestricted),
),
);
}
}
Scenario 2:
Using "google.com"
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(Audio());
}
class Audio extends StatefulWidget {
#override
_AudioState createState() => _AudioState();
}
class _AudioState extends State<Audio> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Audio"),
),
body: WebView(
key: UniqueKey(),
initialUrl: "google.com",
javascriptMode: JavascriptMode.unrestricted),
),
);
}
}
Scenario 3:
Using "https://www.google.com/"
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() {
runApp(Audio());
}
class Audio extends StatefulWidget {
#override
_AudioState createState() => _AudioState();
}
class _AudioState extends State<Audio> {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text("Audio"),
),
body: WebView(
key: UniqueKey(),
initialUrl: "https://www.google.com/",
javascriptMode: JavascriptMode.unrestricted),
),
);
}
}

Flutter webview failed to fit webpage with screen

i'm using webview_flutter: ^0.3.14+1.
Webview can't load web page https://m.bilibili.com/video/av57346110.html correctly. The web page is oversized
But if I open it with chrome, the web page fits screen correctly.
And I don't understand the difference between web browser and flutter webview.
Here's minimal codes to reproduce:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
void main() => runApp(new MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return new MaterialApp(
home: new Scaffold(
appBar: new AppBar(),
body: Container(
child: WebView(
initialUrl: "https://m.bilibili.com/video/av57346110.html",
javascriptMode: JavascriptMode.unrestricted,
navigationDelegate: (NavigationRequest request) {
print("Loading... ${request.url}");
if(request.url.startsWith("http")) {
return NavigationDecision.navigate;
} else {
return NavigationDecision.prevent;
}
},
),
),
),
);
}
}
I implement this with same plugin 'webview_flutter' and it is working just fine.
Here is my code
WebView(
initialUrl: 'https://m.bilibili.com/video/av57346110.html',
javascriptMode: JavascriptMode.unrestricted,
allowsInlineMediaPlayback: true,
)

How can I go back to the previous page with flutter_webview on button click?

I want to build a simple app using webview_flutter with no AppBar, with a static URL, and just a simple floatingActionButton on the bottom of the screen to navigate to the previous page, but I don't know how to do it.
Can someone just give me some guidelines so I can try to make the button do what it is supposed to do?
Here's an image of the app with the button:
I dunno what to try, but I'm trying to learn, sry about that =D
This is my whole code:
=)
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';
import 'dart:async';
void main () {
runApp(MaterialApp(
title: 'Something',
home: AplicativoB2b(),
debugShowCheckedModeBanner: false,
));
SystemChrome.setEnabledSystemUIOverlays ([]);
}
class AplicativoB2b extends StatefulWidget {
#override
_AplicativoB2bState createState() => _AplicativoB2bState();
}
class _AplicativoB2bState extends State<AplicativoB2b> {
Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: FloatingActionButton(
onPressed: () {
//HELP ME HERE!! =(
},
child: const Icon(Icons.arrow_back),
backgroundColor: Colors.black,
),
// bottomNavigationBar: BottomAppBar(color: Colors.white, child: Container(height: 50.0),),
// floatingActionButtonLocation: FloatingActionButtonLocation.endDocked,
);
}
}
Future<bool> _willPopCallback() async {
WebViewController webViewController = await _controller.future;
bool canNavigate = await webViewController.canGoBack();
if (canNavigate) {
webViewController.goBack();
return false;
} else {
return true;
}
}
I did it with different code than the previous answer. I followed this tutorial to get the webview & the floating button working. From there, it is really easy to give the floating button a back arrow icon and make the webview go back a page when the floating button is clicked.
To make the webview go back a page when the floating button is clicked (put this in its onpressed method):
controller.data.goBack();
The icon of the floating button can easily be changed at this line of code:
child: Icon(Icons.arrow_back)
All of the different buttons can be found here: link
Here is all of my code:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'dart:async';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'App'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: "https://google.com",
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: FutureBuilder<WebViewController>(
future: _controller.future,
builder: (BuildContext context,
AsyncSnapshot<WebViewController> controller) {
if (controller.hasData) {
return FloatingActionButton(
child: Icon(Icons.arrow_back),
onPressed: () {
controller.data.goBack();
});
}
return Container();
}
),
);
}
}
I did it! =D
It might look simple to lots of people haha, but for someone who never touched this kind of stuff before, I'm very proud of my ninja Ctrl C + Ctrl V. Just kidding, I looked at loads of exemples and tried this and it workd, if anyone has any suggestions I'd aprecciate it! =)
Here's what I did:
import 'package:flutter/material.dart';
import 'package:webview_flutter/webview_flutter.dart';
import 'package:flutter/services.dart';
import 'dart:async';
void main () {
runApp(MaterialApp(
title: 'Something',
home: AplicativoB2b(),
debugShowCheckedModeBanner: false,
));
SystemChrome.setEnabledSystemUIOverlays ([]);
}
class AplicativoB2b extends StatefulWidget {
#override
_AplicativoB2bState createState() => _AplicativoB2bState();
}
class _AplicativoB2bState extends State<AplicativoB2b> {
Completer<WebViewController> _controller = Completer<WebViewController>();
#override
Widget build(BuildContext context) {
return Scaffold(
body: WebView(
initialUrl: 'https://google.com',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_controller.complete(webViewController);
},
),
floatingActionButton: NavigationControls(_controller.future), // <-- added this
);
}
}
And the class I used for the floatingActionButton.
class NavigationControls extends StatelessWidget {
const NavigationControls(this._webViewControllerFuture)
: assert(_webViewControllerFuture != null);
final Future<WebViewController> _webViewControllerFuture;
#override
Widget build(BuildContext context) {
return FutureBuilder<WebViewController>(
future: _webViewControllerFuture,
builder:
(BuildContext context, AsyncSnapshot<WebViewController> snapshot) {
final bool webViewReady =
snapshot.connectionState == ConnectionState.done;
final WebViewController controller = snapshot.data;
return FloatingActionButton.extended(
onPressed: !webViewReady
? null
: () => navigate(context, controller, goBack: true),
icon: Icon(Icons.arrow_back),
backgroundColor: Colors.black,
label: Text("Voltar"),
);
},
);
}
navigate(BuildContext context, WebViewController controller,
{bool goBack: false}) async {
bool canNavigate =
goBack ? await controller.canGoBack() : await controller.canGoForward();
if (canNavigate) {
goBack ? controller.goBack() : controller.goForward();
} else {
Scaffold.of(context).showSnackBar(
SnackBar(
content: Text("Sem histórico anterior")),
);
}
}
}
That's basically the whole code. Flutter is cool and easy to lean when you really want it.
Thx to all!