{
"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
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.
Integration process
1. Create flutter project
Step 2: Add the App level gradle dependencies. Choose inside project Android > app > build.gradle
Java:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Add root level gradle dependencies
Java:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Add app level gradle dependencies
Java:
implementation 'com.huawei.hms:hianalytics:5.1.0.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: Flutter plugin for Huawei analytics kit.
Unzip downloaded plugin in the parent directory of the project.
Step 5: Declare plugin path in pubspec.yaml file under dependencies.
Step 5 : Create a project in AppGallery Connect.
pubspec.yaml
YAML:
<p style="margin-top: 20.0px;white-space: normal;">name: flutter_app
</p><p style="margin-top: 20.0px;white-space: normal;">description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_analytics:
path: ../huawei_analytics/
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# The following section is specific to Flutter.
flutter:</p>
main.dart
Code:
import 'package:flutter/material.dart';
import 'package:flutter_app/result.dart';
import 'package:huawei_analytics/huawei_analytics.dart';
import './quiz.dart';
import './result.dart';
void main() => runApp(MyApp());
class MyApp extends StatefulWidget {
@override
State<StatefulWidget> createState() {
return _MyAppState();
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
int _totalScore = 0;
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
@override
void initState() {
_enableLog();
_predefinedEvent();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("TestUser123");
await _hmsAnalytics.enableLog();
}
void _restartQuiz() {
setState(() {
_questionIndex = 0;
_totalScore = 0;
});
}
void _predefinedEvent() async {
String name = HAEventType.SIGNIN;
dynamic value = {HAParamType.ENTRY: 06534797};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
void _customEvent(int index, int score) async {
String name = "Question$index";
dynamic value = {'Score': score};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
static const _questions = [
{
'questionText': 'What\'s you favorite color?',
'answers': [
{'text': 'Black', 'Score': 10},
{'text': 'White', 'Score': 1},
{'text': 'Green', 'Score': 3},
{'text': 'Red', 'Score': 5},
]
},
{
'questionText': 'What\'s your favorite place?',
'answers': [
{'text': 'India', 'Score': 1},
{'text': 'Rassia', 'Score': 5},
{'text': 'US', 'Score': 4},
{'text': 'Singapore', 'Score': 7},
]
},
{
'questionText': 'What\'s your childwood nick name?',
'answers': [
{'text': 'Bunty', 'Score': 2},
{'text': 'Binto', 'Score': 1},
{'text': 'Tom', 'Score': 5},
{'text': 'Ruby', 'Score': 3},
]
},
{
'questionText': 'What\'s your favorite subject?',
'answers': [
{'text': 'Math', 'Score': 5},
{'text': 'Physics', 'Score': 1},
{'text': 'Chemistry', 'Score': 3},
{'text': 'Biology', 'Score': 2},
]
}
];
Future<void> _answerQuestion(int score) async {
_totalScore += score;
if (_questionIndex < _questions.length) {
print('Iside if $_questionIndex');
setState(() {
_questionIndex = _questionIndex + 1;
});
print('Current questionIndex $_questionIndex');
} else {
print('Inside else $_questionIndex');
}
_customEvent(_questionIndex, score);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('QuizApp'),
),
body: _questionIndex < _questions.length
? Quiz(
answerQuestion: _answerQuestion,
questionIndex: _questionIndex,
questions: _questions,
)
: Result(_totalScore, _restartQuiz),
));
}
}
question.dart
Code:
import 'package:flutter/material.dart';
class Question extends StatelessWidget {
final String questionText;
Question(this.questionText);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.all(30.0),
child: Text(
questionText,
style: TextStyle(
fontSize: 28,
),
textAlign: TextAlign.center,
),
);
}
}
answer.dart
Code:
import 'package:flutter/material.dart';
class Answer extends StatelessWidget {
final Function selectHandler;
final String answerText;
Answer(this.selectHandler, this.answerText);
@override
Widget build(BuildContext context) {
return Container(
width: double.infinity,
margin: EdgeInsets.fromLTRB(20, 10, 20, 10),
child: RaisedButton(
child: Text(answerText),
color: Colors.blue,
textColor: Colors.white,
onPressed: selectHandler,
),
);
}
}
quiz.dart
Code:
import 'package:flutter/material.dart';
import './answer.dart';
import './question.dart';
class Quiz extends StatelessWidget {
final List<Map<String, Object>> questions;
final int questionIndex;
final Function answerQuestion;
Quiz({
@required this.answerQuestion,
@required this.questions,
@required this.questionIndex,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Question(
questions[questionIndex]['questionText'],
),
...(questions[questionIndex]['answers'] as List<Map<String, Object>>)
.map((answer) {
return Answer(() => answerQuestion(answer['Score']), answer['text']);
}).toList()
],
);
}
}
result.dart
Code:
import 'package:flutter/material.dart';
class Result extends StatelessWidget {
final int resulScore;
final Function restarthandler;
Result(this.resulScore, this.restarthandler);
String get resultPhrase {
String resultText;
if (resulScore <= 8) {
resultText = 'You are awesome and innocent!.';
} else if (resulScore <= 12) {
resultText = 'Pretty likable!.';
} else if (resulScore <= 12) {
resultText = 'You are .. strange!.';
} else {
resultText = 'You are so bad!';
}
return resultText;
}
@override
Widget build(BuildContext context) {
return Center(
child: Column(
children: [
Text(
resultPhrase,
style: TextStyle(fontSize: 36, fontWeight: FontWeight.bold),
textAlign: TextAlign.center,
),
FlatButton(
child: Text('Restart again', style: TextStyle(fontSize: 22)),
textColor: Colors.blue,
onPressed: restarthandler,
),
],
),
);
}
}
Result
Tricks and Tips
Make sure that downloaded plugin is added in specified directory.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added yaml file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
Enable debug mode using following command
Code:
adb shell setprop debug.huawei.hms.analytics.app package_name
Conclusion
In this article, we have learnt how to integrate Huawei Analytics Kit into Flutter QuizApp, which lets you to app analytics like users, predefined events and Custom events in the Ag-connect.
Thank you so much for reading, I hope this article helps you to understand the Huawei Analytics Kit in flutter.
Reference
Official plugin guide for flutter :
Document
developer.huawei.com
Flutter plugin :
Document
developer.huawei.com
HMS Core :
Document
developer.huawei.com
Read In Forum
Does it supports real time analytics?
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 Remote Configuration Service in Flutter QuizApp. Here we will fetch the remote data which is questions and answers JSON data from Ag-console. Huawei provides Remote Configuration service to manage parameters online, with this service you can control or change the behaviour and appearance of you app online without requiring user’s interaction or update to app. By implementing the SDK you can fetch the online parameter values delivered on the AG-console to change the app behaviour and appearance.
Functional features
1. Parameter management: This function enables user to add new parameter, delete, update existing parameter and setting conditional values.
2. Condition management: This function enables user to adding, deleting and modifying conditions, and copy and modify existing conditions. Currently, you can set the following conditions version, country/region, audience, user attribute, user percentage, time and language. You can expect more conditions in the future.
3. Version management: This feature function supports user to manage and rollback up to 90 days of 300 historical versions for parameters and conditions.
4. Permission management: This feature function allows account holder, app administrator, R&D personnel, and administrator and operations personals to access Remote Configuration by default.
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.
Java:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Add root level gradle dependencies
Java:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Add app level gradle dependencies
Java:
implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.4.2.301'
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"/>
Step 4: Add below path in pubspec.yaml file under dependencies.
Step 5 : Create a project in AppGallery Connect
Preparations for Integrating HUAWEI HMS Core(Android)
developer.huawei.com
pubspec.yaml
YAML:
name: flutter_app
description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_account:
path: ../huawei_account/
huawei_analytics:
path: ../huawei_analytics/
huawei_location:
path: ../huawei_location/
huawei_ads:
path: ../huawei_ads/
huawei_push:
path: ../huawei_push
huawei_map:
path: ../huawei_map
huawei_scan:
path: ../huawei_scan
agconnect_crash: ^1.0.0
http: ^0.12.2
fluttertoast: ^7.1.6
agconnect_remote_config: ^1.0.0
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
main.dart
Code:
[CODE=java]import 'dart:convert';
import 'dart:developer';
import 'package:agconnect_remote_config/agconnect_remote_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/login.dart';
import 'package:flutter_app/menuscreen.dart';
import 'package:flutter_app/myquestion.dart';
import 'package:flutter_app/result.dart';
import 'package:huawei_account/hmsauthservice/hms_auth_service.dart';
import 'package:huawei_ads/adslite/ad_param.dart';
import 'package:huawei_ads/adslite/banner/banner_ad.dart';
import 'package:huawei_ads/adslite/banner/banner_ad_size.dart';
import 'package:huawei_ads/hms_ads.dart';
import 'package:huawei_analytics/huawei_analytics.dart';
import './quiz.dart';
import './result.dart';
void main() {
runApp(
MaterialApp(
title: 'TechQuizApp',
// Start the app with the "/" named route. In this case, the app starts
// on the FirstScreen widget.
initialRoute: '/',
routes: {
// When navigating to the "/" route, build the FirstScreen widget.
'/': (context) => MenuScreen(),
// When navigating to the "/second" route, build the SecondScreen widget.
'/second': (context) => MyApp('', null),
},
),
);
}
class MyApp extends StatefulWidget {
final String userName;
List<MyQuestion> _questions;
MyApp(this.userName, this._questions);
@override
State<StatefulWidget> createState() {
// TODO: implement createState
return _MyAppState(_questions);
}
}
class _MyAppState extends State<MyApp> {
var _questionIndex = 0;
int _totalScore = 0;
String name;
List<MyQuestion> _questions;
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
_MyAppState(this._questions);
@override
void initState() {
_enableLog();
_predefinedEvent();
super.initState();
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId(widget.userName);
await _hmsAnalytics.enableLog();
}
void _restartQuiz() {
setState(() {
_questionIndex = 0;
_totalScore = 0;
});
}
void _logoutQuiz() async {
final signOutResult = await HmsAuthService.signOut();
if (signOutResult) {
Navigator.of(context)
.push(MaterialPageRoute(builder: (context) => LoginDemo()));
print('You are logged out');
} else {
print('signOut failed');
}
}
//Predefined
void _predefinedEvent() async {
String name = HAEventType.SIGNIN;
dynamic value = {HAParamType.ENTRY: 06534797};
await _hmsAnalytics.onEvent(name, value);
print("Event posted");
}
void _customEvent(int index, int score) async {
String name = "Question$index";
dynamic value = {'Score': score};
await _hmsAnalytics.onEvent(name, value);
print("_customEvent posted");
}
Future<void> _answerQuestion(int score) async {
_totalScore += score;
if (_questionIndex < _questions.length) {
print('Iside if $_questionIndex');
setState(() {
_questionIndex = _questionIndex + 1;
});
print('Current questionIndex $_questionIndex');
} else {
print('Inside else $_questionIndex');
}
_customEvent(_questionIndex, score);
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Wel come ' + widget.userName),
),
body: callme2()));
}
}
myqueston.dart
Code:
class MyQuestion {
String questionText;
List<Answers> answers;
MyQuestion({this.questionText, this.answers});
MyQuestion.fromJson(Map<String, dynamic> json) {
questionText = json['questionText'];
if (json['answers'] != null) {
answers = new List<Answers>();
json['answers'].forEach((v) {
answers.add(new Answers.fromJson(v));
});
}
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['questionText'] = this.questionText;
if (this.answers != null) {
data['answers'] = this.answers.map((v) => v.toJson()).toList();
}
return data;
}
}
class Answers {
String text;
int score;
Answers({this.text, this.score});
Answers.fromJson(Map<String, dynamic> json) {
text = json['text'];
score = json['Score'];
}
Map<String, dynamic> toJson() {
final Map<String, dynamic> data = new Map<String, dynamic>();
data['text'] = this.text;
data['Score'] = this.score;
return data;
}
}
login.dart
import 'dart:async';
import 'dart:convert';
import 'dart:developer';
import 'package:agconnect_remote_config/agconnect_remote_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/main.dart';
import 'package:flutter_app/myquestion.dart';
import 'package:huawei_account/helpers/hms_auth_param_helper.dart';
import 'package:huawei_account/helpers/hms_scope.dart';
import 'package:huawei_account/hmsauthservice/hms_auth_service.dart';
import 'package:huawei_account/model/hms_auth_huawei_id.dart';
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> {
TextEditingController emailController = new TextEditingController();
TextEditingController passwordController = new TextEditingController();
String email, password, user;
List<MyQuestion> _questions;
@override
void initState() {
// TODO: implement initState
fetchAndActivateImmediately();
super.initState();
}
@override
void dispose() {
// Clean up the controller when the widget is disposed.
emailController.dispose();
passwordController.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Account Login'),
),
body: Center(
child: InkWell(
onTap: signInWithHuaweiAccount,
child: Ink.image(
image: AssetImage('assets/images/icon.jpg'),
// fit: BoxFit.cover,
width: 110,
height: 110,
),
),
)),
);
}
void signInWithHuaweiAccount() async {
HmsAuthParamHelper authParamHelper = new HmsAuthParamHelper();
authParamHelper
..setIdToken()
..setAuthorizationCode()
..setAccessToken()
..setProfile()
..setEmail()
..setScopeList([HmsScope.openId, HmsScope.email, HmsScope.profile])
..setRequestCode(8888);
try {
final HmsAuthHuaweiId accountInfo =
await HmsAuthService.signIn(authParamHelper: authParamHelper);
print('accountInfo ==>' + accountInfo.email);
setState(() {
String accountDetails = accountInfo.displayName;
print("account name: " + accountInfo.displayName);
print("accountDetails: " + accountDetails);
user = accountInfo.displayName;
if (_questions != null) {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => MyApp(user, _questions)));
}
});
} on Exception catch (exception) {
print(exception.toString());
print("error: " + exception.toString());
}
}
Future signOut() async {
final signOutResult = await HmsAuthService.signOut();
if (signOutResult) {
//Route route = MaterialPageRoute(builder: (context) => SignInPage());
// Navigator.pushReplacement(context, route);
print('You are logged out');
} else {
print('Login_provider:signOut failed');
}
}
fetchAndActivateImmediately() async {
await AGCRemoteConfig.instance.fetch().catchError((error) => log(error()));
await AGCRemoteConfig.instance.applyLastFetched();
Map value = await AGCRemoteConfig.instance.getMergedAll();
for (String key in value.keys) {
if (key == 'questions') {
var st = value[key].toString().replaceAll('\\', '');
var myquestionJson = jsonDecode(st) as List;
_questions =
myquestionJson.map((val) => MyQuestion.fromJson(val)).toList();
}
}
print('=================*********************======================');
print(jsonEncode(_questions));
}
}[/CODE]
quiz.dart
Code:
import 'package:flutter/material.dart';
import 'package:flutter_app/myquestion.dart';
import './answer.dart';
import './question.dart';
class Quiz extends StatelessWidget {
final List<MyQuestion> questions;
final int questionIndex;
final Function answerQuestion;
Quiz({
@required this.answerQuestion,
@required this.questions,
@required this.questionIndex,
});
@override
Widget build(BuildContext context) {
return Column(
children: [
Question(
questions[questionIndex].questionText,
),
...(questions[questionIndex].answers).map<Widget>((answer) {
return Answer(() => answerQuestion(answer.score), answer.text);
}).toList()
],
);
}
}
menuscreen.dart
Code:
import 'dart:convert';
import 'dart:developer';
import 'package:agconnect_crash/agconnect_crash.dart';
import 'package:agconnect_remote_config/agconnect_remote_config.dart';
import 'package:flutter/material.dart';
import 'package:flutter_app/AdsDemo.dart';
import 'package:flutter_app/CrashService.dart';
import 'package:flutter_app/locationdata.dart';
import 'package:flutter_app/login.dart';
import 'package:flutter_app/pushdata.dart';
import 'package:flutter_app/remotedata.dart';
class MenuScreen extends StatefulWidget {
@override
_MenuScreenState createState() => _MenuScreenState();
}
class _MenuScreenState extends State<MenuScreen> {
@override
Widget build(BuildContext context) {
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Menu'),
),
body: Center(
child: Column(
children: [
SizedBox(
width: 320,
child: RaisedButton(
color: Colors.red, // background
textColor: Colors.white, // foreground
child: Text('Enter Quiz'),
onPressed: () {
Navigator.of(context).push(
MaterialPageRoute(builder: (context) => LoginDemo()));
},
),
)
],
),
),
),
);
}
}
Result
Tricks and Tips
Makes sure that agconnect-services.json file added.
Make sure dependencies are added build file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
Conclusion
In this article, we have learnt how to integrate Huawei Remote Configuration Service in Flutter QuizApp, Where json data of questions and answers are fetched from remote configurations i.e. Ag-console. Likewise you can configure other parameters like app theme, language, style and country etc. to change the app behaviour and appearance.
Thank you so much for reading, I hope this article helps you to understand the Huawei Remote Configuration Service in flutter.
Reference
Remote configuration service :
Document | Huawei Developers
developer.huawei.com
Original Source
Hi, Using Remote configuration can handle UI related functionality like visible/hide
IntroductionIn this article, we will be integrating Huawei Map kit and Location kit in Food Delivery application. Huawei Map kit currently allows developer to create map, interactions with map and drawing on a map.
We will be covering all three aspects as the delivery application we need to create map and we need to draw polyline from delivery agent location to user location and on interaction also we are providing i.e. on click the marker we are show popup on the map with details as shown in the result section below.
Development OverviewYou 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 processStep 1. Create flutter project
{
"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"
}
Step 2. Add the App level gradle dependencies. Choose inside project Android > app > build.gradle.
Code:
apply plugin:'com.huawei.agconnect'
Add root level gradle dependencies.
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Add app level gradle dependencies.
Code:
implementation 'com.huawei.hms:maps:5.0.3.302'
implementation 'com.huawei.hms:location:5.0.0.301'
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_COARSE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_BACKGROUND_LOCATION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION"/>
Step 4: Add below path in pubspec.yaml file under dependencies.
Step 5 : Create a project in AppGallery Connect.pubspec.yaml
Code:
name: sample_one
description: A new Flutter application.
# The following line prevents the package from being accidentally published to
# pub.dev using `pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.7.0 <3.0.0"
dependencies:
flutter:
sdk: flutter
huawei_map:
path: ../huawei_map/
huawei_location:
path: ../huawei_location/
http: ^0.12.2
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
How to check required permissions are granted or not?
Code:
void hasPermission() async {
try {
bool status = await permissionHandler.hasLocationPermission();
setState(() {
message = "Has permission: $status";
if (status) {
getLastLocationWithAddress();
//requestLocationUpdatesByCallback();
} else {
requestPermission();
}
});
} catch (e) {
setState(() {
message = e.toString();
});
}
}
How do I request permission?
Code:
void requestPermission() async {
try {
bool status = await permissionHandler.requestLocationPermission();
setState(() {
message = "Is permission granted $status";
});
} catch (e) {
setState(() {
message = e.toString();
});
}
}
How do I get location data?
Code:
void getLastLocationWithAddress() async {
try {
HWLocation location =
await locationService.getLastLocationWithAddress(locationRequest);
setState(() {
message = location.street +
" " +
location.city +
" " +
location.state +
" " +
location.countryName +
" " +
location.postalCode;
print("Location: " + message);
});
} catch (e) {
setState(() {
message = e.toString();
print(message);
});
}
}
main.dart
Code:
import 'package:flutter/material.dart';
import 'package:huawei_map/map.dart';
import 'package:sample_one/mapscreen2.dart';
import 'package:sample_one/order.dart';
void main() => runApp(App());
class App extends StatelessWidget {
@override
Widget build(BuildContext context) {
// TODO: implement build
return MaterialApp(
home: Scaffold(
appBar: AppBar(
title: Text('Orders'),
),
body: MyApp(),
),
debugShowCheckedModeBanner: false,
);
}
}
class MyApp extends StatefulWidget {
MyApp({Key key}) : super(key: key);
_MyAppState createState() => _MyAppState();
}
class _MyAppState extends State<MyApp> {
List orders = [
Order(
imageUrl:
"https://www.namesnack.com/images/namesnack-pizza-business-names-5184x3456-20200915.jpeg",
name: "Veg Pizza Special",
username: "Naresh K",
location: new LatLng(12.9698, 77.7500)),
Order(
imageUrl:
"https://www.pizzahutcouponcode.com/wp-content/uploads/2020/12/10.jpg",
name: "Pretzel Rolls ",
username: "Ramesh",
location: new LatLng(12.9698, 77.7500)),
Order(
imageUrl:
"https://www.manusmenu.com/wp-content/uploads/2015/01/1-Chicken-Spring-Rolls-9-1-of-1.jpg",
name: "Special Veg Rolls",
username: "Mahesh N",
location: new LatLng(12.9598, 77.7540)),
Order(
imageUrl:
"https://www.thespruceeats.com/thmb/axBJnjZ_30_-iHgjGzP1tS4ssGA=/4494x2528/smart/filters:no_upscale()/thai-fresh-rolls-with-vegetarian-option-3217706_form-rolls-step-07-f2d1c96942b04dd0830026702e697f17.jpg",
name: "The Great Wall of China",
username: "Chinmay M",
location: new LatLng(12.9098, 77.7550)),
Order(
imageUrl:
"https://cdn.leitesculinaria.com/wp-content/uploads/2021/02/pretzel-rolls-fp.jpg.optimal.jpg",
name: "Pretzel Rolls",
username: "Ramesh",
location: new LatLng(12.9658, 77.7400)),
Order(
imageUrl:
"https://dinnerthendessert.com/wp-content/uploads/2019/01/Egg-Rolls-3.jpg",
name: "Egg Rolls",
username: "Preeti",
location: new LatLng(12.9618, 77.7700)),
Order(
imageUrl:
"https://images.immediate.co.uk/production/volatile/sites/30/2020/08/recipe-image-legacy-id-1081476_12-9367fea.jpg",
name: "Easy Spring Rolls",
username: "Nithin ",
location: new LatLng(12.9218, 77.7100)),
];
@override
void initState() {
// TODO: implement initState
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white60,
body: SingleChildScrollView(
child: Container(
height: MediaQuery.of(context).size.height,
width: MediaQuery.of(context).size.width,
child: Stack(
children: <Widget>[
Container(
padding: EdgeInsets.only(top: 1),
height: MediaQuery.of(context).size.height,
width: double.infinity,
child: ListView.builder(
itemCount: orders.length,
itemBuilder: (context, index) {
return ListTile(
leading: Image.network(orders[index].imageUrl),
title: Text(orders[index].name),
onTap: () {
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => MapPage(
orders[index].name, orders[index].location)));
},
subtitle: Text(orders[index].username),
);
},
),
),
],
),
),
),
);
}
}
mapscreen.dart
Code:
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:huawei_map/map.dart';
import 'package:sample_one/directionapiutil.dart';
import 'package:sample_one/routerequest.dart';
import 'package:sample_one/routeresponse.dart';
class MapPage extends StatefulWidget {
String name;
LatLng location;
MapPage(this.name, this.location);
@override
_MapPageState createState() => _MapPageState(name, location);
}
class _MapPageState extends State<MapPage> {
String name, dist = '';
LatLng location, dest_location = new LatLng(12.9709, 77.7257);
_MapPageState(this.name, this.location);
HuaweiMapController _mapController;
final Set<Marker> _markers = {};
final Set<Polyline> _polyLines = {};
final List<LatLng> _points = [];
BitmapDescriptor _markerIcon;
List<LatLng> polyList = [
LatLng(12.9970, 77.6690),
LatLng(12.9569, 77.7011),
LatLng(12.9177, 77.6238)
];
@override
void initState() {
super.initState();
_loadMarkers(location);
showDirection();
}
@override
Widget build(BuildContext context) {
//_customMarker(context);
return new Scaffold(
appBar: null,
body: Stack(
children: [
_buildMap(),
Positioned(
top: 10,
right: 40,
left: 40,
child: ButtonBar(
buttonPadding: EdgeInsets.all(15),
alignment: MainAxisAlignment.center,
children: <Widget>[
/* new RaisedButton(
onPressed: showDirection,
child: new Text("Show direction",
style: TextStyle(fontSize: 20.0)),
color: Colors.green,
),*/
Center(
child: new Text(
"$dist",
style:
TextStyle(fontSize: 20.0, backgroundColor: Colors.cyan),
),
),
/* new RaisedButton(
onPressed: _showPolygone,
child: new Text("Polygon",
style: TextStyle(fontSize: 20.0, color: Colors.white)),
color: Colors.lightBlueAccent,
),*/
],
),
)
],
),
);
}
_buildMap() {
return HuaweiMap(
initialCameraPosition: CameraPosition(
target: location,
zoom: 12.0,
bearing: 30,
),
onMapCreated: (HuaweiMapController controller) {
_mapController = controller;
},
mapType: MapType.normal,
tiltGesturesEnabled: true,
buildingsEnabled: true,
compassEnabled: true,
zoomControlsEnabled: true,
rotateGesturesEnabled: true,
myLocationButtonEnabled: true,
myLocationEnabled: true,
trafficEnabled: true,
markers: _markers,
polylines: _polyLines,
onClick: (LatLng latlong) {
setState(() {
//createMarker(latlong);
});
},
);
}
void showRouteBetweenSourceAndDestination(
LatLng sourceLocation, LatLng destinationLocation) async {
RouteRequest request = RouteRequest(
origin: LocationModel(
lat: sourceLocation.lat,
lng: sourceLocation.lng,
),
destination: LocationModel(
lat: destinationLocation.lat,
lng: destinationLocation.lng,
),
);
try {
RouteResponse response = await DirectionUtils.getDirections(request);
setState(() {
drawRoute(response);
dist = response.routes[0].paths[0].distanceText;
});
} catch (Exception) {
print('Exception: Failed to load direction response');
}
}
drawRoute(RouteResponse response) {
if (_polyLines.isNotEmpty) _polyLines.clear();
if (_points.isNotEmpty) _points.clear();
var steps = response.routes[0].paths[0].steps;
for (int i = 0; i < steps.length; i++) {
for (int j = 0; j < steps[i].polyline.length; j++) {
_points.add(steps[i].polyline[j].toLatLng());
}
}
setState(() {
_polyLines.add(
Polyline(
width: 2,
polylineId: PolylineId("route"),
points: _points,
color: Colors.blueGrey),
);
/*for (int i = 0; i < _points.length - 1; i++) {
totalDistance = totalDistance +
calculateDistance(
_points[i].lat,
_points[i].lng,
_points[i + 1].lat,
_points[i + 1].lng,
);
}*/
});
}
void _loadMarkers(LatLng location) {
if (_markers.length > 0) {
setState(() {
_markers.clear();
});
} else {
setState(() {
_markers.add(Marker(
markerId: MarkerId('marker_id_1'),
position: location,
icon: _markerIcon,
infoWindow: InfoWindow(
title: 'Delivery agent',
snippet: 'location',
),
rotation: 5));
_markers.add(Marker(
markerId: MarkerId('marker_id_2'),
position: dest_location,
draggable: true,
icon: _markerIcon,
clickable: true,
infoWindow: InfoWindow(
title: 'User',
snippet: 'location',
),
rotation: 5));
});
}
}
void _customMarker(BuildContext context) async {
if (_markerIcon == null) {
final ImageConfiguration imageConfiguration =
createLocalImageConfiguration(context);
BitmapDescriptor.fromAssetImage(
imageConfiguration, 'assets/images/icon.png')
.then(_updateBitmap);
}
}
void _updateBitmap(BitmapDescriptor bitmap) {
setState(() {
_markerIcon = bitmap;
});
}
void createMarker(LatLng latLng) {
Marker marker;
marker = new Marker(
markerId: MarkerId('Welcome'),
position: LatLng(latLng.lat, latLng.lng),
icon: BitmapDescriptor.defaultMarker);
setState(() {
_markers.add(marker);
});
}
void remove() {
setState(() {
_markers.clear();
});
}
showDirection() {
Future.delayed(const Duration(seconds: 1), () {
//setState(() {
showRouteBetweenSourceAndDestination(location, dest_location);
//});
});
}
}
Result
Tips and Tricks
Make sure you have downloaded latest plugin.
Make sure that updated plugin path in yaml.
Make sure that plugin unzipped in parent directory of project.
Makes sure that agconnect-services.json file added.
Make sure dependencies are added build file.
Run flutter pug get after adding dependencies.
Generating SHA-256 certificate fingerprint in android studio and configure in Ag-connect.
ConclusionIn this article, we have learnt how to integrate Huawei Map kit and Location kit in Flutter for the DeliveryApp, where application gets the list of orders and delivery agent click on the order to navigate to map. Similar way you can use Huawei Map kit as per user requirement in your application.
Thank you so much for reading, I hope this article helps you to understand the Huawei Map kit and Location kit in flutter.
ReferencesFlutter map
Flutter plugin
Location Kit
Original Source
What are all the different types of maps it will supports?
can we implement start navigation feature like google map feature?
Introduction
In this article, we will learn how to implement Image Classification feature in flutter application. Image classification uses the transfer learning algorithm to perform multi-level learning training. Huawei ML Kit provides many useful machine learning related features to developers and one of them is Image Classification.
{
"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"
}
About Image Classification
Image classification is one of the features of HMS ML Kit. By this service we can classify the objects in images. This service analyses an image, classifies it into possible categories in real world, like people, animal, objects etc. and it returns the recognized results.
We can detects images two ways static or from camera stream. Image recognition it supports both cloud and device recognition.
Device based recognition
1. More efficient.
2. Supports more than 400 image categories.
3. Supports both static image detection and camera stream detection.
Cloud based recognition
1. More accurate.
2. Supports more than1200 image categories.
3. Supports only static image detection.
Requirements
1. Any operating system (MacOS, Linux and Windows etc.)
2. Any IDE with Flutter SDK installed (IntelliJ, Android Studio and VsCode etc.)
3. A little knowledge of Dart and Flutter.
4. Minimum API Level 19 is required.
5. Required EMUI 5.0 and later version devices.
Setting up the Awareness kit
1. First create a developer account in AppGallery Connect. After create your developer account, you can create a new project and new app. For more information, click here.
2. Enable the ML kit in the Manage API section and add the plugin.
3. Add the required dependencies to the build.gradle file under root folder.
Code:
maven {url'http://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
4. Add the required permissions to the AndroidManifest.xml file under app/src/main folder.
Code:
<uses-permission android:name ="android.permission.CAMERA"/>
<uses-permission android:name ="android.permission.READ_EXTERNAL_STORAGE"/>
After completing all the above steps, you need to add the required kits’ Flutter plugins as dependencies to pubspec.yaml file. Refer this URL for cross-platform plugins to download the latest versions.
Code:
huawei_ml:
path: ../huawei_ml/
After adding them, run flutter pub get command. Now all the plugins are ready to use.
Note: Set multiDexEnabled to true in the android/app directory, so the app will not crash.
Code Integration
In this sample, I used both static and camera detection. First we have to initialize the ML service, then check camera permissions.
Code:
class ImageClassification extends StatefulWidget {
@override
_ImageClassificationState createState() => _ImageClassificationState();
}
class _ImageClassificationState extends State<ImageClassification> {
MLClassificationAnalyzer mlClassificationAnalyzer;
MLClassificationAnalyzerSetting mlClassificationAnalyzerSetting;
String _name = " ";
File _imageFile;
PickedFile _pickedFile;
@override
void initState() {
mlClassificationAnalyzer = new MLClassificationAnalyzer();
mlClassificationAnalyzerSetting = new MLClassificationAnalyzerSetting();
_setApiKey();
_checkPermissions();
super.initState();
}
_setApiKey() async {
await MLApplication().setApiKey(
apiKey:
"CgB6e3x9vOdMNP0juX6Wj65ziX/FR0cs1k37FBOB3iYL+ecElA9k+K9YUQMAlD4pXRuEVvb+hoDQB2KDdXYTpqfH");
}
_checkPermissions() async {
if (await MLPermissionClient().checkCameraPermission()) {
Scaffold.of(context).showSnackBar(SnackBar(
content: Text("Permission Granted"),
));
} else {
await MLPermissionClient().requestCameraPermission();
}
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Column(
children: [
SizedBox(height: 15),
_setImageView(),
SizedBox(height: 15),
_setText(),
SizedBox(height: 15),
_showImagePickingOptions(),
],
));
}
Widget _showImagePickingOptions() {
return Expanded(
child: Align(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Container(
margin: EdgeInsets.only(left: 20.0, right: 20.0),
width: MediaQuery.of(context).size.width,
child: MaterialButton(
color: Colors.amber,
textColor: Colors.white,
child: Text("TAKE PICTURE"),
onPressed: () async {
final String path = await getImage(ImageSource.camera);
setState(() {
_imageFile = File(path);
});
_startRecognition(path);
})),
Container(
width: MediaQuery.of(context).size.width,
margin: EdgeInsets.only(left: 20.0, right: 20.0),
child: MaterialButton(
color: Colors.amber,
textColor: Colors.white,
child: Text("PICK FROM GALLERY"),
onPressed: () async {
final String path = await getImage(ImageSource.gallery);
setState(() {
_imageFile = File(path);
});
_startRecognition(path);
})),
],
),
),
);
}
Widget _setImageView() {
if (_imageFile != null) {
return Image.file(_imageFile, width: 300, height: 300);
} else {
return Text(" ");
}
}
Widget _setText() {
return Text(
_name,
style: (TextStyle(fontWeight: FontWeight.bold)),
);
}
_startRecognition(String path) async {
mlClassificationAnalyzerSetting.path = path;
mlClassificationAnalyzerSetting.isRemote = true;
mlClassificationAnalyzerSetting.largestNumberOfReturns = 6;
mlClassificationAnalyzerSetting.minAcceptablePossibility = 0.5;
try {
List<MLImageClassification> list = await mlClassificationAnalyzer
.asyncAnalyzeFrame(mlClassificationAnalyzerSetting);
if (list.length != 0) {
setState(() {
_name = list.first.name;
});
}
} on Exception catch (er) {
print(er.toString());
}
}
Future<String> getImage(ImageSource imageSource) async {
final picker = ImagePicker();
_pickedFile = await picker.getImage(source: imageSource);
return _pickedFile.path;
}
}
Demo
Tips and Tricks
1. Download latest HMS Flutter plugin.
2. Set minSDK version to 19 or later.
3. Do not forget to add Camera permission in Manifest file.
4. Latest HMS Core APK is required.
5. The PNG, JPG, JPEG, and BMP formats are supported.
Conclusion
That’s it!
This article will help you to use Image classification feature in your flutter application, Image classification service of ML Kit gives a real-time experience for AI apps of analyzing elements available in image or camera stream.
Thanks for reading! If you enjoyed this story, please click the Like button and Follow. Feel free to leave a Comment below.
Reference
ML kit URL
Original Source
{
"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 learn how to make use of Huawei Cloud Functions service as Chatbot service in ChatBotApp in flutter. Cloud Functions enables serverless computing. It provides the Function as a Service (FaaS) capabilities to simplify app development and O&M by splitting service logic into functions and offers the Cloud Functions SDK that works with Cloud DB and Cloud Storage so that your app functions can be implemented more easily. Cloud Functions automatically scales in or out functions based on actual traffic, freeing you from server resource management and helping you reduce costs.
Key Functions
Key Concepts
How the Service Works
To use Cloud Functions, you need to develop cloud functions that can implement certain service functions in AppGallery Connect and add triggers for them, for example, HTTP triggers for HTTP requests, and Cloud DB triggers for data deletion or insertion requests after Cloud DB is integrated. After your app that integrates the Cloud Functions SDK meets conditions of specific function triggers, your app can call the cloud functions, which greatly facilitates service function building.
Platform Support
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 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
main.dart
[/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: 'ChatBotService',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'ChatBotService'),
);
}
}
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> {
bool isLoggedIn = false;
String str = 'Login required';
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
List<String> gridItems = ['Email Service', 'Call Center', 'FAQ', 'Chat Now'];
@override
void initState() {
_enableLog();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Visibility(
visible: true,
child: Card(
child: Padding(
padding: EdgeInsets.all(20),
child: Text(
str,
style: const TextStyle(color: Colors.teal, fontSize: 22),
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isLoggedIn) {
setState(() {
isLoggedIn = true;
signInWithHuaweiID();
});
print('$isLoggedIn');
} else {
setState(() {
isLoggedIn = false;
signOutWithID();
});
print('$isLoggedIn');
}
},
tooltip: 'Login/Logout',
child: isLoggedIn ? const Icon(Icons.logout) : const Icon(Icons.login),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void signInWithHuaweiID() async {
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) => setLoginSuccess(value),
);
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("ChatBotServiceApp");
await _hmsAnalytics.enableLog();
}
void setLoginSuccess(AuthAccount value) {
setState(() {
str = 'Welcome ' + value.displayName.toString();
});
showToast(value.displayName.toString());
print('Login Success');
}
Future<void> signOutWithID() async {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
setState(() {
str = 'Login required';
showToast('You are logged out.');
});
}
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast(String name) async {
Fluttertoast.showToast(
msg: "$name",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
}
[B]
Result
Tricks and Tips
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, analytics kit in flutter ChatBotApp. Once Account kit integrated, users can login quickly and conveniently sign in to apps with their Huawei IDs after granting initial access permission. In part-2 we will learn the actual Cloud Functions as Chatbot service.
Thank you so much for reading. I hope this article helps you to understand the integration of Huawei Account kit and Analytics kit in flutter ChatBotApp.
Reference
Cloud Functions
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 learn how to use Huawei Cloud Functions service as Chatbot service in ChatBotApp in flutter. Cloud Functions enables serverless computing.
It provides the Function as a Service (FaaS) capabilities to simplify app development and O&M by splitting service logic into functions and offers the Cloud Functions SDK that works with Cloud DB and Cloud Storage so that your app functions can be implemented more easily. Cloud Functions automatically scales in or out functions based on actual traffic, freeing you from server resource management and helping you reduce costs.
Key Functions
Key Concepts
How the Service Works
To use Cloud Functions, you need to develop cloud functions that can implement certain service functions in AppGallery Connect and add triggers for them, for example, HTTP triggers for HTTP requests, and Cloud DB triggers for data deletion or insertion requests after Cloud DB is integrated. After your app that integrates the Cloud Functions SDK meets conditions of specific function triggers, your app can call the cloud functions, which greatly facilitates service function building.
Platform Support
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
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
Step 3: Add the below permissions in Android Manifest file.
<uses-permission android:name="android.permission.INTERNET" />
Step 4: Add downloaded file into parent directory of the project. Declare plugin path in pubspec.yaml file under dependencies.
Add path location for asset image.
Prevoius article
Using Huawei Cloud Functions as Chatbot Service in Flutter ChatBotApp Part-1
Let's start coding
main.dart
[/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: 'ChatBotService',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: const MyHomePage(title: 'ChatBotService'),
);
}
}
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> {
bool isLoggedIn = false;
String str = 'Login required';
final HMSAnalytics _hmsAnalytics = new HMSAnalytics();
List<String> gridItems = ['Email Service', 'Call Center', 'FAQ', 'Chat Now'];
@override
void initState() {
_enableLog();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child:
Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Visibility(
visible: true,
child: Card(
child: Padding(
padding: EdgeInsets.all(20),
child: Text(
str,
style: const TextStyle(color: Colors.teal, fontSize: 22),
),
),
),
),
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
if (!isLoggedIn) {
setState(() {
isLoggedIn = true;
signInWithHuaweiID();
});
print('$isLoggedIn');
} else {
setState(() {
isLoggedIn = false;
signOutWithID();
});
print('$isLoggedIn');
}
},
tooltip: 'Login/Logout',
child: isLoggedIn ? const Icon(Icons.logout) : const Icon(Icons.login),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void signInWithHuaweiID() async {
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) => setLoginSuccess(value),
);
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> _enableLog() async {
_hmsAnalytics.setUserId("ChatBotServiceApp");
await _hmsAnalytics.enableLog();
}
void setLoginSuccess(AuthAccount value) {
setState(() {
str = 'Welcome ' + value.displayName.toString();
});
showToast(value.displayName.toString());
print('Login Success');
}
Future<void> signOutWithID() async {
try {
final bool result = await AccountAuthService.signOut();
if (result) {
setState(() {
str = 'Login required';
showToast('You are logged out.');
});
}
} on Exception catch (e) {
print(e.toString());
}
}
Future<void> showToast(String name) async {
Fluttertoast.showToast(
msg: "$name",
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.CENTER,
timeInSecForIosWeb: 1,
backgroundColor: Colors.lightBlue,
textColor: Colors.white,
fontSize: 16.0);
}
}
[B]
ChatPage.dart
[/B][/B]
class ChatPage extends StatefulWidget {
const ChatPage({Key? key}) : super(key: key);
@override
_ChatPageState createState() => _ChatPageState();
}
class _ChatPageState extends State<ChatPage> {
List<types.Message> _messages = [];
final _user = const types.User(id: '06c33e8b-e835-4736-80f4-63f44b66666c');
final _bot = const types.User(id: '06c33e8b-e835-4736-80f4-63f54b66666c');
void _addMessage(types.Message message) {
setState(() {
_messages.insert(0, message);
});
}
void _handleSendPressed(types.PartialText message) {
final textMessage = types.TextMessage(
author: _user,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: message.text,
);
_addMessage(textMessage);
callCloudFunction2(message.text);
}
void _loadMessages() async {
final response = await rootBundle.loadString('assets/messages.json');
final messages = (jsonDecode(response) as List)
.map((e) => types.Message.fromJson(e as Map<String, dynamic>))
.toList();
setState(() {
_messages = messages;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Chat(
messages: _messages,
onAttachmentPressed: null,
onMessageTap: null,
onPreviewDataFetched: null,
onSendPressed: _handleSendPressed,
user: _user,
),
);
}
Future<void> callCloudFunction2(String msg) async {
try {
RequestData data = RequestData(msg);
List<Map<String, Object>> params = <Map<String, Object>>[data.toMap()];
var input = data.toMap();
FunctionCallable functionCallable =
FunctionCallable('test-funnel-\$latest');
FunctionResult functionResult = await functionCallable.call(input);
print("Input " + input.toString());
var result = functionResult.getValue();
final textMessage = types.TextMessage(
author: _bot,
createdAt: DateTime.now().millisecondsSinceEpoch,
id: const Uuid().v4(),
text: jsonDecode(result)['response'].toString(),
);
_addMessage(textMessage);
} on PlatformException catch (e) {
print(e.message);
}
}
}
[B][B]
handler.js
[/B][/B][/B]
let myHandler = function(event, context, callback, logger) {
try {
var _body = JSON.parse(event.body);
var reqData = _body.message;
var test = '';
if(reqData == '1'){
test = "Thank you for choosing, you will get callback in 10 min.";
}else if(reqData == '2'){
test = "Please click on the link https://feedback.com/myfeedback";
}else if(reqData == '3'){
test = "Please click on the link https://huawei.com/faq";
}
else if(reqData == 'Hi'){
test = " Welcome to ChatBot Service.";
}else{
test = "Enter 1. For call back. 2. For send feedback. 3. For FAQ ";
}
let res = new context.HTTPResponse({"response": test}, {
"res-type": "simple example",
"faas-content-type": "json"
}, "application/json", "200");
callback(res);
} catch (error) {
let res = new context.HTTPResponse({"response": error}, {
"res-type": "simple example",
"faas-content-type": "json"
}, "application/json", "300");
callback(res);
}
};
module.exports.myHandler = myHandler;
[B][B][B]
Result
Tricks and Tips
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, analytics kit and ChatBot function using Cloud Functions in flutter ChatBotApp. 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, Analytics kit and Huawei Cloud Functions in flutter ChatBotApp.
Reference
Cloud Functions
Training Videos
Checkout in forum