FCm push notification click not working in flutter - flutter

Notification click time FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) { } not calling . how to solve this issue anyone help me .
FCM response :
{load_id: 1045, type: load_created_by_client, title: New load created, click_action: FLUTTER_NOTIFICATION_CLICK, message: New load #1045 created., added_on: 2022-06-11 08:56:16}
Manifest file :
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
package="com.xxx.xxx.xxx">
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE"></uses-permission>
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE"></uses-permission>
<application
android:label="etruxx"
android:usesCleartextTraffic="true"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:exported="true"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<!-- Displays an Android View that continues showing the launch screen
Drawable until Flutter paints its first frame, then this splash
screen fades out. A splash screen is useful to avoid any visual
gap between the end of Android's launch screen and the painting of
Flutter's first frame. -->
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- <meta-data-->
<!-- android:name="firebase_messaging_auto_init_enabled"-->
<!-- android:value="false" />-->
<!-- <meta-data-->
<!-- android:name="firebase_analytics_collection_enabled"-->
<!-- android:value="false" />-->
<!-- <meta-data-->
<!-- android:name="firebase_analytics_collection_deactivated"-->
<!-- android:value="false" />-->
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="high_importance_channel" />
</application>
</manifest>
Main.dart file code here
import 'dart:async';
import 'package:xxxx/home/dispatch_home.dart';
import 'package:xxxx/size_config.dart';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'Dashboard.dart';
import 'home/load_view_dispatch.dart';
/// To verify things are working, check out the native platform logs.
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
// If you're going to use other Firebase services in the background, such as Firestore,
// make sure you call `initializeApp` before using other Firebase services.
await Firebase.initializeApp();
print('Handling a background message ${message.messageId}');
print(message.data.toString());
RemoteNotification? notification = message.notification;
// print(message.notification.toString());
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
AndroidNotification? android = message.notification?.android;
print(notification);
print(android);
print(!kIsWeb);
// if (notification != null && android != null && !kIsWeb) {
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'456546545675', // id
'High 45654654 Notifications', // title
//'This channel is used for important notifications.', // description
importance: Importance.high, playSound: true
);
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
print('A new onMessageOpenedApp event was published! : '+loadid);
});
flutterLocalNotificationsPlugin.show(
int. parse(dataval['load_id']),
dataval['title'],
dataval['message'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
//channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
playSound: true,
priority: Priority.high,
importance: Importance.high,
icon: "#mipmap/ic_launcher",
),
),
);
}else{
print('go to else');
}
}
/// Create a [AndroidNotificationChannel] for heads up notifications
late AndroidNotificationChannel channel;
/// Initialize the [FlutterLocalNotificationsPlugin] package.
late FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin;
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
// Set the background messaging handler early on, as a named top-level function
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
if (!kIsWeb) {
channel = const AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
//'This channel is used for important notifications.', // description
importance: Importance.high, playSound: true
);
flutterLocalNotificationsPlugin = FlutterLocalNotificationsPlugin();
/// Create an Android Notification Channel.
///
/// We use this channel in the `AndroidManifest.xml` file to override the
/// default FCM channel to enable heads up notifications.
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
/// Update the iOS foreground notification presentation options to allow
/// heads up notifications.
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
}
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
// SizeConfig().init(context);
return MaterialApp(
title: 'Etruux',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'Welcome Etruux'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
void initState() {
super.initState();
FirebaseMessaging.instance
.getInitialMessage()
.then((RemoteMessage? message) {
if (message != null) {
print("calling initial");
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => load_view_dispatch(loadid)));
}
});
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print(message.data.toString());
RemoteNotification? notification = message.notification;
// print(message.notification.toString());
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
AndroidNotification? android = message.notification?.android;
print(notification);
print(android);
print(!kIsWeb);
// if (notification != null && android != null && !kIsWeb) {
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
print('A new onMessageOpenedApp event was published!');
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => load_view_dispatch(loadid)));
});
if (!kIsWeb) {
flutterLocalNotificationsPlugin.show(
int. parse(dataval['load_id']),
dataval['title'],
dataval['message'],
NotificationDetails(
android: AndroidNotificationDetails(
channel.id,
channel.name,
//channel.description,
// TODO add a proper drawable resource to android, for now using
// one that already exists in example app.
playSound: true,
priority: Priority.high,
importance: Importance.high,
icon: "#mipmap/ic_launcher",
),
),
);
}else{
print('go to else');
}
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
Map<String, dynamic> dataval=message.data;
print(dataval['load_id']);
String loadid=dataval['load_id'];
print('A new onMessageOpenedApp event was published!');
Navigator.of(context).push(MaterialPageRoute(
builder: (BuildContext context) => load_view_dispatch(loadid)));
});
getToken();
Timer(Duration(seconds: 5),
()=>Navigator.pushReplacement(context,
MaterialPageRoute(builder:
(context) =>
Dashboard()
)
)
);
}
#override
void didChangeAppLifecycleState(final AppLifecycleState state) {
if (state == AppLifecycleState.resumed) {
setState(() {
// ...your code goes here...
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
// RemoteNotification? notification = message.notification;
// AndroidNotification? android = message.notification?.android;
print("fail");
Map<String, dynamic> dataval=message.data;
print(dataval['type']);
if(dataval['type'].compareTo("load_created_by_client")==0) {
print("success");
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => dispatch_home()
),
);
}
});
});
}
}
late String token;
getToken() async {
token = (await FirebaseMessaging.instance.getToken())!;
print(token);
}
#override
Widget build(BuildContext context) {
SizeConfig().init(context);
return Scaffold(
appBar: AppBar(
title: Text("testttt"),
),
body: Stack(
fit: StackFit.expand,
children: <Widget>[
// Container(
// decoration: BoxDecoration(color: Colors.deepPurple),
// ),
Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Expanded(
flex: 4,
child: Container(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
// FlutterLogo(
// size: 100.0,
// ),
Image.asset('assets/testicon.png', height: 170,
width: 250,),
Padding(
padding: EdgeInsets.only(top: 10.0),
),
],
),
),
),
],
)
],
),
);
}
}
pubspec.file
firebase_core: ^1.17.1
firebase_messaging: ^11.4.1
flutter_local_notifications: ^9.5.3+1
firebase_analytics: ^9.1.9
fluttertoast: ^8.0.9
cloud_firestore: ^3.1.17
overlay_support: ^2.0.0
firebase_auth: ^3.3.19
App closed or open scenario notification working and also values print but notification click time that related functionality not calling. inside print value also not working. anyone help. how to solve this issue. any mistake here

Related

Flutter Image Cropp Doesnt show Image

I use Flutter Image Crop, Image editing working but doesnt show image. I press the button. I choose the picture. I'm arranging. Then I hit the 'check' button. However, the picture does not appear on the screen.I don't know what to do. I've been working on it for 2 days but I couldn't find the error.
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:image_picker/image_picker.dart';
void main() {
runApp(cropBen1());
}
class cropBen1 extends StatelessWidget {
const cropBen1({Key? key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
title: "Image Cropper Ben",
home: cropBen2(),
);
}
}
class cropBen2 extends StatefulWidget {
const cropBen2({Key? key}) : super(key: key);
#override
State<cropBen2> createState() => _cropBen2State();
}
class _cropBen2State extends State<cropBen2> {
File? _image,imageFile;
Future getImage(ImageSource source) async{
try {
final image=await ImagePicker().pickImage(source: source);
if(image==null) return;
final imageTemporary = File(image.path);
this._image=imageTemporary;
_cropImage(image?.path);
} on PlatformException catch (e) {
print('Failed to pick image : $e');
}
}
_cropImage(filePath) async {
final croppedImage = await ImageCropper().cropImage(sourcePath: filePath,maxHeight: 1080,maxWidth: 1080);
if (croppedImage != null) {
imageFile = croppedImage as File?;
setState(() {});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(centerTitle:true,title: Text("Image Cropper Ben"),),
body: Center(child: Column(children: [
SizedBox(height: 30,),
Container(child: imageFile != null ? Image.file(imageFile!,width: 300,height: 300,fit: BoxFit.cover,)
: Image.network('http://gezilecekyerler.com/wp-content/uploads/2017/03/van.jpg'),),
SizedBox(height: 20,),
ElevatedButton(
onPressed: ()=>{getImage(ImageSource.gallery)},
child: Container(
width: 250,
height: 50,
child: Row(children: [
Icon(Icons.image_outlined),
SizedBox(width: 20,),
Text("Resim Yükle",style: TextStyle(fontWeight: FontWeight.bold,fontSize: 24),),
],),
)),
],),),
);
}
}
AndroidManifest.XML
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.deneme_flutter">
<uses-permission android:name="android.permission.INTERNET"/>
<application
android:label="deneme_flutter"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>

Lower android version storage permission issue. Flutter

I am using a package permission handler in my app. I am using an android 9 mobile.
This is my AndroidManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.light_chat">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
android:maxSdkVersion="28"/>
<uses-permission android:name="android.permission.ACTION_MANAGE_ALL_FILES_ACCESS_PERMISSION"/>
<application
android:requestLegacyExternalStorage="true">
android:label="light_chat"
android:name="${applicationName}"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges=
"orientation|keyboardHidden|keyboard|screenSize|
smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="#style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
android:usesCleartextTraffic="true"
</application>
</manifest>
And This is my homePage where I am making the permission function
and calling in initState();
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:flutter/material.dart';
import 'package:light_chat/layout/const_size.dart';
import 'package:light_chat/layout/repeateCode.dart';
import 'package:permission_handler/permission_handler.dart';
import 'sign_in.dart';
import 'functions.dart';
import 'chat_room.dart';
import 'package:permission_handler/permission_handler.dart';
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> with WidgetsBindingObserver {
late final size = MediaQuery
.of(context)
.size;
bool isLoading = false;
Map<String, dynamic>? userMap;
TextEditingController _serachBarController = TextEditingController();
FirebaseAuth _auth = FirebaseAuth.instance;
String chatRoomId(String user1, String user2){
if(user1[0].toLowerCase().codeUnits[0] >
user2[0].toLowerCase().codeUnits[0]){
return '$user1 $user2';
}
else
{
return '$user2 $user1';
}
}
#override
void onSearch() async {
FirebaseFirestore _firestore = FirebaseFirestore.instance;
setState(() {
isLoading = true;
});
await _firestore.collection('users').where(
'email', isEqualTo: _serachBarController.text)
.get().then((value) {
setState(() {
if (value.docs.length > 0) {
userMap = value.docs[0].data();
print(userMap);
isLoading = false;
}
});
});
}
FirebaseFirestore _firestore = FirebaseFirestore.instance;
#override
void initState() {
permission();
WidgetsBinding.instance.addObserver(this);
statusChange('Online');
// TODO: implement initState
super.initState();
}
Here is the permission function i want to allow my mobile second permission
var status1
but my stack thorwing exception that is no permission in menifest file.
i am using android 9 so this is the problem
those permissions i am adding in menifest, for android 11.
i want to know which permission i add in menifest for android 9 or under 9.
void permission ()async{
// var status0= await Permission.storage.status;
// if (!status0.isGranted){
// await Permission.storage.request();
// }
var status1= await Permission.manageExternalStorage.status;
if (!status1.isGranted){
await Permission.manageExternalStorage.request();
}
}
void statusChange(String status)async{
await _firestore.collection('users').doc(_auth.currentUser!.uid).update(
{
'status' : status
});
}
#override
void didChangeAppLifecycleState(AppLifecycleState state) {
if(state == AppLifecycleState.resumed){
statusChange('Online');
}
else
{
statusChange('Offline');
}
// TODO: implement didChangeAppLifecycleState
super.didChangeAppLifecycleState(state);
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Home',),
actions: [
IconButton(onPressed: () => logOut(context), icon: Icon(Icons.logout))
],
backgroundColor: Colors.blue,),
body: isLoading ?
Center(child:
Container(
height: size.height / 20,
width: size.width / 20,
child: CircularProgressIndicator(),
),)
: Column(
children: [
SizedBox(height: 10.0,),
RepeateTextFieldCode(controller: _serachBarController,
keyboardType: TextInputType.emailAddress,
lableText: 'Search'),
ElevatedButton(onPressed: () => onSearch(),
child: Text('Search', style: buttonText,),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.blue),
),
),
userMap != null ?
ListTile(
onTap: () {
String roomId = chatRoomId(_auth.currentUser!.displayName!,
userMap?['name']);
Navigator.push(context,MaterialPageRoute(builder: (_)=> ChatRoom(
chatRoomId: roomId,
userMap: userMap,
)));
},
title: Text(userMap?['name'], style: titleText,),
subtitle: Text(userMap?['email'], style: subtitleText,),
leading: Icon(Icons.account_box, color: Colors.black,),
trailing: Icon(Icons.chat, color: Colors.black,),
) :
Container(),
],
),
);
}
}

Null check operator used on a null value. Error thrown null in platform_views.dart

App is crashing a lot while starting it.
In my app, I am using Crashlytics to log the errors.
As I can see in Crashlytics, users are getting below errors and app is unresponsive.
Non-fatal Exception: io.flutter.plugins.firebase.crashlytics.FlutterError: Null check operator used on a null value. Error thrown null.
at State.setState(framework.dart:1141)
at _PlatformViewLinkState._onPlatformViewCreated(platform_view.dart:898)
at AndroidViewController.create(platform_views.dart:775)
Seems like this error is getting occured on app load only.
main.dart file
import 'dart:async';
import 'package:firebase_core/firebase_core.dart';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:my_app/Home_screen.dart';
import 'package:my_app/utils/helpers/admob_helper.dart';
import 'package:my_app/utils/helpers/interstitial_ad_helper.dart';
import 'package:my_app/utils/helpers/notification_helper.dart';
import 'package:my_app/widgets/shared/rate_my_app.dart';
import 'config/theme_config.dart';
import 'utils/helpers/dark_theme_listener.dart';
const AndroidNotificationChannel channel = AndroidNotificationChannel(
'high_importance_channel', // id
'High Importance Notifications', // title
description:
'This channel is used for important notifications.', // description
importance: Importance.high,
playSound: true,
);
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
Future<void> _firebaseMessagingBackgroundHandler(RemoteMessage message) async {
await Firebase.initializeApp();
print('A bg message just showed up : ${message.messageId}');
}
Future<void> main() async {
runZonedGuarded(() async {
WidgetsFlutterBinding.ensureInitialized();
await Firebase.initializeApp();
FirebaseMessaging.onBackgroundMessage(_firebaseMessagingBackgroundHandler);
FirebaseMessaging.instance.subscribeToTopic(
"ScratchNotiftest"); //Replace with JHNotifTest for Live
await flutterLocalNotificationsPlugin
.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>()
?.createNotificationChannel(channel);
await FirebaseMessaging.instance
.setForegroundNotificationPresentationOptions(
alert: true,
badge: true,
sound: true,
);
AdmobHelper.initialize();
await new ThemeHelper().initialize();
InterstitialAdHelper.calculateNextAdDisplay();
FlutterError.onError = FirebaseCrashlytics.instance.recordFlutterError;
runApp(MyApp());
SystemChrome.setSystemUIOverlayStyle(
SystemUiOverlayStyle(statusBarColor: Color(0xff004175)));
}, (Object error, StackTrace stack) {
FirebaseCrashlytics.instance.recordError(error, stack);
});
}
class MyApp extends StatefulWidget {
MyApp({
Key? key,
}) : super(key: key);
#override
State<MyApp> createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
#override
void initState() {
super.initState();
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
RemoteNotification notification = message.notification!;
flutterLocalNotificationsPlugin.show(
notification.hashCode,
notification.title,
notification.body,
NotificationDetails(
android: NotificationHelper.getAndroidNotificationDetails(channel),
));
});
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('A new onMessageOpenedApp event was published!');
RemoteNotification notification = message.notification!;
showDialog(
context: context,
builder: (_) {
return AlertDialog(
title: Text(notification.title ?? 'my_app'),
content: SingleChildScrollView(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [Text(notification.body ?? 'New Notification')],
),
),
);
});
});
}
#override
Widget build(BuildContext context) {
// Only call clearSavedSettings() during testing to reset internal values.
// Upgrader().clearSavedSettings(); // REMOVE this for release builds
return ValueListenableBuilder<bool>(
valueListenable: isDark,
builder: (ctx, theme, child) => MaterialApp(
themeMode: theme ? ThemeMode.dark : ThemeMode.light,
debugShowCheckedModeBanner: false,
title: 'my_app',
theme: lightThemeData(context),
darkTheme: darkThemeData(context),
home: RateAppInitWidget(
builder: (rateMyApp) => HomeScreen(
rateMyApp: rateMyApp,
),
),
),
);
}
}
My Qestions:
Is there anything wrong in my main.dart file?
If flutter is null safe, then why it is breaking? (Again if bang operator is not that safe to use, why it is getting used everywhere).
I really appricate any help. Thanks in advance.
Try Removing the ! from this line & Pass Some Default Value for RemoteNotification Type:
RemoteNotification notification = message.notification!;

Flutter workmanager not work when app is terminated [2022]

I'm trying in Android to show a local notification as a test, everything works fine if the app is foreground and background, but I need the notification to show when the app is terminated, which is this mode (when I terminate the app) workmanager doesn't work .
I have seen many questions and answers but I have not found anything clear, does anyone know how to make the notification appear when the application is finished? I don't want to use push notifications or Fcm, I know that, but I need to know how to do this locally.
my main.dart
I'm trying to show a local notification as a test, everything works fine if the app is foreground and background, but I need the notification to show when the app is terminated, which is this mode (when I terminate the app) workmanager doesn't work .
I have seen many questions and answers but I have not found anything clear, does anyone know how to make the notification appear when the application is finished? I don't want to use push notifications or Fmc, I know that, but I need to know how to do this locally.
my main.dart
import 'package:flutter/material.dart';
import 'package:workmanager/workmanager.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) async {
if (task == 'uniqueKey') {
///do the task in Backend for how and when to send notification
final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidNotificationDetails androidPlatformChannelSpecifics =
AndroidNotificationDetails('your channel id', 'your channel name',
'your channel description',
importance: Importance.max,
priority: Priority.high,
showWhen: false);
const NotificationDetails platformChannelSpecifics =
NotificationDetails(android: androidPlatformChannelSpecifics);
await flutterLocalNotificationsPlugin.show(
0,
'hello',
'1245',
platformChannelSpecifics,
payload: 'item x');
}
return Future.value(true);
});
}
Future<void> main() async {
WidgetsFlutterBinding.ensureInitialized();
Workmanager.initialize(
callbackDispatcher,
isInDebugMode:
true);
FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
const AndroidInitializationSettings initializationSettingsAndroid =
AndroidInitializationSettings(
'#mipmap/ic_launcher');
final IOSInitializationSettings initializationSettingsIOS =
IOSInitializationSettings();
final MacOSInitializationSettings initializationSettingsMacOS =
MacOSInitializationSettings();
final InitializationSettings initializationSettings = InitializationSettings(
android: initializationSettingsAndroid,
iOS: initializationSettingsIOS,
macOS: initializationSettingsMacOS);
await flutterLocalNotificationsPlugin.initialize(initializationSettings,
onSelectNotification: selectNotification);
runApp(const MyApp());
}
Future selectNotification(String payload) async {
if (payload != null) {
debugPrint('notification payload: $payload');
}
}
class MyApp extends StatelessWidget {
const MyApp({Key key}) : super(key: key);
#override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
#override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
centerTitle: true,
title: const Text("Work manager Example"),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
ElevatedButton(
onPressed: () {
Workmanager.registerPeriodicTask(
"1",
"uniqueKey",
frequency: Duration(minutes: 15),
initialDelay: Duration(seconds:10),
);
print('START');
},
child: Text("Run Task")),
SizedBox(
height: 10,
),
ElevatedButton(
onPressed: () {
Workmanager.cancelByUniqueName("1");
print('cancel');
},
child: Text("Cancel Task"))
],
),
),
);
}
#override
void initState() {
// TODO: implement initState
super.initState();
}
}

Flutter | How to click square image from camera and display square image

Here I am working with one project where I need to click an image from the camera and preview it in another screen. so I've done it. but there is some issue here I need to click square image and display also the square image I've tried lots of solutions but it won't work. hope you understand the question. please help me. your little help can make my day.
Here is my code.
availableCameras().then((availableCameras) {
cameras = availableCameras;
if (cameras.length > 0) {
setState(() {
selectedCameraIdx = 0;
});
_initCameraController(cameras[selectedCameraIdx]).then((void v) {});
} else {
print("No camera available");
}
}).catchError((err) {
print('Error: $err.code\nError Message: $err.message');
});
//---------------------------------------------------------------------
AspectRatio(
aspectRatio: 1,
child: ClipRect(
child: Transform.scale(
scale: 1 / controller.value.aspectRatio,
child: Center(
child: AspectRatio(
aspectRatio: controller.value.aspectRatio,
child: CameraPreview(controller),
),
),
),
),
)
This is for Display image
Image.file(
File(widget.imagePath),
)
I hope , This is the suitable answer as you wanted.
Plugins: camera, image_cropper
Run this code:
import 'dart:async';
import 'dart:io';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import 'package:image_cropper/image_cropper.dart';
import 'package:path/path.dart' show join;
import 'package:path_provider/path_provider.dart';
Future<void> main() async {
// Ensure that plugin services are initialized so that `availableCameras()`
// can be called before `runApp()`
WidgetsFlutterBinding.ensureInitialized();
// Obtain a list of the available cameras on the device.
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
runApp(
MyApp(firstCamera: firstCamera,)
);
}
class MyApp extends StatelessWidget {
final firstCamera;
// This widget is the root of your application.
MyApp({this.firstCamera});
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
// routes: routes,
home: TakePictureScreen(
// Pass the appropriate camera to the TakePictureScreen widget.
camera: firstCamera,
),
);
}
}
// A screen that allows users to take a picture using a given camera.
class TakePictureScreen extends StatefulWidget {
final CameraDescription camera;
const TakePictureScreen({
Key key,
#required this.camera,
}) : super(key: key);
#override
TakePictureScreenState createState() => TakePictureScreenState();
}
class TakePictureScreenState extends State<TakePictureScreen> {
CameraController _controller;
Future<void> _initializeControllerFuture;
#override
void initState() {
super.initState();
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
widget.camera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
_initializeControllerFuture = _controller.initialize();
}
#override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
#override
Widget build(BuildContext context) {
final size = MediaQuery.of(context).size.width;
return Scaffold(
appBar: AppBar(title: Text('Take a picture')),
// Wait until the controller is initialized before displaying the
// camera preview. Use a FutureBuilder to display a loading spinner
// until the controller has finished initializing.
body: Center(
child: Container(
width: size,
height: size,
child: ClipRect(
child: OverflowBox(
alignment: Alignment.center,
child: FittedBox(
fit: BoxFit.fitWidth,
child: Container(
width: size,
height:size,
child:FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return Center(child: CircularProgressIndicator());
}
},
),
),
),
),
),
)
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.camera_alt),
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
await _controller.takePicture().then((value) {
Navigator.push(
context,
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(imagePath: value.path),
),
);
});
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
),
);
}
}
// A widget that displays the picture taken by the user.
class DisplayPictureScreen extends StatefulWidget {
final String imagePath;
const DisplayPictureScreen({Key key, this.imagePath}) : super(key: key);
#override
_DisplayPictureScreenState createState() => _DisplayPictureScreenState();
}
class _DisplayPictureScreenState extends State<DisplayPictureScreen> {
var finalImage ;
#override
void initState() {
super.initState();
croppingImage();
}
croppingImage()async{
File croppedFile = await ImageCropper.cropImage(
sourcePath: File(widget.imagePath).path,
aspectRatioPresets: [
CropAspectRatioPreset.square,
CropAspectRatioPreset.ratio3x2,
CropAspectRatioPreset.original,
CropAspectRatioPreset.ratio4x3,
CropAspectRatioPreset.ratio16x9
],
androidUiSettings: AndroidUiSettings(
toolbarTitle: 'Cropper',
toolbarColor: Colors.pink,
toolbarWidgetColor: Colors.white,
initAspectRatio: CropAspectRatioPreset.original,
lockAspectRatio: false),
iosUiSettings: IOSUiSettings(
minimumAspectRatio: 1.0,
)
);
if(croppedFile!=null){
setState(() {
finalImage = croppedFile;
});
}else{
setState(() {
finalImage = File(widget.imagePath);
});
}
}
#override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Display the Picture')),
// The image is stored as a file on the device. Use the `Image.file`
// constructor with the given path to display the image.
body: Center(
child:
finalImage !=null ?
Container(
height: MediaQuery.of(context).size.height/2, //400
// width: MediaQuery.of(context).size.width/1.2,//400
decoration: BoxDecoration(
border: Border.all(color: Colors.red),
image: DecorationImage(
image: FileImage(finalImage),
fit: BoxFit.cover
)
),
)
:Container()
)
);
}
}
Modify with your AndroidManifest.xml with this
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.myapp">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<application
android:name="io.flutter.app.FlutterApplication"
android:label="myapp"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-Add Crop Activity -->
<!-Add this line -->
<activity
android:name="com.yalantis.ucrop.UCropActivity"
android:screenOrientation="portrait"
android:theme="#style/Theme.AppCompat.Light.NoActionBar"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
</manifest>
Camera View in Square shape:
Cropping captured image before showing:
Captured image in Square view:
You should use image cropper for this feature. when you take image from camera or gallery just crop image through this : https://pub.dev/packages/image_cropper