Is there AdMob support for Flutter web? - flutter

Is there AdMob support for Flutter web? All libraries that I found are intended only for Android and IOS

As you can see in the image below, Google Admobe is not supported for the web so you can not use it for flutter web or other web frameworks.
On other hand, you can use adsense and set your ads for flutter web,
and I find this solution for using Adsense as HTML(with IFrameElement)
first created an html file adview.html
<script async src="https://pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<ins class="adsbygoogle"
style="display:inline-block;width:320px;height:80px"
data-ad-client="ca-pub-xxxxxx"
data-ad-slot="xxxxxxx"></ins>
<script>
(adsbygoogle = window.adsbygoogle || []).push({});
</script>
And then, an IFrameElement to make use of the HTML:
import 'dart:html';
import 'dart:ui' as ui;
import 'package:flutter/material.dart';
Widget adsenseAdsView() {
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'adViewType',
(int viewID) => IFrameElement()
..width = '320'
..height = '100'
..src = 'adview.html'
..style.border = 'none');
return SizedBox(
height: 100.0,
width: 320.0,
child: HtmlElementView(
viewType: 'adViewType',
),
);
}

firebase_admob is now deprecated in favour of google_mobile_ads and both of them do not support flutter web. However, you can use display ads on websites using Google Adsense.
You can create a blank web page and add ads and embed the flutter app in the HTML page.
Ref:
Google Adsense
Embed flutter App in website

Related

Flutter web: The communication between Flutter web and Flutter APP fails

APP : Developed with Flutter
Web: Develop with Flutter
Use the webview_flutter plugin to load web pages in app.
Now the web page wants to communicate with the APP.
It is possible to use JavaScript methods to interact with flutter.
JavaScript code
function toast() {
Toast.postMessage("message from web page");
}
Flutter APP code
JavascriptChannel _toasterJavascriptChannel(BuildContext context) {
return JavascriptChannel(
name: 'Toast',
onMessageReceived: (JavascriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
});
}
The above method is possible.
But now Flutter web tries to interact with Flutter APP and fails, code show as below
Flutter web code
void toast() {
html.window.postMessage("message from web page", "Toast");
}
Flutter APP code same as above.
The error message is as follows
I/chromium(25735): [INFO:CONSOLE(14560)] "SyntaxError: Failed to
execute 'postMessage' on 'Window': Invalid target origin 'Toast' in a
call to 'postMessage'."
Is there something wrong with my calling method?
There's a way, but it doesn't feel good.
Define a JavaScript file in the web directory, here called toast.js. This file defines the methods to communicate with Dart.
function makeToast(msg) {
Toast.postMessage(msg);
}
Import toast.js in index.html in the web directory
<head>
// ...
<!-- This script adds the flutter initialization JS code -->
<script src="flutter.js" defer></script>
<!-- new line -->
<script src="toast.js"></script>
</head>
Go back to the Flutter project and create a dart file in the lib directory, called js_channel.dart here, declare a method in this file for Dart to call JavaScript methods
import 'package:js/js.dart';
#JS('makeToast')
external void makeToast(String msg);
Call makeToast method
void toast() {
makeToast("msg from flutter web")
}
The above steps are all done in the flutter web project.
Next, you need to use the webview in the Flutter native (android or ios) project to load the web page built by the Flutter web project, and then listen to the message sent by the Toast object in the webview.
Here I am using the webview_flutter plugin
Widget _buildWebView() {
return WebView(
debuggingEnabled: true,
initialUrl: "your web url",
javascriptMode: JavascriptMode.unrestricted,
javascriptChannels: <JavascriptChannel>{
JavascriptChannel(
name: 'Toast',
onMessageReceived: (JavascriptMessage message) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(content: Text(message.message)),
);
},
),
},
),
}

Calling postMessage on iframeElement in flutter web

I have a flutter web application. I need to call postMessage to be handled by the page opened in an iframe element using
ui.platformViewRegistry.registerViewFactory(
'hello-world-html',
(int viewId) => html.IFrameElement()
..width = '100%'
..height = '100%'
..src = widget.url
..style.border = 'none'
);
Is there a way to do this?
Technically, PostMessage sends to the main document's window, not to the iframe's.
Specify the iframe's window object in Javascript:
document.getElementById('hello-world-html').contentWindow.postMessage(.......)
or in Dart you can do:
import 'dart:html' as html;
// Your code
html.document.getElementById.getElementById('hello-world-html').contentWindow.postMessage(.......)
this works for an iframe that has a cross domain src
import 'dart:html';
IFrameElement element = document.getElementById('iframe') as IFrameElement;
element.contentWindow?.postMessage(data.toJson(),'*');

Ionic 5 / React: Use ion-icon to embed custom SVG

I have a React app in Ionic 5 and I want to add some custom SVGs to it.
This SO question is about Angular, but my question is about React.
My app folder structure looks like this:
src
assets
listen.svg
SvgListen.tsx
Here is SvgListen.tsx:
import React from 'react';
import { ReactComponent as ListenSvg } from './listen.svg';
import { IonIcon } from '#ionic/react';
const SvgListen = () => (
<>
<ListenSvg />
<IonIcon src="./listen.svg" font-size="48px" />
</>
);
export default SvgListen;
When testing the app in Chrome, I get this HTML:
<ion-icon src="./listen.svg" font-size="48px" role="img" class="ios hydrated"></ion-icon>
The <ListenSvg /> that I imported is displayed correctly; however, the ion-icon is not displayed. There is no error message, either.
I checked this blog post, but no luck with the approach outlined there, either.
How can I show a custom SVG using <IonIcon> in Ionic 5?
According do the Create React App docs you can import images to get their final path in the output bundle:
import React from 'react';
import { IonIcon } from '#ionic/react';
import listenSvg from './listen.svg';
const SvgListen = () => (
<IonIcon src={listenSvg} font-size="48px" />
);
export default SvgListen;

Embedding a Youtube video in Flutter Web

Is it possible to embed a Youtube video in a Flutter web page? I tried the following code to have a Youtube embedded in my Flutter website, but nothing appears on the page without any error message.
import 'package:flutter_html_view/flutter_html_view.dart';
Container(child: HtmlView(data: """
<iframe src="https://www.youtube.com/embed/xMzkWfIR9Pk" width="560" height="315"></iframe>
""")),
Also tried the solution recommended here (WebView in Flutter Web) but that doesn't work either.
import 'dart:ui' as ui
//ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
'hello-world-html',
(int viewId) => html.IFrameElement()
..width = '640'
..height = '360'
..src = 'https://www.youtube.com/embed/IyFZznAk69U'
..style.border = 'none');
I used to package called flutter_html
But this gave me some scrolling issues.
Html(
data: '<iframe width="560" height="315" src="https://www.youtube.com/embed/D_mCZlQZg9Y" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>',
)
You should go like this
import 'dart:html' as html;
import 'dart:js' as js;
import 'dart:ui' as ui;
String viewID = "your-view-id";
#override
Widget build(BuildContext context) {
// ignore: undefined_prefixed_name
ui.platformViewRegistry.registerViewFactory(
viewID,
(int id) => html.IFrameElement()
..width = MediaQuery.of(context).size.width.toString()
..height = MediaQuery.of(context).size.height.toString()
..src = 'https://www.youtube.com/embed/IyFZznAk69U'
..style.border = 'none');
return SizedBox(
height: 500,
child: HtmlElementView(
viewType: viewID,
),
);
}
You can use the youtube_player_iframe
YoutubePlayerController _controller = YoutubePlayerController(
initialVideoId: 'K18cpp_-gP8',
params: YoutubePlayerParams(
playlist: ['nPt8bK2gbaU', 'gQDByCdjUXw'], // Defining custom playlist
startAt: Duration(seconds: 30),
showControls: true,
showFullscreenButton: true,
),
);
YoutubePlayerIFrame(
controller: _controller,
aspectRatio: 16 / 9,
),
ext_video_player supports Android, iOS and web for YouTube. You can try running sample code from ext_video_player repo.
I tested with different browsers of different OS. Android, Mac, Windows browsers are working fine with ext_video_player. But it's not playing with iOS browser.
There are, at least, two solutions:
a) video_player package now works fine in the three main platforms: android, ios and web
b) This article explains a good way to embed video source in a flutter web widget, even when the article is for local files, the final procedure works fine for web sources, like youtube, too: https://vermahitesh.medium.com/play-local-video-on-flutter-web-d757bab0141c

How do I open a web browser (URL) from my Flutter code?

I am building a Flutter app, and I'd like to open a URL into a web browser or browser window (in response to a button tap). How can I do this?
TL;DR
This is now implemented as Plugin
const url = "https://flutter.io";
if (await canLaunchUrl(url))
await launchUrl(url);
else
// can't launch url, there is some error
throw "Could not launch $url";
Full example:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(new Scaffold(
body: new Center(
child: new RaisedButton(
onPressed: _launchURL,
child: new Text('Show Flutter homepage'),
),
),
));
}
_launchURL() async {
const url = 'https://flutter.io';
final uri = Uri.parse(url);
if (await canLaunchUrl(uri)) {
await launchUrl(uri);
} else {
throw 'Could not launch $url';
}
}
In pubspec.yaml
dependencies:
url_launcher: ^6.1.7
Check out the latest url_launcher package.
Special Characters:
If the url value contains spaces or other values that are now allowed in URLs, use
Uri.encodeFull(urlString) or Uri.encodeComponent(urlString) and pass the resulting value instead.
If you target sdk 30 or above canLaunch will return false by default due to package visibility changes: https://developer.android.com/training/basics/intents/package-visibility
in the androidManifest.xml you'll need to add the following directly under <manifest>:
<queries>
<intent>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" />
</intent>
</queries>
Then the following should word - for flutter 3 upwards:
const uri = Uri.parse("https://flutter.io");
if (await canLaunchUrl(uri)){
await launchUrl(uri);
} else {
// can't launch url
}
or for older versions of flutter use this instead:
const url = "https://flutter.io";
if (await canLaunch(url)){
await launch(url);
} else {
// can't launch url
}
launchUrl has a mode parameter which can be used to control where the url gets launched.
So, passing in launchUrl(uri, mode: LaunchMode.platformDefault) leaves the decision of how to launch the URL to the platform
implementation. But you can also specify
LaunchMode.inAppWebView which will use an in-app web view
LaunchMode.externalApplication for it to be handled by an external application
Or LaunchMode.externalNonBrowserApplication to be handled by a non-browser application.
For Flutter:
As described above by Günter Zöchbauer
For Flutter Web:
import 'dart:html' as html;
Then use:
html.window.open(url, name);
Make sure that you run flutter clean if the import doesn't resolve.
For those who wants to implement LAUNCH BROWSER AND EXIT APP by using url_launcher. Remember to use (forceSafariVC: false) to open the url in default browser of the phone. Otherwise, the launched browser exit along with your APP.
await launch(URL, forceSafariVC: false);
The best way is to use url_launcher package .
Add url_launcher as a dependency in your pubspec.yaml file.
dependencies:
url_launcher:
An example of how to use it :
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
void main() {
runApp(
MaterialApp(
home: Scaffold(
appBar: AppBar(title: Text('Flutter is beautiful'),),
body: Center(
child: RaisedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
)),
);
}
_launchURL() async {
const url = 'https://flutter.dev';
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
} else {
throw 'Could not launch $url';
}
}
Output :
The launch method takes a string argument containing a URL .
By default, Android opens up a browser when handling URLs. You can
pass forceWebView: true parameter to tell the plugin to open a WebView
instead. If you do this for a URL of a page containing JavaScript,
make sure to pass in enableJavaScript: true, or else the launch method
will not work properly. On iOS, the default behavior is to open all
web URLs within the app. Everything else is redirected to the app
handler.
This is now implemented as Plugin
const url = "https://flutter.io";
final Uri _url = Uri.parse(url);
await launchUrl(_url,mode: LaunchMode.externalApplication);
pubspec.yaml
Add dependencies
dependencies: url_launcher: ^6.0.12
Output
If you want to use url_launcher than please use it in this form
environment:
sdk: ">=2.1.0 <3.0.0"
dependencies:
url_launcher: ^5.0.2
flutter:
sdk: flutter
This answer is also for absolute beginners: They are thinking behind the flutter sdk.
No that was a failure. The packages were extras and not in the flutter Sdk. These were secondary packages (single small framework helpers).
The PLUGIN plugin works great, as you explain in your examples.
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
final Uri _url = Uri.parse('https://flutter.dev');
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: launchUrlStart(url: "https://flutter.dev"),
child: Text('Show Flutter homepage'),
),
),
),
),
);
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url))) {
throw 'Could not launch $url';
}
}
But when trying to open PDF https://www.orimi.com/pdf-test.pdf it remained blank, the problem was that the browser handled it in its own way. Therefore the solution was to tell it to open with an external application and it worked as expected.
Future<void> launchUrlStart({required String url}) async {
if (!await launchUrl(Uri.parse(url),mode: LaunchMode.externalApplication)) {
throw 'Could not launch $url';
}
}
In pubspec.yaml
#https://pub.dev/packages/url_launcher
url_launcher: ^6.1.5
using the url_launcher package to do the following:
dependencies:
url_launcher: ^latest_version
if (await canLaunchUrl(Uri.parse(url))) {
await launchUrl(Uri.parse(url));
}
Note: Ensure you are trying to open a URI, not a String.