Camera renders slowly when using websockets in CameraImage stream - android

Flutter camera app renders very slowly when using websockets in image streams. How can I improve my app performance? what is the best way to overcome this? On emulator it works just fine but on real device there is lot of delay and stuttering. Can we use async for camera app? If yes, how can I use it with this code?
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:camera/camera.dart';
import 'package:web_socket_channel/io.dart';
import 'dart:convert';
import 'package:archive/archive.dart';
List<CameraDescription> cameras;
Future<void> main() async {
cameras = await availableCameras();
runApp(App());
}
class App extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Title',
theme: ThemeData(
primarySwatch: Colors.teal,
),
home: CameraApp(),
);
}
}
class CameraApp extends StatefulWidget {
#override
_CameraAppState createState() => _CameraAppState();
}
class _CameraAppState extends State<CameraApp> {
CameraController controller;
IOWebSocketChannel channel = IOWebSocketChannel.connect('ws://192.168.0.6:8000/');
#override
void initState() {
super.initState();
controller = CameraController(cameras[1], ResolutionPreset.low);
controller.initialize().then((_) async{
await controller.startImageStream((onAvailable) {
sd(onAvailable);
});
if (!mounted) {
return;
}
setState(() {});
});
}
#override
void dispose() {
controller?.dispose();
super.dispose();
}
#override
void sd(onAvailable) {
var framesY = onAvailable.planes[0].bytes;
List<int> gzipBytes = new GZipEncoder().encode(framesY);
String compressedString = base64Encode(gzipBytes);
channel.sink.add(compressedString);
}
Widget build(BuildContext context) {
if (!controller.value.isInitialized) {
return Container();
}
return new Scaffold(
body: new Container(
child: new AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: new CameraPreview(controller),
),
),
);
}
}

Related

Run code after closed Flutter app (detached)

I want to run some tasks when I closed application using flutter, This tasks are some functions to delete data from firebase when the app is closing (detached)
I used WorkManager and didChangeAppLifecycleState, it is work when state == AppLifecycleState.pused but not work if the state == AppLifecycleState.detached.
what I can to do that, thank you
const task = 'test';
void callbackDispatcher() {
Workmanager().executeTask((task, inputData) async {
await Firebase.initializeApp();
currentFirebaseUser = fAuth.currentUser;
FirebaseFirestore.instance.collection('locations').doc(currentFirebaseUser!.uid).delete();
print(currentFirebaseUser!.uid+"++++++++++++++++++");
return Future.value(true);
});
}
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await Workmanager().initialize(
callbackDispatcher,
isInDebugMode: true,
);
AwesomeNotifications().initialize(null, [
NotificationChannel(
channelKey: 'test_channel',
channelName: 'Test Notification',
channelDescription: 'Notifications for basic testing',
)
]);
await Firebase.initializeApp(options: DefaultFirebaseOptions.currentPlatform);
runApp(
MyApp(
child: ChangeNotifierProvider(
create: (context) => AppInfo(),
child: GetMaterialApp(
initialBinding: ControllerBindings(),
title: 'Drivers App',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const AuthGate(),
debugShowCheckedModeBanner: false,
),
),
),
);
}
class MyApp extends StatefulWidget {
final Widget? child;
const MyApp({this.child});
static void restartApp(BuildContext context) {
context.findAncestorStateOfType<_MyAppState>()!.restartApp();
}
#override
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> with WidgetsBindingObserver{
Key key = UniqueKey();
void restartApp() {
setState(() {
key = UniqueKey();
});
}
#override
void initState() {
WidgetsBinding.instance.addObserver(this);
super.initState();
}
#override
void dispose() {
WidgetsBinding.instance.removeObserver(this);
// TODO: implement dispose
super.dispose();
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) async {
if (state == AppLifecycleState.detached) {
var uniqueName = DateTime.now().second.toString();
await Workmanager().registerOneOffTask(uniqueName, task);
print("------------------------");
}
}
#override
Widget build(BuildContext context) {
return KeyedSubtree(
key: key,
child: widget.child!,
);
}
}

How to detect a phone shake in Flutter?

i tried to get run the ShakeDetector in my Flutter app. I got a sample app here. Can somebody help me to fix the problem?
This codesample below is from the shake.dart github example. I dont get it why it is not working.
import 'package:flutter/material.dart';
import 'package:shake/shake.dart';
void main() {
runApp(DemoPage());
}
class DemoPage extends StatefulWidget {
#override
_DemoPageState createState() => _DemoPageState();
}
var phoneShakes;
class _DemoPageState extends State<DemoPage> {
#override
void initState() {
super.initState();
ShakeDetector detector = ShakeDetector.autoStart(onPhoneShake: () {
print('shaking');
});
// To close: detector.stopListening();
// ShakeDetector.waitForStart() waits for user to call detector.startListening();
phoneShakes = detector.mShakeCount;
}
#override
Widget build(BuildContext context) {
return MaterialApp(
home: AppBar(
title: Text(phoneShakes.toString()),
),
);
}
}
It's because there was no call to setState. Try this code:
class _DemoPageState extends State<DemoPage> {
late ShakeDetector _detector;
#override
void initState() {
super.initState();
_detector = ShakeDetector.autoStart(onPhoneShake: () {
setState(() {}); // Call setState every time phone shakes.
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Text('Count: ${_detector.mShakeCount}'),
),
);
}
}

Flutter Image Picker doesn't pick image from Album/Gallery

I'm trying to implement imagepicker library in my app. My app runs without any errors but I can't pick/select images from the album/gallery. On selecting the image the app should display the image in the body but nothing happens. I have to tap on Cancel to go back to the main screen. I should also mention that the console returns null for the print statement print('image: $image');
Kindly help.
import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:image_picker/image_picker.dart';
import 'package:flutter/material.dart';
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
brightness: Brightness.dark,
),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
File image;
final picker = ImagePicker();
Future getImage() async {
final pickedFile = await picker.getImage(source: ImageSource.gallery);
setState(() {
if (pickedFile != null) {
image = File(pickedFile.path);
} else {
print('image: $image');
}
});
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Image Picker'),
),
body: Center(
child: image == null
? Text('No image selected.')
: Image.file(image),
),
floatingActionButton: FloatingActionButton(
onPressed: getImage,
tooltip: 'Pick Image',
child: Icon(Icons.add_a_photo),
),
);
}
}
Try with the below code
Future getImage() async {
File pickedFile = await picker.getImage(source: ImageSource.gallery);
if (pickedFile != null) {
setState(() {
image = File(pickedFile.path);
});
} else {
print('image: $image');
}
}

How to Switch Widgets after certain time in Flutter?

I am facing problems with this tematic, I would like to change a widget after certain time. e.g
I have this animatedFlutter Screen (screen 1) and then after the animation end I would like to change the screen to any screen that I have, for example. Login();
Any tips? Thanks.
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(AnimatedFlutterLogo());
class AnimatedFlutterLogo extends StatefulWidget {
#override
State<StatefulWidget> createState() => new _AnimatedFlutterLogoState();
}
class _AnimatedFlutterLogoState extends State<AnimatedFlutterLogo> {
Timer _timer;
FlutterLogoStyle _logoStyle = FlutterLogoStyle.markOnly;
_AnimatedFlutterLogoState() {
_timer = new Timer(const Duration(milliseconds: 800), () {
setState(() {
_logoStyle = FlutterLogoStyle.horizontal;
});
});
}
#override
void dispose() {
super.dispose();
_timer.cancel();
}
#override
Widget build(BuildContext context) {
return new FlutterLogo(
size: 200.0,
textColor: Colors.white,
style: _logoStyle,
);
}
}
try this,
_Act_NotificationScreenState() {
_timer = new Timer(const Duration(milliseconds: 800), () {
setState(() {
_logoStyle = FlutterLogoStyle.horizontal;
});
_timer = new Timer(const Duration(seconds: 1), () {
Navigator.push(context, MaterialPageRoute(builder: (context) => Act_Login()));
});
});
}
Wrap your AnimatedFlutterLogo with MaterialApp and in the callback function of Timer use Navigator to navigate to respective Page
Example:
import 'package:flutter/material.dart';
import 'dart:async';
void main() => runApp(MaterialApp(home:AnimatedFlutterLogo()));
class AnimatedFlutterLogo extends StatefulWidget {
#override
State<StatefulWidget> createState() => new _AnimatedFlutterLogoState();
}
class _AnimatedFlutterLogoState extends State<AnimatedFlutterLogo> {
Timer _timer;
FlutterLogoStyle _logoStyle = FlutterLogoStyle.markOnly;
_AnimatedFlutterLogoState() {
_timer = new Timer(const Duration(milliseconds: 800), () {
setState(() {
_logoStyle = FlutterLogoStyle.horizontal;
});
Navigator.push( //<-- Navigate to loginPage on Timeout
context,
MaterialPageRoute(builder: (context) => LoginPage()),
);
});
}
#override
void dispose() {
super.dispose();
_timer.cancel();
}
#override
Widget build(BuildContext context) {
return new FlutterLogo(
size: 200.0,
textColor: Colors.white,
style: _logoStyle,
);
}
}
class LoginPage extends StatelessWidget{
#override
Widget build(BuildContext context){
return Container(alignment: Alignment.center,child: Text("LOG IN PAGE"));
}
}
You need to write code of navigating to another screen (Widget in case of Flutter)
Navigator.push(
context,
MaterialPageRoute(builder: (context) => Login()),
);
You need to import Login in your current screen.

Show running clock on flutter

I wanted to know if there is any way to show a real time clock in dart?
Date and time (e.g 11/14/2018 19:34) and the time will continue to run.
Time can be taken from the device itself.
The below uses the intl plugin to format the time into MM/dd/yyyy hh:mm:ss. Make sure to update your pubspec.yaml.
import 'dart:async';
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Time Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'Flutter Time Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);
final String title;
#override
_MyHomePageState createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
String _timeString;
#override
void initState() {
_timeString = _formatDateTime(DateTime.now());
Timer.periodic(Duration(seconds: 1), (Timer t) => _getTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Text(_timeString),
),
);
}
void _getTime() {
final DateTime now = DateTime.now();
final String formattedDateTime = _formatDateTime(now);
setState(() {
_timeString = formattedDateTime;
});
}
String _formatDateTime(DateTime dateTime) {
return DateFormat('MM/dd/yyyy hh:mm:ss').format(dateTime);
}
}
Simplest solution:
import 'package:flutter/material.dart';
import 'package:intl/intl.dart';
class ClockWidget extends StatelessWidget {
const ClockWidget({super.key});
#override
Widget build(BuildContext context) {
return StreamBuilder(
stream: Stream.periodic(const Duration(seconds: 1)),
builder: (context, snapshot) {
return Text(DateFormat('MM/dd/yyyy hh:mm:ss').format(DateTime.now()));
},
);
}
}
Put it anywhere you like.
This is the same code which Albert had given, but in case you don't want to use the intl package, you can make these changes to this code:
import 'package:flutter/material.dart';
import 'dart:async';
void main () => runApp(MyApp());
class MyApp extends StatelessWidget{
#override
Widget build(BuildContext context) {
return MaterialApp(
theme: ThemeData(primarySwatch: Colors.red),
home: FlutterTimeDemo(),
);
}
}
class FlutterTimeDemo extends StatefulWidget{
#override
_FlutterTimeDemoState createState()=> _FlutterTimeDemoState();
}
class _FlutterTimeDemoState extends State<FlutterTimeDemo>
{
String _timeString;
#override
void initState(){
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
Timer.periodic(Duration(seconds:1), (Timer t)=>_getCurrentTime());
super.initState();
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Fluter Test'),),
body:Center(
child: Text(_timeString, style: TextStyle(fontSize: 30),),
),
);
}
void _getCurrentTime() {
setState(() {
_timeString = "${DateTime.now().hour} : ${DateTime.now().minute} :${DateTime.now().second}";
});
}
}

Categories

Resources