Huawei Remote Configuration integration with Unity - Huawei Developers

More information like this, you can visit HUAWEI Developer Forum​
Introduction:
In this article, we will cover Integration of Remote Configuration in Unity Project using Official Plugin (Huawei HMS Core App Services).
Requirements:
1. Unity Editor
2. Huawei device
3. Visual Studio
Follows the steps:
Step 1. Create Unity Project.
Click unity icon.
Click NEW, select 3D, Project Name and Location.
Click CREATE, as follows.
{
"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. Click Asset Store, search Huawei HMS Core App Services and click Import, as follows.
Step 3. Once import is successful, verify directory in Assets > Huawei HMS Core App Services path, as follows.
Step 4. Click Console and create a New Project.
Step 5. Choose Project Settings > Player and edit the required options in Publishing Settings, as follows.
Step 6. Verify the files created in Step 5.
Step 7. Download agconnect-services.json and copy to Assets>Plugins>Android, as follows.
Step 8. Update the Package Name.
Step 9. Open LauncherTemplate.gradle and add below line
Code:
apply plugin: 'com.huawei.agconnect'
Step 10. Open "baseProjectTemplate.gradle" and add lines, as follows.
Code:
maven {url 'https://developer.huawei.com/repo/'}
Code:
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 11. Open "mainTemplate.gradle" and add lines like shown below
Code:
apply plugin: 'com.huawei.agconnect'
Code:
implementation 'com.huawei.agconnect:agconnect-core:1.3.1.300'
implementation 'com.huawei.agconnect:agconnect-remoteconfig:1.4.1.300'
Step 12. Open AndroidManifest file and Add Activity like shown below.
Code:
<activity android:name="com.hms.hms_analytic_activity.TestAppLinksActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
</activity>
Step 13. Create TestAppLinksActivity.java and place it in Assets->Plugins->Android.
TestAppLinksActivity.java
Code:
//package com.test.applinks;
package com.hms.hms_analytic_activity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;
import android.widget.Toast;
import android.graphics.Typeface;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
import com.huawei.agconnect.remoteconfig.AGConnectConfig;
import com.huawei.agconnect.remoteconfig.ConfigValues;
import com.huawei.hmf.tasks.OnFailureListener;
import com.huawei.hmf.tasks.OnSuccessListener;
import com.unity3d.player.R;
//import com.test.remote.config.R;
import com.test.mylibrary.MyLibClass;
import com.test.mylibrary.MyContext;
//import androidx.appcompat.app.AppCompatActivity;
public class TestAppLinksActivity extends UnityPlayerActivity {
private static final String GREETING_KEY = "GREETING_KEY";
private static final String SET_BOLD_KEY = "SET_BOLD_KEY";
private static AGConnectConfig config;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestAppLinksActivity ", "onCreate>> @@");
config = AGConnectConfig.getInstance();
MyLibClass a = new MyLibClass(new MyContext(this));
//config.applyDefault(R.xml.remote_config);
config.applyDefault(a.getRemoteConfigFileId());
String key = config.getValueAsString(GREETING_KEY);
Boolean isBold = config.getValueAsBoolean(SET_BOLD_KEY);
Log.e("TestAppLinksActivity ", " values from remote config files-key->>"+key+"<-----isBold---->"+isBold);
}
public static void getSavedConfig() {
Log.e("TestAppLinksActivity ", " getSavedConfig >>");
config = AGConnectConfig.getInstance();
String key = config.getValueAsString(GREETING_KEY);
Boolean isBold = config.getValueAsBoolean(SET_BOLD_KEY);
Log.e("TestAppLinksActivity ", "values from saved remote config -key->>"+key+"<-----isBold---->"+isBold);
}
public static void setCallback() {
Log.e("TestAppLinksActivity ", "setCallback>> @@");
fetchAndApply();
}
private static void fetchAndApply(){
config = AGConnectConfig.getInstance();
Log.e("TestAppLinksActivity", "fetchAndApply config>>"+config);
String key = config.getValueAsString(GREETING_KEY);
Boolean isBold = config.getValueAsBoolean(SET_BOLD_KEY);
Log.e("TestAppLinksActivity", "values from remote config files-key->>"+key+"<-----isBold---->"+isBold);
Log.e("TestAppLinksActivity", "fetchAndApply>>");
config.fetch(0).addOnSuccessListener(new OnSuccessListener<ConfigValues>() {
@Override
public void onSuccess(ConfigValues configValues) {
Log.e("TestAppLinksActivity", "fetchAndApply onSuccess>>"+configValues);
// Apply Network Config to Current Config
config.apply(configValues);
//updateUI();
String key = config.getValueAsString(GREETING_KEY);
Boolean isBold = config.getValueAsBoolean(SET_BOLD_KEY);
Log.e("TestAppLinksActivity", "values from updated remote config files-key->>"+key+"<-----isBold---->"+isBold);
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
//textView.setText("fetch setting failed: " + e.getMessage());
Log.e("TestAppLinksActivity", " fetchAndApply onFailure>>"+e.getMessage());
}
});
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
//handleAppLinking(intent);
}
}
Code Explanation - Please refer
https://developer.huawei.com/consumer/en/codelab/RemoteConfig/index.html#8
For full content, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201361479871390297&fid=0101188387844930001

Related

Android App Bundle - Features on demand--Part 2

More articles like this, you can visit HUAWEI Developer Forum.​
In this article, we will build Android App Bundle (AAB).
In the previous article, we have learned about Huawei Dynamic Ability. Refer the URL:
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201297090480680014&fid=0101187876626530001
If you have not read my previous article which is part 1 of this article. I would recommend you to kindly go through the link below:
https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0201297090480680014&fid=0101187876626530001
1. Dynamic Ability:
Dynamic Ability is a service in which HUAWEI AppGallery implements dynamic loading based on the Android App Bundle technology.
Apps integrated with the Dynamic Ability SDK can dynamically download features or language packages from HUAWEI AppGallery as required, reducing the unnecessary consumption of network traffic and device storage space.
2. Android App Bundle:
It is a new upload format that includes all your apps compiled code and resources, but accepts APK generation and signing to AppGallery. Traditionally, Android apps are distributed using a special file called an Android Package (.apk).
Let’s start development:
We have created following project directory:
{
"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"
}
Let’s see the gradle file:
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
android {
compileSdkVersion 28
buildToolsVersion "28.0.3"
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
dataBinding {
enabled = true
}
defaultConfig {
applicationId "com.hms.manoj.aab"
minSdkVersion 26
targetSdkVersion 28
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
dynamicFeatures = [":repository", ":retrofit", ":viewmodel"]
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
// Android MVVM Components
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
// Android Support Library
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'com.google.android.material:material:1.1.0-alpha04'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
//Huawei Dynamic ability
api 'com.huawei.hms:dynamicability:1.0.11.302'
}
Let’s see the manifest file:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.hms.manoj.aab">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application
android:name="com.hms.manoj.aab.MyApp"
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="com.hms.manoj.aab.ui.ShowsActivity"
android:launchMode="singleTask"
android:theme="@style/AppTheme"
android:windowSoftInputMode="adjustNothing">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name="com.hms.manoj.aab.ui.ShowDetailActivity"
android:screenOrientation="fullSensor"
android:label="@string/app_name" />
<activity
android:name="com.hms.manoj.aab.ui.CastActivity"
android:screenOrientation="fullSensor"
android:label="@string/app_name" />
</application>
</manifest>
Let’s see the implementation of feature installation inside the code:
Code:
package com.hms.manoj.aab.ui;
import android.content.Intent;
import android.content.IntentSender;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import androidx.annotation.Nullable;
import androidx.appcompat.app.AppCompatActivity;
import androidx.databinding.DataBindingUtil;
import androidx.lifecycle.ViewModelProviders;
import androidx.recyclerview.widget.GridLayoutManager;
import com.hms.manoj.aab.R;
import com.hms.manoj.aab.apiconnector.response.Show;
import com.hms.manoj.aab.databinding.ActivityShowsBinding;
import com.hms.manoj.aab.ui.adapter.ShowAdapter;
import com.hms.manoj.aab.viewmodel.ShowsViewModel;
import com.huawei.hms.feature.install.FeatureInstallManager;
import com.huawei.hms.feature.install.FeatureInstallManagerFactory;
import com.huawei.hms.feature.listener.InstallStateListener;
import com.huawei.hms.feature.model.FeatureInstallException;
import com.huawei.hms.feature.model.FeatureInstallRequest;
import com.huawei.hms.feature.model.FeatureInstallSessionStatus;
import com.huawei.hms.feature.model.InstallState;
import com.huawei.hms.feature.tasks.FeatureTask;
import com.huawei.hms.feature.tasks.listener.OnFeatureCompleteListener;
import com.huawei.hms.feature.tasks.listener.OnFeatureFailureListener;
import com.huawei.hms.feature.tasks.listener.OnFeatureSuccessListener;
import java.util.List;
import static com.hms.manoj.aab.utils.Utils.KEY_SHOW_ID;
public class ShowsActivity extends AppCompatActivity {
public static final String TAG=ShowsActivity.class.getName();
private FeatureInstallManager mFeatureInstallManager;
private int sessionId = 10086;
private ActivityShowsBinding mBinding;
private ShowsViewModel mShowsViewModel;
private InstallStateListener mStateUpdateListener = new InstallStateListener() {
@Override
public void onStateUpdate(InstallState state) {
Log.d(TAG, "install session state " + state);
if (state.status() == FeatureInstallSessionStatus.REQUIRES_USER_CONFIRMATION) {
try {
mFeatureInstallManager.triggerUserConfirm(state, ShowsActivity.this, 1);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
return;
}
if (state.status() == FeatureInstallSessionStatus.REQUIRES_PERSON_AGREEMENT) {
try {
mFeatureInstallManager.triggerUserConfirm(state, ShowsActivity.this, 1);
} catch (IntentSender.SendIntentException e) {
e.printStackTrace();
}
return;
}
if (state.status() == FeatureInstallSessionStatus.INSTALLED) {
Log.i(TAG, "installed success ,can use new feature");
return;
}
if (state.status() == FeatureInstallSessionStatus.UNKNOWN) {
Log.e(TAG, "installed in unknown status");
return;
}
if (state.status() == FeatureInstallSessionStatus.DOWNLOADING) {
long process = state.bytesDownloaded() * 100 / state.totalBytesToDownload();
Log.d(TAG, "downloading percentage: " + process);
return;
}
if (state.status() == FeatureInstallSessionStatus.FAILED) {
Log.e(TAG, "installed failed, errorcode : " + state.errorCode());
return;
}
}
};
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getSupportActionBar().setTitle("All Shows");
mFeatureInstallManager = FeatureInstallManagerFactory.create(this);
mBinding = DataBindingUtil.setContentView(this, R.layout.activity_shows);
mShowsViewModel = ViewModelProviders.of(this).get(ShowsViewModel.class);
wait(true);
getShowList();
}
public void installFeature(View view) {
if (mFeatureInstallManager == null) {
return;
}
FeatureInstallRequest request = FeatureInstallRequest.newBuilder()
.addModule("repository")
.addModule("retrofit")
.addModule("viewmodel")
.build();
final FeatureTask<Integer> task = mFeatureInstallManager.installFeature(request);
task.addOnListener(new OnFeatureSuccessListener<Integer>() {
@Override
public void onSuccess(Integer integer) {
Log.d(TAG, "load feature onSuccess.session id:" + integer);
}
});
task.addOnListener(new OnFeatureFailureListener<Integer>() {
@Override
public void onFailure(Exception exception) {
if (exception instanceof FeatureInstallException) {
int errorCode = ((FeatureInstallException) exception).getErrorCode();
Log.d(TAG, "load feature onFailure.errorCode:" + errorCode);
} else {
exception.printStackTrace();
}
}
});
task.addOnListener(new OnFeatureCompleteListener<Integer>() {
@Override
public void onComplete(FeatureTask<Integer> featureTask) {
if (featureTask.isComplete()) {
Log.d(TAG, "complete to start install.");
if (featureTask.isSuccessful()) {
Integer result = featureTask.getResult();
sessionId = result;
Log.d(TAG, "succeed to start install. session id :" + result);
} else {
Log.d(TAG, "fail to start install.");
Exception exception = featureTask.getException();
exception.printStackTrace();
}
}
}
});
Log.d(TAG, "start install func end");
}
private void wait(boolean isLoading) {
if (isLoading) {
mBinding.loaderLayout.rootLoader.setVisibility(View.VISIBLE);
mBinding.layout.shows.setVisibility(View.GONE);
} else {
mBinding.loaderLayout.rootLoader.setVisibility(View.GONE);
mBinding.layout.shows.setVisibility(View.VISIBLE);
}
}
private void getShowList() {
mShowsViewModel.getShowsLiveData().observeForever(showList -> {
if (showList != null) {
wait(false);
String eventName = "Show Success";
Bundle bundle = new Bundle();
bundle.putInt("Show Size", showList.size());
setDataIntoAdapter(showList);
} else {
wait(false);
}
});
}
private void setDataIntoAdapter(List<Show> list) {
mBinding.layout.shows.setLayoutManager(new GridLayoutManager(this, 2));
mBinding.layout.shows.setAdapter(new ShowAdapter(list, (item) -> {
Intent intent = new Intent(getBaseContext(), ShowDetailActivity.class);
intent.putExtra(KEY_SHOW_ID, String.valueOf(item.getId()));
String eventName = "Choosed Show";
Bundle bundle = new Bundle();
bundle.putInt("Show ID", item.getId());
startActivity(intent);
}));
}
@Override
protected void onResume() {
super.onResume();
if (mFeatureInstallManager != null) {
mFeatureInstallManager.registerInstallListener(mStateUpdateListener);
}
}
@Override
protected void onPause() {
super.onPause();
if (mFeatureInstallManager != null) {
mFeatureInstallManager.unregisterInstallListener(mStateUpdateListener);
}
}
}
We will create 3 Dynamic Feature module under android project.
1. Repository Module
2. Network Module
3. ViewModel Module
Let’s create Repository Module:
In this module, we have created ShowRepository class which communicate between network and UI components.
Let’s see gradle file:
Code:
apply plugin: 'com.android.dynamic-feature'
android {
compileSdkVersion 29
defaultConfig {
minSdkVersion 27
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':app')
// RxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
}
Note: Module should have this in the first line, as it is a dynamic feature:
Code:
apply plugin: 'com.android.dynamic-feature'
Let’s see manifest file of this module:
Code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.hms.android.repository">
<dist:module
dist:instant="false"
dist:title="@string/title_repository">
<dist:delivery>
<dist:on-demand />
</dist:delivery>
<dist:fusing dist:include="true" />
</dist:module>
</manifest>
Let’s create Network Module:
In this module, we have implemented all business model.
Let’s see gradle file:
Code:
apply plugin: 'com.android.dynamic-feature'
android {
compileSdkVersion 29
compileOptions {
sourceCompatibility = 1.8
targetCompatibility = 1.8
}
defaultConfig {
minSdkVersion 27
targetSdkVersion 29
versionCode 1
versionName "1.0"
}
}
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation project(':app')
// RxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
// Android MVVM Components
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
}
Let’s see manifest file of this module:
Code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:dist="http://schemas.android.com/apk/distribution"
package="com.hms.android.viewmodel">
<dist:module
dist:instant="false"
dist:title="@string/title_viewmodel">
<dist:delivery>
<dist:on-demand />
</dist:delivery>
<dist:fusing dist:include="true" />
</dist:module>
</manifest>
Let’s build Android App Bundle:
We need to follow the following steps to generate .aab file.
Follow the steps to generate aab file.
1. Step: Goto->Build->Build Bundle(s)/APK(s)->Build Bundle(s). Choose Build > Build Bundle(s)/APK(s) > Build Bundle(s)
2. After build success, following dialog-box displayed.
3. Click locate text and the output folder will be displayed.
Note: Singing the aab file carefully and upload on AppGallery portal.
4. Provide your project/app information in AppGallery portal:
5. Upload your aab/apk file in draft section.
Now We can download the application from app gallery(After approval).
Time being, we can run that apk in our mobile device.
Let's see the result.
If you have any doubts or queries. Leave your valuable comment below.

Huawei AGC App Linking integration with Unity

More information like this, you can visit HUAWEI Developer Forumhttps://forums.developer.huawei.com...l/en/home?channelname=HuoDong59&ha_source=xda​
Introduction:
In this article, we will cover Integration of AGC App Linking in Unity Project using Official Plugin (Huawei HMS Core App Services).
Requirements:
1. Unity Editor
2. Huawei device
3. Visual Studio
Follows the steps.
Step 1. Create Unity Project.
Click unity icon.
Click NEW, select 3D, Project Name and Location.
Click CREATE, as follows.
{
"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. Click Asset Store, search Huawei HMS Core App Services and click Import, as follows.
Step 3. Once import is successful, verify directory in Assets > Huawei HMS Core App Services path, as follows.
Step 4. Click Console and create a New Project.
Step 5. Choose Project Settings > Player and edit the required options in Publishing Settings, as follows.
Step 6. Verify the files created in Step 5.
Step 7. Download agconnect-services.json and copy to Assets>Plugins>Android, as follows.
Step 8. Update the Package Name.
Step 9. Open LauncherTemplate.gradle and add below line
Code:
apply plugin: 'com.huawei.agconnect'
Step 10. Open "baseProjectTemplate.gradle" and add lines, as follows.
Code:
maven {url 'https://developer.huawei.com/repo/'}
Code:
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 11. Open "mainTemplate.gradle" and add lines like shown below
Code:
apply plugin: 'com.huawei.agconnect'
Code:
implementation 'com.huawei.agconnect:agconnect-core:1.4.1.300'
implementation 'com.huawei.agconnect:agconnect-applinking:1.4.0.300'
implementation 'com.huawei.hms:hianalytics:5.0.3.300'
Step 12. Open AndroidManifest file and Add Activity like shown below.
Code:
<activity android:name="com.hms.hms_analytic_activity.TestAppLinksActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="developer.huawei.com" android:scheme="https" />
<data android:host="developer.huawei.com" android:scheme="http" />
</intent-filter>
</activity>
Step 13. Create TestAppLinksActivity.java, JavaCallBack.java and place it in Assets->Plugins->Android.
Code:
//package com.test.applinks;
package com.hms.hms_analytic_activity;
import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import com.unity3d.player.UnityPlayerActivity;
import android.widget.Toast;
import com.huawei.agconnect.applinking.AGConnectAppLinking;
import com.huawei.agconnect.applinking.AppLinking;
import com.huawei.agconnect.applinking.ShortAppLinking;
//import androidx.appcompat.app.AppCompatActivity;
import com.huawei.agconnect.applinking.AGConnectAppLinking;
public class TestAppLinksActivity extends UnityPlayerActivity {
public static JavaCallback callback;
private static String agcLink = null;
private static final String DOMAIN_URI_PREFIX = "https://testulink.dra.agconnect.link";
//private static final String DEEP_LINK = "rmOb2";
private static final String DEEP_LINK = "https://developer.huawei.com/consumer/cn/doc/development/AppGallery-connect-Guides?id=123";
private static String deepLinkData = "";
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
Log.e("TestAppLinksActivity", "TestAppLinksActivity onCreate>> @@");
mContext = this.getApplicationContext();
handleAppLinking(getIntent());
}
public static void setCallback(JavaCallback callback1) {
Log.e("TestAppLinksActivityl", "setCallback>> @@");
callback = callback1;
if(callback != null){
Log.e("TestAppLinksActivity", "update c # script >>>>");
callback.OnJavaCallback(deepLinkData);
}else{
Log.e("TestAppLinksActivity", "TestAppLinksActivity callback is null plz initialize >>>>");
}
}
private void handleAppLinking(Intent intent) {
AGConnectAppLinking.getInstance().getAppLinking(this, intent).addOnSuccessListener(resolvedLinkData -> {
Uri deepLink = null;
if (resolvedLinkData != null) {
deepLink = resolvedLinkData.getDeepLink();
Log.e("TestAppLinksActivity", " [email protected]!!!$$->"+deepLink.toString());
deepLinkData = deepLink.toString();
if(callback != null){
Log.e("TestAppLinksActivity", "update c # script");
callback.OnJavaCallback(deepLink.toString());
}else{
Log.e("TestAppLinksActivity", "callback is null plz initialize");
}
}
}).addOnFailureListener(e -> {
Log.e("TestAppLinksActivity", "getAppLinking:onFailure", e);
});
}
@Override
protected void onNewIntent(Intent intent) {
super.onNewIntent(intent);
setIntent(intent);
handleAppLinking(intent);
}
public static void createAppLinking() {
AppLinking.Builder builder = new AppLinking.Builder().setUriPrefix(DOMAIN_URI_PREFIX)
.setDeepLink(Uri.parse(DEEP_LINK));
//longTextView.setText(builder.buildAppLinking().getUri().toString());
Log.e("TestAppLinksActivity", "createAppLinking long -->"+builder.buildAppLinking().getUri().toString());
agcLink = builder.buildAppLinking().getUri().toString();
builder.buildShortAppLinking(ShortAppLinking.LENGTH.SHORT).addOnSuccessListener(shortAppLinking -> {
//shortTextView.setText(shortAppLinking.getShortUrl().toString());
Log.e("TestAppLinksActivity", "createAppLinking short -->"+shortAppLinking.getShortUrl().toString());
agcLink = shortAppLinking.getShortUrl().toString();
}).addOnFailureListener(e -> {
//Toast.makeText(this, e.getMessage(), Toast.LENGTH_LONG).show();
Log.e("TestAppLinksActivity", "createAppLinking failure -->"+e.getMessage());
});
}
//public void shareLink() {
public static void shareLink(Activity activity){
if (agcLink != null) {
Log.e("TestAppLinksActivity", "shareLink agcLink is not null start activity");
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_TEXT, agcLink);
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
activity.startActivity(intent);
//startActivity(intent);
}else{
Log.e("TestAppLinksActivity", " shareLink agcLink is null");
}
}
private static Context mContext;
public static Context getAppContext(){
return mContext;
}
}
code explanation : https://developer.huawei.com/consumer/en/codelab/AppLinking/index.html#7
Code:
package com.hms.hms_analytic_activity;
public interface JavaCallback {
void OnJavaCallback(String index);
}
Note : Java classes are using package name com.hms.hms_analytic_activity & we dont create any folder structure, this is allowed.
For full content, you can visit https://forums.developer.huawei.com/forumPortal/en/topicview?tid=0202361288668900258&fid=0101188387844930001

Integrating HUAWEI Analytics Kit Using Unity

This document describes how to integrate Analytics Kit using the official Unity asset. After the integration, your app can use the services of this Kit on HMS mobile phones.
For details about Analytics Kit, please visit HUAWEI Developers.
1.1 Preparations​1.1.1 Importing Unity Assets​1.1.2 Generating .gradle Files​1. Enable project gradle.
Go to Edit > Project Settings > Player in Unity, click the Android icon, and go to Publishing Settings > Build.
Enable Custom Base Gradle Template.
Enable Custom Launcher Gradle Template.
Enable Custom Main Gradle Template.
Enable Custom Main Manifest.
{
"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"
}
2. Signature
You can use an existing keystore file or create a new one to sign your app.
Go to Edit > Project Settings > Player in Unity, click the Android icon, and go to Publishing Settings > Keystore Manager > Keystore... > Create New.
Enter the password when you open Unity. Otherwise, you cannot build the APK.
1.1.3 Configuring .gradle Files and the AndroidManifest.xml File​1. Configure the BaseProjectTemplate.gradle file.
Code:
<p style="line-height: 1.5em;">Configure the Maven repository address.
buildscript {
repositories {**ARTIFACTORYREPOSITORY**
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
}
dependencies {
// If you are changing the Android Gradle Plugin version, make sure it is compatible with the Gradle version preinstalled with Unity.
// For the Gradle version preinstalled with Unity, please visit https://docs.unity3d.com/Manual/android-gradle-overview.html.
// For the official Gradle and Android Gradle Plugin compatibility table, please visit https://developer.android.com/studio/releases/gradle-plugin#updating-gradle.
// To specify a custom Gradle version in Unity, go do Preferences > External Tools, deselect Gradle Installed with Unity (recommended), and specify a path to a custom Gradle version.
classpath 'com.android.tools.build:gradle:3.4.0'
classpath 'com.huawei.agconnect:agcp:1.2.1.301'
**BUILD_SCRIPT_DEPS**
}
repositories {**ARTIFACTORYREPOSITORY**
google()
jcenter()
maven { url 'https://developer.huawei.com/repo/' }
flatDir {
dirs "${project(':unityLibrary').projectDir}/libs"
}
}</p>
2. Configure the launcherTemplate.gradle file.
Code:
<p style="line-height: 1.5em;">// Generated by Unity. Remove this comment to prevent overwriting when exporting again.
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
dependencies {
implementation project(':unityLibrary')
implementation 'com.huawei.hms:hianalytics:5.1.0.300'
implementation 'com.android.support:appcompat-v7:28.0.0'
implementation 'com.huawei.agconnect:agconnect-core:1.2.0.300'
}</p>
3. Configure the mainTemplate.gradle file.
Code:
<p style="line-height: 1.5em;">apply plugin: 'com.android.library'
apply plugin: 'com.huawei.agconnect'
dependencies {
implementation fileTree(dir: 'libs', include: ['*.jar'])
implementation 'com.huawei.agconnect:agconnect-core:1.2.0.300'
implementation 'com.huawei.hms:hianalytics:5.0.0.301'
**DEPS**}</p>
4. Configure the AndroidManifest.xml file.
Code:
<p style="line-height: 1.5em;"><?xml version="1.0" encoding="utf-8"?>
<!-- Generated by Unity. Remove this comment to prevent overwriting when exporting again. -->
<manifest
xmlns:android="http://schemas.android.com/apk/res/android"
package="com.unity3d.player"
xmlns:tools="http://schemas.android.com/tools">
<application>
<activity android:name="com.hms.hms_analytic_activity.HmsAnalyticActivity"
android:theme="@style/UnityThemeSelector">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:host="unity.cn"
android:scheme="https" />
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true" />
</activity>
</application></p>
1.1.4 Adding the agconnect-services.json File​1. Create an app by following instructions in Creating an AppGallery Connect Project and Adding an App to the Project.
Run keytool -list -v -keystore C:\TestApp.keyStore to generate the SHA-256 certificate fingerprint based on the keystore file of the app. Then, configure the fingerprint in AppGallery Connect.
2. Download the agconnect-services.json file and place it in the Assets/Plugins/Android directory of your Unity project.
1.1.5 Enabling HUAWEI Analytics​For details, please refer to the development guide.
1.1.6 Adding the HmsAnalyticActivity.java File​1. Destination directory:
2. File content:
Code:
<p style="line-height: 1.5em;">package com.hms.hms_analytic_activity;
import android.os.Bundle;
import com.huawei.hms.analytics.HiAnalytics;
import com.huawei.hms.analytics.HiAnalyticsTools;
import com.unity3d.player.UnityPlayerActivity;
import com.huawei.agconnect.appmessaging.AGConnectAppMessaging;
import com.huawei.hms.aaid.HmsInstanceId;
import com.hw.unity.Agc.Auth.ThirdPartyLogin.LoginManager;
import android.content.Intent;
import java.lang.Boolean;
import com.unity3d.player.UnityPlayer;
import androidx.core.app.ActivityCompat;
public class HmsAnalyticActivity extends UnityPlayerActivity {
private AGConnectAppMessaging appMessaging;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
HiAnalyticsTools.enableLog();
HiAnalytics.getInstance(this);
appMessaging = AGConnectAppMessaging.getInstance();
if(appMessaging != null){
appMessaging.setFetchMessageEnable(true);
appMessaging.setDisplayEnable(true);
appMessaging.setForceFetch();
}
LoginManager.getInstance().initialize(this);
boolean pretendCallMain = false;
if(pretendCallMain == true){
main();
}
}
private static void callCrash() {
throwCrash();
}
private static void throwCrash() {
throw new NullPointerException();
}
public static void main(){
JavaCrash();
}
private static void JavaCrash(){
new Thread(new Runnable() {
@Override
public void run() { // Sub-thread.
UnityPlayer.currentActivity.runOnUiThread(new Runnable() {
@Override
public void run() {
callCrash();
}
});
}
}).start();
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data)
{
LoginManager.getInstance().onActivityResult(requestCode, resultCode, data);
}
}</p>
1.2 App Development with the Official Asset​1.2.1 Sample Code​
Code:
<p style="line-height: 1.5em;">using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using HuaweiHms;
public class AnalyticTest : MonoBehaviour
{
private HiAnalyticsInstance instance;
private int level = 0;
// Start() is called before the first frame update.
void Start()
{
}
// Update() is called once per frame.
void Update()
{
}
public AnalyticTest()
{
// HiAnalyticsTools.enableLog();
// instance = HiAnalytics.getInstance(new Context());
}
public void AnalyticTestMethod()
{
HiAnalyticsTools.enableLog();
instance = HiAnalytics.getInstance(new Context());
instance.setAnalyticsEnabled(true);
Bundle b1 = new Bundle();
b1.putString("test", "123456");
instance.onEvent("debug", b1);
}
public void SetUserId()
{
instance.setUserId("unity test Id");
// Util.showToast("userId set");
}
public void SendProductId()
{
Bundle b1 = new Bundle();
b1.putString(HAParamType.PRODUCTID, "123456");
instance.onEvent(HAEventType.ADDPRODUCT2CART, b1);
// Util.showToast("product id set");
}
public void SendAnalyticEnable()
{
enabled = !enabled;
instance.setAnalyticsEnabled(enabled);
// TestTip.Inst.ShowText(enabled ? "ENABLED" : "DISABLED");
}
public void CreateClearCache()
{
instance.clearCachedData();
// Util.showToast("Clear Cache");
}
public void SetFavoriteSport()
{
instance.setUserProfile("favor_sport", "running");
// Util.showToast("set favorite");
}
public void SetPushToken()
{
instance.setPushToken("fffff");
// Util.showToast("set push token as ffff");
}
public void setMinActivitySessions()
{
instance.setMinActivitySessions(10000);
// Util.showToast("setMinActivitySessions 10000");
}
public void setSessionDuration()
{
instance.setSessionDuration(900000);
// Util.showToast("setMinActivitySessions 900000");
}
public void getUserProfiles()
{
getUserProfiles(false);
getUserProfiles(true);
}
public void getUserProfiles(bool preDefined)
{
var profiles = instance.getUserProfiles(preDefined);
var keySet = profiles.keySet();
var keyArray = keySet.toArray();
foreach (var key in keyArray)
{
// TestTip.Inst.ShowText($"{key}: {profiles.getOrDefault(key, "default")}");
}
}
public void pageStart()
{
instance.pageStart("page test", "page test");
// TestTip.Inst.ShowText("set page start: page test, page test");
}
public void pageEnd()
{
instance.pageEnd("page test");
// TestTip.Inst.ShowText("set page end: page test");
}
public void enableLog()
{
HiAnalyticsTools.enableLog(level + 3);
// TestTip.Inst.ShowText($"current level {level + 3}");
level = (level + 1) % 4;
}
}</p>
1.2.2 Testing the APK​1. Generate the APK.
Go to File > Build Settings > Android, click Switch Platform, and then Build And Run.
2. Enable the debug mode.
3. Go to the real-time overview page of Analytics Kit in AppGallery Connect.
Sign in to AppGallery Connect and click My projects. Select one of your projects and go to HUAWEI Analytics > Overview > Real-time overview.
4. Call AnalyticTestMethod() to display analysis events reported.
Our official website
Demo for Analytics Kit
Our Development Documentation page, to find the documents you need:
Android SDK
Web SDK
Quick APP SDK
If you have any questions about HMS Core, you can post them in the community on the HUAWEI Developers website or submit a ticket online.
We’re looking forward to seeing what you can achieve with HUAWEI Analytics!
More Information
To join in on developer discussion forums
To download the demo app and sample code
For solutions to integration-related issues
Checkout in forum

Extract table data from Image using Huawei Table Recognition by Huawei HiAI in Android

Introduction
The API can perfectly retrieve the information of tables as well as text from cells, besides, merged cells can also be recognized. It supports recognition of tables with clear and unbroken lines, but not supportive of tables with crooked lines or cells divided by color background. Currently the API supports recognition from printed materials and snapshots of slide meetings, but it is not functioning for the screenshots or photos of excel sheets and any other table editing software.
Here, the image resolution should be higher than 720p (1280×720 px), and the aspect ratio (length-to-width ratio) should be lower than 2:1.
In this article, we will learn how to implement Huawei HiAI kit using Table Recognition service into android application, this service helps us to extract the table content from images.
Software requirements
1. Any operating system (MacOS, Linux and Windows).
2. Any IDE with Android SDK installed (IntelliJ, Android Studio).
3. HiAI SDK.
4. Minimum API Level 23 is required.
5. Required EMUI 9.0.0 and later version devices.
6. Required processors kirin 990/985/980/970/ 825Full/820Full/810Full/ 720Full/710Full
How to integrate Table recognition.
1. Configure the application on the AGC.
2. Apply for HiAI Engine Library.
3. Client application development process.
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.
Apply for HiAI Engine Library
What is Huawei HiAI?
HiAI is Huawei's AI computing platform. HUAWEI HiAI is a mobile terminal–oriented artificial intelligence (AI) computing platform that constructs three layers of ecology: service capability openness, application capability openness, and chip capability openness. The three-layer open platform that integrates terminals, chips, and the cloud brings more extraordinary experience for users and developers.
How to apply for HiAI Engine?
Follow the steps
Step 1: Navigate to this URL, choose App Service > Development and click HUAWEI HiAI.
{
"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: Click Apply for HUAWEI HiAI kit.
Step 3: Enter required information like Product name and Package name, click Next button.
Step 4: Verify the application details and click Submit button.
Step 5: Click the Download SDK button to open the SDK list.
Step 6: Unzip downloaded SDK and add into your android project under libs folder.
Step 7: Add jar files dependences into app build.gradle file.
implementation fileTree(include: ['*.aar', '*.jar'], dir: 'libs')
implementation 'com.google.code.gson:gson:2.8.6'
repositories {
flatDir {
dirs 'libs'
}
}Copy code
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'
Root level gradle dependencies.
Code:
maven { url 'https://developer.huawei.com/repo/' }
classpath 'com.huawei.agconnect:agcp:1.4.1.300'
Step 3: Add permission in AndroidManifest.xml
XML:
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_INTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
Step 4: Build application.
Java:
import android.Manifest;
import android.content.Intent;
import android.graphics.Bitmap;
import android.provider.MediaStore;
import android.support.annotation.Nullable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TextView;
import android.widget.Toast;
import com.huawei.hiai.vision.common.ConnectionCallback;
import com.huawei.hiai.vision.common.VisionBase;
import com.huawei.hiai.vision.common.VisionImage;
import com.huawei.hiai.vision.image.sr.ImageSuperResolution;
import com.huawei.hiai.vision.text.TableDetector;
import com.huawei.hiai.vision.visionkit.text.config.VisionTableConfiguration;
import com.huawei.hiai.vision.visionkit.text.table.Table;
import com.huawei.hiai.vision.visionkit.text.table.TableCell;
import com.huawei.hiai.vision.visionkit.text.table.TableContent;
import java.util.List;
public class TableRecognition extends AppCompatActivity {
private boolean isConnection = false;
private int REQUEST_CODE = 101;
private int REQUEST_PHOTO = 100;
private Bitmap bitmap;
private Button btnImage;
private ImageView originalImage;
private ImageView conversionImage;
private TextView textView;
private TextView tableContentText;
private final String[] permission = {
Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE,
Manifest.permission.READ_EXTERNAL_STORAGE};
private ImageSuperResolution resolution;
private TableLayout tableLayout;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_table_recognition);
requestPermissions(permission, REQUEST_CODE);
initializeVisionBase();
originalImage = findViewById(R.id.super_origin);
conversionImage = findViewById(R.id.super_image);
textView = findViewById(R.id.text);
tableContentText = findViewById(R.id.content_text);
btnImage = findViewById(R.id.btn_album);
tableLayout = findViewById(R.id.tableLayout);
btnImage.setOnClickListener(v -> {
selectImage();
tableLayout.removeAllViews();
});
}
private void initializeVisionBase() {
VisionBase.init(this, new ConnectionCallback() {
@Override
public void onServiceConnect() {
isConnection = true;
DoesDeviceSupportTableRecognition();
}
@Override
public void onServiceDisconnect() {
}
});
}
private void DoesDeviceSupportTableRecognition() {
resolution = new ImageSuperResolution(this);
int support = resolution.getAvailability();
if (support == 0) {
Toast.makeText(this, "Device supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Device doesn't supports HiAI Image super resolution service", Toast.LENGTH_SHORT).show();
}
}
public void selectImage() {
Intent intent = new Intent(Intent.ACTION_PICK);
intent.setType("image/*");
startActivityForResult(intent, REQUEST_PHOTO);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (resultCode == RESULT_OK) {
if (data != null && requestCode == REQUEST_PHOTO) {
try {
bitmap = MediaStore.Images.Media.getBitmap(getContentResolver(), data.getData());
originalImage.setImageBitmap(bitmap);
if (isConnection) {
extractTableFromTheImage();
}
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
private void extractTableFromTheImage() {
tableContentText.setVisibility(View.VISIBLE);
TableDetector mTableDetector = new TableDetector(this);
VisionImage image = VisionImage.fromBitmap(bitmap);
VisionTableConfiguration mTableConfig = new VisionTableConfiguration.Builder()
.setAppType(VisionTableConfiguration.APP_NORMAL)
.setProcessMode(VisionTableConfiguration.MODE_OUT)
.build();
mTableDetector.setVisionConfiguration(mTableConfig);
mTableDetector.prepare();
Table table = new Table();
int mResult_code = mTableDetector.detect(image, table, null);
if (mResult_code == 0) {
int count = table.getTableCount();
List<TableContent> tc = table.getTableContent();
StringBuilder sbTableCell = new StringBuilder();
List<TableCell> tableCell = tc.get(0).getBody();
for (TableCell c : tableCell) {
List<String> words = c.getWord();
StringBuilder sb = new StringBuilder();
for (String s : words) {
sb.append(s).append(",");
}
String cell = c.getStartRow() + ":" + c.getEndRow() + ": " + c.getStartColumn() + ":" +
c.getEndColumn() + "; " + sb.toString();
sbTableCell.append(cell).append("\n");
tableContentText.setText("Count = " + count + "\n\n" + sbTableCell.toString());
}
}
}
}Copy code
Result
Tips and Tricks
Recommended image should be larger than 720px.
Multiple table recognition currently not supported.
If you are taking Video from a camera or gallery make sure your app has camera and storage permission.
Add the downloaded huawei-hiai-vision-ove-10.0.4.307.aar, huawei-hiai-pdk-1.0.0.aar file to libs folder.
Check dependencies added properly.
Latest HMS Core APK is required.
Min SDK is 21. Otherwise you will get Manifest merge issue.
Conclusion
In this article, we have done table content extraction from image, for further analysis with statistics or just for editing it. This works for tables with clear and simple structure information. We have learnt the following concepts.
1. Introduction of Table recognition?
2. How to integrate Table using Huawei HiAI
3. How to Apply Huawei HiAI
4. How to build the application
Reference
Table Recognition
Apply for Huawei HiAI
Happy coding
useful sharing,thanks!

Expert: Courier App MVVM Jetpack (HMS CloudDB Kit) in Android using Kotlin- Part-3

Overview
In this article, I will create a Courier android application using Kotlin in which I will integrate HMS Core kits such as HMS Account, AuthService, Push and Cloud DB Kit.
We have integrated HMS Account and AuthService Kit in part-1 and Client Push Notification Using HMS Push Kit in Part-2 of this series. Kindly go through the link below-
Part-1 https://forums.developer.huawei.com/forumPortal/en/topic/0202841957497640128
Part-2 https://forums.developer.huawei.com/forumPortal/en/topic/0201847982965230092
App will make use of android MVVM clean architecture using Jetpack components such as DataBinding, AndroidViewModel, Observer, LiveData and much more.
In this article, we are going to implement DataBinding using Observable pattern.
Huawei Cloud DB Kit Introduction
Huawei Cloud DB is a device-cloud synergy database product that enables seamless data synchronization between the device and cloud and between devices, and supports offline application operations, helping you quickly develop device-cloud and multi-device synergy applications.
Prerequisite
Huawei Phone EMUI 3.0 or later.
Non-Huawei phones Android 4.4 or later (API level 19 or higher).
HMS Core APK 4.0.0.300 or later
Android Studio
AppGallery Account
App Gallery Integration process
Sign In and Create or Choose a project on AppGallery Connect portal.
{
"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"
}
Navigate to Project settings and download the configuration file.
Navigate to General Information, and then provide Data Storage location.
Navigate to My Projects > Project Settings > Build > Cloud DB, and click Enable now.
Click Add
Click Export, select Java, android and Package Name, and click OK.
App Development
Add Required Dependencies:
Launch Android studio and create a new project. Once the project is ready.
Navigate to the Gradle scripts folder and open build.gradle (module: app) and Add following dependency for HMS Cloud DB Kits.
Code:
implementation 'com.huawei.agconnect:agconnect-cloud-database:1.5.0.300'
implementation "com.huawei.agconnect:agconnect-auth-huawei:1.6.0.300"
implementation 'com.huawei.agconnect:agconnect-auth:1.5.0.300'
Navigate to the Gradle scripts folder and open build.gradle (project: app).
Code:
ext.kotlin_version = "1.4.21"
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.huawei.agconnect:agcp:1.4.2.300'
Code Implementation
Created following package model, clouddb, viewmodel.
Model: In your primary folder, create a new package and name it model.
CloudInfo.java:
Code:
package com.hms.corrierapp.clouddb;import com.huawei.agconnect.cloud.database.CloudDBZoneObject;
import com.huawei.agconnect.cloud.database.annotations.DefaultValue;
import com.huawei.agconnect.cloud.database.annotations.EntireEncrypted;
import com.huawei.agconnect.cloud.database.annotations.Indexes;
import com.huawei.agconnect.cloud.database.annotations.NotNull;
import com.huawei.agconnect.cloud.database.annotations.PrimaryKeys;@PrimaryKeys({"CourierID"})
@Indexes({"ID:CourierID"})
public final class CourierInfo extends CloudDBZoneObject {
private Integer CourierID;@NotNull
@DefaultValue(stringValue = "Courier Name")
private String CourierName;@DefaultValue(stringValue = "Desc")
private String Desc;@EntireEncrypted(isEncrypted = true)
private String FromAdress;@EntireEncrypted(isEncrypted = true)
private String ToAddress;public CourierInfo() {
super(CourierInfo.class);
this.CourierName = "Courier Name";
this.Desc = "Desc";
}public Integer getCourierID() {
return CourierID;
}public void setCourierID(Integer CourierID) {
this.CourierID = CourierID;
}public String getCourierName() {
return CourierName;
}public void setCourierName(String CourierName) {
this.CourierName = CourierName;
}public String getDesc() {
return Desc;
}public void setDesc(String Desc) {
this.Desc = Desc;
}public String getFromAdress() {
return FromAdress;
}public void setFromAdress(String FromAdress) {
this.FromAdress = FromAdress;
}public String getToAddress() {
return ToAddress;
}public void setToAddress(String ToAddress) {
this.ToAddress = ToAddress;
}}
ObjectTypeInfoHelper.java:
Code:
package com.hms.corrierapp.clouddb;import com.huawei.agconnect.cloud.database.CloudDBZoneObject;
import com.huawei.agconnect.cloud.database.ObjectTypeInfo;import java.util.ArrayList;
import java.util.Collections;
import java.util.List;public final class ObjectTypeInfoHelper {
private static final int FORMAT_VERSION = 2;
private static final int OBJECT_TYPE_VERSION = 1;public static ObjectTypeInfo getObjectTypeInfo() {
ObjectTypeInfo objectTypeInfo = new ObjectTypeInfo();
objectTypeInfo.setFormatVersion(FORMAT_VERSION);
objectTypeInfo.setObjectTypeVersion(OBJECT_TYPE_VERSION);
List<Class<? extends CloudDBZoneObject>> objectTypeList = new ArrayList<>();
Collections.addAll(objectTypeList, CourierInfo.class);
objectTypeInfo.setObjectTypes(objectTypeList);
return objectTypeInfo;
}
}
CloudDBViewModel.kt:
Code:
package com.hms.corrierapp.viewmodelimport android.app.Application
import com.hms.corrierapp.push.NotificationMessageBody
import android.content.Context
import android.text.TextUtils
import android.util.Log
import android.widget.Toast
import androidx.databinding.Bindable
import androidx.databinding.Observable
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.hms.corrierapp.clouddb.ObjectTypeInfoHelper
import com.hms.corrierapp.model.Email
import com.hms.corrierapp.model.SMS
import com.hms.corrierapp.push.*
import com.huawei.agconnect.cloud.database.AGConnectCloudDB
import com.huawei.agconnect.cloud.database.CloudDBZone
import com.huawei.agconnect.cloud.database.CloudDBZoneConfig
import com.huawei.agconnect.cloud.database.exceptions.AGConnectCloudDBException
import com.huawei.agconnect.config.AGConnectServicesConfig
import com.huawei.hms.aaid.HmsInstanceId
import retrofit2.Call
import retrofit2.Callback
import retrofit2.Responseclass CloudDBViewModel(application: Application) : AndroidViewModel(application), Observable {var mCloudDBZone: CloudDBZone? = nullprivate fun setAGC_DB() {
// val user = AGConnectAuth.getInstance().currentUser
AGConnectCloudDB.initialize(getApplication())
val mCloudDB = AGConnectCloudDB.getInstance()
try {
mCloudDB.createObjectType(ObjectTypeInfoHelper.getObjectTypeInfo())
} catch (e: AGConnectCloudDBException) {
e.printStackTrace()
}
val mConfig = CloudDBZoneConfig("Zone1",
CloudDBZoneConfig.CloudDBZoneSyncProperty.CLOUDDBZONE_CLOUD_CACHE,
CloudDBZoneConfig.CloudDBZoneAccessProperty.CLOUDDBZONE_PUBLIC)
mConfig.persistenceEnabled = true
val openDBZoneTask = mCloudDB.openCloudDBZone2(mConfig, true)
openDBZoneTask.addOnSuccessListener { cloudDBZone ->
Toast.makeText(getApplication(),"Cloud DB successfully opened", Toast.LENGTH_SHORT).show()
if (mCloudDBZone == null) {
mCloudDBZone = cloudDBZone
}
}.addOnFailureListener { e -> e.printStackTrace() }
}override fun addOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
TODO("Not yet implemented")
}override fun removeOnPropertyChangedCallback(callback: Observable.OnPropertyChangedCallback?) {
TODO("Not yet implemented")
}
}
CloudDBViewModelFactory.kt:
Code:
package com.hms.corrierapp.viewmodelimport androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProviderclass CloudDBViewModelFactory : ViewModelProvider.Factory {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
if (modelClass.isAssignableFrom(CloudDBViewModel::class.java)) {
return CloudDBViewModel() as T
}
throw IllegalArgumentException("UnknownViewModel")
}
}
App Build Result
Tips and Tricks
Identity Kit displays the HUAWEI ID registration or sign-in page first. The user can use the functions provided by Identity Kit only after signing in using a registered HUAWEI ID.
Make sure you have added SHA-256 fingerprint without fail.
Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
Conclusion
In this article, we have learned how to integrate Huawei ID, Push and Cloud DB Kit in Android application. After completely read this article user can easily implement Huawei ID and Client Side Push Notification and submit courier information on Cloud DB in the Courier android application using Kotlin.
Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.
References
HMS Docs:
https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870
https://developer.huawei.com/consum...-Guides/service-introduction-0000001050040060
https://developer.huawei.com/consum...des/agc-clouddb-introduction-0000001054212760
Cloud DB Kit Training Video:
https://developer.huawei.com/consumer/en/training/course/video/101628259491513909

Categories

Resources