How to get push notification click event with Flutter Huawei Push Kit plugin? - flutter

I am integrating Huawei Push Kit (https://pub.dev/packages/huawei_push) in Flutter application and everything works fine except I am unable to get the event when received push notification message is clicked to be able to act on it.
Is this possible to achieve via this plugin or do I need to write this part in native Android code?

Currently, you can achieve this with another plugin that listens for the custom intents. Uni_links package from pub.dev is easy to use. Here is a quick guide to uni_links package:
Add uni_links to your pubspec.yaml file:
dependencies:
flutter:
sdk: flutter
huawei_push: 4.0.4+300
uni_links: 0.4.0
Define an intent filter on your AndroidManifest.xml file:
<application
<!-- . . . Other Configurations . . . -->
<activity/>
<!-- . . . Other Configurations . . . -->
<!-- Add the intent filter below.(inside the application and activity tags) -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="app"/>
</intent-filter>
</activity>
</application
Call the uni links methods in your initState() that will listen for the custom intents. The notification's custom intent I've sent from the Push Kit Console looks like this:
app:///ContentPage?name=Push Kit&url=https://developer.huawei.com/consumer/en/hms/huawei-pushkit
// Get the initial intent that opens the app
Future<void> initInitialLinks() async {
// Platform messages may fail, so we use a try/catch PlatformException.
try {
String initialLink = await getInitialLink();
if (initialLink != null) {
var uri = Uri.dataFromString(initialLink);
String page = uri.path.split('://')[1];
String serviceName = uri.queryParameters['name'];
String serviceUrl = uri.queryParameters['url'];
try {
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
Navigator.of(context).pushNamed(
page,
arguments: ContentPageArguments(serviceName, serviceUrl),
); // Navigate to the page from the intent
});
} catch (e) {
Push.showToast(e);
}
}
} on PlatformException {
print('Error: Platform Exception');
}
}
// Get intents as a stream
Future<Null> initLinkStream() async {
if (!mounted) return;
_sub = getLinksStream().listen((String link) {
var uri = Uri.dataFromString(link);
String page = uri.path.split('://')[1];
// Parse the string ...
Navigator.of(context).pushNamed(page); // Navigate to a page from the intent
}, onError: (err) {
print("Error while listening for the link stream: " + err.toString());
});
}
For more information, visit: Deep Linking on Flutter using Huawei Push Kit’s Custom Intents
The accompanying github repository of the article includes the codes.

I also looked into their flutter plugin and couldn't any method for that. I guess you will have to write platform specific code and for that you can refer to their demo native android project with PushKit.
https://github.com/HMS-Core/hms-push-clientdemo-android

Related

Error opening Apps like WhatsApp to share text: Flutter

I am trying to open apps like WhatsApp, Twitter and Facebook from inside my flutter app but I get a URL scheme error. Please help!
The code I am using is
child: ElevatedButton(
onPressed: () async {
String url =
"https://api.whatsapp.com/send?text=Hello there!";
var encoded = Uri.encodeFull(url);
Uri whatsAppUri = Uri.parse(encoded);
if (await canLaunchUrl(whatsAppUri)) {
await launchUrl(whatsAppUri);
}
},
I get the following error screen-
Please help me find the correct method and URL. Also please help me with Twitter and Facebook as I need to use them as well. Thank You!
You can use below code:
String url() {
if (Platform.isAndroid) {
return "https://wa.me/$phone/?text=Hello there!";
} else {
return "https://api.whatsapp.com/send?phone=$phone=Hello there!}";
}
}
String url = url();
var encoded = Uri.encodeFull(url);
Uri whatsAppUri = Uri.parse(encoded);
if (await canLaunchUrl(whatsAppUri)) {
await launchUrl(whatsAppUri);
}
In the place of $phone you can write phone number of user to which you want to send.
Use this:
const url = "whatsapp://send?text=Hello World!"
or
const url = "https://wa.me/?text=Hello World!";
and add this to your info.plist if your using ios:
<key>LSApplicationQueriesSchemes</key>
<array>
<string>whatsapp</string>
</array>
for facebook:
const url = "fb://facewebmodal/f?href=$username";
for twitter:
const url = "https://twitter.com/username";
last but not least make sure you add configuration right like:
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
</intent>
<intent>
<action android:name="android.intent.action.SEND" />
<data android:mimeType="*/*" />
</intent>
you can find more information from here

How can we handle deep links in flutter with Get X for go to Custom pages of the application?

How can we handle deep links in flutter with Get X for go to Custom pages of the application ?
By default, by adding the desired address to the Android Manifest file:
<meta-data android:name="flutter_deeplinking_enabled" android:value="true" />
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="http" android:host="flutterbooksample.com" />
<data android:scheme="https" android:host="flutterbooksample.com"/>
</intent-filter>
when the application opens, the main page of application will be displayed to us.
I am looking to implement this I can direct the user to any page of the application that is needed. A practical example is to pay on the web page and return to the application. When we return, we should show the user a message about the status of the payment, not direct the user to the first page of the application.
Do the page routing in your app, when you process the deeplink.
In my apps, I usually use uni_links (https://pub.dev/packages/uni_links) and in my main.dart, I have something like this:
StreamSubscription<String> _subUniLinks;
#override
initState() {
super.initState();
// universal link setup
initUniLinks();
}
Future<void> initUniLinks() async {
try {
final String initialLink = await getInitialLink();
await processLink(initialLink);
} on PlatformException {
}
_subUniLinks = linkStream.listen(processLink, onError: (err) {});
}
processLink(String link) async {
// parse link and decide what to do:
// - use setState
// - or use Navigator.pushReplacement
// - or whatever mechanism if you have in your app for routing to a page
}
#override
dispose() {
if (_subUniLinks != null) _subUniLinks.cancel();
super.dispose();
}

Flutter Square Plugin crashes in release only

Flutter Square plugin crashes only in release when I use invalid card or press back.
But when I use flutter run --release & hook up my mobile. the crashes don't occur & the app works perfectly!
here's the code we used
void _pay() async {
await InAppPayments.setSquareApplicationId(sqAppId);
try {
await InAppPayments.startCardEntryFlowWithBuyerVerification(
money: Money((money) => money
..amount = 0
..currencyCode = 'USD'),
collectPostalCode: true,
contact: Contact((ContactBuilder contact) {
return contact.givenName = username;
}),
buyerAction: "Store",
squareLocationId: sqLocationId,
onBuyerVerificationSuccess: (BuyerVerificationDetails result) {
addCard(result.nonce, result.card.postalCode);
},
onBuyerVerificationFailure: (err) {
return showErrorDialog(context, err.toString());
},
onCardEntryCancel: () {});
} on Exception catch (e) {
print(e);
}
}
What is the difference between flutter build & flutter run --release ?
Could I use the APK out from flutter run & upload it to google play ?
In the release version you have to add the PERMISSIONS explicitly.
Try adding android.permission.INTERNET to the Manifest file.
Add
<uses-permission android:name="android.permission.INTERNET"/>
to the AndroidManifest.xml located in android/app/src/main.
For your question about uploading a debuggable apk, Google Play-Upload will reject your file.
Refer to this link for the differences between release and debug.

How can I implement video playback in flutter web?

I'm trying to play videos hosted on firebase on my flutter web app.
I can't figure out how this will be possible.
With flutter native, the video-player plugin is used but that only works for ios and android.
Can someone tell me if it is possible to integrate video in a flutter web app?
I have tried using the dart:html package to achieve this. The videoElement class in the package looks relevant. But I'm unable to render the element as a widget.
prefix1.VideoElement element = prefix1.VideoElement();
element.height = 200;
element.width = 200;
)
I want to add a video playback option to my flutter web page.
I've detailed here a solution that uses the Afterglow video player.
You can replace this with any HTML/JS video player of your choice, the approach would be the same.
Basically, you need to alter the index.html template file and interact with the DOM using either dart:html or universal_html packages to get your desired video file playing.
index.html will look like:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Web Video Player</title>
<script src="https://cdn.jsdelivr.net/npm/afterglowplayer#1.x"></script></head>
<body>
<script src="main.dart.js" type="application/javascript"></script>
<a id="triggerVideoPlayer" class="afterglow" href="#videoPlayer"></a>
<video id="videoPlayer" width="960" height="540" data-skin="dark">
</video>
</body>
</html>
You'll need a playVideo method like the following:
import 'package:flutter/foundation.dart';
import 'package:universal_html/html.dart' as html;
void playVideo(String atUrl) {
if(kIsWeb) {
final v = html.window.document.getElementById('videoPlayer');
if(v != null) {
v.setInnerHtml(
'<source type="video/mp4" src="$atUrl">',
validator: html.NodeValidatorBuilder()
..allowElement('source', attributes: ['src', 'type']));
final a = html.window.document.getElementById( 'triggerVideoPlayer' );
if(a != null) {
a.dispatchEvent(html.MouseEvent('click'));
}
}
} else {
// we're not on the web platform
// and should use the video_player package
}
}
And you'll play the video like this:
playVideo('http://distribution.bbb3d.renderfarming.net/video/mp4/bbb_sunflower_1080p_30fps_normal.mp4');
Before the 10th of December 2019, this method was one of the only ways of playing videos in a Flutter web app. At Flutter Interact 2019 the web support for a couple of packages, including the video_player_web package. The option presented above still work and may serve you better in your use case.
The Flutter video_player plugin now supports web using the video_player_web plugin through federation.
Here is a quote from the Pub page:
To use this plugin in your Flutter Web app, simply add it as a
dependency in your pubspec using a git dependency. This is only
temporary: in the future we hope to make this package an "endorsed"
implementation of video_player, so that it is automatically included
in your Flutter Web app when you depend on package:video_player.
dependencies:
video_player: ^0.10.4
video_player_web:
git:
url: git://github.com/flutter/plugins.git
path: packages/video_player/video_player_web
Once you have the video_player_web dependency in your pubspec, you
should be able to use package:video_player as normal.
the code below worked for me:
Open
[image_picker_for_web / video_player_web] Can't preview PickedFile videos on the web
#58527
void initializeVideo() {
if (_pickedFile != null) {
if (kIsWeb) {
_controller = VideoPlayerController.network(_pickedFile!.path);
} else {
_controller = VideoPlayerController.file(File(_pickedFile!.path));
}
_controller.initialize().then((value) => setState(() {}));
} else {
_controller = VideoPlayerController.file(File(''));
}
}
based on code example above, i updated my code to:
#override
void initState() {
super.initState();
setState(() {
if (kIsWeb) {
controller = VideoPlayerController.network(widget.videoFile.path);
;
} else {
controller = VideoPlayerController.file(widget.videoFile);
}
});
controller.initialize();
controller.play();
controller.setVolume(1);
controller.setLooping(true);
}

I can't receiving notifications when the app is closed or swiped away on huawei device?

I'm using onsignal notifications with my flutter app,I've tested my app on three Samsunge devices and notifcations working perfectly in all these devices when the app on foreground, background, and also when I swiped it away.
after that I tested the app on huawei device which using EMUI 9.0.1 Os
the notifications only works if the app is active or on background
if I swiped it away I can't receiving any notifications.
Any help would be greatly appreciated, I've been struggling with this for a long time. I'll post my code for setting onesignal below
Future<void> initPlatformState() async {
if (!mounted) return;
OneSignal.shared.setLogLevel(OSLogLevel.verbose, OSLogLevel.none);
OneSignal.shared.setRequiresUserPrivacyConsent(true);
OneSignal.shared.consentGranted(true);
var settings = {
OSiOSSettings.autoPrompt: false,
OSiOSSettings.promptBeforeOpeningPushUrl: true
};
OneSignal.shared.setNotificationReceivedHandler((notification) {
this.setState(() {
print('Notifiaction received');
});
});
OneSignal.shared
.setNotificationOpenedHandler((OSNotificationOpenedResult result) {
this.setState(() {
newUrl = result.notification.payload.additionalData['url'].toString();
});
Navigator.of(context).pushReplacement(
MaterialPageRoute(builder: (context) => WebNotification(newUrl)));
});
// NOTE: Replace with your own app ID from https://www.onesignal.com
await OneSignal.shared
.init("xxxx-xxxx-xxxx-xxxx-xxxx", iOSSettings: settings);
OneSignal.shared
.setInFocusDisplayType(OSNotificationDisplayType.notification);
OneSignal.shared.inFocusDisplayType();
}
You need to set up a service extension. Take a look at our docs on Background Notifications. Also, consider Notification Behavior when designing your implementation
make sure you sue latest version of onesignal
for huwaii use HMS if possible ( onesignal support HMS )
In your root build.gradle, under buildscript, add the following 2 new lines to your existing repositories and dependencies sections
buildscript {
repositories {
// ...
maven { url 'https://plugins.gradle.org/m2/' } // Gradle Plugin Portal
}
dependencies {
// ...
// OneSignal-Gradle-Plugin
classpath 'gradle.plugin.com.onesignal:onesignal-gradle-plugin:[0.12.8, 0.99.99]'
}
}
Add the following to the top of your app/build.gradle
apply plugin: 'com.onesignal.androidsdk.onesignal-gradle-plugin'
you need to make user add your app to ignore battry optmztion in huwaii it is (protacted app )
in flutter you can make button and attach it to the app setting ( use these plugin https://pub.dev/packages/app_settings)