Today we are going to take a look at how we can integrate the AppGallery Connect crash service into your Xamarin app.
But why might you want to do this? The AppGallery Connect Crash service provides a powerful yet lightweight solution to app crash problems. With the service, you can quickly detect, locate, and resolve app crashes (unexpected exits of apps), and have access to highly readable crash reports in real-time, without the need to write any code.
The service is completely free to use and can be a great addition to your project!
Below is a simple app example you can follow along with to get a good idea of how you might use this service in your own app!
Preparing the Xamarin Environment and Configuring Your ProjectInstall the Xamarin environment.
You’ll need to install Visual Studio first, and then select Mobile development with .NET in Visual Studio to install the Xamarin environment.
{
"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"
}
Create a project in AppGallery Connect and enable HUAWEI Analytics for your project.
Install the service SDK. Right-click your project and choose Manage NuGet Packages
Search for crash on the Browse tab. Click Xamarin.Android bindings for HMS Core — AgconnectCrash in the search results and install it.
Add the JSON file to the Assets directory
Next, implement LazyInputStream to read the agconnect-services.json file.
For details, please refer to Getting Started with Xamarin
Finally set a package name in Android Manifest.
Example ApplicationLets start by creating a simple layout that has three buttons.
XML:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="300dp"
android:layout_height="wrap_content"
android:gravity="center"
android:orientation="vertical">
<Button
android:id="@+id/btn_crash"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="MakeCrash" />
<Button
android:id="@+id/btnRecordException"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="CatchException" />
<Button
android:id="@+id/btnCustomReport"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAllCaps="false"
android:text="CustomReport" />
</LinearLayout>
</LinearLayout>
In the MainActivity.cs file, call * AGConnectCrash.Instance.TestIt* to trigger a crash, call AGConnectCrash.Instance.SetUserId to set a custom user ID, call AGConnectCrash.Instance.SetCustomKey to set the key and value for a custom key-value pair, call AGConnectCrash.Instance.Log to set the log level, and call AGConnectCrash.Instance.RecordException to record a non-fatal exception.
C#:
private void BtnCreateCrash_Click(object sender, EventArgs e) {
AGConnectCrash.Instance.TestIt(this);
}
private void BtnCustomReport_Click(object sender, EventArgs e) {
AGConnectCrash.Instance.SetUserId("testuser");
AGConnectCrash.Instance.SetCustomKey("doublekey", "1.1");
AGConnectCrash.Instance.SetCustomKey("floatkey", "1.12f");
AGConnectCrash.Instance.SetCustomKey("intkey", "123");
AGConnectCrash.Instance.SetCustomKey("stringkey", "hello world");
AGConnectCrash.Instance.Log("default log level");
AGConnectCrash.Instance.Log(3, "3 is debug log level");
}
private void BtnRecordException_Click(object sender, EventArgs e) {
try {
ArrayIndexOutOfBoundsException arrayIndexOutOfBoundsException = new ArrayIndexOutOfBoundsException();
throw arrayIndexOutOfBoundsException;
} catch (Java.Lang.Exception ex) {
AGConnectCrash.Instance.RecordException(ex);
}
}
View the Crash ReportTap MakeCrash, CatchException, and CustomReport in sequence, and check the report in AppGallery Connect.
Crash statistics:
Exceptions:
Debugging:
View custom key-value pairs:
View custom log level:
View custom user IDs:
For more information, please refer to:
Crash document for Android
Codelab of Crash for Xamarin.Android
Does it works on offline?
How long does it take to log in the console?
Thanks for sharing!!!
muraliameakula said:
Does it works on offline?
Click to expand...
Click to collapse
It does indeed! crash reports are stored locally and uploaded to the server once a stable internet connection is found
Related
When you release a paid application it is normal that you want to reach a large number of users, after all, more users = more purchases = more revenues, or not?
When a user downloads your app he can use some tools to make a backup of the app, until now everything is fine but, what if the user share the APK with his friends, in this case your paid app will become in a free app distributed by an unofficial way.
To avoid this situation you can integrate the AGC DRM SDK which will be executed on each startup to check if the current user has purchased your app.
Previous requirements
An Enterprise developer account
A paid app project on ACG
An android project with the HMS Core SDK and the AGC plugin configured
Obtaining the DRM keys
From your AGC console choose your project and then go to Develop > Earning > Pay Downloads
{
"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"
}
Adding the DRM SDK
Download the SDK from the Huawei developers website
Extract the content and copy the jar file to your libs folder
Merge the res folder with your res folder, the DRM kit will show a message if the app hasn’t been installed from app gallery and this message can be displayed in many languages, the res folder of the kit contains the strings for all supported languages.
Add the next permissions to your Android Manifest and register the DRM dialog
Code:
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.READ_PHONE_STATE" />
<uses-permission android:name="android.permission.INTERNET" />
<activity
android:name="com.huawei.android.sdk.drm.DrmDialogActivity"
android:exported="false"
android:configChanges="screenSize|orientation|keyboardHidden"
android:label="@string/app_name"
android:theme="@android:style/Theme.Translucent" >
<meta-data
android:name="hwc-theme"
android:value="androidhwext:style/Theme.Emui.Translucent" />
</activity>
If you are using obfuscation, add this to you proguard-rules.pro
Code:
-keep class com.huawei.android.sdk.drm.**{*;}
Performing the check
You can check if your app has been purchased from any activity, as suggestion, perform the check in your launcher activity, so invalid users cannot access to your app functions.
Code:
private val DRM_PUBLIC_KEY=" THE_DRM_KEY_FROM_AGC "
private val DRM_ID="THE_DRM_ID_FROM_AGC"
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main2)
val task =Iap.getIapClient(this).isEnvReady
Drm.check(
this, this.packageName, DRM_ID, DRM_PUBLIC_KEY,object :DrmCheckCallback{
override fun onCheckSuccess() {
//The app has been purchased from app gallery
}
override fun onCheckFailed() {
//The app has been installed by other ways
//You maybe want to finish the app here
}
}
)
}
Conclusion
Integrating the DRM SDK is very quick and will avoid unofficial distributions of your app.
When a user opens your paid app, the SDK checks whether the user has purchased the app. If the user has not purchased the app, the SDK prompts the user to purchase it.
What are you waiting to add this SDK to your Paid App?
More information like this, you can visit HUAWEI Developer Forum
Introduction
Online food ordering is process that delivers food from local restaurants. Mobile apps make our world better and easier customer to prefer comfort and quality instead of quantity.
Sign In Module
User can login with mobile number to access food order application. Using auth service we can integrate third party sign in options. Huawei Auth service provides a cloud based auth service and SDK.
In this article, following Kits are covered:
1. AGC Auth Service
2. Ads Kit
3. Site kit
Steps
1. Create App in Android.
2. Configure App in AGC.
3. Integrate the SDK in our new Android project.
4. Integrate the dependencies.
5. Sync project.
Screens
{
"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"
}
Configuration
1. Login into AppGallery Connect, select FoodApp in My Project list.
2. Enable required APIs in manage APIs tab.
Choose Project Settings > ManageAPIs
3. Enable auth service before enabling Authentication modes as we need to enable Auth Service.
Choose Build > Auth Service and click Enable now top right-corner
4. Enable sign in modes required for application
Integration
Create Application in Android Studio.
App level gradle dependencies.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Gradle dependencies
Code:
implementation 'com.google.android.material:material:1.3.0-alpha02'
implementation 'com.huawei.agconnect:agconnect-core:1.4.0.300'
implementation 'com.huawei.agconnect:agconnect-auth:1.4.0.300'
implementation 'com.huawei.hms:hwid:4.0.4.300'
implementation 'com.huawei.hms:site:4.0.3.300'
implementation 'com.huawei.hms:ads-lite:13.4.30.307'
Root level gradle dependencies
Code:
maven {url 'https://developer.huawei.com/repo/'}
classpath 'com.huawei.agconnect:agcp:1.3.1.300'
Add the below permissions in Android Manifest file
Code:
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...
</manifest>
Ads Kit: Huawei ads SDK to quickly integrate ads into your app, ads can be a powerful assistant to attract users.
Code Snippet
Code:
<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"
hwads:adId="testw6vs28auh3"
hwads:bannerSize="BANNER_SIZE_360_57" />
Code:
BannerView hwBannerView = findViewById(R.id.huawei_banner_view);
AdParam adParam = new AdParam.Builder()
.build();
hwBannerView.loadAd(adParam);
Auth Service:
1. Create Object for VerifyCodeSettings. Apply for verification code by mobile number based login.
Code:
VerifyCodeSettings mVerifyCodeSettings = VerifyCodeSettings.newBuilder()
.action(VerifyCodeSettings.ACTION_REGISTER_LOGIN)
.sendInterval(30)
.locale(Locale.getDefault())
.build();
2. Send mobile number, country code and verify code settings object.
Code:
if (!mMobileNumber.isEmpty() && mMobileNumber.length() == 10) {
Task<VerifyCodeResult> resultTask = PhoneAuthProvider.requestVerifyCode("+91", mMobileNumber, mVerifyCodeSettings);
resultTask.addOnSuccessListener(verifyCodeResult -> {
Toast.makeText(SignIn.this, "verify code has been sent.", Toast.LENGTH_SHORT).show();
if (!isDialogShown) {
verfiyOtp();
}
}).addOnFailureListener(e -> Toast.makeText(SignIn.this, "Send verify code failed.", Toast.LENGTH_SHORT).show());
Toast.makeText(this, mEdtPhone.getText().toString(), Toast.LENGTH_SHORT).show();
} else {
Toast.makeText(this, "Invalid Phone Number!", Toast.LENGTH_SHORT).show();
}
3. Create object for Phone User Builder.
Code:
PhoneUser mPhoneUser = new PhoneUser.Builder()
.setCountryCode("+91")
.setPhoneNumber(mMobileNumber)
.setVerifyCode(otp)
.setPassword(null)
.build();
4. Check below code snippet to validate OTP.
Code:
AGConnectAuth.getInstance().createUser(mPhoneUser)
.addOnSuccessListener(signInResult -> {
Toast.makeText(SignIn.this, "Verfication success!", Toast.LENGTH_LONG).show();
SharedPrefenceHelper.setPreferencesBoolean(SignIn.this, IS_LOGGEDIN, true);
redirectActivity(MainActivity.class);
}).addOnFailureListener(e -> Toast.makeText(SignIn.this, "Verfication failed!", Toast.LENGTH_LONG).show());
Site kit: Using HMS Site kit we can provide easy access to hotels and places.
Code:
searchService.textSearch(textSearchRequest, new SearchResultListener<TextSearchResponse>() {
@Override
public void onSearchResult(TextSearchResponse response) {
for (Site site : response.getSites()) {
SearchResult searchResult = new SearchResult(site.getAddress().getLocality(), site.getName());
String result = site.getName() + "," + site.getAddress().getSubAdminArea() + "\n" +
site.getAddress().getAdminArea() + "," +
site.getAddress().getLocality() + "\n" +
site.getAddress().getCountry() + "\n";
list.add(result);
searchList.add(searchResult);
}
mAutoCompleteAdapter.clear();
mAutoCompleteAdapter.addAll(list);
mAutoCompleteAdapter.notifyDataSetChanged();
autoCompleteTextView.setAdapter(mAutoCompleteAdapter);
Toast.makeText(getActivity(), String.valueOf(response.getTotalCount()), Toast.LENGTH_SHORT).show();
}
@Override
public void onSearchError(SearchStatus searchStatus) {
Toast.makeText(getActivity(), searchStatus.getErrorCode(), Toast.LENGTH_SHORT).show();
}
});
Result:
Conclusion:
In this article we have learnt Auth service,Ads Kit & site kit Integration in food application.
Reference:
Auth Service:
https://developer.huawei.com/consumer/en/doc/development/Tools-Guides/agc-conversion-auth-0000001050157270
Ads Kit :
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/publisher-service-introduction-0000001050064960
Site Kit :
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158571
More information like this, you can visit HUAWEI Developer Forum
Introduction
Online food ordering is process to deliver food from restaurants. In this article will do how to integrate Map kit in food applications. Huawei Map kit offers to work and create custom effects. This kit will work only Huawei device.
In this article, will guide you to show selected hotel locations on Huawei map.
Steps
1. Create App in Android.
2. Configure App in AGC.
3. Integrate the SDK in our new Android project.
4. Integrate the dependencies.
5. Sync project.
Map Module
Map kit covers map info more than 200 countries and it will support many languages. It will support different types of maps like Normal, Hybrid, Satellite, terrain Map.
Use Case
1. Display Map: show buildings, roads, temples etc.
2. Map Interaction: custom interaction with maps, create buttons etc.
3. Draw Map: Location markers, create custom shapes, draw circle etc.
Output
{
"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"
}
Configuration
1. Login into AppGallery Connect, select FoodApp in My Project list.
2. Enable Map Kit APIs in manage APIs tab.
Choose Project Settings > ManageAPIs
Integration
Create Application in Android Studio.
App level gradle dependencies.
Code:
apply plugin: 'com.android.application'
apply plugin: 'com.huawei.agconnect'
Gradle dependencies
Code:
implementation 'com.huawei.hms:maps:4.0.0.301'
Root level gradle dependencies
Code:
maven <strong>{</strong>url <strong>'https://developer.huawei.com/repo/'</strong><strong>}
</strong>classpath <strong>'com.huawei.agconnect:agcp:1.3.1.300'</strong>
Add the below permissions in Android Manifest file
Code:
<manifest xlmns:android...>
...
<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<application ...
</manifest>
Map Kit:
1. Create xml layout class define below snippet.
Code:
<com.huawei.hms.maps.MapView
android:layout_marginTop="?actionBarSize"
android:id="@+id/mapView"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:cameraZoom="8.5"
map:mapType="normal"
map:uiCompass="true"1)
map:uiZoomControls="true"/>
2. Implement OnMapReadyCallback method in activity/fragment, import onMapReady() method.
Initialize map in onCreate() then Call getMapSync().
Code:
Bundle mapViewBundle = null;
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(BUNDLE_KEY);
}
mMapView.onCreate(mapViewBundle);
mMapView.getMapAsync(this);
4. onMapReady() method enable required settings like location button, zoom controls, title gestures, etc.
Code:
@Override
public void onMapReady(HuaweiMap huaweiMap) {
hMap = huaweiMap;
hMap.isBuildingsEnabled();
hMap.setMapType(0);
hMap.isTrafficEnabled();
hMap.setMaxZoomPreference(10);
………
}
5. addMarker() using this method we can add markers on map we can define markers position, title, icon etc. We can create custom icons.
Code:
MarkerOptions markerOptions = new MarkerOptions()
.position(new LatLng(location.lat, location.lng))
.title(response.name)
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_hotel));
hMap.addMarker(markerOptions)
.showInfoWindow();
6. animateCamera() using this method we can animate the movement of the camera from the current position to the position which we defined.
Code:
CameraPosition build = new CameraPosition.Builder()
.target(new LatLng(location.lat, location.lng))
.zoom(15)
.bearing(90)
.tilt(30)
.build();
CameraUpdate cameraUpdate = CameraUpdateFactory.newCameraPosition(build);
hMap.animateCamera(cameraUpdate);
Result:
Conclusion
In this Article, I have explained how to integrate the Map on food application, displaying selected hotel on Map.
Reference:
Map Kit :
https://developer.huawei.com/consumer/en/doc/development/HMSCore-Guides/android-sdk-introduction-0000001050158633
The Huawei Search Kit provide awesome capabilities to build your own search engine or even go beyond. With Search Kit you can add a mini web browser to your app app with web searching capabilities, by this way, the user will be able to surf into the Internet without knowing the complete URL of the website. In this article we will build a Web Browser application powered by Search Kit.
Previous Requirements
A verified developer account
A configured project in AppGallery Connect
Configuring and adding the Search Kit
Once you have propely configured you project in AGC, go to "Manage APIs" from your project settings and enable Search Kit.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Note: Search Kit require to choose a Data Storage Location, make sure to choose a DSL which support the countries where you plan to release your app.
Once you have enabled the API and choosen the Data Storage Location, download (or re-download) you agconnect-services.json and add it to your Android Project. Then, add the Serach Kit latest dependency to your app-level build.gradle file, we will also need the related dependencies of coroutines and data binding.
Code:
implementation "androidx.lifecycle:lifecycle-runtime-ktx:2.2.0"
implementation "android.arch.lifecycle:extensions:1.1.1"
implementation 'com.huawei.agconnect:agconnect-core:1.4.2.301'
implementation 'com.huawei.hms:searchkit:5.0.4.303'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.3.9'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.3.9'
Initializing the SDK
Before using Search Kit, you must apply for an access token, in order to authenticate the requests yo made by using the kit. If you don't provide the proper credentials, Search Kit will not work.
To get your Access Token, perform the next POST request:
Endpoint:
https://oauth-login.cloud.huawei.com/oauth2/v3/token
Headers:
content-type: application/x-www-form-urlencoded
Body:
"grant_type=client_credentials&client_secret=APP_SECRET&client_id=APP_ID"
Your App Id and App Secret will be available from your App dashboard in AGC
Note: Before sending the request, you must encode your AppSecret with URLEncode.
In order to perform the token request, let's create a request helper
HTTPHelper.kt
Code:
object HTTPHelper {
fun sendHttpRequest(
url: URL,
method: String,
headers: HashMap<String, String>,
body: ByteArray
): String {
val conn = url.openConnection() as HttpURLConnection
conn.apply {
requestMethod = method
doOutput = true
doInput = true
for (key in headers.keys) {
setRequestProperty(key, headers[key])
}
if(method!="GET"){
outputStream.write(body)
outputStream.flush()
}
}
val inputStream = if (conn.responseCode < 400) {
conn.inputStream
} else conn.errorStream
return convertStreamToString(inputStream).also { conn.disconnect() }
}
private fun convertStreamToString(input: InputStream): String {
return BufferedReader(InputStreamReader(input)).use {
val response = StringBuffer()
var inputLine = it.readLine()
while (inputLine != null) {
response.append(inputLine)
inputLine = it.readLine()
}
it.close()
response.toString()
}
}
}
We will take advantage of the Kotlin Extensions to add the token request to the SearchKitInstance class, if we initialize the Search Kit from the Application Class, a fresh token will be obtained upon each app startup. When you have retrieved the token, call the method SearchKitInstance.getInstance().setInstanceCredential(token)
BrowserApplication.kt
Code:
class BrowserApplication : Application() {
companion object {
const val TOKEN_URL = "https://oauth-login.cloud.huawei.com/oauth2/v3/token"
const val APP_SECRET = "YOUR_OWN_APP_SECRET"
}
override fun onCreate() {
super.onCreate()
val appID = AGConnectServicesConfig
.fromContext(this)
.getString("client/app_id")
SearchKitInstance.init(this, appID)
CoroutineScope(Dispatchers.IO).launch {
SearchKitInstance.instance.refreshToken([email protected])
}
}
}
fun SearchKitInstance.refreshToken(context: Context) {
val config = AGConnectServicesConfig.fromContext(context)
val appId = config.getString("client/app_id")
val url = URL(BrowserApplication.TOKEN_URL)
val headers = HashMap<String, String>().apply {
put("content-type", "application/x-www-form-urlencoded")
}
val msgBody = MessageFormat.format(
"grant_type={0}&client_secret={1}&client_id={2}",
"client_credentials", URLEncoder.encode(APP_SECRET, "UTF-8"), appId
).toByteArray(Charsets.UTF_8)
val response = HTTPHelper.sendHttpRequest(url, "POST", headers, msgBody)
Log.e("token", response)
val accessToken = JSONObject(response).let {
if (it.has("access_token")) {
it.getString("access_token")
} else ""
}
setInstanceCredential(accessToken)
}
In short words, the basic setup of Search Kit is as follows:
Init the service, by calling SearchKitInstance.init(Context, appID)
Rerieve an App-Level access token
Call SearchKitInstance.getInstance().setInstanceCredential(token) to specify the access token which Search Kit will use to authenticate the requests
Auto Complete Widget
Let's create a custom widget wich can be added to any Activity or Fragment, this widget will show some search suggestions to the user when begins to write in the search bar.
First, we must design the Search Bar, it will contain an Image View and an Edit Text.
view_search.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:background="@drawable/gray_rec"
android:paddingHorizontal="5dp"
android:paddingVertical="5dp"
>
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@android:drawable/ic_menu_search"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@android:drawable/ic_menu_search" />
<EditText
android:id="@+id/textSearch"
android:layout_width="0dp"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@+id/imageView"
app:layout_constraintTop_toTopOf="parent"
/>
</androidx.constraintlayout.widget.ConstraintLayout>
Now is time to create the widget layout, it will contain our search bar and a recycler view to show the suggestions
More details, you can check https://forums.developer.huawei.com/forumPortal/en/topic/0202455305475510024
Overview
In this article, I will create a demo app along with the integration of OneSignal which is based on Cross platform Technology Xamarin. It provides messages that are "pushed" from a server and pop up on a user's device, even if the app is not in running state. They are a powerful re-engagement tool meant to provide actionable and timely information to subscribers.
OneSignal Service Introduction
OneSignal is the fastest and most reliable service to send push notifications, in-app messages, and emails to your users on mobile and web, including content management platforms like WordPress and Shopify. Users can discover resources and training to implement One Signal’s SDKs.
Prerequisite
1. Xamarin Framework
2. Huawei phone
3. Visual Studio 2019
4. OneSignal Account
App Gallery Integration process
1. Sign In and Create or Choose a project on AppGallery Connect portal.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
2. Navigate to Project settings and download the configuration file.
3. Navigate to General Information, and then provide Data Storage location.
OneSignal SDK Integration process
1. Choose Huawei Android (HMS) and provide app name.
2. Choose Xamarin then click Next.
3. Copy your App Id.
4. Create New Push message from One Signal’s Dashboard.
5. Find Review Your Message tab, then click Send Message button.
Installing the Huawei ML NuGet package
1. Navigate to Solution Explore > Project > Right Click > Manage NuGet Packages.
2. Search on Browser Com.OneSignal and Install the package.
Xamarin App Development
1. Open Visual Studio 2019 and Create A New Project.
2. Configure Manifest file and add following permissions and tags.
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.0"
package="com.hms.onesignal">
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="28" ></uses-sdk>
<permission android:name="${applicationId}.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<uses-permission android:name="${applicationId}.permission.C2D_MESSAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme">
<receiver android:name="com.onesignal.GcmBroadcastReceiver"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<category android:name="${applicationId}" />
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
</manifest>
3. Create Activity class with XML UI.
MainActivity.cs
This activity performs all the operation regarding Push notification.
Code:
using System;
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Support.Design.Widget;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
namespace OneSignalDemo
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme.NoActionBar", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.activity_main);
Android.Support.V7.Widget.Toolbar toolbar = FindViewById<Android.Support.V7.Widget.Toolbar>(Resource.Id.toolbar);
SetSupportActionBar(toolbar);
}
private void setUpOneSignal()
{
OneSignal.Current.SetLogLevel(LOG_LEVEL.VERBOSE, LOG_LEVEL.NONE);
OneSignal.Current.StartInit("83814abc-7aad-454a-9d20-34e3681efcd1")
.InFocusDisplaying(OSInFocusDisplayOption.Notification)
.EndInit();
}
public override bool OnCreateOptionsMenu(IMenu menu)
{
MenuInflater.Inflate(Resource.Menu.menu_main, menu);
return true;
}
public override bool OnOptionsItemSelected(IMenuItem item)
{
int id = item.ItemId;
if (id == Resource.Id.action_settings)
{
return true;
}
return base.OnOptionsItemSelected(item);
}
private void FabOnClick(object sender, EventArgs eventArgs)
{
View view = (View) sender;
Snackbar.Make(view, "Replace with your own action", Snackbar.LengthLong)
.SetAction("Action", (Android.Views.View.IOnClickListener)null).Show();
}
public override void OnRequestPermissionsResult(int requestCode, string[] permissions, [GeneratedEnum] Android.Content.PM.Permission[] grantResults)
{
Xamarin.Essentials.Platform.OnRequestPermissionsResult(requestCode, permissions, grantResults);
base.OnRequestPermissionsResult(requestCode, permissions, grantResults);
}
}
}
Xamarin App Build Result
1. Navigate to Build > Build Solution.
2. Navigate to Solution Explore > Project > Right Click > Archive/View Archive to generate SHA-256 for build release and Click on Distribute.
3. Choose Archive > Distribute.
4. Choose Distribution Channel > Ad Hoc to sign apk.
5. Choose Demo keystore to release apk.
6. Build succeed and click Save.
7. Result.
Message Deliver statistics
Tips and Tricks
Notification Types-25 means OneSignal timed out waiting for a response from Huawei's HMS to get a push token. This is most likely due to another 3rd-party HMS push SDK or your own HmsMessageService getting this event instead of OneSignal.
Conclusion
In this article, we have learned how to integrate OneSignal Push Notification in Xamarin based Android application. Developer can send OneSignal’s Push Message to users for new updates or any other information.
Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.
References
OneSignal Docs: click here
OneSignal Developer: click here
Original Source