Protecting Digital Works' Copyright by Using the Blockchain of DCI Kit - Huawei Developers

To create is human nature. It is this urge that has driven the rapid growth of self-media. But wherever content is created, it is at risk of being copied or stolen, which is why regulators, content platforms, and creators are trying to crack down on plagiarism and protect the rights of creators.
As a solution to this challenge, DCI Kit, developed by Huawei and Copyright Protection Center of China (CPCC), safeguards digital works' copyright by leveraging technologies such as blockchain and big data. It now offers capabilities like DCI user registration, copyright registration, and copyright safeguarding. Information about successfully registered works (including their DCI codes) will be stored in the blockchain, ensuring that all copyright information is reliable and traceable. In this respect, DCI Kit offers all-round copyright protection for creators anywhere.
Effects​After a DCI user initiates a request to register copyright for a work, CPCC will record the copyright-related information and issue a DCI code for the registered work. With blockchain and big data technologies, DCI Kit frees creators from the tedious process of registering for copyright protection, helping maximize the copyright value.
{
"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"
}
Development Preparations​1. Configuring the Build Dependency for the DCI SDK
Add build dependencies on the DCI SDK in the dependencies block in the app-level build.gradle file.
Code:
// Add DCI SDK dependencies.
implementation 'com.huawei.hms:dci:3.0.1.300'
2. Configuring AndroidManifest.xml
Open the AndroidManifest.xml file in the main folder. Add the following information before <application> to apply for the storage read and write permissions and Internet access permission as needed.
Code:
<!-- Permission to write data into and read data from storage. -->
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<!-- Permission to access the Internet. -->
<uses-permission
android:name="android.permission.INTERNET" />
Development Procedure​1. Initializing the DCI SDK
Initialize the DCI SDK in the onCreate() method of Application.
Code:
@Override
public void onCreate() {
super.onCreate();
// Initialize the DCI SDK.
HwDciPublicClient.initApplication(this);
}
2. Registering a User as the DCI User
Code:
// Obtain the OpenID and access token through Account Kit.
AccountAuthParams authParams = new AccountAuthParamsHelper(AccountAuthParams.DEFAULT_AUTH_REQUEST_PARAM)
.setAccessToken()
.setProfile()
.createParams();
AccountAuthService service = AccountAuthManager.getService(activity, authParams);
Task<AuthAccount> mTask = service.silentSignIn();
mTask.addOnSuccessListener(new OnSuccessListener<AuthAccount() {
@Override
public void onSuccess(AuthAccount authAccount) {
// Obtain the OpenID.
String hmsOpenId = authAccount.getOpenId();
// Obtain the access token.
String hmsAccessToken= authAccount.getAccessToken();
}
});
// Set the input parameters.
ParamsInfoEntity paramsInfoEntity = new ParamsInfoEntity();
// Pass the app ID obtained from AppGallery Connect.
paramsInfoEntity.setHmsAppId(hmsAppId);
// Pass the OpenID.
paramsInfoEntity.setHmsOpenId(hmsOpenId);
// hmsPushToken: push token provided by Push Kit. If you do not integrate Push Kit, do not pass this value.
paramsInfoEntity.setHmsPushToken(hmsPushToken);
// Pass the access token.
paramsInfoEntity.setHmsToken(hmsAccessToken);
// Customize the returned code, which is used to check whether the result belongs to your request.
int myRequestCode = 1;
// Launch the user registration screen.
HwDciPublicClient.registerDciAccount(activity,paramsInfoEntity ,myRequestCode);
// After the registration is complete, the registration result can be obtained from onActivityResult.
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode != myRequestCode || resultCode != RESULT_OK || data == null) {
return;
}
int code = data.getIntExtra(HwDciConstant.DCI_REGISTER_RESULT_CODE, 0);
if (code == 200) {
// A DCI UID is returned if the DCI user registration is successful.
AccountInfoEntity accountInfoEntity = data.getParcelableExtra(HwDciConstant.DCI_ACCOUNT_INFO_KEY);
String dciUid = accountInfoEntity.getUserId();
} else {
// Process the failure based on the code if the DCI user registration fails.
}
}
3. Registering Copyright for a Work
Pass information related to the work by calling applyDciCode of HwDciPublicClient to register its copyright.
Code:
paramsInfoEntity.setDciUid(dciUid);
paramsInfoEntity.setHmsAppId(hmsAppId);
paramsInfoEntity.setHmsOpenId(hmsOpenId);
paramsInfoEntity.setHmsToken(hmsToken);
// Obtain the local path for storing the digital work.
String imageFilePath = imageFile.getAbsolutePath();
// Obtain the name of the city where the user is now located.
String local = "Beijing";
// Obtain the digital work creation time, which is displayed as a Unix timestamp. The current time is used as an example.
long currentTime = System.currentTimeMillis();
// Call the applyDciCode method.
HwDciPublicClient.applyDciCode(paramsInfoEntity, imageFilePath,local,currentTime, new HwDciClientCallBack<String>() {
@Override
public void onSuccess(String workId) {
// After the copyright registration request is submitted, save workId locally, which will be used to query the registration result.
}
@Override
public void onFail(int code, String msg) {
// Failed to submit the request for copyright registration.
}
});
4. Querying the Copyright Registration Result
Call queryWorkDciInfo of HwDciPublicClient to check the copyright registration result according to the returned code. If the registration is successful, obtain the DCI code issued for the work.
Code:
ParamsInfoEntity paramsInfoEntity = new ParamsInfoEntity();
paramsInfoEntity.setDciUid(dciUid);
paramsInfoEntity.setHmsAppId(hmsAppId);
paramsInfoEntity.setHmsOpenId(hmsOpenId);
paramsInfoEntity.setHmsToken(hmsToken);
paramsInfoEntity.setWorkId(workId);
HwDciPublicClient.queryWorkDciInfo(paramsInfoEntity, new HwDciClientCallBack<WorkDciInfoEntity>() {
@Override
public void onSuccess(WorkDciInfoEntity result) {
if (result == null) {
return;
}
// Check the copyright registration result based on the returned status code. 0 indicates that the registration is being processed, 1 indicates that the registration is successful, and 2 indicates that the registration failed.
if (result.getRegistrationStatus() == 1) {
// If the copyright registration is successful, a DCI code will be returned.
mDciCode = result.getDciCode();
}else if (result.getRegistrationStatus() == 0) {
// The copyright registration is being processed.
}else {
// If the copyright registration fails, a failure cause will be returned.
String message = result.getMessage()
}
}
@Override
public void onFail(int code, String msg) {
// Query failed.
}});
5. Adding a DCI Icon for a Digital Work
Call addDciWatermark of HwDciPublicClient to add a DCI icon for the work whose copyright has been successfully registered. The icon serves as an identifier, indicating that the work copyright has been registered.
Code:
// Pass the local path of the digital work that requires a DCI icon.
String imageFilePath = imageFile.getAbsolutePath();
HwDciPublicClient.addDciWatermark(imageFilePath, new HwDciClientCallBack<String>() {
@Override
public void onSuccess(String imageBase64String) {
// After the DCI icon is successfully added, the digital work is returned as a Base64-encoded character string.
}
@Override
public void onFail(int code, String msg) {
// Failed to add the DCI icon.
}
});
Source Code​To obtain the source code, please visit GitHub sample code repo.

Thanks for sharing..

Related

HMS Safety Detect API integration — (MVVM RxAndroid)

This article is originally from HUAWEI Developer Forum
Forum link: https://forums.developer.huawei.com/forumPortal/en/home​
This is all about integration of HMS Safety Detect API in the Android app using MVVM RxAndroid.
What is HMS Safety Detect API?
Ø The Safety Detect provides system integrity check (SysIntegrity), app security check (AppsCheck), malicious URL check (URLCheck), and fake user detection (UserDetect), helping you prevent security threats to your app.
{
"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 create a Demo Project:
HUAWEI HMS Safety Detect integration requires the following preparations
Ø Creating an AGC Application.
Ø Creating an Android Studio Project.
Ø Generating a signature certificate.
Ø Generating a signature certificate fingerprint.
Ø Configuring the signature certificate fingerprint.
Ø Adding the application package name and save the configuration file.
Ø Configure the Maven address and AGC gradle plug-in.
Ø Configure the signature file in Android Studio.
In this article, we will implement SysIntegrity API in demo project using with RxAndroid and MVVM.
Call the API and handle responses.
Verify the certificate chain, signature, and domain name on the server.
1. Open AppGallery Console:
1. We need to create an application inside console.
2. We need to enable the Safety Detect api.
Go to Console > AppGallery Connect > My apps, click your app, and go to Develop > Manage APIs.
Now enable Safety Detect Api
Download the agconnect-services.json
Move the downloaded agconnect-services.json file to the app root directory of your Android Studio project.
We need to add HMS SDK dependency in app:gradle file
Code:
implementation 'com.huawei.hms:safetydetect:4.0.0.300'
We need to add maven dependency inside project:gradle file
Code:
maven { url 'http://developer.huawei.com/repo/' }
We need to add two more dependencies in app:gradle file
Code:
// MVVM
implementation 'androidx.lifecycle:lifecycle-extensions:2.1.0'
// RxAndroid
implementation 'io.reactivex.rxjava2:rxjava:2.2.8'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
Enable Data Binding
Code:
dataBinding {
enabled = true
}
2. Let’s implement api :
I have created following classes.
1. SysIntegrityDataSource : Which invoke the System Integrity Api with help of RxJava.
2. SysIntegrityViewModel : Which handle the response from System Integrity api and provide LiveData for view componets.
3. SysIntegrityFragment : Which observe the livedata from viewmodel class and set values in views such as textviews and button.
Note: If you are not familiar with MVVM or RxAndroid then I would like to suggest you to please go through my following articles:
· Android MyShows App — Rxandroid MVVM LiveData ViewModel DataBinding, Networking with Retrofit, Gson & Glide — Series
· Demystifying Data Binding — Android Jetpack — Series
Let’s see the implementation of SysIntegrityDataSource.java class.
Code:
public class SysIntegrityDataSource {
private static final String APP_ID = "XXXXXXXX";
private Context context;
public SysIntegrityDataSource(Context context) {
this.context = context;
}
public Single<SysIntegrityResp> executeSystemIntegrity() {
return Single.create(this::invokeSysIntegrity);
}
private void invokeSysIntegrity(SingleEmitter<SysIntegrityResp> emitter) {
byte[] nonce = ("Sample" + System.currentTimeMillis()).getBytes();
SafetyDetect.getClient(context)
.sysIntegrity(nonce, APP_ID)
.addOnSuccessListener(emitter::onSuccess)
.addOnFailureListener(emitter::onError);
}
}
invokeSysIntegrity() : This method invoke the System Integrity api and emit the data onSuccess/OnError and past it to Single<SysIntegrityResp> observable.
executeSystemIntegrity() : This method will create Single observable and return the response from invokeSysIntegrity() method.
3. Let’s implement ViewModel :
I have created SysIntegrityViewModel.java class.
Code:
public class SysIntegrityViewModel extends AndroidViewModel {
private final CompositeDisposable disposables = new CompositeDisposable();
private SysIntegrityDataSource sysIntegrityDataSource;
private MutableLiveData<SysIntegrityResp> systemIntegrityLiveData;
private MutableLiveData<String> error;
public SysIntegrityViewModel(Application app) {
super(app);
sysIntegrityDataSource = new SysIntegrityDataSource(app.getBaseContext());
systemIntegrityLiveData = new MutableLiveData<>();
error = new MutableLiveData<>();
}
public LiveData<SysIntegrityResp> observerSystemIntegrity() {
sysIntegrityDataSource.executeSystemIntegrity()
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new SingleObserver<SysIntegrityResp>() {
@Override
public void onSubscribe(Disposable d) {
disposables.add(d);
}
@Override
public void onSuccess(SysIntegrityResp response) {
systemIntegrityLiveData.setValue(response);
}
@Override
public void onError(Throwable e) {
error.setValue(e.getMessage());
}
});
return systemIntegrityLiveData;
}
public LiveData<String> getError() {
return error;
}
@Override
protected void onCleared() {
disposables.clear();
}
}
MutableLiveData<SysIntegrityResp> systemintegrityLiveData: This field which provide the live data and return the value from viewmodel to fragment class.
observerSysIntegrity() : Which observe RxAndroid’s Single(observable) on main thread and set the value in systemIntegrityLiveData. If we got error while observing it will post the error in MutableLiveData<String> error.
4. Let’s implement Fragment :
I have created SysIntegrityFragment.java class Which obaserve the System Integrity api’s reponse and set the values in views.
Code:
public class SysIntegrityFragment extends Fragment {
private SysIntegrityViewModel sysIntegrityViewModel;
private FragmentSysBinding sysBinding;
public View onCreateView(@NonNull LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
sysBinding=DataBindingUtil.inflate(inflater, R.layout.fragment_sys, container, false);
sysIntegrityViewModel = ViewModelProviders.of(this).get(SysIntegrityViewModel.class);
sysBinding.btnSys.setOnClickListener(v->{
processView();
sysIntegrityViewModel.observerSystemIntegrity().observe(getViewLifecycleOwner(), this::setSystemIntegrity);
sysIntegrityViewModel.getError().observe(getViewLifecycleOwner(),this::showError);
});
return sysBinding.getRoot();
}
private void setSystemIntegrity(SysIntegrityResp response){
String jwsStr = response.getResult();
String[] jwsSplit = jwsStr.split("\\.");
String jwsPayloadStr = jwsSplit[1];
String payloadDetail = new String(Base64.decode(jwsPayloadStr.getBytes(), Base64.URL_SAFE));
try {
final JSONObject jsonObject = new JSONObject(payloadDetail);
final boolean basicIntegrity = jsonObject.getBoolean("basicIntegrity");
sysBinding.btnSys.setBackgroundResource(basicIntegrity ? R.drawable.btn_round_green : R.drawable.btn_round_red);
sysBinding.btnSys.setText(R.string.rerun);
String isBasicIntegrity = String.valueOf(basicIntegrity);
String basicIntegrityResult = "Basic Integrity: " + isBasicIntegrity;
sysBinding.txtBasicIntegrityTitle.setText(basicIntegrityResult);
if (!basicIntegrity) {
String advice = "Advice: " + jsonObject.getString("advice");
sysBinding.txtPayloadAdvice.setText(advice);
}
} catch (JSONException e) {
}
}
private void showError(String error){
Toast.makeText(getActivity().getApplicationContext(), error, Toast.LENGTH_SHORT).show();
sysBinding.btnSys.setBackgroundResource(R.drawable.btn_round_yellow);
sysBinding.btnSys.setText(R.string.rerun);
}
private void processView() {
sysBinding.txtBasicIntegrityTitle.setText("");
sysBinding.txtPayloadBasicIntegrity.setText("");
sysBinding.btnSys.setText(R.string.processing);
sysBinding.btnSys.setBackgroundResource(R.drawable.btn_round_processing);
}
}
We have instantiated instance of view model using ViewModel factory method.
We will consume the response on button click’s event.
If we got success response then we will display inside textviews and button otherwise we will show the error toast.
5. Let’s see the result:
Build the app and hit run button.
Click > RunDetection Case 1: Success Case 2: SDK Error Case 3: Integrity false (Rooted)
I hope you have learnt something new today. If you have any query regarding this article, please feel free to post any comments.
Any questions about this, you can try to acquire answers from HUAWEI Developer Forum.​
Useful sharing,thanks
Thank you so much for sharing, very useful.
Thank you so much for sharing, very useful.
Thank you so much for sharing, very useful.
Does it work offline?
useful sharing,thanks!

Product Visual Search – Ultimate Guide

More information like this, you can visit HUAWEI Developer Forum​
Introduction
HMS ML kit service searches in pre-established product image library for the same or similar products based on a product image taken by a customer, and returns the IDs of those products and related information.
{
"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"
}
Use Case
We will capture the product image using device camera from our developed shopping application.
We will show the returned products list in recycle view.
Prerequisite
Java JDK 1.8 or higher is recommended.
Android Studio is recommended.
Huawei android device with HMS core 4.0.0.300 or higher.
Before developing an app, you will need to register as a HUAWEI developer. Refer to Register a HUAWEI ID.
Integrating app gallery connect SDK. Refer to AppGallery Connect Service Getting Started.
Implementation
Enable ML kit in Manage APIs. Refer to Service Enabling.
Integrate following dependencies in app-level build.gradle.
Code:
// Import the product visual search SDK.
implementation 'com.huawei.hms:ml-computer-vision-cloud:2.0.1.300'
3. Add agc plugin in the top of app.gradle file.
Code:
apply plugin: 'com.huawei.agconnect'
4. Add the following permission in manifest.
Camera permission android.permission.CAMERA: Obtains real-time images or videos from a camera.
Internet access permission android.permission.INTERNET: Accesses cloud services on the Internet.
Storage write permission android.permission.WRITE_EXTERNAL_STORAGE: Upgrades the algorithm version.
Storage read permission android.permission.READ_EXTERNAL_STORAGE: Reads photos stored on a device.
5. To request camera permission in realtime.
Code:
private void requestCameraPermission() {
final String[] permissions = new String[] {Manifest.permission.CAMERA};
if (!ActivityCompat.shouldShowRequestPermissionRationale(this, Manifest.permission.CAMERA)) {
ActivityCompat.requestPermissions(this, permissions, this.CAMERA_PERMISSION_CODE);
return;
}
}
6. Add following code in Application class
Code:
public class MyApplication extends Application {
@Override
public void onCreate() {
super.onCreate();
MLApplication.getInstance().setApiKey("API KEY");
}
}
API key can be obtained either from AGC or integrated agcconnect-services.json.
7. To create an analyzer for product visual search.
Code:
private void initializeProductVisionSearch() {
MLRemoteProductVisionSearchAnalyzerSetting settings = new MLRemoteProductVisionSearchAnalyzerSetting.Factory()
// Set the maximum number of products that can be returned.
.setLargestNumOfReturns(16)
// Set the product set ID. (Contact [email protected] to obtain the configuration guide.)
// .setProductSetId(productSetId)
// Set the region.
.setRegion(MLRemoteProductVisionSearchAnalyzerSetting.REGION_DR_CHINA)
.create();
analyzer
= MLAnalyzerFactory.getInstance().getRemoteProductVisionSearchAnalyzer(settings);
}
8. To capture image from camera.
Code:
Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
startActivityForResult(intent, REQ_CAMERA_CODE);
9. Once image has been captured, onActivityResult() method will be executed.
Code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.d(TAG, "onActivityResult");
if(requestCode == 101) {
if (resultCode == RESULT_OK) {
Bitmap bitmap = (Bitmap) data.getExtras().get("data");
if (bitmap != null) {
// Create an MLFrame object using the bitmap, which is the image data in bitmap format.
MLFrame mlFrame = new MLFrame.Creator().setBitmap(bitmap).create();
mlImageDetection(mlFrame);
}
}
}
}
private void mlImageDetection(MLFrame mlFrame) {
Task> task = analyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener>() {
public void onSuccess(List products) {
// Processing logic for detection success.
displaySuccess(products);
}})
.addOnFailureListener(new OnFailureListener() {
public void onFailure(Exception e) {
// Processing logic for detection failure.
// Recognition failure.
try {
MLException mlException = (MLException)e;
// Obtain the result code. You can process the result code and customize respective messages displayed to users.
int errorCode = mlException.getErrCode();
// Obtain the error information. You can quickly locate the fault based on the result code.
String errorMessage = mlException.getMessage();
} catch (Exception error) {
// Handle the conversion error.
}
}
});
}
private void displaySuccess(List productVisionSearchList) {
List productImageList = new ArrayList();
String prodcutType = "";
for (MLProductVisionSearch productVisionSearch : productVisionSearchList) {
Log.d(TAG, "type: " + productVisionSearch.getType() );
prodcutType = productVisionSearch.getType();
for (MLVisionSearchProduct product : productVisionSearch.getProductList()) {
productImageList.addAll(product.getImageList());
Log.d(TAG, "custom content: " + product.getCustomContent() );
}
}
StringBuffer buffer = new StringBuffer();
for (MLVisionSearchProductImage productImage : productImageList) {
String str = "ProductID: " + productImage.getProductId() + "
ImageID: " + productImage.getImageId() + "
Possibility: " + productImage.getPossibility();
buffer.append(str);
buffer.append("
");
}
Log.d(TAG , "display success: " + buffer.toString());
FragmentTransaction transaction = getFragmentManager().beginTransaction();
transaction.replace(R.id.main_fragment_container, new SearchResultFragment(productImageList, prodcutType ));
transaction.commit();
}
onSuccess() callback will give us list of MLProductVisionSearch objects, which can be used to get product id and image URL of each product. Also we can get the product type using productVisionSearch.getType(). getType() returns number which can be mapped.
10. We can achieve the product type mapping with following code.
Code:
private String getProductType(String type) {
switch(type) {
case "0":
return "Others";
case "1":
return "Clothing";
case "2":
return "Shoes";
case "3":
return "Bags";
case "4":
return "Digital & Home appliances";
case "5":
return "Household Products";
case "6":
return "Toys";
case "7":
return "Cosmetics";
case "8":
return "Accessories";
case "9":
return "Food";
}
return "Others";
}
11. To get product id and image URL from MLVisionSearchProductImage.
Code:
@Override
public void onBindViewHolder(ViewHolder holder, int position) {
final MLVisionSearchProductImage mlProductVisionSearch = productVisionSearchList.get(position);
holder.tvTitle.setText(mlProductVisionSearch.getProductId());
Glide.with(context)
.load(mlProductVisionSearch.getImageId())
.diskCacheStrategy(DiskCacheStrategy.ALL)
.into(holder.imageView);
}
Images
Reference
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides-V5/sdk-data-security-0000001050040129-V5

Huawei Flight Booking Application (Account kit and Ads kit)

More information like this, you can visit HUAWEI Developer Forum​
Introduction
Huawei Flight booking application is to explore HMS kits in real time scenario. This app can be used as reference to CP during HMS integration.
Prerequisite
1) You must have Huawei developer account.
2) Huawei phone with HMS 4.0.0.300 or later
3) Android Studio, JDK 1.8, SDK platform 26 and Gradle 4.6 installed.
Permissions
Provide following permissions in manifest.
Code:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
User Sign in
HUAWEI Account Kit offers easy, stable and fast login, and authorization functions to developers. Instead of entering accounts and passwords, you can simply tap the sign-in button with HUAWEI ID to log in your application easily and safely.
Setup:
1) Create a project in android studio.
2) Get the SHA-256 Key.
3) Create an app in the Huawei app gallery connect.
4) Enable account kit setting in Manage APIs Section.
5) Provide the SHA-256 Key in App Information Section.
6) Provide storage location.
7) Enable Huawei account under Auth Service in AGC.
{
"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"
}
8) After completing all the above points we need to download the agconnect-services.json from App Information Section. Place the json file in the app folder of the android project.
9) Enter the below maven URL inside the repositories of buildscript and allprojects respectively (project build.gradle file).
Code:
maven { url 'http://developer.huawei.com/repo/' }
10) Enter the below plugin in the app build.gradle file.
Code:
apply plugin: 'com.huawei.agconnect'
dependencies {
implementation 'com.huawei.hms:hwid:4.0.0.300'
11) Now Sync the gradle.
Implementation
1) In this app, we can implement Authorization code method.
Code:
HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM).setAuthorizationCode().createParams();
huaweiservice = HuaweiIdAuthManager.getService(MainActivity.this, authParams);
startActivityForResult(huaweiservice.getSignInIntent(), HUAWEI_SIGNIN);
 2) To Process the sign-in result after the authorization is complete.
Code:
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == HUAWEI_SIGNIN) {
com.huawei.hmf.tasks.Task<AuthHuaweiId> authHuaweiIdTask = HuaweiIdAuthManager.parseAuthResultFromIntent(data);
if (authHuaweiIdTask.isSuccessful()) {
//The sign-in is successful, and the user's HUAWEI ID information and authorization code are obtained.
AuthHuaweiId huaweiAccount = authHuaweiIdTask.getResult();
Log.i(TAG, "Authorization code:" + huaweiAccount.getAuthorizationCode());
Log.d(TAG, "name: " + huaweiAccount.getDisplayName());
Log.d(TAG, "email: " + huaweiAccount.getEmail());
Log.d(TAG , "avatar : "+huaweiAccount.getAvatarUriString());
launchLoggedinActivity(huaweiAccount.getFamilyName() , huaweiAccount.getGivenName() , huaweiAccount.getAvatarUriString(),"huawei");
} else {
// The sign-in failed.
Log.e(TAG, "sign in failed : " + ((com.huawei.hms.common.ApiException) authHuaweiIdTask.getException()).getStatusCode());
}
}
}
3) To handle silent Sign-in
The authorization is required only for first registration with the HUAWEI ID. Then no approval is required for subsequent registrations with the same HUAWEI ID.
Code:
private void handleHuaweiSilentSignIn() {
HuaweiIdAuthParams authParams = new HuaweiIdAuthParamsHelper(HuaweiIdAuthParams.DEFAULT_AUTH_REQUEST_PARAM).createParams();
HuaweiIdAuthService service = HuaweiIdAuthManager.getService(MainActivity.this, authParams);
com.huawei.hmf.tasks.Task<AuthHuaweiId> task = service.silentSignIn();
task.addOnSuccessListener(new OnSuccessListener<AuthHuaweiId>() {
@Override
public void onSuccess(AuthHuaweiId authHuaweiId) {
// Obtain the user's HUAWEI ID information.
Log.i(TAG, "displayName:" + authHuaweiId.getDisplayName());
launchLoggedinActivity(authHuaweiId.getFamilyName() , authHuaweiId.getGivenName() , authHuaweiId.getAvatarUriString(),"huawei");
}
});
task.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// The sign-in failed. Try to sign in explicitly using getSignInIntent().
if (e instanceof ApiException) {
ApiException apiException = (ApiException)e;
Log.i(TAG, "sign failed status:" + apiException.getStatusCode());
}
}
});
}
4) To sign out from Huawei account.
Code:
Task<Void> signOutTask = service.signOut();
signOutTask.addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
Log.i(TAG, "signOut complete");
}
});
5) To revoke authorization
Code:
service.cancelAuthorization().addOnCompleteListener(new OnCompleteListener<Void>() {
@Override
public void onComplete(Task<Void> task) {
if (task.isSuccessful()) {
// Processing after a successful authorization revoking.
Log.i(TAG, "onSuccess: ");
} else {
// Handle the exception.
Exception exception = task.getException();
if (exception instanceof ApiException){
int statusCode = ((ApiException) exception).getStatusCode();
Log.i(TAG, "onFailure: " + statusCode);
}
}
}
Integrating Huawei Banner Ads
Ad kit service makes easy for developers to raise money with high-quality advertising from mobile devices. It maximizes the value of every impression by combining global advertiser demand, innovative ad formats, and advanced app monetization technology.
Showing ads to app users helps you to create a reliable revenue stream to help your company grow while concentrating on creating and improving quality apps. Advertisers can attract new consumers and users can discover related goods and services while enjoying free apps. So it is a win for developers, users, and advertisers.
In this app, we will integrate Huawei banner ad. It is a Rectangular advertising on the top or bottom of the screen show. When users interact with the app, banner ads remain on the screen and it can be refreshed periodically for a period of time.
Usecase
We will show banner ad at the bottom of flight search screen.
Implementation
1) Enter the below maven URL inside the repositories of buildscript and allprojects (project build.gradle file).
Code:
implementation 'com.huawei.hms:ads-lite:13.4.30.307'
2) To integrate Huawei banner ad, add BannerView in xml.
Code:
<RelativeLayout xmlns:hwads="http://schemas.android.com/apk/res-auto" >
<com.huawei.hms.ads.banner.BannerView
android:id="@+id/huawei_banner_view"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:visibility="gone"
hwads:adId="testw6vs28auh3"
hwads:bannerSize="BANNER_SIZE_360_57"/>
Note: We are using test ad ID. "testw6vs28auh3" is a dedicated test ad slot ID.
3) To show Banner Ad.
Code:
if(Utility.isDeviceHuaweiManufacturer() && Utility.isHuaweiMobileServicesAvailable(this)) {
hwBannerView = findViewById(R.id.huawei_banner_view);
hwBannerView.setVisibility(View.VISIBLE);
// Create an ad request to load an ad.
AdParam adParam = new AdParam.Builder().build();
hwBannerView.loadAd(adParam);
hwBannerView.setAdListener(adListener);
} private AdListener adListener = new AdListener() {
@Override
public void onAdLoaded() {
// Called when an ad is loaded successfully.
Log.d(TAG , "onAdLoaded");
}
@Override
public void onAdFailed(int errorCode) {
// Called when an ad fails to be loaded.
Log.d(TAG , "onAdFailed");
}
@Override
public void onAdOpened() {
// Called when an ad is opened.
Log.d(TAG , "onAdOpened");
}
@Override
public void onAdClicked() {
// Called when a user taps an ad.
Log.d(TAG , "onAdClicked");
}
@Override
public void onAdLeave() {
// Called when a user has left the app.
Log.d(TAG , "onAdLeave");
}
@Override
public void onAdClosed() {
// Called when an ad is closed.
Log.d(TAG , "onAdClosed");
}
};
Conclusion:
We have learnt how easy it is to integrate Huawei account and ads kit in the flight booking application.
Stay tune for next article to see more Huawei kit integration in flight booking app.
Links:
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/introduction-0000001050048870
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/publisher-service-introduction-0000001050064960
does huawei mobile services provide flight booking api?

How a Programmer Created a Helpful Travel App for His Girlfriend

{
"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"
}
"Hey, they say it's five centimeters per second. The falling speed of a cherry blossom petal. Five centimeters per second."
Upon hearing these famous lines from a well-known Japanese anime, John, a Huawei programmer, realized that cherry trees are currently blossoming.
John's girlfriend, Jenny, also loves cherry blossoms and planned to visit Paris's most famous park for cherry blossoms, Parc de Sceaux, on the weekend. John, unfortunately, was still on a business trip that weekend and could not go with his girlfriend.
So John said to himself, "How about I make an intelligent travel app, I am a programmer after all, for Jenny, so that she can enjoy the cherry blossoms in the best possible way?" John then listed the following requirements for the app he was about to quickly create:
l Considerate travel reminders: remind her of important events in advance in her schedule, such as when to depart.
l Weather forecast: provide suggestions on what to bring and wear based on the weather conditions at her destination.
l Push messages: push helpful tips and discount information to her once she arrives at the destination.
...
Luckily for John, the preceding capabilities can be implemented without hassle using the time and weather awareness capabilities of HUAWEI Awareness Kit, the geofence capabilities of HUAWEI Location Kit, and the message pushing capabilities of HUAWEI Push Kit.
Overview​Awareness Kit provides your app the ability to obtain contextual information including users' current time, location, behavior, headset status, weather, ambient light, car stereo connection status, and beacon connection status, which can be combined to create various barriers that run in the background and trigger once the predefined context is met.
Location Kit combines GNSS, Wi-Fi, and base station positioning capabilities into your app, allowing you to provide flexible location-based services for users around the world.
Push Kit is a messaging service tailored for developers, which helps create a cloud-to-device messaging channel. With Push Kit integrated, your app can send messages to users' devices in real time.
Code Development​1. Awareness Kit Integration​Preparations​The following three key steps are required for integrating Awareness Kit. For details, please refer to the development guide on the HUAWEI Developers website.
1. Configure app information in AppGallery Connect.
2. Integrate the HMS Core Awareness SDK.
3. Configure obfuscation scripts.
Development Procedure​ 1. Declare required permissions in the AndroidManifest.xml file.
XML:
<p style="line-height: 1.5em;"><
uses-permission
android
:name
="android.permission.ACCESS_FINE_LOCATION"
/>
<
uses-permission
android
:name
="android.permission.ACCESS_BACKGROUND_LOCATION"
/></p>
2. Obtain weather information based on the city name.
Java:
String city = edCity.getText().toString();
if (city != null && !city.equals("")) {
WeatherPosition weatherPosition = new WeatherPosition();
weatherPosition.setCity(city);
// Pass the language type of the passed address. The value format is "Language_country", such as "zh_CN", "en_US".
weatherPosition.setLocale("en_US");
// Obtain the Capture Client of Awareness Kit, and call the weather query capability.
Awareness.getCaptureClient(getApplicationContext()).getWeatherByPosition(weatherPosition)
.addOnSuccessListener(new OnSuccessListener<WeatherStatusResponse>() {
@Override
public void onSuccess(WeatherStatusResponse weatherStatusResponse) {
// Process the returned weather data.
WeatherStatus weatherStatus = weatherStatusResponse.getWeatherStatus();
WeatherSituation weatherSituation = weatherStatus.getWeatherSituation();
Situation situation = weatherSituation.getSituation();
String weather;
// Match the weather ID with the weather.
weather = getApplicationContext().getResources().getStringArray(R.array.cnWeather)[situation.getCnWeatherId()];
// Update UI.
((TextView) findViewById(R.id.tv_weather)).setText(weather);
((TextView) findViewById(R.id.tv_windDir)).setText(situation.getWindDir());
((TextView) findViewById(R.id.tv_windSpeed)).setText(situation.getWindSpeed() + " km/h");
((TextView) findViewById(R.id.tv_temperature)).setText(situation.getTemperatureC() + "℃");
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});
}
3. Implement scheduled reminders and message pushing once a user arrives at the destination.
(1) Register a static broadcast receiver to receive notifications when the app is terminated.
The sample code in the AndroidManifest.xml file is as follows:
XML:
<receiver android:name=".BarrierReceiver">
<intent-filter>
<action android:name="com.test.awarenessdemo.TimeBarrierReceiver.BARRIER_RECEIVER_ACTION"/>
</intent-filter>
</receiver>
The Java sample code is as follows:
Java:
Intent intent = new Intent();
intent.setComponent(new ComponentName(MainActivity.this, BarrierReceiver.class));
mPendingIntent = PendingIntent.getBroadcast(this, 0, intent, PendingIntent.FLAG_UPDATE_CURRENT);
(2) Define the time barrier and corresponding label, then add the barrier.
Java:
// Obtain the entered time.
String timeHour = edTimeHour.getText().toString();
String timeMinute = edTimeMinute.getText().toString();
int hour = 0;
int minute = 0;
if (!timeHour.equals("")) {
hour = Integer.parseInt(timeHour);
if (!timeMinute.equals("")) {
minute = Integer.parseInt(timeMinute);
}
}
long oneHourMilliSecond = 60 * 60 * 1000L;
long oneMinuteMilliSecond = 60 * 1000L;
// Define the duringPeriodOfDay barrier to send notifications within a specified time period in a specified time zone.
AwarenessBarrier periodOfDayBarrier = TimeBarrier.duringPeriodOfDay(TimeZone.getDefault(),
// Set the notification time to two hours in advance.
(hour - 2) * oneHourMilliSecond + minute * oneMinuteMilliSecond,
hour * oneHourMilliSecond + minute * oneMinuteMilliSecond);
String timeBarrierLabel = "period of day barrier label";
// Define a request for updating a barrier.
BarrierUpdateRequest.Builder builder = new BarrierUpdateRequest.Builder();
BarrierUpdateRequest request = builder.addBarrier(timeBarrierLabel, periodOfDayBarrier, mPendingIntent).build();
Awareness.getBarrierClient(getApplicationContext()).updateBarriers(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});
(3) Define the location barrier and corresponding label, then add the barrier.
Java:
if (city != null && !city.equals("")) {
// Obtain the longitude and latitude of the city based on the city name from the assets folder.
String data = cityMap.get(city);
if (data != null){
int flag = data.indexOf(",");
double latitude = Double.parseDouble(data.substring(flag+1));
double longitude = Double.parseDouble(data.substring(0,flag));
double radius = 50;
long timeOfDuration = 5000;
// Define the stay barrier. If a user enters a specified area and stays for a specified time period, a barrier event is triggered and reported.
AwarenessBarrier stayBarrier = LocationBarrier.stay(latitude, longitude, radius, timeOfDuration);
String stayBarrierLabel = "stay barrier label";
// Define a request for updating a barrier.
BarrierUpdateRequest.Builder builder = new BarrierUpdateRequest.Builder();
BarrierUpdateRequest request = builder.addBarrier(stayBarrierLabel, stayBarrier, mPendingIntent).build();
Awareness.getBarrierClient(getApplicationContext()).updateBarriers(request)
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
}
});
}
}
(4) Define the broadcast receiver to listen for the barrier event for further processing
Java:
class BarrierReceiver extends BroadcastReceiver {
@Override
public void onReceive(Context context, Intent intent) {
BarrierStatus barrierStatus = BarrierStatus.extract(intent);
String label = barrierStatus.getBarrierLabel();
int barrierPresentStatus = barrierStatus.getPresentStatus();
String city = intent.getStringExtra("city");
switch (label) {
case DURING_PERIOD_OF_DAT_BARRIER_LABEL:
if (barrierPresentStatus == BarrierStatus.TRUE) {
initNotification(context,"1","time_channel","Travel reminder","Two hours before departure");
} else if (barrierPresentStatus == BarrierStatus.FALSE) {
showToast(context, "It's not between ");
} else {
showToast(context, "The time status is unknown.");
}
break;
case STAY_BARRIER_LABEL:
if (barrierPresentStatus == BarrierStatus.TRUE) {
initNotification(context,"2","area_channel","Welcome to"+city,"View travel plans");
} else if (barrierPresentStatus == BarrierStatus.FALSE) {
showToast(context,"You are not staying in the area set by locationBarrier" +
" or the time of duration is not enough.");
} else {
showToast(context, "The location status is unknown.");
}
break;
}
}
}
2. Location-based Message Pushing
Preparations​1. Add the Huawei Maven repository address to the build.gradle file in the root directory of your project. The sample code is as follows:
XML:
<p style="line-height: 1.5em;">buildscript {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
}
dependencies {
...
// Add AppGallery Connect plugin configuration.
classpath 'com.huawei.agconnect:agcp:1.4.2.300'
}
}allprojects {
repositories {
maven { url 'http://developer.huawei.com/repo/'}
}
}</p>
2. Add dependencies on the Location and Push SDKs to the build.gradle file in the app directory of your project.
Java:
<p style="line-height: 1.5em;">dependencies {
implementation 'com.huawei.hms:location:5.0.2.300'
implementation 'com.huawei.hms:push: 5.0.2.301'
}</p>
Key Steps​1. Declare system permissions in the AndroidManifest.xml file.
Location Kit incorporates GNSS, Wi-Fi, and base station positioning capabilities into your app. In order to do this, it requires the network, precise location, and coarse location permissions. If you want the app to continuously obtain user locations when running in the background, you also need to declare the ACCESS_BACKGROUND_LOCATION permission in the AndroidManifest.xml file.
XML:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="com.huawei.hms.permission.ACTIVITY_RECOGNITION" />
<uses-permission android:name="android.permission.ACTIVITY_RECOGNITION" />
Note: The ACCESS_FINE_LOCATION, WRITE_EXTERNAL_STORAGE, and READ_EXTERNAL_STORAGE permissions are dangerous system permissions, so you need to dynamically apply for these permissions. If your app does not have the permissions, Location Kit will be unable to provide services for your app.
2. Create a geofence and trigger it.
Create a geofence or geofence group as needed, and set related parameters.
Java:
LocationSettingsRequest.Builder builders = new LocationSettingsRequest.Builder();
builders.addLocationRequest(mLocationRequest);
LocationSettingsRequest locationSettingsRequest = builders.build();
// Before requesting location update, call checkLocationSettings to check device settings.
Task<LocationSettingsResponse> locationSettingsResponseTasks = mSettingsClient.checkLocationSettings(locationSettingsRequest);
locationSettingsResponseTasks.addOnSuccessListener(new OnSuccessListener<LocationSettingsResponse>() {
@Override
public void onSuccess(LocationSettingsResponse locationSettingsResponse) {
Log.i(TAG, "check location settings success");
mFusedLocationProviderClient
.requestLocationUpdates(mLocationRequest, mLocationCallbacks, Looper.getMainLooper())
.addOnSuccessListener(new OnSuccessListener<Void>() {
@Override
public void onSuccess(Void aVoid) {
LocationLog.i(TAG, "geoFence onSuccess");
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
LocationLog.e(TAG,
"geoFence onFailure:" + e.getMessage());
}
});
}
})
3. Trigger message pushing.
Send a push message when onReceive of GeoFenceBroadcastReceiver detects that the geofence is triggered successfully. The message will be displayed in the notification panel on the device.
Java:
if (geofenceData != null) {
int errorCode = geofenceData.getErrorCode();
int conversion = geofenceData.getConversion();
ArrayList<Geofence> list = (ArrayList<Geofence>) geofenceData.getConvertingGeofenceList();
Location myLocation = geofenceData.getConvertingLocation();
boolean status = geofenceData.isSuccess();
sb.append("errorcode: " + errorCode + next);
sb.append("conversion: " + conversion + next);
if (list != null) {
for (int i = 0; i < list.size(); i++) {
sb.append("geoFence id :" + list.get(i).getUniqueId() + next);
}
}
if (myLocation != null) {
sb.append("location is :" + myLocation.getLongitude() + " " + myLocation.getLatitude() + next);
}
sb.append("is successful :" + status);
LocationLog.i(TAG, sb.toString());
Toast.makeText(context, "" + sb.toString(), Toast.LENGTH_LONG).show();
//
new PushSendUtils().netSendMsg(sb.toString());
}
Note: The geofence created using the sample code will trigger two callbacks for conversion types 1 and 4. One is triggered when a user enters the geofence and the other is triggered when the user stays in the geofence. If Trigger is set to 7 in the code, callbacks for all scenarios, including entering, staying, and leaving the geofence, are configured.
Let's see this Demo:
For more details, you can go to:
l Our official website
l Our Development Documentation page, to find the documents you need
l Experience the easy-integration process on Codelabs
l GitHub to download demos and sample codes
l Stack Overflow to solve any integration problem
| Original Source
This is so nice, and a great app too.

HUAWEI ML Kit: Recognizes 17,000+ Landmarks

Ever seen a breathtaking landmark or scenic attraction when flipping through a book or magazine, and been frustrated by failing to find its name or location — wouldn't be so nice if there was an app that could tell you what you're seeing!
Fortunately, there's HUAWEI ML Kit, which comes with a landmark recognition service, and makes it remarkably easy to develop such an app.
So let's take a look at how to use this service!
Introduction to Landmark Recognition​The landmark recognition service enables you to obtain the landmark name, landmark longitude and latitude, and even a confidence value for the input image. A higher confidence value indicates that the landmark in the input image is more likely to be recognized. You can then use this information to create a highly-personalized experience for your users. Currently, the service is capable of recognizing more than 17,000 landmarks around the world.
In landmark recognition, the device calls the on-cloud API for detection, and the detection algorithm model runs on the cloud. During commissioning and usage, you'll need to make sure that the device can access the Internet.
Preparations​Configuring the development environment
Create an app in AppGallery Connect.
{
"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"
}
For details, see Getting Started with Android.
2. Enable ML Kit.
Click here for more details.
Download the agconnect-services.json file, which is automatically generated after the app is created. Copy it to the root directory of your Android Studio project.
Configure the Maven repository address for the HMS Core SDK.
Integrate the landmark recognition SDK.
Configure the SDK in the build.gradle file in the app directory.
Code:
// Import the landmark recognition SDK.
implementation 'com.huawei.hms:ml-computer-vision-cloud:2.0.5.304'
Add the AppGallery Connect plugin configuration as needed through either of the following methods:
Method 1: Add the following information under the declaration in the file header:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Method 2: Add the plugin configuration in the plugins block:
plugins {
id 'com.android.application'
id 'com.huawei.agconnect'
}
Code Development​Obtain the camera permission to use the camera.
Code:
(Mandatory) Set the static permission.
<uses-permission android:name="android.permission.CAMERA" />
(Mandatory) Obtain the dynamic permission.
ActivityCompat.requestPermissions(
this, new String[]{Manifest.permission. CAMERA
}, 1);
Set the API key. This service runs on the cloud, which means that an API key is required to set the cloud authentication information for the app. This step is a must, and failure to complete it will result in an error being reported when the app is running.
Code:
// Set the API key to access the on-cloud services.
private void setApiKey() {
// Parse the agconnect-services.json file to obtain its information.
AGConnectServicesConfig config = AGConnectServicesConfig.fromContext(getApplication());
// Sets the API key.
MLApplication.getInstance().setApiKey(config.getString("client/api_key"));
}
Create a landmark analyzer through either of the following methods:
// Method 1: Use default parameter settings.
Code:
MLRemoteLandmarkAnalyzer analyzer = MLAnalyzerFactory.getInstance().getRemoteLandmarkAnalyzer();
// Method 2: Use customized parameter settings through the MLRemoteLandmarkAnalyzerSetting class.
Code:
/**
* Use custom parameter settings.
* setLargestNumOfReturns indicates the maximum number of recognition results.
* setPatternType indicates the analyzer mode.
* MLRemoteLandmarkAnalyzerSetting.STEADY_PATTERN: The value 1 indicates the stable mode.
* MLRemoteLandmarkAnalyzerSetting.NEWEST_PATTERN: The value 2 indicates the latest mode.
*/
private void initLandMarkAnalyzer() {
settings = new MLRemoteLandmarkAnalyzerSetting.Factory()
.setLargestNumOfReturns(1)
.setPatternType(MLRemoteLandmarkAnalyzerSetting.STEADY_PATTERN)
.create();
analyzer = MLAnalyzerFactory.getInstance().getRemoteLandmarkAnalyzer(settings);
}
Convert the image collected from the camera or album to a bitmap. This is not provided by the landmark recognition SDK, so you'll need to implement it on your own.
Code:
// Select an image.
private void selectLocalImage() {
Intent intent = new Intent(Intent.ACTION_PICK, null);
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, REQUEST_SELECT_IMAGE);
}
Enable the landmark recognition service in the callback.
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
// Image selection succeeded.
if (requestCode == REQUEST_SELECT_IMAGE && resultCode == RESULT_OK) {
if (data != null) {
// Obtain the image URI through getData(). imageUri = data.getData();
// Implement the BitmapUtils class by yourself. Obtain the bitmap of the image with its URI. bitmap = BitmapUtils.loadFromPath(this, imageUri, getMaxWidthOfImage(), getMaxHeightOfImage());
}
// Start landmark recognition.
startAnalyzerImg(bitmap);
}
}
Start landmark recognition after obtaining the bitmap of the image. Since this service runs on the cloud, if the network status is poor, data transmission can be slow. Therefore, it's recommended that you add a mask to the bitmap prior to landmark recognition.
Code:
// Start landmark recognition.
private void startAnalyzerImg(Bitmap bitmap) {
if (imageUri == null) {
return;
}
// Add a mask.
progressBar.setVisibility(View.VISIBLE);
img_analyzer_landmark.setImageBitmap(bitmap);
// Create an MLFrame object using android.graphics.Bitmap. JPG, JPEG, PNG, and BMP images are supported. It is recommended that the image size be greater than or equal to 640 x 640 px.
MLFrame mlFrame = new MLFrame.Creator().setBitmap(bitmap).create();
Task<List<MLRemoteLandmark>> task = analyzer.asyncAnalyseFrame(mlFrame);
task.addOnSuccessListener(new OnSuccessListener<List<MLRemoteLandmark>>() {
public void onSuccess(List<MLRemoteLandmark> landmarkResults) {
progressBar.setVisibility(View.GONE);
// Called upon recognition success.
Log.d("BitMapUtils", landmarkResults.get(0).getLandmark());
}
}).addOnFailureListener(new OnFailureListener() {
public void onFailure(Exception e) {
progressBar.setVisibility(View.GONE);
// Called upon recognition failure.
// Recognition failure.
try {
MLException mlException = (MLException) e;
// Obtain the result code. You can process the result code and customize respective messages displayed to users.
int errorCode = mlException.getErrCode();
// Obtain the error information. You can quickly locate the fault based on the result code.
String errorMessage = mlException.getMessage();
// Record the code and message of the error in the log.
Log.d("BitMapUtils", "errorCode: " + errorCode + "; errorMessage: " + errorMessage);
} catch (Exception error) {
// Handle the conversion error.
}
}
});
}
Testing the App​The following illustrates how the service works, using the Oriental Pearl Tower in Shanghai and Pyramid of Menkaure as examples:
More Information​1. Before performing landmark recognition, set the API key to set the cloud authentication information for the app. Otherwise, an error will be reported while the app is running.
2. Landmark recognition runs on the cloud, so it may take some time to complete. It is recommended that you use the mask before performing landmark recognition.
3. If you are interested in other ML Kit services, feel free to check out our official materials.
To learn more, please visit:
HUAWEI Developers official website
Development Guide
Reddit to join developer discussions
GitHub or Gitee to download the demo and sample code
Stack Overflow to solve integration problems
Follow our official account for the latest HMS Core-related news and updates.
Original Source

Categories

Resources