One App, Two Screens — HUAWEI App Multiplier - Huawei Developers

For more articles like this, you can visit HUAWEI Developer Forum and Medium.​
{
"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"
}
Hello there, in this article I will try to explain what is and how to integrate HUAWEI App Multiplier. You can find the demo project source and official guides at the very end of the article.
What is Huawei App Multiplier
App Multiplier is a system-side solution that splits the screen on an activity base. You can significantly improve user experiences thanks to App Multiplier and provide a magic view for your applications on new generation Android devices.
What type of display modes App Multiplier provides?
App Multiplier provides three dual-window display modes which are Shopping, Navigation bar and Custom modes to meet users’ requirements in different scenarios.
Shopping mode:
Shopping display mode is applicable to shopping apps, allowing users to quickly compare product specs, such as the price. Screen shows recently viewed windows, with the latest one on the right and the second latest one on the left.
Any window opened on the left screen will replace the original content on the right screen. When a new window is opened on the right screen, it will display on the right, while the original content displaying on the right will move to the left
When the user touches the back key on the left screen, both the Activity of the right screen and the Activity at the top of the stack on the left screen are destroyed.
Navigation bar mode:
The left screen always displays the app home screen, and the right screen displays the content based on operations on the left screen.
Custom mode:
In this mode, developers can customize how the windows display by defining the activity pairs.
In full screen mode, the Activities that meet the activityPairs rules will trigger split-screen display.
If a new Activity that doesn’t meet the activityPairs rules is triggered in a split-screen scenario, it will display on the right screen, wherever it is triggered.
If a new Activity that meets the activityPairs rules is triggered in a split-screen scenario, the screen will display as follows:
When the Activity is triggered from the left screen, it will replace the right screen.
When the activity is triggered from the right screen, it will display on the right, while the original right screen goes to the left.
When the user touches the back key on the left screen, all Activities of the right screen are destroyed, and the stack top Activity of the left screen is also destroyed.
How to integrate App Multiplier?
You just need to simple few lines configuration code to be added to the app’s configuration file.
Let’s make the app magical!
Notice: If your app is released in AppGallery for the first time, you need to register a HUAWEI ID and create an app in AppGalley Connect. Please, refer to Register a HUAWEI ID for registration, and Preparations for Integrating HUAWEI HMS Core for creating an app.
Create your activity pages, and generate triggering relationships between the pages. In this demo example,
Contacts and Email can be opened from the MainActivity.
FavoriteContacts can be opened from Contacts.
Inbox and JunkEmail can be opened from Email.
Firstly, add the meta-data into application in the AndroidManifest.xml file.
Code:
<meta-data android:name=”EasyGoClient” android:value=”true” />
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hayriaral.appmultiplierexample">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name=".Contacts" />
<activity android:name=".Email" />
<activity android:name=".FavoriteContacts" />
<activity android:name=".Inbox" />
<activity android:name=".JunkEmail" />
<meta-data android:name="EasyGoClient" android:value="true" />
</application>
</manifest>
Next, create a JSON configuration file named easygo.json in the assets folder.
Notice: Assets folder is not be created automatically when you create a project. You need to create it manually. Use the following way to create assets folder.
Click on File →New →Folder →Assets Folder.
The default folder location is src/main/assets. Keep as it is, then click on Finish.
You can use the file as template. Please, don’t forget to modify activities and package names.
Code:
{
"easyGoVersion": "1.0",
"client": "com.hayriaral.appmultiplierexample",
"logicEntities": [
{
"head": {
"function": "magicwindow",
"required": "true"
},
"body": {
"mode": "1",
"activityPairs": [
{
"from": "com.hayriaral.appmultiplierexample.MainActivity",
"to": "*"
},
{
"from": "com.hayriaral.appmultiplierexample.Contacts",
"to": "com.hayriaral.appmultiplierexample.FavoriteContacts"
},
{
"from": "com.hayriaral.appmultiplierexample.Email",
"to": "com.hayriaral.appmultiplierexample.Inbox"
},
{
"from": "com.hayriaral.appmultiplierexample.Email",
"to": "com.hayriaral.appmultiplierexample.JunkEmail"
}
],
"transActivities": [
]
}
}
]
}
Let me describe these parameters:
Code:
easyGoVersion : This parameter has a fixed value of 1.0.
client : App package name.
logicEntities.head.function : This parameter has a fixed value of magicwindow.
logicEntities.head.required : This parameter has a fixed value of true.
logicEntities.body.mode : 0 for Shopping mode, 1 for Custom and Navigation bar mode.
logicEntities.body.activityPairs.from : Source activity that triggers screen splitting.
logicEntities.body.activityPairs.to : Target Activity that triggers screen splitting. * indicates any activity.
That’s it! Your application is set ready for new generation devices.
How to check how it works without having a supported device?
Just as I did, you can use HUAWEI Cloud Debugging Service. Please, follow the guide to use the service.
On which devices are App Multiplier supported?
App Multiplier is supported on HUAWEI foldable devices like HUAWEI Mate Xs, and HUAWEI MediaPad M6 series and later tablets running EMUI 10.X or later.
I hope this article will help you for using App Multiplier. See you in next article.
References:
Source code: App Multiplier Example
Official App Multiplier Development Guide: App Multiplier Development Guide

Related

How to Analyse your user and Improve User Engagement

Notifications play a vital role in your app success. They give you a platform to reach out to your users, interact with them, give them updates, update the app data and much more.
While notification is an important part of the whole app development process, it somehow is typical to integrate as compared to the normal android apis. The reason? Well, while normal apis need configuration inside the app only, notifications need more than that — outside configuration like handling user tokens, and sending notifications using those tokens.
The main goal of this app is to be a sample of how to build an high quality Android application that uses the Architecture components, MVVM, RxJava,HMS PUSH Kit,HMS Analytics Kit etc. in Kotlin
What is Kotlin? The Java alternative explained
{
"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"
}
Kotlin is a general purpose, free, open source, statically typed “pragmatic” programming language initially designed for the JVM (Java Virtual Machine) and Android that combines object-oriented and functional programming features
Safety features in Kotlin
· Speaking of avoiding common errors, Kotlin was designed to eliminate the danger of null pointer references and streamline the handling of null values.
· It does this by making a null illegal for standard types, adding nullable types, and implementing shortcut notations to handle tests for null.
· To avoid the verbose grammar normally needed for null testing, Kotlin introduces a safe call, written ?.. For example, b?.length returns b.length if b is not null, and null otherwise. The type of this expression is Int?.
RxJava:
· RxJava has become the single most important skill for Android development.
· Most of you must have worked with it in some form, either in your own codebase or through other third party libraries, like Fast Android Networking and Retrofit
How does this Reactive Stream implement?
· Publisher: These interfaces(APIs) define the structure of RxJava.
Code:
interface Publisher<T> {
fun subscribe(s: Subscriber<in T?>?)
}
· Subscriber: A Subscriber exposes the following callback methods.
Code:
interface Subscriber<T> {
fun onSubscribe(s: Subscription?)
fun onNext(t: T)
fun onError(t: Throwable?)
fun onComplete()
}
· Subscription: When the Subscriber becomes ready to start handling events, it signals the Publisher through its Subscription
Code:
interface Subscription {
fun request(n: Long)
fun cancel()
}
Publishers
Let’s see how publishers are structured in RxJava. RxJava provides following types of event publishers:
· Flowable: A Publisher that emits 0..N elements, and then completes successfully or with an error.
· Observable: Similar to Flowables but without a backpressure strategy. They were introduced in RxJava 1.x.
· Single: It completes with a value successfully or an error.(doesn’t have onComplete callback, instead onSuccess(val)).
· Maybe: It completes with/without a value or completes with an error.
Completable: It just signals if it has completed successfully or with an error.
What is MVVM?
Model-View-ViewModel architecture consists of 3 parts.
· The View gets user’s actions and sends to the ViewModel, or listens live data stream from the ViewModel and provides to the users.
· The ViewModel gets user’s actions from the View or provides data to View.
· The Model abstracts the data source. View and ViewModel uses that on data stream.
LiveData:
· LiveData is one of the newly introduced architecture components. LiveData is an observable data holder.
· This allows the components in your app to be able to observe LiveData objects for changes without creating explicit and rigid dependency paths between them.
· This decouples completely the LiveData object producer from the LiveData object consumer.
ViewModel:
· ViewModel is also one of the newly introduced architecture components.
· Architecture components provide a new class called ViewModel, which is responsible for preparing the data for the UI/View.
· ViewModel gives you a good base class for your MVVM ViewModel layer since ViewModel (and its children AndroidViewModel)’s extending classes are automatically having their holding data retained during configuration changes.
· This means that after configuration changes, this ViewModel holded data is immediately available to the next activity or fragment instance.
Project Structure:
We will create packages by features. It will make your code more modular and manageable.
DataBinding:
· Android data binding allows for 1 or 2-way binding within the layout XML files of Android. This should be familiar to anyone who has done web based development with Angular or Ember, or C# WPF development.
· The most basic case is to add an on-click listener. This requires no registering of on click listeners in any of your application code, just some XML in the layout file and a function to be called in your ViewModel class
Code:
<?xml version="1.0" encoding="utf-8"?>
<layout >
<data>
<variable
name=" "
type=""/>
</data>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_centerHorizontal="true"
android:text="@{viewModel.getHourOfDay()}"
tools:text="14:00" />
</RelativeLayout>
</layout>
Weather Notification API:
The Weather Notifications API enables you to set weather-driven push notifications to applications. With predefined weather parameter threshold values, you are able to be informed of certain weather phenomena like when rain, strong winds or exceptional heat starts.
The following content will be the coding process.
If you are interested, check the full content by https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201235519702030082&fid=0101187876626530001
More information about HMS, you can visit https://forums.developer.huawei.com/forumPortal/en/home

Development in React Native Platform with HMS Location kit, Map kit, Site Kit-2

Introduction
Hello, in this article, as in my previous article, we will look at the most needed topics in React Native Location, Map, Site Kit development. If you haven’t read my previous post => Click
Since I first wrote the article, many topics have emerged, if you are ready, let’s start.
Getting the Location from the Center of the Map Screen
What? I can hear you say that what is asked from me now is that Huawei Map is open, but I do not want to get the user’s location. I want to get the Latitude and Longitude values of the midpoint by moving the map. Let me share a screenshot with you as an example:
{
"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"
}
Code:
const [lat, setLan] = useState(0);
const [lon, setLon] = useState(0);
{position ? (
<MapView
ref={(e) => (mapView = e)}
onCameraIdle={(e) =>
mapView
.getCoordinateFromPoint({
x: (Dimensions.get('screen').width * PixelRatio.get()) / 2,
y: (Dimensions.get('screen').height * PixelRatio.get()) / 2,
})
.then((a) => {
setLan(a.latitude);
setLon(a.longitude);
console.log(a.latitude);
})
.catch((a) => console.log(a))
}
camera={{
target: {
latitude: position.latitude,
longitude: position.longitude,
},
zoom: 15,
}}
style={{...StyleSheet.absoluteFillObject}}
myLocationEnabled={true}
markerClustering={true}
myLocationButtonEnabled={true}
rotateGesturesEnabled={true}
scrollGesturesEnabled={true}
tiltGesturesEnabled={true}
zoomGesturesEnabled={true}
/>
) : (
<ActivityIndicator size=large color=#0000ff />
)}
<View
style={{
flex: 1,
position: 'absolute',
zIndex: 99,
alignItems: 'center',
}}>
<Icon size={50} name=location-on />
<Text style={style.textField}>
Konum Değerleri:Latitude: {lat.toFixed(3)} / Longitude:
{lon.toFixed(3)}
</Text>
</View>
First of all, we add the setState method for our Latitude and Longitude values that we will obtain from the map. Later, we determine the coordinate information of the middle point of the device for each device using the Dimensions property of the react-native, then with the onCameraIdle, our values will be updated every time the camera moves. In onCameraIdle, we get the location information of the middle point in the layout of the map over the reference we have determined before.
Let’s say you opened the map in a certain location, but you want to direct the map to different locations (reference)
Now think of it like this, first of all, the map opens in the user position. But the user suddenly wanted to focus the map on Paris, Hong Kong, Shenzhen, and yes, he really wanted it, how do we do that? But first, a screen video describing the incident:
Code:
<View
style={{
flex: 1,
zIndex: 99,
justifyContent: 'flex-end',
padding: 72,
}}>
<Button
title={'Change'}
onPress={() => {
let nlat = -90 + Math.random() * 180;
let nlon = -180 + Math.random() * 360;
setLan(nlat);
setLon(nlon);
mapView.setCoordinates({latitude: lat, longitude: lon}, 5);
}}
/>
</View>
As you can see in this code, we have added a button every time I click this button, I have created random Latitude and Longitude values. Using the reference, we can change the location of the map outside the map.
So I Want To Use The Transport Map How Do This I Do
First of all, you should have a Tile that you can use for this. You can view the Tiles you can use on OpenStreetMap. We will develop a transport map for the example. To do this, you must first go to: click and become a member.
Code:
<TileOverlay
tileProvider={{
url:
'https://tile.thunderforest.com/transport/{z}/{x}/{y}.png?apikey=<your_api_key>',
}}
/>
We have added the transportation map by using only TileOverlay in our map. In the Hayat Eve Sığar application, the map coloring is also made with TileOverlay. Think about what you can do from here
Setting a Different Marker Icon to Each of Multiple Markers
Let’s think like this, for example, you have a map, this map shows the subway stops around you and you have assigned a single icon, but you should to assign more than one icon, then what will you do. Let’s take a look together:
Code:
export default {
/**
* LOCATION ICONS
*/
Ümraniye: 'metro/m5.png',
Üsküdar: 'metro/m5.png',
Kadıköy: 'metro/m4.png',
Maltepe: 'metro/m4.png',
Kartal: 'metro/m4.png',
Pendik: 'metro/m4.png',
Ataşehir: 'metro/m4.png',
};
For more, you can check https://forums.developer.huawei.com/forumPortal/en/topic/0202457458724700027
Huawei map kit will supports Roadmap view?
sujith.e said:
Huawei map kit will supports Roadmap view?
Click to expand...
Click to collapse
Yep, it will

Pygmy Collection Application Part 2 (Ads Kit)

{
"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 my last article, I have explained how to integrate account kit finance application. Have a look into Pygmy collection application Part 1 (Account kit).
In this article, we will learn how to integrate Splash Ads kit in Pygmy collection finance application.
First we will understand why we need Ads kit.
Every company makes or builds some kind of product. Building or developing is not a big deal but marketing is the big deal to earn money.
Traditional marketing
1. Putting Banners in City.
2. Advertisement in Radio or TV or newspaper.
3. Painting on the wall.
4. Meeting distributors with sample of product.
So, now let’s understand the drawback of each traditional marketing.
1. Putting Banners in City
You know in one city there will be many localities, sub localities streets, area, main roads, service roads etc. How many places you will put banners? If you consider one city only you need to put so many banners and when it comes to multiple cities and globe level. Imagine you need so many marking people across all the cities. And also think about cost. As an organization they need profit with less investment. But when they go with banner advertisement they have to spent lot of money for marketing only.
2. Advertisement in Radio or TV or newspaper
Now let’s take radio or TV advertisement and newspaper. Let’s take example in one home there are 5 people. How many TV’s will be there?
Max 1 or 2.
What about phones?
Its mobile world everyone will have phone. 5 member’s means 5 phones some times more than 5 because few people will have 2-3 phones.
There are thousands of channels. If you want to give advertisement how many channels you will give, 1 or 2 or max 10 channels you will give advertisement. Do you think all people will watch only those channels which you have provided advertisement?
Radio and newspaper also right. Nowadays who will listen radio? Now everyone is moving towards the social media. And also everybody is reading news in mobile application nobody takes newspaper because people started think about paper is waste and people are thinking about environment.
3. Painting on the wall.
How many houses you will paint? Just think about money and time. As I said earlier, think about multiple cities and multiple streets.
4. Meeting distributors with sample of product.
Meeting distributors with sample product. Do you think this will work out? No it won’t work out because all marketing person will not have same marketing knowledge. On top of that you should have to give training about product for them. Even after training about product they will miss some main key points of product while explaining distributors. If distributors are not convinced about product which is explained by marketing person straight away they will say “no to your product”.
Nowadays, traditional marketing has left its place on digital marketing. Advertisers prefer to place their ads via mobile media rather than printed publications or large billboards. In this way, they can reach their target audience more easily and they can measure their efficiency by analysing many parameters such as ad display and the number of clicks. In addition to in-app purchases, the most common method used by mobile developers to generate revenue from their application is to create advertising spaces for advertisers.
In this sense, Huawei Ads meets the needs of both advertisers and mobile developers. So what is this HMS Ads Kit, let’s take a closer look.
Now let us understand Huawei Ads.
Ads Kit leverages the vast user base of Huawei devices and Huawei's extensive data capabilities to provide you with the Publisher Service, helping you to monetize traffic. Meanwhile, it provides the advertising service for advertisers to deliver personalized campaigns or commercial ads to Huawei device users.
The video on this page introduces traffic monetization through Ads Kit, advantages of HUAWEI Ads Publisher Service, and the process for advertisers to display ads.
You can click here to watch the MOOC video about Ads Kit.
Types of Huawei Ads
Banner Ads.
Native Ads.
Rewarded Ads.
Interstitial Ads.
Splash Ads.
Roll Ads.
Banner Ads.
Banner ads are rectangular images that occupy a spot within an app's layout, either at the top, middle, or bottom of the device screen. Banner ads refresh automatically at regular intervals. When a user clicks a banner ad, the user is redirected to the advertiser's page.
Native Ads.
Native ads can be images, text, or videos, which are less disruptive and fit seamlessly into the surrounding content to match your app design. You can customize native ads as needed.
Rewarded Ads.
Rewarded ads are full-screen video ads that allow users to view in exchange for in-app rewards.
Interstitial Ads.
Interstitial ads are full-screen ads that cover the interface of an app. Such an ad is displayed when a user starts, pauses, or exits an app, without disrupting the user's experience.
Splash Ads.
Splash ads are displayed immediately after an app is launched, even before the home screen of the app is displayed. You need to design a default slogan image for the app in advance, and ensure that the default slogan image is displayed before a splash ad is loaded, enhancing user experience.
Rolls Ads.
Roll ads are displayed as short videos or images, before, during, or after the video content is played.
How to integrate Ads Kit
1. Configure the application on the AGC.
2. Client application development process.
3. Testing a Splash Ad.
Configure application on the AGC
Follow the steps
Step 1: We need to register as a developer account in AppGallery Connect. If you are already a developer ignore this step.
Step 2: Create an app by referring to Creating a Project and Creating an App in the Project
Step 3: Set the data storage location based on the current location.
Step 4: Generating a Signing Certificate Fingerprint.
Step 5: Configuring the Signing Certificate Fingerprint.
Step 6: Download your agconnect-services.json file, paste it into the app root directory.
Client application development process
Follow the steps.
Step 1: Create an Android application in the Android studio (Any IDE which is your favorite).
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'
dependencies {
implementation 'com.huawei.hms:ads:3.4.47.302'
}
Root level gradle dependencies.
Code:
maven { url 'https://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 3: To allow HTTP and HTTPS network requests on devices with targetSdkVersion 28 or later, configure the following information in the AndroidManifest.xml file:
XML:
<application
...
android:usesCleartextTraffic="true"
>
...
</application>
Step 4: Initialize Ads kit activity or application class.
Step 5: Build Application.
SplashScreen.java
Java:
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.widget.FrameLayout;
import com.huawei.agconnect.crash.AGConnectCrash;
import com.huawei.hms.ads.AdListener;
import com.huawei.hms.ads.AdParam;
import com.huawei.hms.ads.AudioFocusType;
import com.huawei.hms.ads.BannerAdSize;
import com.huawei.hms.ads.HwAds;
import com.huawei.hms.ads.banner.BannerView;
import com.huawei.hms.ads.splash.SplashAdDisplayListener;
import com.huawei.hms.ads.splash.SplashView;
import com.shea.pygmycollection.R;
import com.shea.pygmycollection.huaweianalytics.AnalyticUtils;
import com.shea.pygmycollection.huaweianalytics.HuaweiAnalyticsClient;
import com.shea.pygmycollection.huaweianalytics.HuaweiEventParams;
import com.shea.pygmycollection.huaweianalytics.HuaweiLog;
import com.shea.pygmycollection.utils.PygmyNavigator;
import com.shea.pygmycollection.utils.UserDataUtils;
public class SplashScreen extends AppCompatActivity {
private static final int TIME_OUT = 3000;
// "testq6zq98hecj" is a dedicated test ad unit ID. Before releasing your app, replace the test ad unit ID with the formal one.
private static final String AD_ID = "testd7c5cewoj6";
private static final int AD_TIMEOUT = 10000;
private static final int MSG_AD_TIMEOUT = 1001;
private static final String TAG = SplashScreen.class.getSimpleName();
SplashView splashView;
/**
* Pause flag.
* On the splash ad screen:
* Set this parameter to true when exiting the app to ensure that the app home screen is not displayed.
* Set this parameter to false when returning to the splash ad screen from another screen to ensure that the app home screen can be displayed properly.
*/
private boolean hasPaused = false;
// Callback processing when an ad display timeout message is received.
private Handler timeoutHandler = new Handler(new Handler.Callback() {
@Override
public boolean handleMessage(@NonNull Message msg) {
if (SplashScreen.this.hasWindowFocus()) {
jump();
}
return false;
}
});
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_splash_screen);
// Initialize the HUAWEI Ads SDK.
HwAds.init(this);
splashView = findViewById(R.id.splash_ad_view);
// AGConnectCrash.getInstance().testIt(this);
AGConnectCrash.getInstance().enableCrashCollection(true);
AnalyticUtils.logHuaweiAnalyticEvent(new HuaweiLog()
.setScreenName(HuaweiEventParams.ScreenName.MAIN_SPLASH)
.setDescription(HuaweiEventParams.Description.OPEN_SHARE_SCREEN)
.setEventName(HuaweiEventParams.EventName.OPEN)
.setUiElementName(HuaweiEventParams.UiElementName.GALLARY_BUTTON)
);
loadAd();
}
SplashAdDisplayListener adDisplayListener = new SplashAdDisplayListener() {
@Override
public void onAdShowed() {
// Called when an ad is displayed.
Log.d(TAG, "onAdShowed");
AGConnectCrash.getInstance().log("onAdShowed");
}
@Override
public void onAdClick() {
// Called when an ad is clicked.
Log.d(TAG, "onAdClick");
AGConnectCrash.getInstance().log(Log.INFO, "OnAClick");
}
};
/**
* When the ad display is complete, the app home screen is displayed.
*/
private void jump() {
if (!hasPaused) {
hasPaused = true;
if (UserDataUtils.isUserLoggedIn(SplashScreen.this)) {
PygmyNavigator.navigateToHomeScreen(SplashScreen.this);
} else {
PygmyNavigator.navigateToLoginScreen(SplashScreen.this);
}
finish();
}
}
/**
* Set this parameter to true when exiting the app to ensure that the app home screen is not displayed.
*/
@Override
protected void onStop() {
// Remove the timeout message from the message queue.
timeoutHandler.removeMessages(MSG_AD_TIMEOUT);
hasPaused = true;
super.onStop();
}
/**
* Set this parameter to false when returning to the splash ad screen from another screen to ensure that the app home screen can be displayed properly.
*/
@Override
protected void onRestart() {
super.onRestart();
hasPaused = false;
jump();
}
@Override
protected void onDestroy() {
super.onDestroy();
}
private void loadAd() {
int orientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
AdParam adParam = new AdParam.Builder().build();
SplashView.SplashAdLoadListener splashAdLoadListener = new SplashView.SplashAdLoadListener() {
@Override
public void onAdLoaded() {
// Called when an ad is loaded successfully.
}
@Override
public void onAdFailedToLoad(int errorCode) {
// Called when an ad fails to be loaded. The app home screen is then displayed.
jump();
}
@Override
public void onAdDismissed() {
// Called when the display of an ad is complete. The app home screen is then displayed.
jump();
}
};
// Obtain SplashView.
splashView.setAdDisplayListener(adDisplayListener);
// Set the default slogan.
splashView.setSloganResId(R.drawable.ic_baseline_account_balance_wallet_24);
// Set the audio focus type for a video splash ad.
splashView.setAudioFocusType(AudioFocusType.GAIN_AUDIO_FOCUS_ALL);
// Load the ad. AD_ID indicates the ad unit ID.
splashView.load(AD_ID, orientation, adParam, splashAdLoadListener);
// Send a delay message to ensure that the app home screen can be properly displayed after the ad display times out.
timeoutHandler.removeMessages(MSG_AD_TIMEOUT);
timeoutHandler.sendEmptyMessageDelayed(MSG_AD_TIMEOUT, AD_TIMEOUT);
}
}
activity_splash_screen.xml
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:hwads="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.activities.SplashScreen"
android:orientation="vertical"
android:layout_gravity="center"
android:gravity="center"
android:background="@color/colorAccent">
<RelativeLayout
android:id="@+id/logo_area"
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:visibility="visible">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="40dp"
android:orientation="horizontal">
<ImageView
android:id="@+id/iv"
android:layout_width="50dp"
android:layout_height="50dp"
android:layout_centerInParent="true"
android:layout_gravity="center"
android:src="@drawable/splash_image"
android:visibility="visible" />
<TextView
android:id="@+id/appName"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="center"
android:layout_marginLeft="20dp"
android:gravity="center"
android:text="eCollection"
android:textColor="@android:color/white"
android:textSize="40sp"
android:textStyle="bold"
android:visibility="visible" />
</LinearLayout>
</RelativeLayout>
<!-- Splash ad view. -->
<com.huawei.hms.ads.splash.SplashView
android:id="@+id/splash_ad_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_above="@id/logo_area" />
<com.huawei.hms.ads.banner.BannerView
android:id="@+id/hw_banner_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
hwads:adId="testw6vs28auh3"
android:visibility="gone"
hwads:bannerSize="BANNER_SIZE_360_57"/>
</RelativeLayout>
3. Testing a Splash Ads
Result
Tips and Tricks
Make sure you added agconnect-service.json file.
If your app can run both on Huawei mobile phones and non-Huawei Android phones (outside the Chinese mainland), integrate the HUAWEI Ads SDK (com.huawei.hms:ads) into your app.
If your app can run only on Huawei mobile phones, integrate the HUAWEI Ads Lite SDK (com.huawei.hms:ads-lite).
Add internet permission in AndroidManifest.xml
Conclusion
In this article, we have learnt what the traditional marketing. Drawbacks of traditional marketing and Types of Huawei Ads, How to integrate Huawei Splash Ads.
Reference
Huawei Splash Ads
Official Huawei Ads kit
Does this works on offline?
Thanks for sharing!!!

Integration of Huawei Account kit in Navigation Glove IoT application Using Kotlin - Part 1

{
"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 series of article, we will learn about Navigation Glove application and also we will learn about integration of the Huawei Account kit in Navigation Glove IoT application.
It’s really quite interesting application. Have patience to read the full article. Because great things will take time.
Let us understand how this product works.
Gloves
Navigation Glove Application
What is IoT?
IoT stands for Internet of things. IoT refers to the collective network of connected devices and the technology that facilitates communication between devices and the cloud, as well as between the devices themselves. Thanks to the advent of inexpensive computer chips and high bandwidth telecommunication, now we have billions of devices connected to the internet. This means everyday devices like toothbrushes, vacuums, cars, and machines can use sensors to collect data and respond intelligently to users.
Features of the Navigation Glove application.
Quick, Seamless & Mobile phone-less – Navigation Assistance.
Support for Auto Indicators (Left – Right).
Increased Traffic Safety – Obey Rules, Less Violations, Increased Safety.
Docking Point suggestions and Incentives for the customers.
Quick, Seamless & Mobile phone-less – Navigation Assistance
In this application for navigation mobile phone is not required. Gloves should wear in both the hands left hand and right hand. Application will be connected to Navigation gloves, distance and direction will sent to device from application to device.
Support for Auto Indicators (Left and Right).
Since we are sending direction from mobile application depending upon the left and right command left glove or right glove will blink.
Application information.
In this application, we will learn what all the kits required in the application and how this product works.
Account kit
Map Kit
Site kit
Directions API
Location Kit
Analytics Kit
Ads Kit
Remote configuration kit
Crash Service kit
Push Kit
How does this application works?
You need to open application and login with Huawei Account.
Give all necessary permission from the dialogue box.
Select source and destination place.
Select the mode Driving/Walking/Cycling
Click on navigation button.
Connect the device which are shown from the list of devices.
Once connection is done as the user move user location and directions API distance will be calculated and distance will be sent to glove.
When the distance is less 50 meter the blinking will be faster, otherwise it will blink normally.
From the Navigation glove application left and right command will be sent to the respected left and right glove.
Increased Traffic Safety – Obey Rules, Less Violations, Increased Safety
In this situation rider is not using mobile phone, so direction shown in gloves so rider will be very safe and rider obeys the traffic rules and also there will be less violations. Using mobile phone while riding is very risky, this Navigation glove application avoids the usage of mobile for direction, so rider will be safe.
Docking Point suggestions and Incentives for the customers
When the distance is less than 50 meter LED will blink faster, so end users will understand the turning points.
App Supports for.
App supports two modes – Walking and Driving.
Automatically drives the Indicator System – With Single Click (Left / Right)
Normal and Satellite view sup
Hardware components for Glove
A pair of gloves in which the hardware kit can be embedded (Stitched or pasted based on expert inputs)
Kit for Right Hand Glove – ATTINY85 Microcontroller, Bluetooth modules, LED, 9v Battery, Power Control Circuitry.
Kit for Left Hand Glove - ATTINY85 Microcontroller, Bluetooth module, LED, 9v Battery, Power Control Circuitry, NFC reader.
The above same hardware can be made as gloves, check in below image.
Prerequisite​
AppGallery Account
Android Studio 3.X
SDK Platform 19 or later
Gradle 4.6 or later
HMS Core (APK) 4.0.0.300 or later
Huawei Phone EMUI 3.0 or later
Non-Huawei Phone Android 4.4 or later
Service integration on AppGallery.​
1. We need to register as a developer account in AppGallery Connect.
2. Create an app by referring to Creating a Project and Creating an App in the Project.
3. Set the data storage location based on the current location.
4. Enabling Account Kit Service on AppGallery.
5. Generating a Signing Certificate Fingerprint.
6. Configuring the Signing Certificate Fingerprint.
7. Get your agconnect-services.json file to the app root directory.
Client development
1. Create android project in android studio IDE.
2. Add the maven URL inside the repositories of buildscript and allprojects respectively (project level build.gradle file).
Code:
maven { url 'https://developer.huawei.com/repo/' }
3. Add the classpath inside the dependency section of the project level build.gradle file.
Code:
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
4. Add the plugin in the app-level build.gradle file.
Code:
apply plugin: 'com.huawei.agconnect'
5. Add the below library in the app-level build.gradle file dependencies section.
Code:
implementation 'com.huawei.hms:hwid:6.1.0.300'
6. Add all the below permission in the AndroidManifest.xml.
XML:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
7. Sync the project.
Java:
private fun signIn() {
val authParams =
AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setIdToken()
.createParams()
val service = AccountAuthManager.getService([email protected], authParams)
startActivityForResult(service.signInIntent, 8888)
}
LoginActivity.kt
Java:
package com.huawei.navigationglove.ui
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import com.huawei.navigationglove.R
import com.huawei.hms.common.ApiException
import android.widget.Toast
import com.huawei.hms.support.account.result.AuthAccount
import com.huawei.hms.support.account.AccountAuthManager
import android.content.Intent
import android.util.Log
import androidx.annotation.Nullable
import com.huawei.hmf.tasks.Task
import com.huawei.hms.support.account.request.AccountAuthParams
import com.huawei.hms.support.account.request.AccountAuthParamsHelper
import kotlinx.android.synthetic.main.activity_login.*
class LoginActivity : AppCompatActivity() {
private val TAG: String = LoginActivity::class.java.name
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_login)
huaweiLogin.setOnClickListener {
signIn()
}
}
private fun signIn() {
val authParams =
AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setIdToken()
.createParams()
val service = AccountAuthManager.getService([email protected], authParams)
startActivityForResult(service.signInIntent, 8888)
}
override fun onActivityResult(requestCode: Int, resultCode: Int, @Nullable data: Intent?) {
// Process the authorization result and obtain an ID token from AuthAccount.
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == 8888) {
val authAccountTask: Task<AuthAccount> =
AccountAuthManager.parseAuthResultFromIntent(data)
if (authAccountTask.isSuccessful()) {
// The sign-in is successful, and the user's ID information and ID token are obtained.
val authAccount: AuthAccount = authAccountTask.getResult()
Log.i(TAG, "idToken:" + authAccount.idToken)
Toast.makeText(
this,
"Welcome " + authAccount.displayName,
Toast.LENGTH_LONG
).show()
startActivity(Intent(this, HomeScreenActivity::class.java))
} else {
// The sign-in failed. No processing is required. Logs are recorded for fault locating.
Log.e(
TAG,
"sign in failed : " + (authAccountTask.getException() as ApiException).statusCode
)
}
}
}
}
activity_login.xml
XML:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@drawable/background"
tools:context=".ui.LoginActivity">
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtUsername"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="271dp"
android:layout_height="63dp"
android:layout_marginStart="70dp"
android:layout_marginTop="240dp"
android:layout_marginEnd="70dp"
android:hint="Username"
android:textColorHint="#A7A7A7"
app:boxStrokeColor="#EAEAEE"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputUsername"
android:layout_width="match_parent"
android:layout_height="55dp"
android:textColor="#5B5B5B"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="TouchTargetSizeCheck" />
</com.google.android.material.textfield.TextInputLayout>
<com.google.android.material.textfield.TextInputLayout
android:id="@+id/txtPassword"
style="@style/Widget.MaterialComponents.TextInputLayout.OutlinedBox"
android:layout_width="271dp"
android:layout_height="63dp"
android:layout_marginStart="70dp"
android:layout_marginTop="310dp"
android:layout_marginEnd="70dp"
android:hint="Password"
android:textColorHint="#A7A7A7"
app:endIconMode="password_toggle"
app:boxStrokeColor="#EAEAEE"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent">
<com.google.android.material.textfield.TextInputEditText
android:id="@+id/inputPassword"
android:layout_width="match_parent"
android:layout_height="55dp"
android:textColor="#5B5B5B"
android:textSize="15sp"
android:textStyle="bold"
tools:ignore="TouchTargetSizeCheck" />
</com.google.android.material.textfield.TextInputLayout>
<Button
android:id="@+id/button4"
android:layout_width="271dp"
android:layout_height="55dp"
android:layout_marginTop="200dp"
android:text="Login"
android:textAllCaps="false"
android:textAlignment="center"
android:textColor="#FFFFFF"
android:textSize="16sp"
android:textStyle="bold"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent" />
<TextView
android:id="@+id/textView4"
android:layout_width="139dp"
android:layout_height="15dp"
android:layout_marginStart="70dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="283dp"
android:text="Don't have account?"
android:textColor="#A7A7A7"
android:textSize="13sp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.0"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/button4" />
<TextView
android:id="@+id/textView6"
android:layout_width="135dp"
android:layout_height="16dp"
android:layout_marginStart="7dp"
android:layout_marginTop="8dp"
android:layout_marginEnd="68dp"
android:text="Create a new account"
android:textColor="#3BA8BE"
android:textSize="12sp"
android:textStyle="bold"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/textView4"
app:layout_constraintTop_toBottomOf="@+id/button4" />
<TextView
android:id="@+id/textView7"
android:layout_width="286dp"
android:layout_height="66dp"
android:text="Navigation Glove"
android:textAlignment="center"
android:textColor="#4E4E4E"
android:textSize="24sp"
android:textStyle="normal|bold"
app:layout_constraintBottom_toTopOf="@+id/txtUsername"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.496"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.407" />
<TextView
android:id="@+id/textView8"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="228dp"
android:layout_marginTop="6dp"
android:layout_marginEnd="70dp"
android:text="Forgot Password?"
android:textColor="#3BA8BE"
app:layout_constraintBottom_toTopOf="@+id/button4"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/txtPassword" />
<Button
android:id="@+id/tb"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="6dp"
android:text="Forgot Password?"
android:textColor="#fff"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4"
android:visibility="gone"/>
<com.huawei.hms.support.hwid.ui.HuaweiIdAuthButton
android:id="@+id/huaweiLogin"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="8dp"
android:layout_marginEnd="8dp"
android:layout_marginTop="15dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/textView4" />
</androidx.constraintlayout.widget.ConstraintLayout>
Result​
Tips and Tricks​
1. Make sure you are already registered as a Huawei developer.
2. Set min SDK version to 21 or later, otherwise you will get AndriodManifest to merge issue.
3. Make sure you have added the agconnect-services.json file to the app folder.
4. Make sure you have added the SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
6. If you get the 6003 error code, there may be SHA-256 certificate issue.
Conclusion​
In this article, we have learnt the main flow to integration of the Huawei Account Kit in your mobile application using Android Studio and Kotlin. We also learnt the product details and how does this application works and other than the Account Kit, HMS core provides a wider range of services to enhance the user experience with the Huawei platform. We have learnt the steps to create projects and steps to integrate the account kit.
Reference​
Account Kit - Official document
Account Kit - Code lab
Account Kit - Training Video

Integration of Huawei Map kit in Navigation Glove IoT application Using Kotlin - Part 2

{
"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 series of article, we will learn about Navigation Glove application and also we will learn about integration of the Huawei Map kit in Navigation Glove IoT application.
If you are new to this series of article follow my previous article Beginner: Integration of Huawei Account kit in Navigation Glove IoT application Using Kotlin - Part 1
Using Huawei Maps Kit for Android, You can also use API calls to add markers, polygons, and overlays to a basic map, and to change the user's view of a particular map area. These objects provide additional information for map locations, and allows user to interact with the map. You can also customize the map style. If you want to understand about service price follow this link.
In Huawei map you create the map using xml or using instance as well. Adding map type is very easy. Currently it supports 5 types as follows.
1. MAP_TYPE_NORMAL
2. MAP_TYPE_HYBRID
3. MAP_TYPE_NONE
4. MAP_TYPE_SATELLITE
5. MAP_TYPE_TERRAIN
Code:
hMap!!.mapType = HuaweiMap.MAP_TYPE_NORMAL
Map Kit allows to enable location button on the map
Code:
hMap!!.uiSettings.isMyLocationButtonEnabled = true
You can set the following map attributes check the below code
Java:
// Declare a SupportMapFragment object.
val mSupportMapFragment: SupportMapFragment
// Set initial camera attributes.
val cameraPosition = CameraPosition.builder().target(LatLng(12.893478, 77.334595)).zoom(10f).bearing(45f).tilt(20f).build()
// Construct the target area of the camera.
val southwest = LatLng(12.893478, 77.334595)
val northeast = LatLng(12.893478, 77.334595)
val latLngBounds = LatLngBounds(southwest, northeast)
val options = HuaweiMapOptions()
// Set the map type. The options are none, normal, and terrain.
options.mapType(HuaweiMap.MAP_TYPE_NORMAL)
// Set camera attributes.
.camera(cameraPosition)
// Set whether to enable the zoom function. It is enabled by default.
.zoomControlsEnabled(false)
// Set whether to enable the compass. It is enabled by default.
.compassEnabled(true)
// Set whether to enable zoom gestures. They are enabled by default.
.zoomGesturesEnabled(true)
// Set whether to enable scroll gestures. They are enabled by default.
.scrollGesturesEnabled(true)
// Set whether to enable rotation gestures. They are enabled by default.
.rotateGesturesEnabled(false)
// Set whether to enable tilt gestures. They are enabled by default.
.tiltGesturesEnabled(true)
// Set whether to place the map view on the top of the map window. The default value is true.
.zOrderOnTop(true)
// Set whether to bind the map lifecycle to SupportMapFragment or the view of SupportMapFragment. The default value is true.
.useViewLifecycleInFragment(true)
// Set whether to enable the lite mode for the map. It is disabled by default.
.liteMode(false)
// Set the preferred minimum zoom level.
.minZoomPreference(3f)
// Set the preferred maximum zoom level.
.maxZoomPreference(13f)
// Set an area to constrain the camera target so that the camera target does not move outside the bounds when a user scrolls the map camera.
.latLngBoundsForCameraTarget(latLngBounds)
mSupportMapFragment = SupportMapFragment.newInstance(options)
Using Rest services also, you can use the followings
Direction API
Matrix API
Map Static API
Tile API
Elevation API
Snap to Road API
Prerequisite
AppGallery Account
Android Studio 3.X
SDK Platform 19 or later
Gradle 4.6 or later
HMS Core (APK) 4.0.0.300 or later
Huawei Phone EMUI 3.0 or later
Non-Huawei Phone Android 4.4 or later
Service integration on AppGallery.
1. We need to register as a developer account in AppGallery Connect.
2. Create an app by referring to Creating a Project and Creating an App in the Project.
3. Set the data storage location based on the current location.
4. Enabling Map Kit Service on AppGallery Connect.
5. Generating a Signing Certificate Fingerprint.
6. Configuring the Signing Certificate Fingerprint.
7. Get your agconnect-services.json file to the app root directory.
Client development
1. Create android project in android studio IDE.
2. Add the maven URL inside the repositories of buildscript and allprojects respectively (project level build.gradle file).
Code:
maven { url 'https://developer.huawei.com/repo/' }
3. Add the classpath inside the dependency section of the project level build.gradle file.
Code:
classpath 'com.huawei.agconnect:agcp:1.5.2.300'
4. Add the plugin in the app-level build.gradle file.
Code:
apply plugin: 'com.huawei.agconnect'
5. Add the below library in the app-level build.gradle file dependencies section.
implementation 'com.huawei.hms:maps:5.2.0.301'Copy codeCopy code
6. Add all the below permission in the AndroidManifest.xml.
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<!-- Allow the app to obtain the coarse longitude and latitude of a user through the Wi-Fi network or base station. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<!-- Allow the app to receive location information from satellites through the GPS chip. -->
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>Copy codeCopy code
7. Sync the project.
HomeScreenActivity.kt
Java:
package com.huawei.navigationglove.ui
import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.util.Log
import com.huawei.hms.maps.*
import com.huawei.navigationglove.R
import com.huawei.navigationglove.api.ApiClient
import com.huawei.navigationglove.api.ApiService
import io.reactivex.observers.DisposableSingleObserver
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
class HomeScreenActivity : AppCompatActivity(), OnMapReadyCallback {
private val TAG = HomeScreenActivity::class.java.name
var hMap: HuaweiMap? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_home_screen)
val options = HuaweiMapOptions()
// Set the map type. The options are none, normal, and terrain.
options.mapType(HuaweiMap.MAP_TYPE_NORMAL)
// Set camera attributes.
//.camera(cameraPosition)
// Set whether to enable the zoom function. It is enabled by default.
.zoomControlsEnabled(true)
// Set whether to enable the compass. It is enabled by default.
.compassEnabled(true)
// Set whether to enable zoom gestures. They are enabled by default.
.zoomGesturesEnabled(true)
// Set whether to enable scroll gestures. They are enabled by default.
.scrollGesturesEnabled(true)
// Set whether to enable rotation gestures. They are enabled by default.
.rotateGesturesEnabled(false)
// Set whether to enable tilt gestures. They are enabled by default.
.tiltGesturesEnabled(true)
// Set whether to place the map view on the top of the map window. The default value is true.
.zOrderOnTop(true)
// Set whether to bind the map lifecycle to SupportMapFragment or the view of SupportMapFragment. The default value is true.
.useViewLifecycleInFragment(true)
// Set whether to enable the lite mode for the map. It is disabled by default.
.liteMode(false)
// Set the preferred minimum zoom level.
.minZoomPreference(3f)
// Set the preferred maximum zoom level.
.maxZoomPreference(13f)
// Set an area to constrain the camera target so that the camera target does not move outside the bounds when a user scrolls the map camera.
//.latLngBoundsForCameraTarget(latLngBounds)
MapFragment.newInstance(options)
val mSupportMapFragment: SupportMapFragment? = supportFragmentManager.findFragmentById(R.id.mapfragment_mapfragmentdemo) as SupportMapFragment?
mSupportMapFragment!!.getMapAsync(this)
}
override fun onMapReady(huaweiMap: HuaweiMap) {
Log.d(TAG, "onMapReady: ")
hMap = huaweiMap
hMap!!.mapType = HuaweiMap.MAP_TYPE_NORMAL
hMap!!.uiSettings.isMyLocationButtonEnabled = true
}
}
activity_home_screen.xml
XML:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:map="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".ui.HomeScreenActivity">
<fragment
android:id="@+id/mapfragment_mapfragmentdemo"
class="com.huawei.hms.maps.SupportMapFragment"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraTargetLat="12.9716"
map:cameraTargetLng="77.5946"
map:cameraZoom="10"/>
</RelativeLayout>
Result​
Tips and Tricks​
1. Make sure you are already registered as a Huawei developer.
2. Set min SDK version to 21 or later, otherwise you will get AndriodManifest to merge issue.
3. Make sure you have added the agconnect-services.json file to the app folder.
4. Make sure you have added the SHA-256 fingerprint without fail.
5. Make sure all the dependencies are added properly.
6. If you want to location feature in the Map, Make sure you added location permission in AndroidManifest.xml file
7. If you install app in android version 6 or greater than make sure you handled run time permission.
Conclusion​
In this article, we have learnt the integration of the Huawei Map Kit in Navigation Glove application using Android Studio and Kotlin. And also we have learnt the features available by the map kit. We looked what possible APIs are provided by the Huawei for Rest services.
Reference​
Map Kit - Official document
Map Kit - Code lab
Map Kit - Training Video

Categories

Resources