Flutter: How show local html file in webview? - html

I use this plugin in my flutter app - webview_flutter. I need to show the local HTML file in webview. This is not from assets, but I have a path to this file.
I try it:
Read the file as a string
var file = File(_path);
var data = await file.readAsString();
prepare the string
String _getHtml() {
var html = Uri.dataFromString(data, mimeType: 'text/html').toString();
return html;
}
Show this string in my webview
WebView(
initialUrl: _getHtml(),
)
But I have get error(on step Uri.dataFromString) :
How fix it? Any tips?

From here
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:webview_flutter/webview_flutter.dart';
class HelpScreen extends StatefulWidget {
#override
HelpScreenState createState() {
return HelpScreenState();
}
}
class HelpScreenState extends State<HelpScreen> {
WebViewController _controller;
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Help')),
body: WebView(
initialUrl: 'about:blank',
onWebViewCreated: (WebViewController webViewController) {
_controller = webViewController;
_loadHtmlFromAssets();
},
),
);
}
_loadHtmlFromAssets() async {
String fileText = await
rootBundle.loadString('assets/help.html');
_controller.loadUrl( Uri.dataFromString(
fileText,
mimeType: 'text/html',
encoding: Encoding.getByName('utf-8')
).toString());
}
}

Related

Flutter update profile value

I am from Javascript developer and start developing on flutter for company use.
I currently facing an issue about setting profile value to gui.
//profile.dart
import 'package:flutter/material.dart';
import 'package:profile/profile.dart';
import 'package:cs_app/models/user.dart';
import 'package:cs_app/models/cs_data.dart';
import 'package:cs_app/models/profile_data.dart';
import 'package:provider/provider.dart';
class AdminPage extends StatefulWidget {
const AdminPage({Key? key}) : super(key: key);
#override
State<AdminPage> createState() => _AdminPageState();
}
profile_value(key) async {
var value = await profileData.user_profile(key);
print("rtn: " + value);
// rtn: admin, can get the print value
return value;
}
class _AdminPageState extends State<AdminPage> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Profile(
imageUrl:
"https://images.unsplash.com/photo-1598618356794-eb1720430eb4?ixlib=rb-1.2.1&ixid=MnwxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8&auto=format&fit=crop&w=870&q=80",
name: profile_value("username"), // run func, get rtn value, render
website: profile_value("website"),
designation: profile_value("designation"),
email: "xxx#gmail.com",
phone_number: "12345456",
),
));
}
}
//profile_data.dart
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:cs_app/views/login.dart';
import 'dart:convert';
import 'package:cs_app/models/sharedPref.dart';
class profileData {
static user_profile(key) async {
var value = await SharedPref().read("user");
var decode_value = json.decode(value);
var key_decode_value = decode_value[key];
print("key: " + key);
print("value: " + key_decode_value);
// key: username
// value: admin
return key_decode_value;
}
}
In my mindset is when _AdminPageState run, the key will run profile_value(key) to get rtn value.
But it keeps return The argument type 'Future' can't be assigned to the parameter type 'String'.
Future<String>profile_value(key) async {
var value = await profileData.user_profile(key);
print("rtn: " + value);
// rtn: admin, can get the print value
return value;
}
Method profile_value is Future<String>, so you need to add await in front of name.
name: await profile_value("username"),
In flutter, if you use async func, it's will return a value the same Promise in JS. You must use await or .then to handle it.

Flutter html and Webview do not render base64 audio although html viewer works fine

I am trying to download and show offline my html content in my app. Downloading media and converting to base64 string works fine for images. However, when it comes to audio and video, it doesnt work properly. I have tried on htmlviewer website and audio works. I am sharing exact same code with you.
import 'dart:convert';
import 'dart:developer';
import 'dart:io' as io;
import 'dart:io';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:flutter/src/foundation/key.dart';
import 'package:flutter/src/widgets/basic.dart';
import 'package:flutter/src/widgets/framework.dart';
import 'package:flutter_html/flutter_html.dart';
import 'package:flutter_sound/flutter_sound.dart';
import 'package:path_provider/path_provider.dart';
import 'package:pqsmobile/controllers/userController.dart' as userController;
import 'package:webview_flutter/webview_flutter.dart';
class HtmlDeneme extends StatefulWidget {
const HtmlDeneme({Key? key}) : super(key: key);
#override
State<HtmlDeneme> createState() => _HtmlDenemeState();
}
class _HtmlDenemeState extends State<HtmlDeneme> {
String? a ;
#override
Widget build(BuildContext context) {
return Scaffold(
body:
/*Column(
children: [
IconButton(
onPressed: (() async{
await _download("https://samplelib.com/lib/preview/mp3/sample-6s.mp3","aswd");
}),
icon: Icon(Icons.downhill_skiing),
),
Container(
height: 100,
child:
a != null ? WebView(
initialUrl: Uri.dataFromString(' <audio controls=\"controls\" controlslis=\"nodownload\" src="data:audio/mp3;base64,$a"/>', mimeType:'audio/mp3' ).toString(),
) : Container()
),
],
)*/
Column(
children: [
IconButton(
onPressed: (() async{
await _download("https://samplelib.com/lib/preview/mp3/sample-6s.mp3","aswdsadsa");
}),
icon: Icon(Icons.downhill_skiing),
),
a != null ?
Html(
data: '''<audio controls=\"controls\" controlslist=\"nodownload\" src="data:audio/mp3;base64,$a"/> ''',
)
/*Html(
data: '''<p><span style=\"font-family:Arial,Helvetica,sans-serif\"><span style=\"font-size:16px\"><span style=\"color:#ffffff\"><strong><span style=\"background-color:#2980b9\">Listen to the passage. For questions 1-5, choose the best answer.</span></strong></span></span></span></p>\n\n<div class=\"ckeditor-html5-audio\" style=\"float:left; margin-right:10px; text-align:left\">\n<audio controls=\"controls\" controlslist=\"nodownload\" src=\"http://app.pqsglobal.org/uploads/2022-02-01/uiFiles/2fac1d07-5e1e-47f1-968b-136e0c27da84.mp3\"> </audio>\n</div>\n\n<p> </p>\n\n<p> </p>\n\n<p> <img style=\"height:10px; width:50px\" src='data:image/png;base64,$a'"/></p>\n'''
)*/
: Container(),
],
),
);
}
_download(String url, String name) async {
Directory tempDir = await getApplicationDocumentsDirectory();
final file = File('${tempDir.path}/${name}');
try {
//log(internalDir!.path.toString());
final String tokenx = await userController.getToken();
final response = await Dio().get(url,
options: Options(
responseType: ResponseType.bytes,
followRedirects: false,
receiveTimeout: 0));
final raf = file.openSync(mode: io.FileMode.write);
raf.writeFromSync(response.data);
await raf.close();
setState(() {
final bytes = File('${tempDir.path}/${name}').readAsBytesSync();
a = base64Encode(bytes);
//log(a.toString());
});
return file;
} catch (e) {
log(e.toString());
}
}
}

Flutter Provider for Cart page

I need to make a cart page for an e-commerce app. where I am getting JSON data from API.
I can fetch the data and show data. but when it's matter to cart I cannot add this data to my provider page.
This is MY Provider Page For Album
import 'package:flutter/material.dart';
import 'package:provider_test/albumModel.dart';
import '../Service/service.dart';
class MyStore extends ChangeNotifier {
List<Album> _albums = [];
List<Album> _busket = [];
Album _activeAlbum = null;
List<Album> get albums => _albums;
List<Album> get buskets => _busket;
Album get activeAlbum => _activeAlbum;
}
And this is my Album Model Page:
import 'dart:convert';
import 'package:flutter/cupertino.dart';
List<Album> allalbumsFromJson(String str) {
final jsonData = json.decode(str);
return new List<Album>.from(jsonData.map((x) => Album.fromJson(x)));
} //ef
class AlbumList with ChangeNotifier {
final List<Album> albums;
AlbumList({
this.albums,
});
factory AlbumList.fromJson(List<dynamic> parsedJson) {
List<Album> albums = List<Album>();
albums = parsedJson.map((i) => Album.fromJson(i)).toList();
return AlbumList(albums: albums);
}
notifyListeners();
} //ef
class Album with ChangeNotifier {
int userId;
int id;
String title;
Album({this.userId, this.id, this.title});
Album.fromJson(Map<String, dynamic> json) {
userId = json['userId'];
id = json['id'];
title = json['title'];
}
notifyListeners();
} //ef
Album albumFromJson(String str) {
final jsonData = json.decode(str);
return Album.fromJson(jsonData);
} //ef
Now I can fetch Data Using this Function:
import 'package:flutter/cupertino.dart';
import 'package:provider_test/albumModel.dart';
import 'package:http/http.dart' as HTTP;
final url = ('https://jsonplaceholder.typicode.com/albums');
Future<List<Album>> getAllAlbum() async {
final response = await http.get(url);
// print(response.body);
return allalbumsFromJson(response.body);
}
Future<Album> getAlbum() async {
final response = await http.get('$url/1');
return albumFromJson(response.body);
}
How Can I insert getAllAlbums() Data or you can say List Data into the _albums=[] which is situated in Mystore Page?
Hi for the cart I think you the best way you must use a map instead of a list like below:
Map<int, FavoriteModel> _favoites = {};
Map<int, FavoriteModel> get favoitesItem {
return _favoites;
}
And for adding data from you can use of this method:
void addOrRemoveSingleItem({
int foodId,
String title,
double price,
String imageUrl,
int userId
}) async {
if (_favoites.containsKey(foodId)) {
try {
final res = await http.post(
addFavoriteUrl,
body: {
"user_id": userId.toString(),
"food_id": foodId.toString(),
"Is_delete": "1",
},
);
} catch (e) {
print(e);
throw (e);
}
} else {
try {
_favoites.putIfAbsent(
foodId,
() => FavoriteModel(
id: foodId,
name: title,
regularPrice: price,
featureImage: imageUrl,
),
);
http.post(
addFavoriteUrl,
body: {
"user_id": userId.toString(),
"food_id": foodId.toString(),
},
);
} catch (e) {
print(e);
throw (e);
}
}
notifyListeners();
}

how to show local html folder in webview

I want to display a html folder in the webview, which includes CSS and javascript.
Like this folder : javascript_button
And this folder should be on the sdcard path of memory rather than in the application assets folder.
I tried various plugins like webview_flutter, flutter_inappbrowser and flutter_webview_plugin and did not get to the result.
With the following method, I was able to read the index.html only and no other related files were displayed inside the folder.
Please help me to solve this problem.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter_webview_plugin/flutter_webview_plugin.dart';
void main() {
runApp(new MyApp());
}
class MyApp extends StatefulWidget {
#override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
String filePath = '/sdcard/Download/button/index.html';
final flutterWebViewPlugin = FlutterWebviewPlugin();
#override
Widget build(BuildContext context) {
return new MaterialApp(
routes: {
"/": (_) => WebviewScaffold(
url:new Uri.dataFromString(readFileAsync(filePath), mimeType:
'text/html').toString(),
appBar: AppBar(
title: Text("webview"),
),
withJavascript: true,
supportMultipleWindows: true,
withLocalUrl: true,
allowFileURLs: true,
withLocalStorage: true,
)
},
);
}
String readFileAsync(String path) {
String contents = new File('$path').readAsStringSync();
print(contents);
return contents;
}
}
Use This Code using Webview_Flutter plugin in Scaffold:
WebView(
initialUrl: '',
javascriptMode: JavascriptMode.unrestricted,
onWebViewCreated: (WebViewController webViewController) {
_webViewController = webViewController;
_loadHtmlFromAssets();
},
),
// function to load Assets files
//filePath in bellow code for ex.(String filePath = '/assests/files/abc1.html';)
_loadHtmlFromAssets() async {
String fileHtmlContents = await rootBundle.loadString(filePath);
_webViewController.loadUrl(Uri.dataFromString(fileHtmlContents,
mimeType: 'text/html', encoding: Encoding.getByName('utf-8'))
.toString());
}

How to fix error with flutter_google_places_autocomplete.dart?

I make an application with Google maps in which you can find a place and build a path to it on the map. I want to show places and addresses below it according to what the user types.After showing the results, I need to get its latitude and longitude to mark on the map.
I tried to use a flutter_google_places: 0.2.3 but functions(GoogleMapsPlaces, Prediction) were not defined. Next i used flutter_google_places_autocomplete: 0.1.3 and everything was fine. Unfortunately when i tride to run the project I got an error:
Compiler message:
file:///C:/Users/admin/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/flutter_google_places_autocomplete-0.1.3/lib/src/flutter_google_places_autocomplete.dart:337:35:
Error: Too many positional arguments: 0 allowed, but 1 found. Try
removing the extra positional arguments.
_places = new GoogleMapsPlaces(widget.apiKey);
^ file:///C:/Users/admin/AppData/Roaming/Pub/Cache/hosted/pub.dartlang.org/google_maps_webservice-0.0.14/lib/src/places.dart:22:3:
Context: Found this candidate, but the arguments don't match.
GoogleMapsPlaces({ ^ Compiler failed on
C:\Users\admin\AndroidStudioProjects\advertise_me\lib\main.dart
FAILURE: Build failed with an exception.
Where: Script 'C:\Users\admin\flutter\packages\flutter_tools\gradle\flutter.gradle'
line: 647
What went wrong: Execution failed for task ':app:compileflutterBuildDebugandroid-arm64'.
Process 'command 'C:\Users\admin\flutter\bin\flutter.bat'' finished with non-zero exit value 1
Try: Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
Get more help at https://help.gradle.org
BUILD FAILED in 9s Finished with error: Gradle task assembleDebug
failed with exit code 1
My pubspes.yaml:
dependencies: flutter:
sdk: flutter
cupertino_icons: ^0.1.2 url_launcher: ^4.2.0+1
google_maps_flutter: bottom_sheet_stateful: ^0.1.1
flutter_google_places_autocomplete: 0.1.3 geocoder: 0.1.2
google_maps_webservice: 0.0.14
My code:
import 'package:flutter/material.dart';
import 'package:advertise_me/login_screen.dart';
import 'dart:async';
import 'package:google_maps_webservice/geocoding.dart';
//import 'package:flutter_google_places/flutter_google_places.dart';
import 'package:flutter_google_places_autocomplete/flutter_google_places_autocomplete.dart';
import 'package:geocoder/geocoder.dart';
void main() => runApp(MyApp());
const kGoogleApiKey = "My key";
GoogleMapsPlaces _places = GoogleMapsPlaces(apiKey: kGoogleApiKey);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: demo(),
),
);
}
}
class demo extends StatefulWidget {
#override
demoState createState() => new demoState();
}
class demoState extends State<demo> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: RaisedButton(
onPressed: () async {
Prediction p = await showGooglePlacesAutocomplete(
context: context, apiKey: kGoogleApiKey);
displayPrediction(p);
},
child: Text('Find address'),
)
)
);
}
Future<Null> displayPrediction(Prediction p) async {
if (p != null) {
PlacesDetailsResponse detail =
await _places.getDetailsByPlaceId(p.placeId);
var placeId = p.placeId;
double lat = detail.result.geometry.location.lat;
double lng = detail.result.geometry.location.lng;
var address = await Geocoder.local.findAddressesFromQuery(p.description);
print(lat);
print(lng);
}
}
}
How do i fix this error?
Any help is much appreciated.
flutter_google_places_autocomplete is deprecated and you should use flutter_google_places instead. See documentation : https://pub.dev/packages/flutter_google_places_autocomplete
And once you use flutter_google_places, use
Prediction p = await PlacesAutoComplete.show() instead of showGooglePlacesAutoComplete()
======= updated answer =====
import 'package:flutter/material.dart';
//import 'package:advertise_me/login_screen.dart';
import 'dart:async';
import 'package:flutter_google_places/flutter_google_places.dart';
import 'package:geocoder/geocoder.dart';
import 'package:google_maps_webservice/places.dart';
void main() => runApp(MyApp());
const kGoogleApiKey = "My key";
GoogleMapsPlaces _places = GoogleMapsPlaces(apiKey: kGoogleApiKey);
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
body: demo(),
),
);
}
}
class demo extends StatefulWidget {
#override
demoState createState() => new demoState();
}
class demoState extends State<demo> {
#override
Widget build(BuildContext context) {
return Scaffold(
body: Container(
alignment: Alignment.center,
child: RaisedButton(
onPressed: () async {
Prediction p = await PlacesAutocomplete.show(
context: context, apiKey: kGoogleApiKey);
displayPrediction(p);
},
child: Text('Find address'),
)
)
);
}
Future<Null> displayPrediction(Prediction p) async {
if (p != null) {
PlacesDetailsResponse detail =
await _places.getDetailsByPlaceId(p.placeId);
var placeId = p.placeId;
double lat = detail.result.geometry.location.lat;
double lng = detail.result.geometry.location.lng;
var address = await Geocoder.local.findAddressesFromQuery(p.description);
print(lat);
print(lng);
}
}
}
use import 'package:google_maps_webservice/places.dart'; along with, import 'package:flutter_google_places/flutter_google_places.dart';
Use complete list of function parameters like:
Prediction p = await PlacesAutocomplete.show( offset: 0, radius: 1000, types: [], strictbounds: false,
region: "ar", context: context, apiKey: googleAPIKey, mode: Mode.overlay, language: "es", components: [Component(Component.country, "ar")] );