I got this error while using webview in flutter.
error: ERR_CONNECTION_REFUSED
Here is my code:
import 'dart:async'; import 'dart:io';
import 'package:flutter/material.dart'; import 'package:webview_flutter/webview_flutter.dart'; import 'package:flutter/services.dart'; import 'package:mime/mime.dart'; import 'package:provider/provider.dart';
import 'package:num_plus_plus/src/backend/mathmodel.dart'; import 'package:num_plus_plus/src/pages/settingpage.dart';
class Server { class from inAppBrowser
late HttpServer _server;
int _port = 8080;
Server({int port = 8080}) { this._port = port; }
///Closes the server. Future<void> close() async { if (this._server != null) { await this._server.close(force: true); print('Server running on http://localhost:$_port closed'); this._server = null as HttpServer;
} }
Future<void> start() async { if (this._server != null) { throw Exception('Server already started on http://localhost:$_port');
}
var completer = new Completer(); runZoned(() { HttpServer.bind('127.0.0.1', _port, shared: true).then((server) { print('Server running on http://localhost:' + _port.toString());
this._server = server;
server.listen((HttpRequest request) async { var body = <int>[]; var path = request.requestedUri.path; path = (path.startsWith('/')) ? path.substring(1) : path; path += (path.endsWith('/')) ? 'index.html' : '';
try { body = (await rootBundle.load(path)).buffer.asUint8List(); catch (e) { print(e.toString()); request.response.close(); return;
}
var contentType = ['text', 'html']; if (!request.requestedUri.path.endsWith('/') && request.requestedUri.pathSegments.isNotEmpty) { var mimeType = lookupMimeType(request.requestedUri.path, headerBytes: body); if (mimeType != null) { contentType = mimeType.split('/');
}
}
request.response.headers.contentType = new ContentType(contentType[0], contentType[1], charset: 'utf-8'); request.response.add(body); request.response.close();
});
completer.complete();
}); onError: (e, stackTrace) => print('Error: $e $stackTrace'));
return completer.future; } }
class MathBox extends StatelessWidget { #override Widget build(BuildContext context) { final mathBoxController = Provider.of<MathBoxController>(context, listen: false); final mathModel = Provider.of<MathModel>(context, listen: false); final matrixModel = Provider.of<MatrixModel>(context, listen: false); final functionModel = Provider.of<FunctionModel>(context, listen: false); final mode = Provider.of<CalculationMode>(context, listen: false); return Stack( children: <Widget>[ WebView( onWebViewCreated: (controller) { controller.loadUrl("http://localhost:8080/assets/html/homepage.html"); mathBoxController.webViewController = controller;
}, onPageFinished: (s) { final setting = Provider.of<SettingModel>(context, listen: false); if (setting.initPage == 1) { mathBoxController.addExpression('\\\\bmatrix');
}
}, javascriptMode: JavascriptMode.unrestricted, javascriptChannels: Set.from([ JavascriptChannel( name: 'latexString', onMessageReceived: (JavascriptMessage message) { if (mode.value == Mode.Matrix) { matrixModel.updateExpression(message.message); else { if (message.message.contains(RegExp('x|y'))) { mode.changeMode(Mode.Function); functionModel.updateExpression(message.message); else { mode.changeMode(Mode.Basic); mathModel.updateExpression(message.message); mathModel.calcNumber();
}
}
}
), JavascriptChannel( name: 'clearable', onMessageReceived: (JavascriptMessage message) { mathModel.changeClearable(message.message == 'false'?false:true);
}
),
]),
), ClearAnimation(),
],
); } }
class ClearAnimation extends StatefulWidget { #override
_ClearAnimationState createState() => _ClearAnimationState(); }
class _ClearAnimationState extends State<ClearAnimation> with TickerProviderStateMixin {
late AnimationController animationController; late Animation animation;
#override void initState() { super.initState(); animationController = AnimationController(duration: const Duration(milliseconds: 500),vsync: this); final curve = CurvedAnimation(parent: animationController, curve: Curves.easeInOutCubic); animation = Tween<double>(begin: 0, end: 2000).animate(curve); Provider.of<MathBoxController>(context, listen: false).clearAnimationController = animationController; }
#override void dispose() { animationController.dispose(); super.dispose(); }
Widget _buildAnimation(BuildContext context, Widget? child) { return Positioned( top: 10-animation.value/2 as double, right: -animation.value/2, child: ClipOval( child: Container( height: animation.value, width: animation.value, color: Colors.blue[100],
),
),
); }
#override Widget build(BuildContext context) { return AnimatedBuilder( builder: _buildAnimation, animation: animation,
); } }
class MathBoxController {
late WebViewController _webViewController; late AnimationController clearAnimationController;
set webViewController(WebViewController controller) { this._webViewController = controller; }
void addExpression(String msg, {bool isOperator = false}) { assert(_webViewController != null);
_webViewController.evaluateJavascript("addCmd('$msg', {isOperator: ${isOperator.toString()}})"); }
void addString(String msg) { assert(_webViewController != null);
_webViewController.evaluateJavascript("addString('$msg')"); }
void equal() { assert(_webViewController != null);
_webViewController.evaluateJavascript("equal()"); }
void addKey(String key) { assert(_webViewController != null);
_webViewController.evaluateJavascript("simulateKey('$key')"); }
void deleteExpression() { assert(_webViewController != null);
_webViewController.evaluateJavascript("delString()"); }
void deleteAllExpression() { assert(_webViewController != null);
_webViewController.evaluateJavascript("delAll()"); }
}
Related
why im getting this error, im trying to run a object detection app in flutter
while running im getting this error in run time, and the object text also not appear
[ERROR:flutter/runtime/dart_vm_initializer.cc(41)] Unhandled Exception: PlatformException(Failed to run model, Interpreter busy, java.lang.RuntimeException: Interpreter busy
My code,
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:flutter_tflite/flutter_tflite.dart';
//import 'package:tflite/tflite.dart';
String result = "";
class CameraScreen extends StatefulWidget {
final CameraDescription camera;
CameraScreen(this.camera);
#override
_CameraScreenState createState() => _CameraScreenState();
}
class _CameraScreenState extends State<CameraScreen> {
loadModel() async {
await Tflite.loadModel(
model: "assets/mobilenet_v1_1.0_224.tflite",
labels: "assets/mobilenet_v1_1.0_224.txt");
}
late CameraController _controller;
late CameraImage imgCam;
late Future<void> _initializeControllerFuture;
#override
void initState() {
super.initState();
_controller = CameraController(widget.camera, ResolutionPreset.medium);
_initializeControllerFuture = _controller.initialize().then((value) => {
setState((() {
_controller.startImageStream((imageFromStream) => {
imgCam = imageFromStream,
runModel(),
});
}))
});
loadModel();
}
runModel() async {
if (imgCam != null) {
var recognition = await Tflite.runModelOnFrame(
bytesList: imgCam.planes.map((plane) {
return plane.bytes;
}).toList(),
imageHeight: imgCam.height,
imageWidth: imgCam.width,
imageMean: 127.5,
imageStd: 127.5,
rotation: 90,
numResults: 1,
threshold: 0.1,
asynch: true,
);
result = "yes";
recognition?.forEach((response) {
result += response["label"] +
" " +
(response["confidence"] as double).toStringAsFixed(2) +
"\n\n";
print(result);
print("\n\n\n\n\n\n\n\n\n\n");
});
setState(() {
result;
});
}
}
#override
void dispose() async {
_controller.dispose();
await Tflite.close();
super.dispose();
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size;
final deviceRatio = size.width / size.height;
return Scaffold(
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview
return AspectRatio(
aspectRatio: deviceRatio,
child: CameraPreview(
child: Center(
child: Text(result),
),
_controller),
);
} else {
// Otherwise, display a loading indicator
return Center(child: CircularProgressIndicator());
}
}));
}
}
I am trying to get the data from my bluetooth device. My problem is with the Flutter code to get such data.
services/sensor.dart
import 'dart:async';
import 'dart:convert' show utf8;
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:minertti/main.dart';
class SensorPage extends StatefulWidget {
const SensorPage({Key? key, required this.device}) : super(key: key);
final BluetoothDevice device;
#override
_SensorPageState createState() => _SensorPageState();
}
class _SensorPageState extends State<SensorPage> {
String service_uuid = "6E400001-B5A3-F393-E0A9-E50E24DCCA9E";
String charaCteristic_uuid = "6E400003-B5A3-F393-E0A9-E50E24DCCA9E";
late bool isReady;
late Stream<List<int>> stream;
late List _temphumidata;
double _charge = 0;
double _data_1 = 0;
double _data_2 = 0;
#override
void initState() {
super.initState();
super.initState();
isReady = false;
connectToDevice();
}
void dispose() {
widget.device.disconnect();
super.dispose();
}
connectToDevice() async {
if (widget.device == null) {
_pop();
return;
}
new Timer(const Duration(seconds: 15), () {
if (!isReady) {
disconnectFromDevice();
_pop();
}
});
await widget.device.connect();
discoverServices();
}
disconnectFromDevice() {
if (widget.device == null) {
_pop();
return;
}
widget.device.disconnect();
}
discoverServices() async {
if (widget.device == null) {
_pop();
return;
}
List<BluetoothService> services = await widget.device.discoverServices();
services.forEach((service) {
if (service.uuid.toString().isNotEmpty) {
service.characteristics.forEach((characteristic) {
if (characteristic.uuid.toString().isNotEmpty) {
characteristic.setNotifyValue(!characteristic.isNotifying);
stream = characteristic.value;
setState(() {
isReady = true;
});
}
});
}
});
if (!isReady) {
_pop();
}
}
_pop() {
Navigator.of(context).pop(true);
}
String _dataParser(List<int> dataFromDevice) {
return utf8.decode(dataFromDevice);
}
#override
Widget build(BuildContext context) {
return Scaffold(
// appBar: AppBar(
// title: Text('dht11 Sensor'),
// ),
body: Container(
child: !isReady
? Center(
child: Text(
"Waiting...",
style: TextStyle(
fontSize: 24, color: Color.fromARGB(255, 0, 0, 0)),
),
)
: Container(
child: StreamBuilder<List<int>>(
stream: stream,
builder: (BuildContext context,
AsyncSnapshot<List<int>> snapshot) {
if (snapshot.hasError)
return Text('Error: ${snapshot.error}');
if (snapshot.connectionState == ConnectionState.active) {
var data = snapshot.data as List<int>;
var currentValue = _dataParser(data);
print("REALDATA: $data");
_temphumidata = currentValue.split(",");
//_charge = double.parse('${_temphumidata[0]}');
//_data_1 = double.parse('${_temphumidata[1]}');
//_data_2 = _temphumidata[2];
return DeviceScreen1(
device: widget.device,
//charge: _charge,
//data_2: _data_2,
//data_1: _data_1,
charge: 90,
data_1: "Data 1",
data_2: "Data 2");
} else {
return Text('Check the stream');
}
},
),
)),
);
}
}
var data = snapshot.data as List;
var currentValue = _dataParser(data);
They do not show values. But, from my Arduino I know that it does send/notify data. That is, my problem is with reading and obtaining said data.
I have added some routes to my flutter app so that when a specific link is pressed a specific page will be opened
This is the source code of the main page
import 'dart:convert';
import 'package:admob_flutter/admob_flutter.dart';
import 'package:android_alarm_manager/android_alarm_manager.dart';
import 'package:catcher/catcher.dart';
import 'package:dynamic_theme/dynamic_theme.dart';
import 'package:firebase_admob/firebase_admob.dart';
import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:flutter_native_timezone/flutter_native_timezone.dart';
import 'package:videos/c.dart';
import 'package:flutter/foundation.dart';
import 'package:videos/post.dart';
import 'package:timezone/data/latest.dart' as tz;
import 'package:timezone/timezone.dart' as tz;
import 'database/database.dart';
import 'database/database/mobile.dart' as mobile;
import 'src/app_route.dart';
void main() async{
WidgetsFlutterBinding.ensureInitialized();
FirebaseAdMob.instance.initialize(appId: APP_ID);
Admob.initialize(APP_ID);
await AndroidAlarmManager.initialize();
CatcherOptions debugOptions =CatcherOptions(DialogReportMode(), [kIsWeb?ConsoleHandler(): EmailManualHandler(["ahmad.rajab#windowslive.com"])]);
CatcherOptions releaseOptions = CatcherOptions(DialogReportMode(), [
kIsWeb?ToastHandler():EmailManualHandler(["ahmad.rajab#windowslive.com"])
]);
Catcher(MyApp(), debugConfig: debugOptions, releaseConfig: releaseOptions);
}
class MyApp extends StatefulWidget{
#override
State<StatefulWidget> createState()=>MyAppState();
}
class MyAppState extends State<MyApp> {
static Future configureDatabase()async{
/*database = await openDatabase(DATABASE_NAME, version: DATABASE_VERSION,
onCreate: (Database db, int version) async {
await db.execute('create table $WATCHED_VIDEOS ($VIDEO_ID text,$REACHED_SECOND integer default 0,$NOTE text)');
await db.execute('create table $TABLE_FAVORITE_VIDEOS ($VIDEO_TITLE text,$VIDEO_ID text,$VIDEO_DESCRIPTION text,$VIDEO_THUMBURL text)');
await db.execute('create table $CHANNELS ($ID integer ,$NAME text,$LINK text, $PICTURE_LINK text,$VIEWED integer default 0,$GET_NOTIFICATIONS integer default 1,$LAST_VIDEO_TITLE text)');
},
onUpgrade: (db, oldVersion, newVersion)async {
var tableColumns= await db.query('PRAGMA table_info($WATCHED_VIDEOS)');
bool noteColumnExists=false;
for(int c=0;c<tableColumns.length;c++){
if(tableColumns[c]['name'].toString()==NOTE)noteColumnExists=true;
}
if(!noteColumnExists) await db.execute('alter table $WATCHED_VIDEOS add $NOTE text');
},);
*/
}
AppRouterDelegate _routerDelegate = AppRouterDelegate();
AppRouteInformationParser _routeInformationParser =
AppRouteInformationParser();
#override
void initState() {
super.initState();
initialiseNotification();
initialiseTimeZone();
showDailyReminderNotification();
configureDailyNewVideosFitch();
}
void configureDailyNewVideosFitch()async{
await AndroidAlarmManager.periodic(const Duration(days: 1),DAILY_NEW_VIDEOS_FETCH_ALARAM_ID , ()async{
Database d=RepositoryProvider.of<Database>(context);
List<Channel>subscribedChannels=await (d.select($ChannelsTable(d))..where((tbl) => tbl.getNotifications.equals(1))).get();
String channelsIds='';
for(int i=0;i<subscribedChannels.length;i++)channelsIds+=subscribedChannels[i].link+"/";
Map<String,String> map=Map();
map['channels']=channelsIds;
Post p=Post(context,'getVideosFromTime.php',map);
await p.fetchPost();
if(p.connectionSucceed){
dynamic resultJson=json.decode(p.result);
if(resultJson['result']=='success'){
for(int i=0;i<resultJson['data'].length;i++){
dynamic videoJson=resultJson['data'][i];
await flutterLocalNotificationsPlugin.show(videoJson['id'], videoJson['channelName'], videoJson['title'],
NotificationDetails(
android: AndroidNotificationDetails(
APP_NAME,
APP_NAME, NEW_VIDEO_AVAILABLE,
icon: '#mipmap/ic_launcher',
ticker: videoJson['title']
),
),
payload:'/watch?v='+videoJson['videoId']
);
}
}
}
},rescheduleOnReboot: true);
}
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
void showDailyReminderNotification()async{
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails(APP_NAME,
APP_NAME, 'dailyReminder'+APP_NAME,
icon: '#mipmap/ic_launcher',
ticker: TIME_TO_LEARN);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.periodicallyShow(DAILY_REMINDER_NOTIFICATION_ID, TIME_TO_LEARN,
TIME_TO_LEARN_DESCRIPTION, RepeatInterval.daily, platformChannelSpecifics,
androidAllowWhileIdle: false);
}
void initialiseTimeZone()async{
tz.initializeTimeZones();
tz.setLocalLocation(tz.getLocation(await FlutterNativeTimezone.getLocalTimezone()));
}
void initialiseNotification()async{
flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
// initialise the plugin. app_icon needs to be a added as a drawable resource to the Android head project
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings('#mipmap/ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings(
/*onDidReceiveLocalNotification: onDidReceiveLocalNotification*/);
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
await flutterLocalNotificationsPlugin.cancel(DAILY_REMINDER_NOTIFICATION_ID);
}
Future selectNotification(String payload) async {
if(payload!=null)Navigator.pushNamed(context, payload);
}
#override
Widget build(BuildContext context) {
return DynamicTheme(
defaultBrightness: Brightness.light,
data: (brightness) => ThemeData(
primarySwatch: PRIMARY_COLOR,
brightness: brightness
),
themedWidgetBuilder: (context, data) {
return RepositoryProvider<Database>(
create:(context)=>mobile.constructDb() ,
child: BlocProvider(
create: (context){
//final db = RepositoryProvider.of<Database>(context);
//return AppBloc(db);
},
child: MaterialApp.router(
//title: 'Books App',
theme: data,
routerDelegate: _routerDelegate,
routeInformationParser: _routeInformationParser,
)
)
);
}
);
}
}
MobileAdTargetingInfo targetingInfo = MobileAdTargetingInfo(
// ignore: deprecated_member_use
gender: MobileAdGender.unknown,
childDirected: true
);
class AdmobAdd extends StatelessWidget{
#override
Widget build(BuildContext context) {
return !PRO?AdmobBanner(
adUnitId: kReleaseMode?BANNER_AD_UNIT_ID:BannerAd.testAdUnitId,
adSize: AdmobBannerSize.BANNER,
):Container();
}
}
InterstitialAd myInterstitial = InterstitialAd(
adUnitId: InterstitialAd.testAdUnitId,
targetingInfo: targetingInfo,
);
this is the source code of the routes configuration file
import 'package:catcher/catcher.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:videos/home.dart';
import 'package:videos/video.dart';
class AppRouteInformationParser extends RouteInformationParser<AppRoutePath> {
#override
Future<AppRoutePath> parseRouteInformation(
RouteInformation routeInformation) async {
final uri = Uri.parse(routeInformation.location);
// Handle '/'
if (uri.pathSegments.length == 0) {
return AppRoutePath.home();
}
// Handle '/watch?v=fsdfsdfsd
if (uri.pathSegments.length == 1) {
if (!uri.pathSegments[0].startsWith('/watch?')) return AppRoutePath.unknown();
if(uri.pathSegments[0].startsWith('/watch?v=')){
var videoId=uri.queryParameters['v'];
return AppRoutePath.video(videoId);
/*var remaining = uri.pathSegments[1];
var id = int.tryParse(remaining);
if (id == null) return AppRoutePath.unknown();
return AppRoutePath.details(id);*/
}
}
// Handle unknown routes
return AppRoutePath.unknown();
}
#override
RouteInformation restoreRouteInformation(AppRoutePath path) {
if (path.isUnknown) {
return RouteInformation(location: '/404');
}
if (path.isHomePage) {
return RouteInformation(location: '/');
}
if(path.isVideoPage){
return RouteInformation(location: '/watch?v=${path.id}');
}
if (path.isDetailsPage) {
return RouteInformation(location: '/book/${path.id}');
}
return null;
}
}
class AppRouterDelegate extends RouterDelegate<AppRoutePath>
with ChangeNotifier, PopNavigatorRouterDelegateMixin<AppRoutePath> {
final GlobalKey<NavigatorState> navigatorKey;
//Book _selectedBook;
bool show404 = false;
String videoId;
/*List<Book> books = [
Book('Stranger in a Strange Land', 'Robert A. Heinlein'),
Book('Foundation', 'Isaac Asimov'),
Book('Fahrenheit 451', 'Ray Bradbury'),
];*/
AppRouterDelegate() : navigatorKey = GlobalKey<NavigatorState>();
AppRoutePath get currentConfiguration {
if (show404) {
return AppRoutePath.unknown();
}
if(videoId!=null) return AppRoutePath.video(videoId);
/*return _selectedBook == null
? AppRoutePath.home()
: AppRoutePath.details(books.indexOf(_selectedBook));*/
return AppRoutePath.home();
}
#override
Widget build(BuildContext context) {
return Navigator(
key: Catcher.navigatorKey,
pages: [
MaterialPage(
key: ValueKey('Home'),
child: MyHomePage()
),
if (show404)
MaterialPage(key: ValueKey('Unknown'), child: UnknownScreen())
else if(videoId!=null) VideoPageRoute(videoId: videoId)
/*else if (_selectedBook != null)
BookDetailsPage(book: _selectedBook)*/
],
onPopPage: (route, result) {
if (!route.didPop(result)) {
return false;
}
// Update the list of pages by setting _selectedBook to null
//_selectedBook = null;
videoId=null;
show404 = false;
notifyListeners();
return true;
},
);
}
#override
Future<void> setNewRoutePath(AppRoutePath path) async {
if (path.isUnknown) {
//_selectedBook = null;
videoId=null;
show404 = true;
return;
}
/*if (path.isDetailsPage) {
if (path.id < 0 || path.id > books.length - 1) {
show404 = true;
return;
}
_selectedBook = books[path.id];
} else {
_selectedBook = null;
}*/
show404 = false;
}
void videoNotFound(){
videoId=null;
show404=true;
notifyListeners();
}
/*void _handleBookTapped(Book book) {
_selectedBook = book;
notifyListeners();
}*/
}
class AppRoutePath {
final String id;
final bool isUnknown;
AppRoutePath.home()
: id = null,
isUnknown = false;
AppRoutePath.details(this.id) : isUnknown = false;
AppRoutePath.video(this.id): isUnknown=false;
AppRoutePath.unknown()
: id = null,
isUnknown = true;
bool get isHomePage => id == null;
bool get isDetailsPage => id != null;
bool get isVideoPage => id!=null;
}
/*class BooksListScreen extends StatelessWidget {
final List<Book> books;
final ValueChanged<Book> onTapped;
BooksListScreen({
#required this.books,
#required this.onTapped,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: ListView(
children: [
for (var book in books)
ListTile(
title: Text(book.title),
subtitle: Text(book.author),
onTap: () => onTapped(book),
)
],
),
);
}
}
*/
/*class BookDetailsScreen extends StatelessWidget {
final Book book;
BookDetailsScreen({
#required this.book,
});
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Padding(
padding: const EdgeInsets.all(8.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
if (book != null) ...[
Text(book.title, style: Theme.of(context).textTheme.headline6),
Text(book.author, style: Theme.of(context).textTheme.subtitle1),
],
],
),
),
);
}
}
*/
class UnknownScreen extends StatelessWidget {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Center(
child: Text('404!'),
),
);
}
}
The problem is that I have several screens that has no specific url and I do not want to provide them with routes, I want simply to use Navigator.push()
That is working fine, but when pressing the back button or when I use Navigator.pop() the app closes entirely instead of navigating back to the previous page
How can I use Navigator.pushNamed only for named routes and use Navigator.push for other pages without causing the problem to occur
Thanks in advance
This program works okay on first build.When I disconnect my device and reconnects it,it is showing, bad state:stream has already been listened to,
Probably error is generated by stream that listening to Bluetooth characteristic.Whats the work around?
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter_blue/flutter_blue.dart';
import 'package:vibration/vibration.dart';
StreamSubscription _scanSubscription;
StreamSubscription _deviceConnection;
Stream<List<int>> stream;
List<double> traceDust = List();
const String CHAR_UUID = "AA:48:F8:CC:07:12";
const String Device_Name = "myDevice";
const String CHARACTERISTIC_UUID = "00000000-0111-1000-4000-000000000000";
BluetoothDeviceState _state;
Map<DeviceIdentifier, ScanResult> scanResults = new Map();
List<BluetoothService> services = new List();
BluetoothCharacteristic characteristic;
FlutterBlue flutterBlue = FlutterBlue.instance;
BluetoothDevice device;
class SearchScreen extends StatefulWidget {
#override
_SearchScreenState createState() => _SearchScreenState();
}
class _SearchScreenState extends State<SearchScreen> {
#override
void initState() {
super.initState();
_startScan();
}
#override
void dispose() {
super.dispose();
_stopScan();
_deviceConnection?.cancel();
_deviceConnection = null;
device.disconnect();
}
_startScan() {
_scanSubscription =
flutterBlue.scan(timeout: Duration(seconds: 4)).listen((scanResult) {
if (CHAR_UUID == scanResult.device.id.toString()) {
_stopScan();
_connect(scanResult.device);
print('connected');
}
}, onDone: _stopScan());
}
_stopScan() {
_scanSubscription?.cancel();
_scanSubscription = null;
}
_connect(BluetoothDevice d) async {
device = d;
await device.connect(autoConnect: true);
await device.discoverServices().then((value) {
setState(() {
services = value;
});
});
_turnOnCharacterService(services);
}
_turnOnCharacterService(List<BluetoothService> ser) async {
ser.forEach((service) {
service.characteristics.forEach((character) {
if (character.uuid.toString() == CHARACTERISTIC_UUID) {
character.setNotifyValue(!character.isNotifying);
setState(() {
stream = character.value;
});
}
});
});
}
String _dataParser(List<int> dataFromDevice) {
return utf8.decode(dataFromDevice);
}
vibrateOnAlert() async {
if (await Vibration.hasVibrator()) {
Vibration.vibrate(duration: 1000);
}
}
#override
Widget build(BuildContext context) {
return Container(
child: StreamBuilder<BluetoothDeviceState>(
stream: device.state,
initialData: BluetoothDeviceState.connecting,
builder: (context, snapshot) {
if (snapshot.data == BluetoothDeviceState.connected) {
return StreamBuilder<List<int>>(
stream: stream,
builder: (context, snapshot) {
var currentValue;
if (snapshot.hasError) {
return Text('Error');
}
if (snapshot.connectionState == ConnectionState.active) {
currentValue = _dataParser(snapshot.data);
traceDust.add(double.tryParse(currentValue) ?? 0);
if (currentValue.toString().compareTo('vibrate') == 0) {
vibrateOnAlert();
}
} else {
return Text('disconnected');
}
print('$currentValue');
return Text('connected');
});
}
return FlatButton(
color: Colors.white,
child: Text('reconnecct'),
onPressed: () {
setState(() {
flutterBlue.startScan(timeout: Duration(seconds: 2));
});
},
);
},
));
}
}
PS: Here flat button does nothing.Since connection state is a streambuilder it automatically reconnects and shows error.
in my simple code as new screen, unfortunately FutureBuilder work and get data from method twice!!
i'm not sure whats problem and how can i avoid that
class LessonDetail extends StatefulWidget {
final String monthKey;
final String lessonFileKey;
LessonDetail({#required this.monthKey, #required this.lessonFileKey});
#override
State<StatefulWidget> createState() {
return _LessonDetailState(monthKey, lessonFileKey);
}
}
class _LessonDetailState extends BaseState<LessonDetail> {
String monthKey;
String lessonFileKey;
_LessonDetailState(this.monthKey, this.lessonFileKey);
#override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
body: FutureBuilder(
future: _getLessonDetail(),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
PlayLessonResponse response = snapshot.data;
print(response);
}
return Center(
child: CircularProgressIndicator(),
);
}),
),
);
}
Future<PlayLessonResponse> _getLessonDetail() async {
AudioList audioList = AudioList(
'http://www.sample.com',
'aaaaa'
);
List<AudioList> lst = [audioList,audioList,audioList];
PlayLessonResponse response = PlayLessonResponse(
2,
'',
'http://www.sample.com',
'2',
lst,
1,
'ssss'
);
print('++++++++++++++++++++');
return response;
}
}
BaseState class content:
abstract class BaseState<T extends StatefulWidget> extends State {
final Connectivity _connectivity = Connectivity();
StreamSubscription<ConnectivityResult> _connectivitySubscription;
bool isOnline = true;
Future<void> initConnectivity() async {
try {
await _connectivity.checkConnectivity();
} on PlatformException catch (e) {
print(e.toString());
}
if (!mounted) {
return;
}
await _updateConnectionStatus().then((bool isConnected){
if(mounted){
setState(() {
isOnline = isConnected;
});
}
});
}
#override
void initState() {
super.initState();
initConnectivity();
_connectivitySubscription = Connectivity()
.onConnectivityChanged
.listen((ConnectivityResult result) async {
await _updateConnectionStatus().then((bool isConnected){
if(mounted){
setState(() {
isOnline = isConnected;
});
}
});
});
}
#override
void dispose() {
_connectivitySubscription.cancel();
super.dispose();
}
Future<bool> _updateConnectionStatus() async {
bool isConnected;
try {
final List<InternetAddress> result =
await InternetAddress.lookup('google.com');
if (result.isNotEmpty && result[0].rawAddress.isNotEmpty) {
isConnected = true;
}
} on SocketException catch (_) {
isConnected = false;
return false;
}
return isConnected;
}
}
output:
I/flutter (32289): ++++++++++++++++++++
I/flutter (32289): ++++++++++++++++++++
Just like what #Ricardo said, you shouldn't call the function directly inside the FutureBuilder's future method.
Instead, you should 1st run your function in init state, and store the response in a new variable. Only then assign variable to the future of FutureBuilder.
Code Example:
class LessonDetail extends StatefulWidget {
final String monthKey;
final String lessonFileKey;
LessonDetail({#required this.monthKey, #required this.lessonFileKey});
#override
State<StatefulWidget> createState() {
return _LessonDetailState(monthKey, lessonFileKey);
}
}
class _LessonDetailState extends BaseState<LessonDetail> {
String monthKey;
String lessonFileKey;
Future<PlayLesssonResponse> _myResponse; //added this line
_LessonDetailState(this.monthKey, this.lessonFileKey);
#override
void initState() {
_myResponse = _getLessonDetail(); // added this line
super.initState();
}
#override
Widget build(BuildContext context) {
return Directionality(
textDirection: TextDirection.rtl,
child: Scaffold(
body: FutureBuilder(
future: _myResponse, //use _myResponse variable here
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
PlayLessonResponse response = snapshot.data;
print(response);
}
return Center(
child: CircularProgressIndicator(),
);
}),
),
);
}
Future<PlayLessonResponse> _getLessonDetail() async {
AudioList audioList = AudioList(
'http://www.sample.com',
'aaaaa'
);
List<AudioList> lst = [audioList,audioList,audioList];
PlayLessonResponse response = PlayLessonResponse(
2,
'',
'http://www.sample.com',
'2',
lst,
1,
'ssss'
);
print('++++++++++++++++++++');
return response;
}
}