Display notification when app is closed flutter - flutter

I Have try to display notification in flutter app
When app is open the notification is display but
when flutter app is Closed but it is not working or notification is not display I have share my AndroidManifest.xml
file please check it and help me , I'am new in flutter
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.tv_dashboard">
<!-- Internet Connection -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Display Notifications -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<uses-permission android:name="android.permission.VIBRATE" />
<!-- 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="Leads"
android:usesCleartextTraffic="true"
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"
android:showWhenLocked="true"
android:turnScreenOn="true">
<!-- 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>
</activity>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationReceiver" />
<!-- 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>

You can do by using this-
import 'package:flutter/material.dart';
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:workmanager/workmanager.dart';
void main() {
// needed if you intend to initialize in the `main` function
WidgetsFlutterBinding.ensureInitialized();
Workmanager.initialize(
// The top level function, aka callbackDispatcher
callbackDispatcher,
// If enabled it will post a notification whenever
// the task is running. Handy for debugging tasks
isInDebugMode: true
);
// Periodic task registration
Workmanager.registerPeriodicTask(
"2",
//This is the value that will be
// returned in the callbackDispatcher
"simplePeriodicTask",
// When no frequency is provided
// the default 15 minutes is set.
// Minimum frequency is 15 min.
// Android will automatically change
// your frequency to 15 min
// if you have configured a lower frequency.
frequency: Duration(minutes: 15),
);
runApp(MyApp());
}
void callbackDispatcher() {
Workmanager.executeTask((task, inputData) {
// initialise the plugin of flutterlocalnotifications.
FlutterLocalNotificationsPlugin flip = new
FlutterLocalNotificationsPlugin();
// app_icon needs to be a added as a drawable
// resource to the Android head project.
var android = new AndroidInitializationSettings('#mipmap/ic_launcher');
var IOS = new IOSInitializationSettings();
// initialise settings for both Android and iOS device.
var settings = new InitializationSettings(android, IOS);
flip.initialize(settings);
_showNotificationWithDefaultSound(flip);
return Future.value(true);
});
}
Future _showNotificationWithDefaultSound(flip) async {
// Show a notification after every 15 minute with the first
// appearance happening a minute after invoking the method
var androidPlatformChannelSpecifics = new AndroidNotificationDetails(
'your channel id',
'your channel name',
'your channel description',
importance: Importance.Max,
priority: Priority.High
);
var iOSPlatformChannelSpecifics = new IOSNotificationDetails();
// initialise channel platform for both Android and iOS device.
var platformChannelSpecifics = new NotificationDetails(
androidPlatformChannelSpecifics,
iOSPlatformChannelSpecifics
);
await flip.show(0, 'GeeksforGeeks',
'Your are one step away to connect with GeeksforGeeks',
platformChannelSpecifics, payload: 'Default_Sound'
);
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
#override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Geeks Demo',
theme: ThemeData(
// This is the theme
// of your application.
primarySwatch: Colors.green,
),
home: HomePage(title: "GeeksforGeeks"),
);
}
}
class _HomePageState extends State<HomePage> {
#override
Widget build(BuildContext context) {
// This method is rerun every time setState is called.
// The Flutter framework has been optimized
// to make rerunning build methods
// fast, so that you can just rebuild
// anything that needs updating rather
// than having to individually change
//instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from
// the MyHomePage object that was created by
// the App.build method, and use it
// to set our appbar title.
title: Text(widget.title),
),
body: new Container(),
);
}
}
dependencies
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
# Use with the Workmanger class for background jobs headless execution.
workmanager: ^0.2.3
# Use with FlutterLocalNotificationsPlugin class for local push notifications.
flutter_local_notifications: ^1.4.4+2
And
<!-- Add below permission inside 'manifest' tag -->
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>
<!-- Add below permission inside 'application' tag -->
<receiver android:name="com.dexterous.flutterlocalnotifications.ScheduledNotificationBootReceiver">
<intent-filter>
<action android:name="android.intent.action.BOOT_COMPLETED"/>
<action android:name="android.intent.action.MY_PACKAGE_REPLACED"/>
</intent-filter>
</receiver>
and use for more
flutter_local_notifications
thank you

Related

How to solve "No permissions found in manifest for: []9" in flutter

i was trying to make upload features, so users can upload file into firebase account
in the past, it run well, but yesterday, it wont show the files
there is the code
uploadImage() async {
final storage = FirebaseStorage.instance;
final picker = ImagePicker();
PickedFile? image;
//Check Permissions
await Permission.photos.request();
var permissionStatus = await Permission.photos.status;
if (permissionStatus.isGranted) {
//Select Image
image = await picker.getImage(source: ImageSource.gallery);
var file = File(image!.path);
final fileName = basename(file.path);
final destination = 'user/$emaila/identitas/$fileName';
if (image != null) {
//Upload to Firebase
var snapshot = await storage
.ref()
.child(destination)
.putFile(file)
.whenComplete(() => null);
var downloadUrl = await snapshot.ref.getDownloadURL();
setState(() {
imageUrlidentitas = downloadUrl;
});
} else {
print('No Path Received');
}
} else {
print('Grant Permissions and try again');
}
}
here is android manifest
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.rekammedis">
<uses-permission android:name="android.permission.INTERNET"/>
<!-- Permissions options for the `storage` group -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
<uses-permission android:name="android.permission.READ_MEDIA_VIDEO" />
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
<!-- Permissions options for the `camera` group -->
<uses-permission android:name="android.permission.CAMERA"/>
<application
android:label="rekammedis"
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" />
</application>
</manifest>
and the compiler says
D/permissions_handler( 9318): No permissions found in manifest for: []9
D/permissions_handler( 9318): No permissions found in manifest for: []9
I/flutter ( 9318): Grant Permissions and try again
how to solve this ? anyone know ?
i try looking in stackoverflow, but none of them are explain the answer
This is a recent bug which was introduced by the new version of the permissionhandler in 10.2.0. It is discussed here https://github.com/Baseflow/flutter-permission-handler/issues/944 and I will copy the answer to this question as well. This solution was also working for me.
I've fixed this by checking for Permissions.storage.status when the device is Android 12.0 or below, else I use the Permissions.photos.status. I use the device_info_plus plugin to check the Android version:
I added the following to my AndroidManifest.kt
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"
android:maxSdkVersion="32"/>
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES"/>
and in flutter:
if (Platform.isAndroid) {
final androidInfo = await DeviceInfoPlugin().androidInfo;
if (androidInfo.version.sdkInt <= 32) {
/// use [Permissions.storage.status]
} else {
/// use [Permissions.photos.status]
}
}
all credits belong to HinrikHelga on github
Check your targetSdkVersion in build.gradle file.
If you are using targetSdkVersion = 30, you will need to write storage permission in a different way. I think you can try the solution discussed in this post

Flutter audio_service stream update notification with IcyMetadata

I want to to a streamApp for just one stream/url.
In the audio_service example there is an MediaItem added in the AudioPlayerHandler.
This works so fahr but when IcyMedata updated the notification … obviously … has title and stuff from the added MediaItem. In the app i can update per _audioHandler.playbackstate and _player.icyMetadata!.info!.title! and some sting.splits(' - ') I can update Infos in the app with StreamBilder.
Also tried a dirty hack to add title in the PlaybackState object by changing the audio_service and add a title as property and connect it in the custom AudioHandler with _player.icy … .
But there must be a proper way to set metadata new or by this framework by itself. _audioHandler.updateMediaItem does nothing so far to the notification info, this is what i need!
I found a addStream … my try (Snippets)
Stream<MediaItem> _item() async* { MediaItem(
id: "http://stream.drumandbass.fm:9012",
title: "TEST",
artist: "Hello",
album: "Album",
duration: const Duration(milliseconds: 5739820),
genre: 'Drum and Bass',
artUri: Uri.parse('test.jpg'));
}
Future<AudioPlayerHandler> initAH() async {
return await AudioService.init(
builder: () => AudioPlayerHandler(),
config: const AudioServiceConfig(
androidNotificationChannelId: 'com.ryanheise.myapp.channel.audio',
androidNotificationChannelName: 'Audio playback',
androidNotificationOngoing: true,
),
);
class AudioPlayerHandler extends BaseAudioHandler {
/// Initialise our audio handler.
AudioPlayerHandler() {
// So that our clients (the Flutter UI and the system notification) know
// what state to display, here we set up our audio handler to broadcast all
// playback state changes as they happen via playbackState...
_player.playbackEventStream.map(_transformEvent).pipe(playbackState);
// ... and also the current media item via mediaItem.
mediaItem.addStream(_item());
// Load the player.
_player.setAudioSource(AudioSource.uri(Uri.parse(mediaItem.value!.id)));
}
// some play stop the rest of the example of audio_service
Widget:
FutureBuilder<AudioPlayerHandler>(
future: initAH(),
builder: (BuildContext context,
AsyncSnapshot<AudioPlayerHandler> snapshot) {
if (!snapshot.hasData) {
// while data is loading:
return Center(
child: CircularProgressIndicator(),
);
} else {
_audioHandler = snapshot.data!;
loaded = true;
// data loaded:
return Container();
}
},
),
… with _player.add(MediaItem()); like in example i get a snapshot.hasData but with addStream loaded keeps false.
I thankful for any tips to handle this issue properly.
thx,
Tom
As you not seeing the notification. please check your android configuration.
<manifest xmlns:tools="http://schemas.android.com/tools" ...>
<!-- ADD THESE TWO PERMISSIONS -->
<uses-permission android:name="android.permission.WAKE_LOCK"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
<application ...>
...
<!-- EDIT THE android:name ATTRIBUTE IN YOUR EXISTING "ACTIVITY" ELEMENT -->
<activity android:name="com.ryanheise.audioservice.AudioServiceActivity" ...>
...
</activity>
<!-- ADD THIS "SERVICE" element -->
<service android:name="com.ryanheise.audioservice.AudioService"
android:exported="true" tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.media.browse.MediaBrowserService" />
</intent-filter>
</service>
<!-- ADD THIS "RECEIVER" element -->
<receiver android:name="com.ryanheise.audioservice.MediaButtonReceiver"
android:exported="true" tools:ignore="Instantiatable">
<intent-filter>
<action android:name="android.intent.action.MEDIA_BUTTON" />
</intent-filter>
</receiver>
</application>
</manifest>
if you are update you metadata you have just added updatemetadata of your view dart file otherwise set in initstate
like below
before you Add udioHandler.updateMediaItem() you need to update your Audiohandler file
enter image description here
enter image description here
its work for me

Missing Default Notification Channel metadata in AndroidManifest. Default value will be used Flutter

I'm using Firebase Messaging version 10.0.2 and flutterLocalNotification version 6.0.0. Whenever I run my notification using firebase messaging for when my app is in background I keep getting in the console this exception Missing Default Notification Channel metadata in AndroidManifest. Default value will be used even when I have created a Notification channel using the flutter localNotification plugin.
Although, this works perfectly when the app is in foreground
Here's my Manifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.app">
<application
android:label="app"
android:icon="#mipmap/ic_launcher">
<activity
android:name=".MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
<meta-data
android:name="io.flutter.embedding.android.SplashScreenDrawable"
android:resource="#drawable/launch_background"
/>
<meta-data
android:name="com.google.firebase.messaging.default_notification_channel_id"
android:value="app"/>
<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" />
</application>
Here's also my code to create the notification channel
static final FlutterLocalNotificationsPlugin flutterLocalNotificationsPlugin =
FlutterLocalNotificationsPlugin();
static void initialize() {
final InitializationSettings initializationSettings =
InitializationSettings(
android: AndroidInitializationSettings("#mipmap/ic_launcher"));
static void createChannelAndDisplay(RemoteMessage message) async {
final id = DateTime.now().millisecondsSinceEpoch ~/ 1000;
final NotificationDetails notificationDetails = NotificationDetails(
android: AndroidNotificationDetails(
"app", "app_channel", "my app channel",
importance: Importance.max, priority: Priority.high));
await flutterLocalNotificationsPlugin.show(
id,
message.notification!.title,
message.notification!.body,
notificationDetails,
);
What am I getting wrong?

no permissions found in manifest for : 2 [flutter]

im using permission_handle to take permission for location.
and it always saying "No permissions found in manifest"
even i tried "flutter clean"
import 'package:permission_handler/permission_handler.dart';
class PermissionsService {
final PermissionHandler _permissionHandler = PermissionHandler();
Future<bool> _requestPermission(PermissionGroup permission) async {
var result = await _permissionHandler.requestPermissions([permission]);
if (result[permission] == PermissionStatus.granted) {
print('innnn');
return true;
}
return false;
}
Future<bool> requestLocationPermission({Function onPermissionDenied} ) async {
// return _requestPermission(PermissionGroup.locationWhenInUse);
var granted = await _requestPermission(PermissionGroup.location );
if(!granted){
onPermissionDenied();
}
return granted;
}
}
my Manifest.xml file
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.artistry">
<!-- Flutter needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>
You added permission in the Wrong Manifest File, You have to add location permission inside Android Manifest of this Directory android\app\src\main\AndroidManifest
You need to set permissions in main AndroidManifest.xml.
There are three folders debug, main and profile.
Run flutter clean.
See my example:
.../main/AndoridManifest.xml
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="test.packange.name">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<!-- 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="Test app"
android:icon="#mipmap/ic_launcher"
android:roundIcon="#mipmap/ic_launcher_round">
<activity
android:name="test.packange.name.MainActivity"
android:launchMode="singleTop"
android:theme="#style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:windowSoftInputMode="adjustResize">
<!-- This keeps the window background of the activity showing
until Flutter renders its first frame. It can be removed if
there is no splash screen (such as the default splash screen
defined in #style/LaunchTheme). -->
<meta-data
android:name="io.flutter.app.android.SplashScreenUntilFirstFrame"
android:value="true" />
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
</application>
</manifest>
main.dart
Future<void> requestPermission(PermissionGroup permission) async {
final List<PermissionGroup> permissions = <PermissionGroup>[permission];
final Map<PermissionGroup, PermissionStatus> permissionRequestResult =
await PermissionHandler().requestPermissions(permissions);
print(permissionRequestResult);
_permissionStatus = permissionRequestResult[permission];
if (_permissionStatus == PermissionStatus.granted) {
initLocationStreamer();
}
print(_permissionStatus);
}
Update plugin https://github.com/Baseflow/flutter-permission-handler. See example and issues.

How to send email with flutter?

I tried all packages to send email ( flutter_email_sender - flutter_mailer -url_launcher), copy and paste the example, but always the same error message : " MissingPluginException(No implementation found for methode ...), I serach a simple example to send email on press button.
thank you
To use latest version of url_launcher or above version of 4.1.0+1
, you have to migrate to android x.
[https://flutter.dev/docs/development/packages-and-plugins/androidx-compatibility][1]
Example:
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
class SendEmail extends StatelessWidget {
void _contact() async {
final url = 'mailto:dude#gmail.com';
if (await canLaunch(url)) {
await launch(url);
} else {
throw 'Could not launch $url';
}
}
#override
Widget build(BuildContext context) {
return RaisedButton(
onPressed: (){_contact()},
child: Text('Mail'),
),
}
}
try adding these lines on AndroidManifest.xml
<!-- Provide required visibility configuration for API level 30 and above -->
<queries>
<!-- If your app checks for SMS support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
</queries>
then run flutter clean, then build again
it work for me but this is specific for url_launcher