Related
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will be integrating Huawei Account, Analytics and Ads kit in StoryApp. Flutter plugin provides simple and convenient way to experience authorization of users. Flutter Account Plugin allows users to connect to the Huawei ecosystem using their Huawei IDs from the different devices such as mobiles phones and tablets, added users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Huawei Ads kit provides access to range of development capabilities. You can promote your apps quickly and more efficiently to Huawei’s vast users. Ads kit helps your app to be monetize quickly and start generating revenue.
Huawei supports following Ads types
Banner
Interstitial
Native
Reward
Splash
Instream(Roll)
Flutter Analytics Plugin provides wider range of predefined analytics models to get more insight into your application users, products, and content. With this insight, you can prepare data-driven approach to market your apps and optimize your products based on the analytics.
With Analytics Kit's on-device data collection SDK, you can:
Collect and report custom events.
Set a maximum of 25 user attributes.
Automate event collection and session calculation.
Pre-set event IDs and parameters.
Restrictions
1. Devices:
a. Analytics Kit depends on HMS Core (APK) to automatically collect the following events: INSTALLAPP (app installation), UNINSTALLAPP (app uninstallation), CLEARNOTIFICATION (data deletion), INAPPPURCHASE (in-app purchase), RequestAd (ad request), DisplayAd (ad display), ClickAd (ad tapping), ObtainAdAward (ad award claiming), SIGNIN (sign-in), and SIGNOUT (sign-out). These events cannot be automatically collected on third-party devices where HMS Core (APK) is not installed (including but not limited to OPPO, vivo, Xiaomi, Samsung, and OnePlus).
b. Analytics Kit does not work on iOS devices.
2. Number of events:
A maximum of 500 events are supported.
3. Number of event parameters:
You can define a maximum of 25 parameters for each event, and a maximum of 100 event parameters for each project.
4. Supported countries/regions
The service is now available only in the countries/regions listed in Supported Countries/Regions.
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create flutter project.
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Root level gradle dependencies
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 3: Add the below permissions in Android Manifest file.
XML:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
Step 4: Download flutter plugins
Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Let's start coding
loginScreen.dart
Code:
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
// TODO: implement initState
HwAds.init();
_enableLog();
_predefinedEvent();
showBannerAd();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUserStoryApp");
await _hmsAnalytics.enableLog();
}
void _predefinedEvent() async {
String name = HAEventType.SIGNIN;
dynamic value = {HAParamType.ENTRY: 06534797};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login Page"),
backgroundColor: Colors.grey[850],
),
body: RefreshIndicator(
onRefresh: showToast,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/logo_huawei.png')),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter valid email id '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
FlatButton(
onPressed: () {
//TODO FORGOT PASSWORD SCREEN GOES HERE
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: FlatButton(
onPressed: () async {
try {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
final bool response =
await AccountAuthService.cancelAuthorization();
}
} on Exception catch (e) {
print(e.toString());
}
} on Exception catch (e) {
print(e.toString());
}
},
child: GestureDetector(
onTap: () async {
try {
final bool response =
await AccountAuthService.cancelAuthorization();
} on Exception catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
),
SizedBox(
height: 5,
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: HuaweiIdAuthButton(
theme: AuthButtonTheme.FULL_TITLE,
buttonColor: AuthButtonBackground.RED,
borderRadius: AuthButtonRadius.MEDIUM,
onPressed: () {
signInWithHuaweiAccount();
}),
),
SizedBox(
height: 30,
),
GestureDetector(
onTap: () {
showBannerAd();
},
child: Text('New User? Create Account'),
),
],
),
),
),
);
}
void showBannerAd() {
BannerAd _bannerAd;
_bannerAd = createBannerAd();
_bannerAd
..loadAd()
..show(gravity: Gravity.bottom, offset: 5);
}
//Create BannerAd
static BannerAd createBannerAd() {
BannerAd banner = BannerAd(
adSlotId: "testw6vs28auh3",
size: BannerAdSize.sSmart,
adParam: AdParam());
banner.setAdListener = (AdEvent event, {int? errorCode}) {
print("Banner Ad event : $event");
};
return banner;
}
void signInWithHuaweiAccount() async {
AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
helper.setAuthorizationCode();
try {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
Future<AuthAccount> account = AccountAuthService.signIn(helper);
account.then((value) => Fluttertoast.showToast(
msg: "Welcome " + value.displayName.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0));
Navigator.push(context, MaterialPageRoute(builder: (_) => Main1()));
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast() async {
Fluttertoast.showToast(
msg: "Refreshing.. ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
BannerAd createAd() {
return BannerAd(
adSlotId: "testw6vs28auh3",
size: BannerAdSize.s468x60,
adParam: AdParam(),
);
}
}
Main.dart
Code:
class Main extends StatefulWidget {
@override
_Main1State createState() => _Main1State();
}
var cardAspectRation = 12.0 / 20.0;
var widgetAspectRatio = cardAspectRation * 1.2;
var verticalInset = 20.0;
class _Main1State extends State<Main1> {
var currentPage = images.length - 1.0;
bool isMenuClosed = true;
late double screenWidth;
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void dispose() {
// SystemChrome.setEnabledSystemUIOverlays(SystemUiOverlay.values);
super.dispose();
}
@override
initState() {
// SystemChrome.setEnabledSystemUIOverlays([]);
super.initState();
_enableLog();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUserStoryApp");
await _hmsAnalytics.enableLog();
}
@override
Widget build(BuildContext context) {
// The initial todos
PageController controller = PageController(initialPage: images.length - 1);
controller.addListener(() {
setState(() {
currentPage = controller.page!;
});
});
Size size = MediaQuery.of(context).size;
screenWidth = size.width;
return Scaffold(
backgroundColor: Colors.grey[850],
body: Stack(
children: <Widget>[
menu(context),
dashboard(context),
],
),
);
}
Widget menu(context) {
return Padding(
padding: EdgeInsets.fromLTRB(0, 0, screenWidth * 0.15, 0),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Flexible(
flex: 4,
child: Container(
color: Colors.grey[850],
child: Align(
alignment: Alignment.center,
child: circularImage(),
),
),
),
Flexible(
flex: 6,
child: Container(
child: Row(
children: <Widget>[
Flexible(
child: Column(
children: <Widget>[
Flexible(
child: GestureDetector(
onTap: () {
print("Clicked on Ads");
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => SecondScreen()));
},
child: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(218, 107, 107, 1),
borderRadius: new BorderRadius.only(
topLeft: const Radius.circular(80.0))),
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.headset,
color: Colors.white,
size: 50,
),
Text('Ads',
style: TextStyle(
color: Colors.white, fontSize: 22))
],
),
),
),
),
),
Flexible(
child: GestureDetector(
onTap: () {
print("Clicked on browse");
},
child: Container(
color: Color.fromRGBO(211, 96, 96, 1),
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.satellite,
color: Colors.white,
size: 50,
),
Text('Browse',
style: TextStyle(
color: Colors.white, fontSize: 22))
],
),
),
),
),
)
],
),
),
Flexible(
child: Column(
children: <Widget>[
Flexible(
child: GestureDetector(
onTap: () {
print("Clicked on Analytics");
sendCustomEvent();
},
child: Container(
decoration: new BoxDecoration(
color: Color.fromRGBO(211, 96, 96, 1),
borderRadius: new BorderRadius.only(
topRight: const Radius.circular(80.0))),
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.assignment,
color: Colors.white,
size: 50,
),
Text('Analytics',
style: TextStyle(
color: Colors.white, fontSize: 22))
],
),
),
),
),
),
Flexible(
child: GestureDetector(
onTap: () {
print("Clicked on settings");
},
child: Container(
color: Color.fromRGBO(218, 107, 107, 1),
child: Align(
alignment: Alignment.center,
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.settings,
color: Colors.white,
size: 50,
),
Text('Settings',
style: TextStyle(
color: Colors.white, fontSize: 22))
],
),
),
),
),
)
],
),
)
],
),
),
)
],
),
);
}
Widget dashboard(context) {
return AnimatedPositioned(
//top: isMenuClosed? 0 : 100,
//bottom: isMenuClosed? 0 : 100,
top: 0,
bottom: 0,
left: isMenuClosed ? 0 : screenWidth - screenWidth * 0.15,
right: isMenuClosed ? 0 : -90,
duration: Duration(milliseconds: 300),
child: Material(
elevation: 8,
color: Colors.grey[850],
child: Padding(
padding: EdgeInsets.fromLTRB(10, 30, 10, 10),
child: Column(
children: <Widget>[
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: <Widget>[
InkWell(
child: Icon(
Icons.segment,
color: Colors.white,
size: 40,
),
onTap: () {
setState(() {
isMenuClosed = !isMenuClosed;
});
},
),
Icon(
Icons.search_outlined,
color: Colors.white,
size: 40,
),
],
),
Text("Trending",
style: TextStyle(fontSize: 28, color: Colors.white)),
CardScrollWidget(currentPage),
],
),
),
),
);
}
Widget circularImage() {
return Container(
width: 200.0,
height: 200.0,
decoration: new BoxDecoration(
shape: BoxShape.circle,
border: Border.all(
color: Colors.teal, width: 10.0, style: BorderStyle.solid),
image: new DecorationImage(
fit: BoxFit.cover, image: AssetImage("images/logo_huawei.png"))),
);
}
void sendCustomEvent() async {
String value = "This is custom event from app";
dynamic eventData = {'Message': value};
await _hmsAnalytics.onEvent("CustomEvent", eventData);
print("Event posted");
}
}
class CardScrollWidget extends StatelessWidget {
var currentPage;
var padding = 20.0;
CardScrollWidget(this.currentPage);
@override
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: widgetAspectRatio,
child: LayoutBuilder(
builder: (context, constraints) {
var width = constraints.maxWidth;
var height = constraints.maxHeight;
var safeWidth = width - 2 * padding;
var safeHeight = height - 2 * padding;
var heightOfPrimaryCard = safeHeight;
var widthOfPrimaryCard = heightOfPrimaryCard * cardAspectRation;
var primaryCardLeft = safeWidth - widthOfPrimaryCard;
var horizontalInset = primaryCardLeft / 2;
List<Widget> cardList = [];
for (var i = 0; i < images.length; i++) {
var delta = i - currentPage;
bool isOnRight = delta > 0;
var start = padding +
max(
primaryCardLeft -
horizontalInset * -delta * (isOnRight ? 15 : 1),
0.0);
var cardItem = Positioned.directional(
top: padding + verticalInset * max(-delta, 0.0),
bottom: padding + verticalInset * max(-delta, 0.0),
start: start,
textDirection: TextDirection.rtl,
child: ClipRRect(
borderRadius: BorderRadius.circular(16.0),
child: Container(
decoration: BoxDecoration(color: Colors.white, boxShadow: [
BoxShadow(
color: Colors.black12,
offset: Offset(3.0, 6.0),
blurRadius: 10.0)
]),
child: AspectRatio(
aspectRatio: cardAspectRation,
child: Stack(
fit: StackFit.expand,
children: <Widget>[
Image.asset(images[i], fit: BoxFit.cover),
Align(
alignment: Alignment.bottomLeft,
child: Column(
mainAxisSize: MainAxisSize.min,
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
Container(
decoration: BoxDecoration(
color: Colors.black45,
borderRadius: BorderRadius.circular(20.0)),
child: Padding(
padding: EdgeInsets.symmetric(
horizontal: 16.0, vertical: 8.0),
child: Text(title[i],
style: TextStyle(
color: Colors.white,
fontSize: 25.0,
fontFamily: "SF-Pro-Text-Regular")),
),
),
SizedBox(
height: 10.0,
),
Padding(
padding: const EdgeInsets.only(
left: 12.0, bottom: 12.0),
child: Container(
padding: EdgeInsets.symmetric(
horizontal: 22.0, vertical: 6.0),
decoration: BoxDecoration(
color: Colors.blueAccent,
borderRadius:
BorderRadius.circular(20.0)),
child: GestureDetector(
onTap: () {
print("FFFFFF");
},
child: Text(
"Read more..",
style: TextStyle(color: Colors.white),
),
),
),
)
],
),
)
],
),
),
),
),
);
cardList.add(cardItem);
}
return Stack(
children: cardList,
);
},
),
);
}
}
Result
Tricks and Tips
Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion
In this article, we have learnt how to integrate Account kit, Analytics and Ads kit into Huawei StoryApp for flutter. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission. Analytics helps you to analyse the user behaviour and Ads kit helps you to monetize the app.
Thank you so much for reading, I hope thiis article helps you to understand the integration of Huawei Account kit, Ads kit and Analytics kit in flutter.
Reference
Ads Kit
Analytics Kit
Ads Kit – Training Video
Analytics Kit – Training Video
Checkout in forum
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will be integrating Huawei Account, Banner and Splash Ads kit in Flutter StoryApp. Flutter plugin provides simple and convenient way to experience authorization of users. Flutter Account Plugin allows users to connect to the Huawei ecosystem using their Huawei IDs from the different devices such as mobiles phones and tablets, added users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Huawei Ads kit provides access to range of development capabilities. You can promote your apps quickly and more efficiently to Huawei’s vast users. Ads kit helps your app to monetize quickly and start generating revenue.
Huawei supports following Ads
Banner
Interstitial
Native
Reward
Splash
Instream(Roll)
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
A Huawei phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create Flutter project.
Step 2: Add the App level gradle dependencies.
Choose inside project Android > app > build.gradle.
[/B]
[CODE]apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'[/CODE]
[B]Root level gradle [/B]dependencies
[CODE]maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'[/CODE]
[B]
Step 3: Add the below permissions in Android Manifest file.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
<uses-permission android:name="com.huawei.appmarket.service.commondata.permission.GET_COMMON_DATA"/>
Step 4: Download flutter plugins
Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Let's start coding
loginScreen.dart
Code:
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
HwAds.init();
showSplashAd();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login Page"),
backgroundColor: Colors.grey[850],
),
body: RefreshIndicator(
onRefresh: showToast,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/logo_huawei.png')),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter valid email id '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
FlatButton(
onPressed: () {
//TODO FORGOT PASSWORD SCREEN GOES HERE
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: FlatButton(
onPressed: () async {
try {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
final bool response =
await AccountAuthService.cancelAuthorization();
}
} on Exception catch (e) {
print(e.toString());
}
} on Exception catch (e) {
print(e.toString());
}
},
child: GestureDetector(
onTap: () async {
try {
final bool response =
await AccountAuthService.cancelAuthorization();
} on Exception catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
),
SizedBox(
height: 5,
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: HuaweiIdAuthButton(
theme: AuthButtonTheme.FULL_TITLE,
buttonColor: AuthButtonBackground.RED,
borderRadius: AuthButtonRadius.MEDIUM,
onPressed: () {
signInWithHuaweiAccount();
}),
),
SizedBox(
height: 30,
),
GestureDetector(
onTap: () {
//showBannerAd();
},
child: Text('New User? Create Account'),
),
],
),
),
),
);
}
void signInWithHuaweiAccount() async {
AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
helper.setAuthorizationCode();
try {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
Future<AuthAccount> account = AccountAuthService.signIn(helper);
account.then((value) => Fluttertoast.showToast(
msg: "Welcome " + value.displayName.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0));
Navigator.push(
context, MaterialPageRoute(builder: (_) => StoryListScreen()));
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast() async {
Fluttertoast.showToast(
msg: "Refreshing.. ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
//Show Splash Ad
void showSplashAd() {
SplashAd _splashAd = createSplashAd();
_splashAd
..loadAd(
adSlotId: "testq6zq98hecj",
orientation: SplashAdOrientation.portrait,
adParam: AdParam(),
topMargin: 20);
Future.delayed(Duration(seconds: 10), () {
_splashAd.destroy();
});
}
SplashAd createSplashAd() {
SplashAd _splashAd = new SplashAd(
adType: SplashAdType.above,
ownerText: ' Huawei SplashAd',
footerText: 'Test SplashAd',
); // Splash Ad
return _splashAd;
}
}
storyListScreen.dart
Code:
class StoryListScreen extends StatefulWidget {
@override
_StoryListScreenState createState() => _StoryListScreenState();
}
class _StoryListScreenState extends State<StoryListScreen> {
final _itemExtent = 56.0;
final generatedList = List.generate(22, (index) => 'Item $index');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stories'),
),
backgroundColor: Colors.white,
body: CustomScrollView(
controller: ScrollController(initialScrollOffset: _itemExtent * 401),
slivers: [
SliverFixedExtentList(
itemExtent: _itemExtent,
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
margin: EdgeInsets.only(left: 12, right: 12, top: 5, bottom: 5),
child: Center(
child: GestureDetector(
onTap: () {
showStory(index);
},
child: ListTile(
title: Text(
storyTitles[index],
style: TextStyle(
fontSize: 22.0, fontWeight: FontWeight.bold),
),
),
),
),
),
childCount: storyTitles.length,
),
),
],
),
);
}
void showStory(int index) {
print(storyTitles[index] + " Index :" + index.toString());
Navigator.push(
context, MaterialPageRoute(builder: (_) => StoryDetails(index)));
}
}
storyDetails.dart
Code:
class StoryDetails extends StatefulWidget {
int index;
StoryDetails(this.index);
@override
_StoryDetailsState createState() => new _StoryDetailsState(index);
}
class _StoryDetailsState extends State<StoryDetails> {
int index;
BannerAd? _bannerAd = null;
_StoryDetailsState(this.index);
@override
void initState() {
// TODO: implement initState
super.initState();
showBannerAd();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
appBar: AppBar(
title: Text(storyTitles[index]),
),
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 5, right: 5, top: 3, bottom: 50),
child: Column(children: <Widget>[
Card(
child: Image.asset(
"images/image_0" + index.toString() + ".png"),
),
Card(
child: Text(
storyDetails[index],
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 20),
)),
Center(
child: Image.asset(
"images/greeting.gif",
height: 320.0,
width: 620.0,
),
),
]),
),
),
)),
);
}
void showBannerAd() {
_bannerAd = createBannerAd();
_bannerAd!
..loadAd()
..show(gravity: Gravity.bottom, offset: 1);
}
//Create BannerAd
static BannerAd createBannerAd() {
BannerAd banner = BannerAd(
adSlotId: "testw6vs28auh3",
size: BannerAdSize.sSmart,
adParam: AdParam());
banner.setAdListener = (AdEvent event, {int? errorCode}) {
print("Banner Ad event : $event " + banner.id.toString());
};
return banner;
}
Future<bool> _onBackPressed() async {
if (_bannerAd != null) {
_bannerAd?.destroy();
}
return true;
}
}
Result
Tricks and Tips
Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion
we have learnt how to integrate Huawei Account kit and Huawei Banner and Splash Ads in Flutter StoryApp. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission. Banner and Splash Ads helps you to monetize your StoryApp.
Thank you so much for reading, and also I would like to 'thanks author for write-ups'. I hope this article helps you to understand the integration of Huawei Account kit, Huawei Banner and Splash Ads in flutter StoryApp.
Reference
Ads Kit
StoryAuthors: https://momlovesbest.com/short-moral-stories-kids
Ads Kit – Training Video
Account Kit – Training Video
Checkout in forum
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will be integrating Huawei ML kit in Flutter StoryApp to listen stories using ML kit Text To Speech (TTS). ML Kit provides diversified leading machine learning capabilities that are easy to use, helping you to develop various AI apps. ML Kit allows your apps to easily leverage Huawei's long-term proven expertise in machine learning to support diverse artificial intelligence (AI) applications throughout a wide range of industries.
In this flutter sample application, we are using Language/Voice-related services, services are as follows.
Real-time translation: Translates text from the source language into the target language through the server on the cloud.
On-device translation: Translates text from the source language into the target language with the support of an on-device model, even when no Internet service is available.
Real-time language detection: Detects the language of text online. Both single-language text and multi-language text are supported.
On-device language detection: Detects the language of text without Internet connection. Both single-language text and multi-language text are supported.
Automatic speech recognition: Converts speech (no longer than 60 seconds) into text in real time.
Automatic speech recognition: Converts speech (no longer than 60 seconds) into text in real time.
Text to speech: Converts text information into audio output online in real time. Rich timbres, and volume and speed options are supported to produce more natural sounds.
On-device text to speech: Converts text information into speech with the support of an on-device model, even when there is no Internet connection.
Audio file transcription: Converts an audio file (no longer than 5 hours) into text. The generated text contains punctuation and timestamps. Currently, the service supports Chinese and English.
Real-time transcription: Converts speech (no longer than 5 hours) into text in real time. The generated text contains punctuation and timestamps.
Sound detection: Detects sound events in online (real-time recording) mode. The detected sound events can help you perform subsequent actions.
Supported Devices
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
Android phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create Flutter project.
Step 2: Add the App level gradle dependencies.
Choose inside project Android > app > build.gradle.
[/B]
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
[B]
Root level gradle dependencies
[/B]
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
[B]
Step 3: Add the below permissions in Android Manifest file.
[/B]
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
[B]
Step 4: Download flutter plugins
Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies. Add path location for asset image.
Let's start coding
loginScreen.dart
[/B][/B]
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
HwAds.init();
showSplashAd();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login Page"),
backgroundColor: Colors.grey[850],
),
body: RefreshIndicator(
onRefresh: showToast,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/logo_huawei.png')),
),
),
Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter valid email id '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
FlatButton(
onPressed: () {
//TODO FORGOT PASSWORD SCREEN GOES HERE
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: FlatButton(
onPressed: () async {
try {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
final bool response =
await AccountAuthService.cancelAuthorization();
}
} on Exception catch (e) {
print(e.toString());
}
} on Exception catch (e) {
print(e.toString());
}
},
child: GestureDetector(
onTap: () async {
try {
final bool response =
await AccountAuthService.cancelAuthorization();
} on Exception catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
),
SizedBox(
height: 5,
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.red, borderRadius: BorderRadius.circular(20)),
child: HuaweiIdAuthButton(
theme: AuthButtonTheme.FULL_TITLE,
buttonColor: AuthButtonBackground.RED,
borderRadius: AuthButtonRadius.MEDIUM,
onPressed: () {
signInWithHuaweiAccount();
}),
),
SizedBox(
height: 30,
),
GestureDetector(
onTap: () {
//showBannerAd();
},
child: Text('New User? Create Account'),
),
],
),
),
),
);
}
void signInWithHuaweiAccount() async {
AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
helper.setAuthorizationCode();
try {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
Future<AuthAccount> account = AccountAuthService.signIn(helper);
account.then((value) => Fluttertoast.showToast(
msg: "Welcome " + value.displayName.toString(),
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.red,
textColor: Colors.white,
fontSize: 16.0));
Navigator.push(
context, MaterialPageRoute(builder: (_) => StoryListScreen()));
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast() async {
Fluttertoast.showToast(
msg: "Refreshing.. ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
//Show Splash Ad
void showSplashAd() {
SplashAd _splashAd = createSplashAd();
_splashAd
..loadAd(
adSlotId: "testq6zq98hecj",
orientation: SplashAdOrientation.portrait,
adParam: AdParam(),
topMargin: 20);
Future.delayed(Duration(seconds: 10), () {
_splashAd.destroy();
});
}
SplashAd createSplashAd() {
SplashAd _splashAd = new SplashAd(
adType: SplashAdType.above,
ownerText: ' Huawei SplashAd',
footerText: 'Test SplashAd',
); // Splash Ad
return _splashAd;
}
}
[B][B]
storyListScreen.dart
[/B][/B][/B]
class StoryListScreen extends StatefulWidget {
@override
_StoryListScreenState createState() => _StoryListScreenState();
}
class _StoryListScreenState extends State<StoryListScreen> {
final _itemExtent = 56.0;
final generatedList = List.generate(22, (index) => 'Item $index');
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Stories'),
),
backgroundColor: Colors.white,
body: CustomScrollView(
controller: ScrollController(initialScrollOffset: _itemExtent * 401),
slivers: [
SliverFixedExtentList(
itemExtent: _itemExtent,
delegate: SliverChildBuilderDelegate(
(context, index) => Card(
margin: EdgeInsets.only(left: 12, right: 12, top: 5, bottom: 5),
child: Center(
child: GestureDetector(
onTap: () {
showStory(index);
},
child: ListTile(
title: Text(
storyTitles[index],
style: TextStyle(
fontSize: 22.0, fontWeight: FontWeight.bold),
),
),
),
),
),
childCount: storyTitles.length,
),
),
],
),
);
}
void showStory(int index) {
print(storyTitles[index] + " Index :" + index.toString());
Navigator.push(
context, MaterialPageRoute(builder: (_) => StoryDetails(index)));
}
}
[B][B][B]
storyDetails.dart
[/B][/B][/B][/B]
class StoryDetails extends StatefulWidget {
int index;
StoryDetails(this.index);
@override
_StoryDetailsState createState() => new _StoryDetailsState(index);
}
class _StoryDetailsState extends State<StoryDetails> {
int index = 0;
MLTtsEngine? engine = null;
bool toggle = false;
BannerAd? _bannerAd = null;
bool isPaused = false;
_StoryDetailsState(this.index);
@override
void initState() {
// TODO: implement initState
initML();
showBannerAd();
super.initState();
}
@override
Widget build(BuildContext context) {
return WillPopScope(
onWillPop: _onBackPressed,
child: Scaffold(
appBar: AppBar(
title: Text(storyTitles[index]),
actions: <Widget>[
IconButton(
icon: toggle
? Icon(Icons.pause_circle_filled_outlined)
: Icon(
Icons.play_circle_fill_outlined,
),
onPressed: () {
setState(() {
// Here we changing the icon.
toggle = !toggle;
if (toggle) {
if (!isPaused) {
// do something
print("......Play.....");
final stream = storyDetails[index].splitStream(
chunkSize: 499,
splitters: [','],
delimiters: [r'\'],
);
play(stream);
} else {
MLTtsEngine().resume();
isPaused = false;
}
} else {
isPaused = true;
MLTtsEngine().pause();
}
});
}),
],
),
backgroundColor: Colors.white,
body: SafeArea(
child: SingleChildScrollView(
child: Padding(
padding: EdgeInsets.only(left: 5, right: 5, top: 3, bottom: 50),
child: Column(children: <Widget>[
Card(
child: Image.asset(
"images/image_0" + index.toString() + ".png"),
),
Card(
child: Text(
storyDetails[index],
style: TextStyle(
color: Colors.black,
fontWeight: FontWeight.normal,
fontSize: 20),
)),
Center(
child: Image.asset(
"images/greeting.gif",
height: 320.0,
width: 620.0,
),
),
]),
),
),
)),
);
}
void showBannerAd() {
_bannerAd = createBannerAd();
_bannerAd!
..loadAd()
..show(gravity: Gravity.bottom, offset: 1);
}
//Create BannerAd
static BannerAd createBannerAd() {
BannerAd banner = BannerAd(
adSlotId: "testw6vs28auh3",
size: BannerAdSize.sSmart,
adParam: AdParam());
banner.setAdListener = (AdEvent event, {int? errorCode}) {
print("Banner Ad event : $event " + banner.id.toString());
};
return banner;
}
Future<bool> _onBackPressed() async {
if (_bannerAd != null) {
_bannerAd?.destroy();
}
if (engine != null) {
engine!.stop();
}
return true;
}
Future<void> playStory(String parts) async {
// Create MLTtsConfig to configure the speech.
final config = MLTtsConfig(
language: MLTtsConstants.TTS_EN_US,
synthesizeMode: MLTtsConstants.TTS_ONLINE_MODE,
text: parts,
);
// Create an MLTtsEngine object.
engine = new MLTtsEngine();
// Set a listener to track tts events.
engine?.setTtsCallback(MLTtsCallback(
onError: _onError,
onEvent: _onEvent,
onAudioAvailable: _onAudioAvailable,
onRangeStart: _onRangeStart,
onWarn: _onWarn,
));
// Start the speech.
await engine?.speak(config);
}
void _onError(String taskId, MLTtsError err) {
print(err.errorMsg);
}
void _onEvent(String taskId, int eventId) {
}
void _onAudioAvailable(
String taskId, MLTtsAudioFragment audioFragment, int offset) {
}
void _onRangeStart(String taskId, int start, int end) {
}
void _onWarn(String taskId, MLTtsWarn warn) {
}
Future<void> initML() async {
MLLanguageApp().setApiKey(
"DAED8900[p0-tu7au4ZHZuWDrR7oKps/WybCAJ0IOi7UdLfIlsIu9C4pEw0OSNA==");
}
Future<void> play(Stream<List<String>> stream) async {
int i = 0;
await for (List<String> parts in stream) {
// print(parts);
if (i == 0) {
playStory(parts.toString());
}
i++;
}
}
}
[B][B][B][B]
Result
Tricks and Tips
Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Make sure that permissions are added in Manifest file.
Conclusion
In this article, we have learnt how to integrate Huawei ML kit Text to Speech in Flutter StoryApp. It supports maximum of 500 character for one request to convert Text to Speech. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission. Banner and Splash Ads helps you to monetize your StoryApp.
Thank you so much for reading, and also I would like to ‘thanks author for write-ups’. I hope this article helps you to understand the integration of Huawei ML Kit, Banner and Splash Ads in flutter StoryApp.
Reference
ML Kit Text To Speech
StoryAuthors : https://momlovesbest.com/short-moral-stories-kids
Account Kit – Training Video
ML Kit – Training Video
Checkout in forum
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will be integrating Huawei Account and Analytics kit in Flutter DietApp. Flutter plugin provides simple and convenient way to experience authorization of users. Flutter Account Plugin allows users to connect to the Huawei ecosystem using their Huawei IDs from the different devices such as mobiles phones and tablets, added users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Huawei Analytics is a one-stop solution to get user behavior analysis in different platforms for all yours products such as mobile apps, web apps and quick apps. It helps developers to get detailed analysis report and also provides crash reports by default. It offers scenario-specific data collection, management, analysis, and usage, helping enterprises to achieve effective user acquisition, product optimization, precise operations, and business growth.
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
Android phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create Flutter project.
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
[/B][/B]
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
[B][B]
Root level gradle dependencies
[/B][/B]
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
[B][B]
Step 3: Add the below permissions in Android Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
Step 4: Download flutter plugins
Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Let's start coding
loginScreen.dart
[/B]
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
_enableLog();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUserDietApp");
await _hmsAnalytics.enableLog();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
backgroundColor: Colors.grey[850],
),
body: RefreshIndicator(
onRefresh: showToast,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 90.0),
child: Center(
child: Container(
width: 220,
height: 165,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/logo_huawei.png')),
),
),
Padding(
padding: EdgeInsets.only(
left: 40.0, right: 40.0, top: 15, bottom: 0),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter valid email id '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 40.0, right: 40.0, top: 10, bottom: 0),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
FlatButton(
onPressed: () {
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(20)),
child: FlatButton(
onPressed: () async {
try {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
final bool response =
await AccountAuthService.cancelAuthorization();
}
} on Exception catch (e) {
print(e.toString());
}
} on Exception catch (e) {
print(e.toString());
}
},
child: GestureDetector(
onTap: () async {
try {
final bool response =
await AccountAuthService.cancelAuthorization();
} on Exception catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 22),
),
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(5)),
child: HuaweiIdAuthButton(
theme: AuthButtonTheme.FULL_TITLE,
buttonColor: AuthButtonBackground.RED,
borderRadius: AuthButtonRadius.MEDIUM,
onPressed: () {
signInWithHuaweiID();
}),
),
SizedBox(
height: 30,
),
],
),
),
),
);
}
void signInWithHuaweiID() async {
AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
String name = '';
helper.setAuthorizationCode();
try {
Future<AuthAccount> account = AccountAuthService.signIn();
account.then((value) => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MyHomePage(
title: '' + value.displayName.toString(),
))));
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast() async {
Fluttertoast.showToast(
msg: "Refreshing.. ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
}
[B]
main.dart
[/B][/B][/B][/B][/B][/B]
[B][B][B][B]void main() {
runApp(const 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) {
return MaterialApp(
title: 'Exercise&DietApp',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Wel come ',
),
Text(
widget.title.toString(),
style: Theme.of(context).textTheme.headline4,
),
],
),
),
}
}
[B][B]
Result
Tricks and Tips
Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion
In this article, we have learnt how to integrate Huawei Account kit in Flutter DietApp. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Account kit, in flutter DietApp.
Reference
Account Kit – Training Video
Checkout in forum
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Introduction
In this article, we will be integrating Huawei Account, Push kit and Analytics kit in Flutter DietApp. Flutter plugin provides simple and convenient way to experience authorization of users. Flutter Account Plugin allows users to connect to the Huawei ecosystem using their Huawei IDs from the different devices such as mobiles phones and tablets, added users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission.
Huawei Push kit is a messaging service provided for you. It establishes a messaging channel from the cloud to devices. By integrating Push Kit, you can send messages to your apps on user’s devices in real time. This helps you to maintain closer ties with users and increases user awareness and engagement with your apps.
Huawei Analytics is a one-stop solution to get user behaviour analysis in different platforms for all yours products such as mobile apps, web apps and quick apps. It helps developers to get detailed analysis report and also provides crash reports by default. It offers scenario-specific data collection, management, analysis, and usage, helping enterprises to achieve effective user acquisition, product optimization, precise operations, and business growth.
Previous article
Please check my previous article if you have not gone through, click on link.
Development Overview
You need to install Flutter and Dart plugin in IDE and I assume that you have prior knowledge about the Flutter and Dart.
Hardware Requirements
A computer (desktop or laptop) running Windows 10.
Android phone (with the USB cable), which is used for debugging.
Software Requirements
Java JDK 1.7 or later.
Android studio software or Visual Studio or Code installed.
HMS Core (APK) 4.X or later.
Integration process
Step 1: Create Flutter project.
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
[/B][/B]
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
[B][B]
Root level gradle dependencies
[/B][/B][/B]
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
[B][B][B]
Step 3: Add the below permissions in Android Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
Step 4: Download flutter push kit plugins
Step 5: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Let's start coding
loginScreen.dart
[/B][/B]
class LoginScreen extends StatelessWidget {
const LoginScreen({Key? key}) : super(key: key);
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
_enableLog();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUserDietApp");
await _hmsAnalytics.enableLog();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login"),
backgroundColor: Colors.grey[850],
),
body: RefreshIndicator(
onRefresh: showToast,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 90.0),
child: Center(
child: Container(
width: 220,
height: 165,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/logo_huawei.png')),
),
),
Padding(
padding: EdgeInsets.only(
left: 40.0, right: 40.0, top: 15, bottom: 0),
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Email',
hintText: 'Enter valid email id '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 40.0, right: 40.0, top: 10, bottom: 0),
child: TextField(
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter password'),
),
),
FlatButton(
onPressed: () {
//TODO FORGOT PASSWORD SCREEN GOES HERE
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(20)),
child: FlatButton(
onPressed: () async {
try {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
final bool response =
await AccountAuthService.cancelAuthorization();
}
} on Exception catch (e) {
print(e.toString());
}
} on Exception catch (e) {
print(e.toString());
}
},
child: GestureDetector(
onTap: () async {
try {
final bool response =
await AccountAuthService.cancelAuthorization();
} on Exception catch (e) {
print(e.toString());
}
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 22),
),
),
),
),
SizedBox(
height: 20,
),
Container(
height: 50,
width: 270,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(5)),
child: HuaweiIdAuthButton(
theme: AuthButtonTheme.FULL_TITLE,
buttonColor: AuthButtonBackground.RED,
borderRadius: AuthButtonRadius.MEDIUM,
onPressed: () {
signInWithHuaweiID();
}),
),
SizedBox(
height: 30,
),
GestureDetector(
onTap: () {
//showBannerAd();
},
child: Text('New User? Create Account'),
),
],
),
),
),
);
}
void signInWithHuaweiID() async {
AccountAuthParamsHelper helper = new AccountAuthParamsHelper();
String name = '';
helper.setAuthorizationCode();
try {
// The sign-in is successful, and the user's ID information and authorization code are obtained.
Future<AuthAccount> account = AccountAuthService.signIn();
account.then(
(value) => Navigator.push(
context,
MaterialPageRoute(
builder: (_) => MyHomePage(
title: '' + value.displayName.toString(),
),
),
),
);
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast() async {
Fluttertoast.showToast(
msg: "Refreshing.. ",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
}
[B][B]
main.dart
[/B][/B][/B]
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Exercise&DietApp',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: SplashScreen(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key? key, required this.title}) : super(key: key);
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late String gender = '', dietPlan, activeLevel;
late double? age, height, weight, tagetWeight;
TextEditingController ageController = TextEditingController();
TextEditingController heightController = TextEditingController();
TextEditingController weightController = TextEditingController();
TextEditingController targetWeightController = TextEditingController();
late SharedPreferences prefs;
String _genderLabel = "Male";
String _dietLabel = "Veg";
String _activeLable = "Low Active";
final _genderList = ["Male", "Women"];
final _dietPlanList = ["Veg", "Veg-Non Veg", "Egg"];
final _activeLevelList = ["Low Active", "Mid-Active", "Very Active"];
String _token = '';
void initState() {
super.initState();
initPreferences();
initTokenStream();
}
Future<void> initTokenStream() async {
if (!mounted) return;
Push.getTokenStream.listen(_onTokenEvent, onError: _onTokenError);
getToken();
}
void getToken() async {
// Call this method to request for a token
Push.getToken("");
}
void _onTokenEvent(String event) {
// Requested tokens can be obtained here
setState(() {
_token = event;
print("TokenEvent: " + _token);
});
}
void _onTokenError(Object error) {
print("TokenErrorEvent: " + error.toString());
PlatformException? e = error as PlatformException?;
}
@override
Widget build(BuildContext context) {
return SafeArea(
child: Scaffold(
resizeToAvoidBottomInset: true,
appBar: AppBar(
title: Text(widget.title.toString()),
automaticallyImplyLeading: false,
),
body: Center(
child: SingleChildScrollView(
reverse: true,
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 0.0),
child: Center(
child: Container(
width: 120,
height: 120,
decoration: BoxDecoration(
color: Colors.black,
borderRadius: BorderRadius.circular(60.0)),
child: Image.asset('images/nu_icon.png')),
),
),
Padding(
padding: const EdgeInsets.only(
left: 22.0, right: 22.0, top: 15, bottom: 0),
child: TextField(
controller: ageController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Age',
hintText: 'Enter valid age '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 22.0, right: 22.0, top: 15, bottom: 0),
child: TextField(
controller: heightController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Height',
hintText: 'Enter height '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 22.0, right: 22.0, top: 15, bottom: 0),
child: TextField(
controller: weightController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Weight',
hintText: 'Enter Weight '),
),
),
Padding(
padding: const EdgeInsets.only(
left: 22.0, right: 22.0, top: 15, bottom: 0),
child: TextField(
controller: targetWeightController,
decoration: const InputDecoration(
border: OutlineInputBorder(),
labelText: 'Target Weight',
hintText: 'Enter target Weight '),
),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
const Text('Gender :'),
DropdownButton(
items: _genderList
.map((String item) => DropdownMenuItem<String>(
child: SizedBox(
height: 22,
width: 100,
child: Text(item,
style: TextStyle(fontSize: 20))),
value: item))
.toList(),
onChanged: (value) {
setState(() {
_genderLabel = value.toString();
gender = value.toString();
});
},
value: _genderLabel,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Diet Plan :'),
DropdownButton(
items: _dietPlanList
.map((String item) => DropdownMenuItem<String>(
child: SizedBox(
height: 22,
width: 100,
child: Text(item,
style: TextStyle(fontSize: 20))),
value: item))
.toList(),
onChanged: (value) {
setState(() {
_dietLabel = value.toString();
dietPlan = value.toString();
print('Diet plan changed to $value');
});
},
value: _dietLabel,
)
],
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Text('Active Level :'),
DropdownButton(
items: _activeLevelList
.map((String item) => DropdownMenuItem<String>(
child: SizedBox(
height: 22,
width: 100,
child: Text(item,
style: TextStyle(fontSize: 20))),
value: item))
.toList(),
onChanged: (value) {
setState(() {
activeLevel = value.toString();
_activeLable = value.toString();
print('Active level changed to $value');
});
},
value: _activeLable,
)
],
)
,
Padding(
padding: const EdgeInsets.only(
left: 22.0, right: 22.0, top: 20, bottom: 0),
child: MaterialButton(
child: const Text(
'Submit',
style: TextStyle(
fontSize: 22,
color: Colors.white,
fontWeight: FontWeight.w300),
),
height: 45,
minWidth: 140,
color: Colors.lightBlue,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(10.0),
),
onPressed: () {
print('Button clicked.....');
age = double.parse(ageController.text);
height = double.parse(heightController.text);
weight = double.parse(weightController.text);
tagetWeight = double.parse(targetWeightController.text);
storeDataLocally();
},
),
),
],
),
),
),
),
);
}
Future<void> storeDataLocally() async {
prefs.setString("name", widget.title.toString());
prefs.setDouble("age", age!);
prefs.setDouble("height", height!);
prefs.setString("gender", gender.toString());
prefs.setDouble("weight", weight!);
prefs.setString("dietPlan", dietPlan);
prefs.setDouble("targetWeight", tagetWeight!);
prefs.setString("activeLevel", activeLevel);
}
Future<void> initPreferences() async {
prefs = await SharedPreferences.getInstance();
showData();
}
void showData() {
if (prefs.getDouble('age').toString() != null) {
ageController.text = prefs.getDouble('age').toString();
heightController.text = prefs.getDouble('height').toString();
targetWeightController.text = prefs.getDouble('targetWeight').toString();
genderController.text = prefs.getString('gender').toString();
dietPlanController.text = prefs.getString('dietPlan').toString();
activeLevelPlanController.text =
prefs.getString('activeLevel').toString();
}
}
}
[B][B][B]
Result
Tricks and Tips
Make sure that downloaded plugin is unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Make sure that service is enabled in agc.
Makes sure images are defined in yaml file.
Conclusion
In this article, we have learnt how to integrate Huawei Account kit, Push kit and Analytics kit in Flutter DietApp. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission. Push kit enables you to send push notification to user device in real time, you can see the push notification in the result part.
Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Account kit, Push kit and Analytics kit in flutter DietApp.
Reference
Push Kit - Training Video
Account Kit – Training Video
Checkout in forum