Conventional pop-up ads and roll ads in apps not only frustrate users, but are a headache for advertisers. This is because on the one hand, advertising is expensive, but on the other hand, these ads do not necessarily reach their target audience. The emergence of personalized ads has proved a game changer.
To ensure ads are actually sent to their intended audience, publishers usually need to collect the personal data of users to determine their characteristics, hobbies, recent requirements, and more, and then push targeted ads in apps. Some users are unwilling to share privacy data to receive personalized ads. Therefore, if an app needs to collect, use, and share users' personal data for the purpose of personalized ads, valid consent from users must be obtained first.
HUAWEI Ads provides the capability of obtaining user consent. In countries/regions with strict privacy requirements, it is recommended that publishers access the personalized ad service through the HUAWEI Ads SDK and share personal data that has been collected and processed with HUAWEI Ads. HUAWEI Ads reserves the right to monitor the privacy and data compliance of publishers. By default, personalized ads are returned for ad requests to HUAWEI Ads, and the ads are filtered based on the user's previously collected data. HUAWEI Ads also supports ad request settings for non-personalized ads. For details, please refer to "Personalized Ads and Non-personalized Ads" in the HUAWEI Ads Privacy and Data Security Policies.
To obtain user consent, you can use the Consent SDK provided by HUAWEI Ads or the CMP that complies with IAB TCF v2.0. For details, see Integration with IAB TCF v2.0.
Let's see how the Consent SDK can be used to request user consent and how to request ads accordingly.
Development ProcedureTo begin with, you will need to integrate the HMS Core SDK and HUAWEI Ads SDK. For details, see the development guide.
Using the Consent SDK
1. Integrate the Consent SDK.
a. Configure the Maven repository address.
The code library configuration of Android Studio is different in versions earlier than Gradle 7.0, Gradle 7.0, and Gradle 7.1 and later versions. Select the corresponding configuration procedure based on your Gradle plugin version.
b. Add build dependencies to the app-level build.gradle file.
{
"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"
}
Replace {version} with the actual version number. For details about the version number, please refer to the version updates. The sample code is as follows:
Code:
dependencies {
implementation 'com.huawei.hms:ads-consent:3.4.54.300'
}
After completing all the preceding configurations, click
on the toolbar to synchronize the build.gradle file and download the dependencies.
2. Update the user consent status.
When using the Consent SDK, ensure that the Consent SDK obtains the latest information about the ad technology providers of HUAWEI Ads. If the list of ad technology providers changes after the user consent is obtained, the Consent SDK will automatically set the user consent status to UNKNOWN. This means that every time the app is launched, you should call the requestConsentUpdate() method to determine the user consent status. The sample code is as follows:
Code:
...
import com.huawei.hms.ads.consent.*;
...
public class ConsentActivity extends BaseActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Check the user consent status.
checkConsentStatus();
...
}
...
private void checkConsentStatus() {
...
Consent consentInfo = Consent.getInstance(this);
...
consentInfo.requestConsentUpdate(new ConsentUpdateListener() {
@Override
public void onSuccess(ConsentStatus consentStatus, boolean isNeedConsent, List<AdProvider> adProviders) {
// User consent status successfully updated.
...
}
@Override
public void onFail(String errorDescription) {
// Failed to update user consent status.
...
}
});
...
}
...
}
If the user consent status is successfully updated, the onSuccess() method of ConsentUpdateListener provides the updated ConsentStatus (specifies the consent status), isNeedConsent (specifies whether consent is required), and adProviders (specifies the list of ad technology providers).
3. Obtain user consent.
You need to obtain the consent (for example, in a dialog box) of a user and display a complete list of ad technology providers. The following example shows how to obtain user consent in a dialog box:
a. Collect consent in a dialog box.
The sample code is as follows:
Code:
...
import com.huawei.hms.ads.consent.*;
...
public class ConsentActivity extends BaseActivity {
...
@Override
protected void onCreate(Bundle savedInstanceState) {
...
// Check the user consent status.
checkConsentStatus();
...
}
...
private void checkConsentStatus() {
...
Consent consentInfo = Consent.getInstance(this);
...
consentInfo.requestConsentUpdate(new ConsentUpdateListener() {
@Override
public void onSuccess(ConsentStatus consentStatus, boolean isNeedConsent, List<AdProvider> adProviders) {
...
// The parameter indicating whether the consent is required is returned.
if (isNeedConsent) {
// If ConsentStatus is set to UNKNOWN, ask for user consent again.
if (consentStatus == ConsentStatus.UNKNOWN) {
...
showConsentDialog();
}
// If ConsentStatus is set to PERSONALIZED or NON_PERSONALIZED, no dialog box is displayed to ask for user consent.
else {
...
}
} else {
...
}
}
@Override
public void onFail(String errorDescription) {
...
}
});
...
}
...
private void showConsentDialog() {
// Start to process the consent dialog box.
ConsentDialog dialog = new ConsentDialog(this, mAdProviders);
dialog.setCallback(this);
dialog.setCanceledOnTouchOutside(false);
dialog.show();
}
}
Sample dialog box
Note: This image is for reference only. Design the UI based on the privacy page.
More information will be displayed if users tap here.
Note: This image is for reference only. Design the UI based on the privacy page.
b. Display the list of ad technology providers.
Display the names of ad technology providers to the user and allow the user to access the privacy policies of the ad technology providers.
After a user taps here on the information screen, the list of ad technology providers should appear in a dialog box, as shown in the following figure.
Note: This image is for reference only. Design the UI based on the privacy page.
c. Set consent status.
After obtaining the user's consent, use the setConsentStatus() method to set their content status. The sample code is as follows:
Code:
Consent.getInstance(getApplicationContext()).setConsentStatus(ConsentStatus.PERSONALIZED);
d. Set the tag indicating whether a user is under the age of consent.
If you want to request ads for users under the age of consent, call setUnderAgeOfPromise to set the tag for such users before calling requestConsentUpdate().
Code:
// Set the tag indicating whether a user is under the age of consent.
Consent.getInstance(getApplicationContext()).setUnderAgeOfPromise(true);
If setUnderAgeOfPromise is set to true, the onFail (String errorDescription) method is called back each time requestConsentUpdate() is called, and the errorDescription parameter is provided. In this case, do not display the dialog box for obtaining consent. The value false indicates that a user has reached the age of consent.
4. Load ads according to user consent.
By default, the setNonPersonalizedAd method is not called for requesting ads. In this case, personalized and non-personalized ads are requested, so if a user has not selected a consent option, only non-personalized ads can be requested.
The parameter of the setNonPersonalizedAd method can be set to the following values:
ALLOW_ALL: personalized and non-personalized ads.
ALLOW_NON_PERSONALIZED: non-personalized ads.
The sample code is as follows:
Code:
// Set the parameter in setNonPersonalizedAd to ALLOW_NON_PERSONALIZED to request only non-personalized ads.
RequestOptions requestOptions = HwAds.getRequestOptions();
requestOptions = requestOptions.toBuilder().setNonPersonalizedAd(ALLOW_NON_PERSONALIZED).build();
HwAds.setRequestOptions(requestOptions);
AdParam adParam = new AdParam.Builder().build();
adView.loadAd(adParam);
Testing the Consent SDK
To simplify app testing, the Consent SDK provides debug options that you can set.
1. Call getTestDeviceId() to obtain the ID of your device.
The sample code is as follows:
Code:
String testDeviceId = Consent.getInstance(getApplicationContext()).getTestDeviceId();
2. Use the obtained device ID to add your device as a test device to the trustlist.
The sample code is as follows:
Code:
Consent.getInstance(getApplicationContext()).addTestDeviceId(testDeviceId);
3. Call setDebugNeedConsent to set whether consent is required.
The sample code is as follows:
Code:
// Require consent for debugging. In this case, the value of isNeedConsent returned by the ConsentUpdateListener method is true.
Consent.getInstance(getApplicationContext()).setDebugNeedConsent(DebugNeedConsent.DEBUG_NEED_CONSENT);
// Not to require consent for debugging. In this case, the value of isNeedConsent returned by the ConsentUpdateListener method is false.
Consent.getInstance(getApplicationContext()).setDebugNeedConsent(DebugNeedConsent.DEBUG_NOT_NEED_CONSENT);
After these steps are complete, the value of isNeedConsent will be returned based on your debug status when calls are made to update the consent status.
For more information about the Consent SDK, please refer to the sample code.
References
Ads Kit
Development Guide of Ads Kit
Related
More information like this, you can visit HUAWEI Developer Forum
Introduction
Flight booking app allows user to search and book flight. In this article, we will integrate app messaging and analytics into demo flight booking application.
UseCase
1. We will show app-messaging image on app screen showing list of searched flight. When user tap on app-messaging image, it will redirect to webpage showing guidelines for international arrivals and departures. Add following image URL on Huawei App gallery 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"
}
2. We will use Huawei analytics to report few events like successful sign in and number of flights available between source destination.
For prerequisite and set up, refer to part 1.
Huawei App messaging
App Messaging of AppGallery Connect used to send relevant messages to target users actively using your app to encourage them to use key app functions. For example, you can send in-app messages to encourage users to subscribe certain products, provide tips on passing a game level, or recommend activities of a restaurant.
Implemetation
1. Add dependency in the app build.gradle file.
Code:
dependencies {
implementation 'com.huawei.agconnect:agconnect-appmessaging:1.4.0.300'
}
2. We need AAID for later use in sending In-App Messages. To obtain AAID, we will use getAAID() method.
3. Add following code in your project to obtain AAID.
Code:
HmsInstanceId inst = HmsInstanceId.getInstance(this);
Task<AAIDResult> idResult = inst.getAAID();
idResult.addOnSuccessListener(new OnSuccessListener<AAIDResult>() {
@Override
public void onSuccess(AAIDResult aaidResult) {
String aaid = aaidResult.getId();
Log.d(TAG, "getAAID success:" + aaid );
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
Log.d(TAG, "getAAID failure:" + e);
}
});
4. To initialize the AGConnectAppMessaging instance we will use.
Code:
AGConnectAppMessaging appMessaging = AGConnectAppMessaging.getInstance();
5. To allow data synchronization from the AppGallery Connect server we will use.
Code:
appMessaging.setFetchMessageEnable(true);
6. To enable message display.
Code:
appMessaging.setDisplayEnable(true);
7. To specify that the in-app message data must be obtained from the AppGallery Connect server by force we will use.
Code:
appMessaging.setForceFetch();
Since we are using a test device to demonstrate the use of In-App Messaging, so we use setForceFetch API. The setForceFetch API can be used only for message testing. Also In-app messages can only be displayed to users who have installed our officially released app version.
Creating Image In-App Messaging on App Gallery connect
1. Sign in to AppGallery Connect and select My projects.
2. Select your project from the project list.
3. Navigate Growing > App Messaging and click New.
4. Set Name and Description for your in-app message.
5. Provide the in-app message Type. For image in-app message, select type as Image.
6. Provide image URL.
7. Provide the action for image tapping.
8. Click Next to move on to the next section, that is, Select Sending Target section. Here we can define Condition for matching target users. In this article, we did not use any condition.
9. The next section is the Set Sending Time section.
We can schedule a date and time to send in-app message.
We can also provide an End data and time to stop sending message.
We can also display message on an events by using trigger event functionality.
Also we can flexibly set the frequency for displaying the in-app message.
10. Click Next, find Set conversation events. It associates the display or tap of the app message with a conversion event. The conversion relationship will be displayed in statistics. As off now we will keep it as none.
11. Click Save in the upper-right corner to complete message creation.
12. In-app messages can only be displayed to users who have installed our officially released app version. App Messaging allows us to test an in-app message when our app is still under tests. Find the message that you need to test, and click Test in the Operation column as shown below.
13. Provide the AAID of the test device in the text box. Click Save.
14. Click Publish.
Huawei Analytics
In this section, will show you how to use main APIs of HUAWEI Analytics Kit to report some custom events. App will report event like successful login, number of search flights.
1. Add the dependencies in app build.gradle file.
Code:
implementation 'com.huawei.hms:hianalytics:5.0.1.301'
2. The MainActivity.java is launched once user has successfully signed in. In onCreate(), we will call initializeAnalytics()to report successful signed in event.
Code:
private void initializeAnalytics() {
//Enable Analytics Kit Log
HiAnalyticsTools.enableLog();
//Generate the Analytics Instance
instance = HiAnalytics.getInstance(this);
//Parameter definition
Bundle bundle = new Bundle();
bundle.putBoolean("IsLoggedIn", true);
//Reporting event
instance.onEvent("LoginStatus", bundle);
}
3. To report number of flight available between origin and destination.
Code:
httpHandler.setFlightSearchListner(new OnFightSearchListner() {
@Override
public void onSuccess(ArrayList<Quote> quoteList) {
if(quoteList!= null && quoteList.size() > 0) {
Bundle bundle = new Bundle();
bundle.putBoolean("FlightSearchStatus", true);
bundle.putInt("FlightSearchCount", quoteList.size());
//Reporting event
instance.onEvent("FlightSearchStatus", bundle);
}
adapter = new OneWayFlightAdapter(quoteList);
recyclerView.setAdapter(adapter);
}
@Override
public void OnFailure(Exception e) {
// not implemented yet.. will do later
Log.e(TAG, e.getMessage());
}
});
To Check Analysis on App Gallery Connect
1. On the left side panel, click on Huawei Analyze > Behaviour Analysis > Event Analysis.
Conclusion:
In this article, we learnt how to integrate Huawei app-messaging and analytics to report event in application.
Can we integrate push messages along with in-app messaging?
well explained, can we load gifs also?
BackgroundThe real-time onscreen subtitle is a must-have function in an ordinary video app. However, developing such a function can prove costly for small- and medium-sized developers. And even when implemented, speech recognition is often prone to inaccuracy. Fortunately, there's a better way — HUAWEI ML Kit, which is remarkably easy to integrate, and makes real-time transcription an absolute breeze!
Introduction to ML KitML Kit allows your app to leverage Huawei's longstanding machine learning prowess to apply cutting-edge artificial intelligence (AI) across a wide range of contexts. With Huawei's expertise built in, ML Kit is able to provide a broad array of easy-to-use machine learning capabilities, which serve as the building blocks for tomorrow's cutting-edge AI apps. ML Kit capabilities include those related to:
Text (including text recognition, document recognition, and ID card recognition)
Language/Voice (such as real-time/on-device translation, automatic speech recognition, and real-time transcription)
Image (such as image classification, object detection and tracking, and landmark recognition)
Face/Body (such as face detection, skeleton detection, liveness detection, and face verification)
Natural language processing (text embedding)
Custom model (including the on-device inference framework and model development tool)
Real-time transcription is required to implement the function mentioned above. Let's take a look at how this works in practice:
{
"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"
}
Now let's move on to how to integrate this service.
Integrating Real-Time TranscriptionSteps
Registering as a Huawei developer on HUAWEI Developers
Creating an app
Create an app in AppGallery Connect. For details, see Getting Started with Android.
We have provided some screenshots for your reference:
3. Enabling ML Kit
4. Integrating the HMS Core SDK.
Add the AppGallery Connect configuration file by completing the steps below:
Download and copy the agconnect-service.json file to the app directory of your Android Studio project.
Call setApiKey during app initialization.
To learn more, go to Adding the AppGallery Connect Configuration File.
5.Configuring the maven repository address
Add build dependencies.
Import the real-time transcription SDK.
Code:
implementation 'com.huawei.hms:ml-computer-voice-realtimetranscription:2.2.0.300'
Add the AppGallery Connect plugin configuration.
Method 1: Add the following information under the declaration in the file header:
Code:
apply plugin: 'com.huawei.agconnect'
Method 2: Add the plugin configuration in the plugins block.
Code:
plugins {
id 'com.android.application'
// Add the following configuration:
id 'com.huawei.agconnect'
}
Please refer to Integrating the Real-Time Transcription SDK to learn more.
Setting the cloud authentication information
When using on-cloud services of ML Kit, you can set the API key or access token (recommended) in either of the following ways:
Access token
You can use the following API to initialize the access token when the app is started. The access token does not need to be set again once initialized.
MLApplication.getInstance().setAccessToken("your access token");
API key
You can use the following API to initialize the API key when the app is started. The API key does not need to be set again once initialized.
MLApplication.getInstance().setApiKey("your ApiKey");
For details, see Notes on Using Cloud Authentication Information.
Code Development
Create and configure a speech recognizer.
Code:
MLSpeechRealTimeTranscriptionConfig config = new MLSpeechRealTimeTranscriptionConfig.Factory()
// Set the language. Currently, this service supports Mandarin Chinese, English, and French.
.setLanguage(MLSpeechRealTimeTranscriptionConstants.LAN_ZH_CN)
// Punctuate the text recognized from the speech.
.enablePunctuation(true)
// Set the sentence offset.
.enableSentenceTimeOffset(true)
// Set the word offset.
.enableWordTimeOffset(true)
// Set the application scenario. MLSpeechRealTimeTranscriptionConstants.SCENES_SHOPPING indicates shopping, which is supported only for Chinese. Under this scenario, recognition for the name of Huawei products has been optimized.
.setScenes(MLSpeechRealTimeTranscriptionConstants.SCENES_SHOPPING)
.create();
MLSpeechRealTimeTranscription mSpeechRecognizer = MLSpeechRealTimeTranscription.getInstance();
Create a speech recognition result listener callback.
Code:
// Use the callback to implement the MLSpeechRealTimeTranscriptionListener API and methods in the API.
protected class SpeechRecognitionListener implements MLSpeechRealTimeTranscriptionListener{
@Override
public void onStartListening() {
// The recorder starts to receive speech.
}
@Override
public void onStartingOfSpeech() {
// The user starts to speak, that is, the speech recognizer detects that the user starts to speak.
}
@Override
public void onVoiceDataReceived(byte[] data, float energy, Bundle bundle) {
// Return the original PCM stream and audio power to the user. This API is not running in the main thread, and the return result is processed in a sub-thread.
}
@Override
public void onRecognizingResults(Bundle partialResults) {
// Receive the recognized text from MLSpeechRealTimeTranscription.
}
@Override
public void onError(int error, String errorMessage) {
// Called when an error occurs in recognition.
}
@Override
public void onState(int state,Bundle params) {
// Notify the app of the status change.
}
}
The recognition result can be obtained from the listener callbacks, including onRecognizingResults. Design the UI content according to the obtained results. For example, display the text transcribed from the input speech.
Bind the speech recognizer.
Code:
mSpeechRecognizer.setRealTimeTranscriptionListener(new SpeechRecognitionListener());
Call startRecognizing to start speech recognition.
Code:
mSpeechRecognizer.startRecognizing(config);
Release resources after recognition is complete.
Code:
if (mSpeechRecognizer!= null) {
mSpeechRecognizer.destroy();
}
(Optional) Obtain the list of supported languages.
Code:
MLSpeechRealTimeTranscription.getInstance()
.getLanguages(new MLSpeechRealTimeTranscription.LanguageCallback() {
@Override
public void onResult(List<String> result) {
Log.i(TAG, "support languages==" + result.toString());
}
@Override
public void onError(int errorCode, String errorMsg) {
Log.e(TAG, "errorCode:" + errorCode + "errorMsg:" + errorMsg);
}
});
We have finished integration here, so let's test it out on a simple screen.
Tap START RECORDING. The text recognized from the input speech will display in the lower portion of the screen.
We've now built a simple audio transcription function.
Eager to build a fancier UI, with stunning animations, and other effects? By all means, take your shot!
For reference:Real-Time Transcription
Sample Code for ML Kit
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
f users have not installed GMS on their phones, they cannot directly sign in to your app using a Google account. In this case, you can let them sign in to your app in web mode by obtaining the access token for sign-in authentication from Google. The procedure is as follows:
Sign in to the Google Play Console, click Credentials, and create an OAuth 2.0 client ID with Type set to Web application.
{
"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"
}
Go to the settings page and find Client ID and Client secret on the right side of the page, which are needed for integrating Google sign-in. Add a URI of the page to be displayed after the web sign-in is complete to Authorized redirect URIs.
When users want to sign in with their Google accounts, the web page domain name that is https://accounts.google.com/o/oauth2/v2/auth, query should be opened. Add the following parameters to it.
client_id — Required — The client ID for your application. You can find this value in the API Console Credentials page.
redirect_uri — Required — Determines where the API server redirects the user after the user completes the authorization flow. The value must exactly match one of the authorized redirect URIs for the OAuth 2.0 client, which you configured in your client’s API Console Credentials page. If this value doesn’t match an authorized redirect URI for the provided client_id you will get a redirect_uri_mismatch error.
Note that the http or https scheme, case, and trailing slash (‘/’) must all match.
response_type — Required — Determines whether the Google OAuth 2.0 endpoint returns an authorization code.
Set the parameter value to code for web server applications.
scope — Required — A space-delimited list of scopes that identify the resources that your application could access on the user’s behalf. These values inform the consent screen that Google displays to the user.
Scopes enable your application to only request access to the resources that it needs while also enabling users to control the amount of access that they grant to your application. Thus, there is an inverse relationship between the number of scopes requested and the likelihood of obtaining user consent.
We recommend that your application request access to authorization scopes in context whenever possible. By requesting access to user data in context, via incremental authorization, you help users to more easily understand why your application needs the access it is requesting.
access_type — Recommended — Indicates whether your application can refresh access tokens when the user is not present at the browser. Valid parameter values are online, which is the default value, and offline.
Set the value to offline if your application needs to refresh access tokens when the user is not present at the browser. This is the method of refreshing access tokens described later in this document. This value instructs the Google authorization server to return a refresh token and an access token the first time that your application exchanges an authorization code for tokens.
state — Recommended — Specifies any string value that your application uses to maintain state between your authorization request and the authorization server’s response. The server returns the exact value that you send as a name=value pair in the URL fragment identifier (#) of the redirect_uri after the user consents to or denies your application’s access request.
You can use this parameter for several purposes, such as directing the user to the correct resource in your application, sending nonces, and mitigating cross-site request forgery. Since your redirect_uri can be guessed, using a state value can increase your assurance that an incoming connection is the result of an authentication request. If you generate a random string or encode the hash of a cookie or another value that captures the client’s state, you can validate the response to additionally ensure that the request and response originated in the same browser, providing protection against attacks such as cross-site request forgery. See the OpenID Connect documentation for an example of how to create and confirm a state token.
include_granted_scopes — Optional — Enables applications to use incremental authorization to request access to additional scopes in context. If you set this parameter’s value to true and the authorization request is granted, then the new access token will also cover any scopes to which the user previously granted the application access. See the incremental authorization section for examples.
login_hint — Optional — If your application knows which user is trying to authenticate, it can use this parameter to provide a hint to the Google Authentication Server. The server uses the hint to simplify the login flow either by prefilling the email field in the sign-in form or by selecting the appropriate multi-login session.
Set the parameter value to an email address or sub identifier, which is equivalent to the user’s Google ID.
prompt — Optional — A space-delimited, case-sensitive list of prompts to present the user. If you don’t specify this parameter, the user will be prompted only the first time your project requests access.
Possible values are:
none Do not display any authentication or consent screens. Must not be specified with other values.
consent Prompt the user for consent.
select_account Prompt the user to select an account.
Examples
Code:
https://accounts.google.com/o/oauth2/v2/auth?
scope=profile&
access_type=offline&
include_granted_scopes=true&
response_type=code&
state=state_parameter_passthrough_value&
redirect_uri=https%3A//oauth2.example.com/code&
client_id=342746900306-vmpmbn8dgulp7eun1i8haiu86kocn8t6.apps.googleusercontent.com
redirect_uri is the URI we configured in step 2.
When the web page we generated in step 3 is opened, the Google account sign-in page is displayed. Once users are signed in, they will be redirected to the URI we set for redirect_uri. You should save the code value that clings to this domain name.
Example:
Code:
https://oauth2.example.com/code?
state=state_parameter_passthrough_value&
code=4%2FzAFyRfnDjPJKLRlkcZCedy-P6GpYbmAPpOvbmeUwXCfv0lXkUWjjHRXGtrwpoordursX2wfKShoGakKbLGzS4Ac&
scope=email+profile+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email+openid+https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile
&authuser=0
&prompt=none
In this case, the code value is as follows:
4%2FzAFyRfnDjPJKLRlkcZCedy-P6GpYbmAPpOvbmeUwXCfv0lXkUWjjHRXGtrwpoordursX2wfKShoGakKbLGzS4Ac
After obtaining the code value, send an HTTP request to https://oauth2.googleapis.com/token to obtain the value of access_token required for AppGallery Connect authentication.
The parameters are as follows.
client_id — The client ID obtained from the API Console Credentials page.
client_secret — The client secret obtained from the API Console Credentials page.
code — The authorization code returned from the initial request.
grant_type — As defined in the OAuth 2.0 specification, this field must contain a value of authorization_code.
redirect_uri — One of the redirect URIs listed for your project in the API Console Credentials page for the given client_id.
Example:
Code:
POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded
code=4%2FzAFyRfnDjPJKLRlkcZCedy-P6GpYbmAPpOvbmeUwXCfv0lXkUWjjHRXGtrwpoordursX2wfKShoGakKbLGzS4Ac
client_id=your_client_id&
client_secret=your_client_secret&
redirect_uri=https%3A//oauth2.example.com/code&
grant_type=authorization_code
The return result of the request carries the access_token you need.
Example of the return result:
JSON:
{
"access_token": "1/fFAGRNJru1FTz70BzhT3Zg",
"expires_in": 3920,
"token_type": "Bearer",
"scope": "https://www.googleapis.com/auth/drive.metadata.readonly",
"refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI"
}
Use the token to pass the AppGallery Connect authentication. Sample code
Java:
// accesstoken is the value of access_token obtained in the previous step.
AGConnectAuthCredential credential = GoogleAuthProvider.credentialWithToken(accesstoken);
AGConnectAuth.getInstance().signIn(credential)
.addOnSuccessListener(new OnSuccessListener<SignInResult>() {
@Override
public void onSuccess(SignInResult signInResult) {
// onSuccess
AGConnectUser user = signInResult.getUser();
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// onFail
}
});
References
Create a client ID on Google Play Console
Sign in to AppGallery Connect with a Google account
Can we use both HMS and GMS in application?
Basavaraj.navi said:
Can we use both HMS and GMS in application?
Click to expand...
Click to collapse
You certainly can! there are lots of ways you could implement this https://stackoverflow.com/questions/59974428/have-both-gms-and-hms-in-the-project has some great examples on how you might check for which services to use on a specific device.
View attachment Featured image.jpg
As the start of the new academic year approaches, many college students will be leaving their parents to start college life. However, a lack of experience makes it easy for college students to become victims of electronic fraud such as phone scams.
The start of the new academic year is often a period of time that sees an uptick in phone scams, especially those targeting college students. Some scammers trick students to download and register an account on malicious financial apps embedded with viruses and Trojan horses or ones that imitate legitimate apps. With such malicious apps installed on students' phones, scammers are able to steal students' sensitive data, such as bank card numbers and passwords. Some scammers trick students, by offering them small gifts or coupons, to scan QR codes which then direct them to pages that ask users to enter their personal information, such as their phone number and address. Once a student has done this, they will receive a large number of fraudulent calls and junk SMS messages from then on. If the students scan QR codes linking to phishing websites, their personal data may be leaked and sold for malicious purposes. Some scammers even lie about offering students scholarships or grants, in order to trick them into visiting phishing websites and entering their bank account numbers and passwords, causing significant financial losses to such students.
{
"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"
}
To deal with the ever-changing tricks of fraudsters, an app needs to detect phishing websites, malicious apps, and other risks and remind users to be on the lookout for such risks with in-app tips, in order to keep users and their data safe. So, is there a one-stop service that can enhance app security from multiple dimensions? Fortunately, HMS Core Safety Detect can help developers quickly build security capabilities into their apps, and help vulnerable user groups such as college students safeguard their information and property.
The AppsCheck API in Safety Detect allows your app to obtain a list of malicious apps installed on a user's device. The API can identify 99% of malicious apps and detect unknown threats based on app behavior. Your app can then use this information to determine whether to restrict users from performing in-app payments and other sensitive operations.
The URLCheck API in Safety Detect checks whether an in-app URL is malicious. If the URL is determined to be malicious, the app can warn the user of the risk or block the URL.
Safety Detect also provides capabilities to check system integrity and detect fake users, helping developers quickly improve their app security. The integration process is straightforward, which I'll describe below.
Demo
Integration ProcedurePreparationsYou can follow the instructions here to prepare for the integration.
Using the AppsCheck APIYou can directly call getMaliciousAppsList of SafetyDetectClient to obtain a list of malicious apps. The sample code is as follows:
Code:
private void invokeGetMaliciousApps() {
SafetyDetectClient appsCheckClient = SafetyDetect.getClient(MainActivity.this);
Task task = appsCheckClient.getMaliciousAppsList();
task.addOnSuccessListener(new OnSuccessListener<MaliciousAppsListResp>() {
@Override
public void onSuccess(MaliciousAppsListResp maliciousAppsListResp) {
// Indicates that communication with the service was successful.
// Use resp.getMaliciousApps() to obtain a list of malicious apps.
List<MaliciousAppsData> appsDataList = maliciousAppsListResp.getMaliciousAppsList();
// Indicates that the list of malicious apps was successfully obtained.
if(maliciousAppsListResp.getRtnCode() == CommonCode.OK) {
if (appsDataList.isEmpty()) {
// Indicates that no known malicious apps were detected.
Log.i(TAG, "There are no known potentially malicious apps installed.");
} else {
Log.i(TAG, "Potentially malicious apps are installed!");
for (MaliciousAppsData maliciousApp : appsDataList) {
Log.i(TAG, "Information about a malicious app:");
// Use getApkPackageName() to obtain the APK name of the malicious app.
Log.i(TAG, "APK: " + maliciousApp.getApkPackageName());
// Use getApkSha256() to obtain the APK SHA-256 of the malicious app.
Log.i(TAG, "SHA-256: " + maliciousApp.getApkSha256());
// Use getApkCategory() to obtain the category of the malicious app.
// Categories are defined in AppsCheckConstants.
Log.i(TAG, "Category: " + maliciousApp.getApkCategory());
}
}
}else{
Log.e(TAG,"getMaliciousAppsList failed: "+maliciousAppsListResp.getErrorReason());
}
}
}).addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// An error occurred during communication with the service.
if (e instanceof ApiException) {
// An error with the HMS API contains some
// additional details.
ApiException apiException = (ApiException) e;
// You can retrieve the status code using the apiException.getStatusCode() method.
Log.e(TAG, "Error: " + SafetyDetectStatusCodes.getStatusCodeString(apiException.getStatusCode()) + ": " + apiException.getStatusMessage());
} else {
// A different, unknown type of error occurred.
Log.e(TAG, "ERROR: " + e.getMessage());
}
}
});
}
Using the URLCheck API1. Initialize the URLCheck API.
Before using the URLCheck API, you must call the initUrlCheck method to initialize the API. The sample code is as follows:
Code:
SafetyDetectClient client = SafetyDetect.getClient(getActivity());
client.initUrlCheck();
2. Request a URL check.
You can pass target threat types to the URLCheck API as parameters. The constants in the UrlCheckThreat class include the current supported threat types.
Code:
public class UrlCheckThreat {
// URLs of this type are marked as URLs of pages containing potentially malicious apps (such as home page tampering URLs, Trojan-infected URLs, and malicious app download URLs).
public static final int MALWARE = 1;
// URLs of this type are marked as phishing and spoofing URLs.
public static final int PHISHING = 3;
}
a. Initiate a URL check request.
The URL to be checked contains the protocol, host, and path but does not contain the query parameter. The sample code is as follows:
Code:
String url = "https://developer.huawei.com/consumer/cn/";
SafetyDetect.getClient(this).urlCheck(url, appId, UrlCheckThreat.MALWARE, UrlCheckThreat.PHISHING).addOnSuccessListener(this, new OnSuccessListener<UrlCheckResponse >(){
@Override
public void onSuccess(UrlCheckResponse urlResponse) {
if (urlResponse.getUrlCheckResponse().isEmpty()) {
// No threat exists.
} else {
// Threats exist.
}
}
}).addOnFailureListener(this, new OnFailureListener() {
@Override
public void onFailure(@NonNull Exception e) {
// An error occurred during communication with the service.
if (e instanceof ApiException) {
// HMS Core (APK) error code and corresponding error description.
ApiException apiException = (ApiException) e;
Log.d(TAG, "Error: " + CommonStatusCodes.getStatusCodeString(apiException.getStatusCode()));
// Note: If the status code is SafetyDetectStatusCode.CHECK_WITHOUT_INIT,
// you did not call the initUrlCheck() method or you have initiated a URL check request before the call is completed.
// If an internal error occurs during the initialization, you need to call the initUrlCheck() method again to initialize the API.
} else {
// An unknown exception occurred.
Log.d(TAG, "Error: " + e.getMessage());
}
}
});
b. Call the getUrlCheckResponse method of the returned UrlCheckResponse object to obtain the URL check result.
The result contains List<UrlCheckThreat>, which includes the detected URL threat type. If the list is empty, no threat is detected. Otherwise, you can call getUrlCheckResult in UrlCheckThreat to obtain the specific threat code. The sample code is as follows:
Code:
final EditText testRes = getActivity().findViewById(R.id.fg_call_urlResult);
List<UrlCheckThreat> list = urlCheckResponse.getUrlCheckResponse();
if (list.isEmpty()) {
testRes.setText("ok");
}
else{
for (UrlCheckThreat threat : list) {
int type = threat.getUrlCheckResult();
}
}
3. Close the URL check session.
If your app does not need to call the URLCheck API anymore or will not need to for a while, you can call the shutdownUrlCheck method to close the URL check session and release relevant resources.
Code:
SafetyDetect.getClient(this).shutdownUrlCheck();
ConclusionElectronic fraud such as phone scams are constantly evolving and becoming more and more difficult to prevent, bringing great challenges to both developers and users. To combat such risks, developers must utilize technical means to identify phishing websites, malicious apps, and other risks, in order to safeguard users' personal information and property.
In this article, I demonstrated how HMS Core Safety Detect can be used to effectively combat electronic fraud. The whole integration process is straightforward and cost-efficient, and is a quick and effective way to build comprehensive security capabilities into an app.
In the mobile Internet era, people are increasingly using mobile apps for a variety of different purposes, such as buying products online, hailing taxis, and much more. When using such an app, a user usually needs to manually enter their address for package delivery or search for an appropriate pick-up and drop-off location when they hail a taxi, which can be inconvenient.
To improve user experience, many apps nowadays allow users to select a point on the map and then use the selected point as the location, for example, for package delivery or getting on or off a taxi. Each location has a longitude-latitude coordinate that pinpoints its position precisely on the map. However, longitude-latitude coordinates are simply a string of numbers and provide little information to the average user. It would therefore be useful if there was a tool which an app can use to convert longitude-latitude coordinates into human-readable addresses.
Fortunately, the reverse geocoding function in HMS Core Location Kit can obtain the nearest address to a selected point on the map based on the longitude and latitude of the point. Reverse geocoding is the process of converting a location as described by geographic coordinates (longitude and latitude) to a human-readable address or place name, which is much more useful information for users. It permits the identification of nearby street addresses, places, and subdivisions such as neighborhoods, counties, states, and countries.
Generally, the reverse geocoding function can be used to obtain the nearest address to the current location of a device, show the address or place name when a user taps on the map, find the address of a geographic location, and more. For example, with reverse geocoding, an e-commerce app can show users the detailed address of a selected point on the map in the app; a ride-hailing or takeout delivery app can show the detailed address of a point that a user selects by dragging the map in the app or tapping the point on the map in the app, so that the user can select the address as the pick-up address or takeout delivery address; and an express delivery app can utilize reverse geocoding to show the locations of delivery vehicles based on the passed longitude-latitude coordinates, and intuitively display delivery points and delivery routes to users.
Bolstered by a powerful address parsing capability, the reverse geocoding function in this kit can display addresses of locations in accordance with local address formats with an accuracy as high as 90%. In addition, it supports 79 languages and boasts a parsing latency as low as 200 milliseconds.
{
"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"
}
DemoThe file below is a demo of the reverse geocoding function in this kit.
Preparations
Before getting started with the development, you will need to make the following preparations:
Register as a Huawei developer and complete identity verification on the HUAWEI Developers website. You can click here to find out the detailed registration and identity verification procedure.
Create a project and then create an app in the project in AppGallery Connect. Before doing so, you must have a Huawei developer account and complete identity verification.
Generate a signing certificate fingerprint and configure it in AppGallery Connect. The signing certificate fingerprint is used to verify the authenticity of an app. Before releasing an app, you must generate a signing certificate fingerprint locally based on the signing certificate and configure it in AppGallery Connect.
Integrate the Location SDK into your app. If you are using Android Studio, you can integrate the SDK via the Maven repository.
Here, I won't be describing how to generate and configure a signing certificate fingerprint and integrate the SDK. You can click here to learn about the detailed procedure.
Development Procedure
After making relevant preparations, you can perform the steps below to use the reverse geocoding service in your app. Before using the service, ensure that you have installed HMS Core (APK) on your device.
1. Create a geocoding service client.
In order to call geocoding APIs, you first need to create a GeocoderService instance in the onClick() method of GeocoderActivity in your project. The sample code is as follows:
Code:
Locale locale = new Locale("zh", "CN");
GeocoderService geocoderService = LocationServices.getGeocoderService(GeocoderActivity.this, locale);
2. Obtain the reverse geocoding information.
To empower your app to obtain the reverse geocoding information, you need to call the getFromLocation() method of the GeocoderService object in your app. This method will return a List<HWLocation> object containing the location information based on the set GetFromLocationRequest object.
a. Set reverse geocoding request parameters.
There are three request parameters in the GetFromLocationRequest object, which indicate the latitude, longitude, and maximum number of returned results respectively. The sample code is as follows:
Code:
// Parameter 1: latitude
// Parameter 2: longitude
// Parameter 3: maximum number of returned results
// Pass valid longitude-latitude coordinates. If the coordinates are invalid, no geographical information will be returned. Outside China, pass longitude-latitude coordinates located outside China and ensure that the coordinates are correct.
GetFromLocationRequest getFromLocationRequest = new GetFromLocationRequest(39.985071, 116.501717, 5);
b. Call the getFromLocation() method to obtain reverse geocoding information.
The obtained reverse geocoding information will be returned in a List<HWLocation> object. You can add listeners using the addOnSuccessListener() and addOnFailureListener() methods, and obtain the task execution result using the onSuccess() and onFailure() methods.
The sample code is as follows:
Code:
private void getReverseGeocoding() {
// Initialize the GeocoderService object.
if (geocoderService == null) {
geocoderService = new GeocoderService(this, new Locale("zh", "CN"));
}
geocoderService.getFromLocation(getFromLocationRequest)
.addOnSuccessListener(new OnSuccessListener<List<HWLocation>>() {
@Override
public void onSuccess(List<HWLocation> hwLocation) {
// TODO: Define callback for API call success.
if (null != hwLocation && hwLocation.size() > 0) {
Log.d(TAG, "hwLocation data set quantity: " + hwLocation.size());
Log.d(TAG, "CountryName: " + hwLocation.get(0).getCountryName());
Log.d(TAG, "City: " + hwLocation.get(0).getCity());
Log.d(TAG, "Street: " + hwLocation.get(0).getStreet());
}
}
})
.addOnFailureListener(new OnFailureListener() {
@Override
public void onFailure(Exception e) {
// TODO: Define callback for API call failure.
}
});
}
Congratulations, your app is now able to use the reverse geocoding function to obtain the address of a location based on its longitude and latitude.
Conclusion
The quick development and popularization of the mobile Internet has caused many changes to our daily lives. One such change is that more and more people are using mobile apps on a daily basis, for example, to buy daily necessities or hail a taxi. These tasks traditionally require users to manually enter the delivery address or pick-up and drop-off location addresses. Manually entering such addresses is inconvenient and prone to mistakes.
To solve this issue, many apps allow users to select a point on the in-app map as the delivery address or the address for getting on or off a taxi. However, the point on the map is usually expressed as a set of longitude-latitude coordinates, which most users will find hard to understand.
As described in this post, my app resolves this issue using the reverse geocoding function, which is proven a very effective way for obtaining human-readable addresses based on longitude-latitude coordinates. If you are looking for a solution to such issues, have a try to find out if this is what your app needs.