I am using flutter_webview_plugin: ^0.3.8 but I have the same problem with webview_flutter: ^0.3.13.
In webview, I want to make use of a website which triggers a file download on successful completion of a captcha. However, I complete the captcha and nothing happens, no download.
Is there something in Flutter like a webview download listener ("webview.setDownloadListener")? I only need this for Android.
If not, is there a way of downloading files from a webview in Flutter?
A similar issue can be found here!
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. It can recognize downloadable files in both Android (using setDownloadListener) and iOS platforms!
I report here the same answer that I gave to the similar issue:
To be able to recognize downloadable files, you need to set the useOnDownloadStart: true option, and then you can listen the onDownloadStart event!
Also, for example, on Android you need to add write permission inside your AndroidManifest.xml file:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
Then, you need to ask permission using the permission_handler plugin. Instead, to effectively download your file, you can use the flutter_downloader plugin.
Here is a complete example using http://ovh.net/files/ (in particular, the http://ovh.net/files/1Mio.dat as URL) to test the download:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:flutter_downloader/flutter_downloader.dart';
import 'package:path_provider/path_provider.dart';
import 'package:permission_handler/permission_handler.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await FlutterDownloader.initialize(
debug: true // optional: set false to disable printing logs to console
);
await Permission.storage.request();
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
InAppWebViewController webView;
#override
void initState() {
super.initState();
}
#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: "http://ovh.net/files/1Mio.dat",
initialHeaders: {},
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
debuggingEnabled: true,
useOnDownloadStart: true
),
),
onWebViewCreated: (InAppWebViewController controller) {
webView = controller;
},
onLoadStart: (InAppWebViewController controller, String url) {
},
onLoadStop: (InAppWebViewController controller, String url) {
},
onDownloadStart: (controller, url) async {
print("onDownloadStart $url");
final taskId = await FlutterDownloader.enqueue(
url: url,
savedDir: (await getExternalStorageDirectory()).path,
showNotification: true, // show download progress in status bar (for Android)
openFileFromNotification: true, // click on notification to open downloaded file (for Android)
);
},
))
])),
),
);
}
}
Here, as you can see, I'm using also the path_provider plugin to get the folder where I want to save the file.
just add this code to your AndroidManifest.xml
<provider
android:name="vn.hunghd.flutterdownloader.DownloadedFileProvider"
android:authorities="${applicationId}.flutter_downloader.provider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="#xml/provider_paths"/>
</provider>
and add this code to your AndroidManifest.xml
it works to me
it works for me
require plugin https://pub.dev/packages/url_launcher
add this code to your project to download file from flutter webview
onDownloadStart: (controller, url,) async {
// print("onDownloadStart $url");
final String _url_files = "$url";
void _launchURL_files() async =>
await canLaunch(_url_files) ? await launch(_url_files) : throw 'Could not launch $_url_files';
_launchURL_files();
},
Related
I am creating a webview app using flutter_webview_plugin. I am stack at allowing the app to launch phone call and mailto links. When I use webview_flutter I get the bottom menus and the address bar at the top does not disappear
try using the url launcher package
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
const String _url = 'mailto:example#example.com';
void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: _launchURL,
child: Text('Show Flutter homepage'),
),
),
),
),
);
void _launchURL() async {
if (!await launch(_url)) throw 'Could not launch $_url';
}
I have managed to come up with this simple solution, just add these few lines of code in your initState, you can add 'mailto:' and 'sms' if necessary.
final flutterWebviewPlugin = new FlutterWebviewPlugin();
flutterWebviewPlugin.onUrlChanged.listen((String url) {
if (url.contains("tel:")) launch(url);
});
I need to integrate Jitsi Meet in webview for our flutter application. Initially I used the following jitsi-meet plugin "https://pub.dev/packages/jitsi_meet" but unfortunately had to switch to InAppwebview plugin "https://pub.dev/packages/flutter_inappwebview" because of missing features such as jitsi reconnection after internet drop and participant information in jitsi-meet plugin. I have successfully integrated the jitsi in webview but have no idea how to include jitsi callbacks like onConferenceJoined, onParticipantLeft etc. Any help would be much appreciated
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_inappwebview/flutter_inappwebview.dart';
import 'package:permission_handler/permission_handler.dart';
Future main() async {
WidgetsFlutterBinding.ensureInitialized();
await Permission.camera.request();
await Permission.microphone.request();
runApp(MyApp());
}
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => new _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
Widget build(BuildContext context) {
return MaterialApp(home: InAppWebViewPage());
}
}
class InAppWebViewPage extends StatefulWidget {
#override
_InAppWebViewPageState createState() => new _InAppWebViewPageState();
}
class _InAppWebViewPageState extends State<InAppWebViewPage> {
InAppWebViewController _webViewController;
#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://meet.jit.si/hello",
initialOptions: InAppWebViewGroupOptions(
crossPlatform: InAppWebViewOptions(
mediaPlaybackRequiresUserGesture: false,
debuggingEnabled: true,
),
),
onWebViewCreated: (InAppWebViewController controller) {
_webViewController = controller;
},
androidOnPermissionRequest:
(InAppWebViewController controller, String origin,
List<String> resources) async {
return PermissionRequestResponse(
resources: resources,
action: PermissionRequestResponseAction.GRANT);
}),
),
),
])));
}
}
Sorry to say, but you can't access such features through webview, because when you access thorough webview it's similar to open the site on the browser as a user. You can use Jitsi SDK or plugins which allow you to modify the settings.
Suggestion: Use the jitsi meet plugin which you had used before it already has such features as which you want:
onConferenceWillJoin Meeting is loading.
onConferenceJoined User has joined meeting.
onConferenceTerminated User has exited the conference.
onPictureInPictureWillEnter User entered PIP mode.
onPictureInPictureTerminated User exited PIP mode.
onError Error has occurred with listening to meeting events.
But there is no feature for participant information. But you can achieve this all by hosting your own jitsi server, which would allow you to either customize it or directly have such settings on your custom domain so that on the app you can simply access through webview.
I have used this plugin for a long time and made an app published on the play store. Check that out do you something similar to that? app name Just Meet. If you want like that then I can help you out with my repo.
Maybe you can use socket.io to communicate between the app and webview.
Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 1 year ago.
Improve this question
In Android Studio Emulator, the pdf file is opening but when I release its .apk file and install it on my phone, pdf file does not open. I used flutter_pdfview package to load pdf file.
This is where the page is shown.
import 'package:darpandentalhome/services/api_for_report.dart';
import 'package:darpandentalhome/shared/loading.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_pdfview/flutter_pdfview.dart';
import 'package:google_fonts/google_fonts.dart';
class Report extends StatefulWidget {
final String url;
Report({this.url});
#override
_ReportState createState() => _ReportState();
}
class _ReportState extends State<Report> {
String path;
#override
void initState() {
// TODO: implement initState
super.initState();
ApiService(pdfURL: widget.url).loadPDF().then((value){
setState(() {
path=value;
});
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
elevation: 0,
centerTitle: true,
title: Text(
'Report',
style: GoogleFonts.rubik(
textStyle: TextStyle(
color: Colors.black,
fontWeight: FontWeight.w500
)
),
),
leading: IconButton(
icon: Icon(Icons.arrow_back_ios,color: Colors.black,),
onPressed: () {
Navigator.pop(context);
},
),
backgroundColor: Color(0xfff9f9f9),
),
backgroundColor: Color(0xfff9f9f9),
body: path != null ? Container(
child: PDFView(
filePath: path,
),
) : Loading(),
floatingActionButton: IconButton(
icon: Icon(Icons.refresh,size: 30,),
onPressed: () {
setState(() {
path = null;
ApiService(pdfURL: widget.url).loadPDF().then((value){
setState(() {
path=value;
});
});
});
},
),
);
}
}
This is for the HTTP API service for fetching pdf file from HTTP URL.
import 'dart:io';
import 'package:http/http.dart' as http;
import 'package:path_provider/path_provider.dart';
class ApiService{
final String pdfURL;
ApiService({this.pdfURL});
Future<String> loadPDF() async {
var response = await http.get(pdfURL);
var dir = await getExternalStorageDirectory();
File file = File(dir.path + "/data.pdf");
await file.writeAsBytes(response.bodyBytes, flush: true);
return file.path;
}
}
I thought it was a permission issue of the phone then I used storage permission in AndroidManifest file then manually allowed this permission on my phone but it also didn't work.
What is the problem here?
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
it's because difference between android version
if your android version is 29 use this code in your manifest
android:requestLegacyExternalStorage="true"
This problem was solved after giving internet permission to the app since the http api need to fetch data from internet.
Here are the steps to fix:
1. Add proguard-rules.pro in android/app folder file if its not already there
2. Inside of the proguard-rules.pro file put this:
-keep class com.shockwave.**
-keepclassmembers class com.shockwave.** { *; }
3.In app/build.gradle add this:
buildTypes{
release{
shrinkResources true
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
I'm trying to play vimeo videos in flutter app using the video_player plugin but got no success, it's throwing bunch of errors.
please help me how I might go about implementing this in flutter app? using webview or any plugin etc? perhaps a code snippet would be huge help for me!
here is my code snippet
import 'package:video_player/video_player.dart';
import 'package:flutter/material.dart';
void main() => runApp(VideoApp());
class VideoApp extends StatefulWidget {
#override
_VideoAppState createState() => _VideoAppState();
}
class _VideoAppState extends State<VideoApp> {
VideoPlayerController _controller;
#override
void initState() {
super.initState();
_controller = VideoPlayerController.network(
'https://vimeo.com/{some-video-id}')
..initialize().then((_) {
// Ensure the first frame is shown after the video is initialized, even before the play button has been pressed.
setState(() {});
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Video Demo',
home: Scaffold(
body: Center(
child: _controller.value.initialized
? AspectRatio(
aspectRatio: _controller.value.aspectRatio,
child: VideoPlayer(_controller),
)
: Container(),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
setState(() {
_controller.value.isPlaying
? _controller.pause()
: _controller.play();
});
},
child: Icon(
_controller.value.isPlaying ? Icons.pause : Icons.play_arrow,
),
),
),
);
}
#override
void dispose() {
super.dispose();
_controller.dispose();
}
}
THE ERROR IN DEBUG CONSOLE -
E/AccessibilityBridge(28662): VirtualView node must not be the root
node. E/ExoPlayerImplInternal(28662): Source error.
E/ExoPlayerImplInternal(28662):
com.google.android.exoplayer2.upstream.HttpDataSource$InvalidResponseCodeException:
Response code: 404 E/ExoPlayerImplInternal(28662): at
com.google.android.exoplayer2.upstream.DefaultHttpDataSource.open(DefaultHttpDataSource.java:300)
E/ExoPlayerImplInternal(28662): at
com.google.android.exoplayer2.upstream.StatsDataSource.open(StatsDataSource.java:83)
E/ExoPlayerImplInternal(28662): at
com.google.android.exoplayer2.source.ExtractorMediaPeriod$ExtractingLoadable.load(ExtractorMediaPeriod.java:885)
E/ExoPlayerImplInternal(28662): at
com.google.android.exoplayer2.upstream.Loader$LoadTask.run(Loader.java:381)
E/ExoPlayerImplInternal(28662): at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
E/ExoPlayerImplInternal(28662): at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
E/ExoPlayerImplInternal(28662): at
java.lang.Thread.run(Thread.java:919)
You cant use Vimeo URL https://vimeo.com/{some-video-id}. VideoPlayerController requires the streamable video URL.
Solution 1
Required premium account of Vimeo
go to https://vimeo.com/manage/ and select the video you want to play
select the distribution tab from the left side panel.
select video file link
select the play video.. copay the video link(its the mp4 stealable video link)..use this URL for VideoPlayerController.
Solution 2
Video link will expire in every 15 mins
call the API https://player.vimeo.com/video/{video_id}/config you will get the JSON response.
progressive object you will get mp4 video url .
Solution 3
Replace the video controller with webivew give this url
https://vimeo.com/{some-video-id} ..enable the javascript, video
will play in webview .
Install vimeoplayer: ^0.1.8 on pubspec
return Scaffold(
appBar: AppBar(title: Text('Video EasyRider')),
body: ListView(children: <Widget>[
VimeoPlayer(id: '123456789', autoPlay: false),
]));
}
You can use vimeo_player_flutter package to achieve this. It is easy & supports Android and IOS platforms. It works based on webview.
Refer this link for more details on this.
I want to disable logging of Firebase Analytics in a Flutter project when the app is being run on Firebase Test Lab. According to Firebase docs, TestLab can be detected by adding the following in MainActivity.java
String testLabSetting = Settings.System.getString(getContentResolver(), "firebase.test.lab");
if ("true".equals(testLabSetting)) {
// Do something when running in Test Lab
// ...
}
How can I access the result of this test on the dart side in main.dart which is where I want to disable logging (as there are some other reasons logging is disabled already in the dart code).
Thanks!
I just found this. I didn't try it yet though:
https://pub.dev/packages/flutter_runtime_env
This project allows you to check if you're running in the Firebase
Test Labs
You can use it like their example:
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:flutter_runtime_env/flutter_runtime_env.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
bool _shouldBeEnabled = false;
#override
void initState() {
super.initState();
initPlatformState();
}
// Platform messages are asynchronous, so we initialize in an async method.
Future<void> initPlatformState() async {
var result = await shouldEnableAnalytics();
setState(() {
_shouldBeEnabled = result;
});
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: const Text('Should Enable Analytics'),
),
body: Center(
child: Text('Should Analytics be Enabled: $_shouldBeEnabled\n'),
),
),
);
}
}
EDIT:
I think I found a better solution.
https://pub.dev/packages/flutter_sentry
It has the follow method
/// Return `true` if running under Firebase Test Lab (includes pre-launch
/// report environment) on Android, `false` otherwise.
static Future<bool> isFirebaseTestLab() async
It seems to be the best solution so far...
EDIT 2:
Fuck it! I just created a small plugin.
https://pub.dev/packages/is_firebase_test_lab_activated