[Q] Help with Android app development - Android Q&A, Help & Troubleshooting

Hello there
i'm trying to make an app that change the ringer profile when receiving a specific sms
i've reached here and i tested the app on the emulator and it's working only with the buttons
here's my codes
MainActivity.java
Code:
import android.media.AudioManager;
import android.os.Bundle;
import android.app.Activity;
import android.content.Context;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
private Button Vibrate , Ring , Silent , Mode;
private TextView Status;
private static AudioManager myAudioManager;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
Vibrate = (Button)findViewById(R.id.button2);
Ring = (Button)findViewById(R.id.button4);
Silent = (Button)findViewById(R.id.button3);
Mode = (Button)findViewById(R.id.button1);
Status = (TextView)findViewById(R.id.textView2);
myAudioManager = (AudioManager)getSystemService(Context.AUDIO_SERVICE);
}
public static void vibrate(View view){
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_VIBRATE);
}
public static void ring(View view){
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_NORMAL);
}
public static void silent(View view){
myAudioManager.setRingerMode(AudioManager.RINGER_MODE_SILENT);
}
public void mode(View view){
int mod = myAudioManager.getRingerMode();
if(mod == AudioManager.RINGER_MODE_NORMAL){
Status.setText("Current Status: Ring");
}
else if(mod == AudioManager.RINGER_MODE_SILENT){
Status.setText("Current Status: Silent");
}
else if(mod == AudioManager.RINGER_MODE_VIBRATE){
Status.setText("Current Status: Vibrate");
}
else{
}
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
RecieveSMS.java
Code:
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.telephony.SmsMessage;
import android.view.View;
public class RecieveSMS extends BroadcastReceiver
{
private static final String ACTION_SMS_RECEIVED = "android.provider.Telephony.SMS_RECEIVED";
private Context mContext;
private Intent mIntent;
@Override
public void onReceive(Context context, Intent intent) {
mContext = context;
mIntent = intent;
String action = intent.getAction();
if(action.equals(ACTION_SMS_RECEIVED)){
String str = "";
View v = null;
/* Get all messages contained in the Intent*/
SmsMessage[] msgs = getMessagesFromIntent(mIntent);
if (msgs != null) {
for (int i = 0; i < msgs.length; i++) {
str += msgs[i].getMessageBody().toString();
}
if(str=="ring")
MainActivity.ring(v);
else if (str=="vibrate")
MainActivity.vibrate(v);
else if(str=="silent")
MainActivity.silent(v);
}
// ---send a broadcast intent to update the SMS received in the
// activity---
Intent broadcastIntent = new Intent();
broadcastIntent.setAction("SMS_RECEIVED_ACTION");
context.sendBroadcast(broadcastIntent);
}
}
public static SmsMessage[] getMessagesFromIntent(Intent intent) {
Object[] messages = (Object[]) intent.getSerializableExtra("pdus");
byte[][] pduObjs = new byte[messages.length][];
for (int i = 0; i < messages.length; i++) {
pduObjs[i] = (byte[]) messages[i];
}
byte[][] pdus = new byte[pduObjs.length][];
int pduCount = pdus.length;
SmsMessage[] msgs = new SmsMessage[pduCount];
for (int i = 0; i < pduCount; i++) {
pdus[i] = pduObjs[i];
msgs[i] = SmsMessage.createFromPdu(pdus[i]);
}
return msgs;
}
activity_main.xml
Code:
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context=".MainActivity" >
<TextView
android:id="@+id/textView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentTop="true"
android:layout_centerHorizontal="true"
android:layout_marginTop="25dp"
android:text="@string/audio"
android:textAppearance="?android:attr/textAppearanceLarge" />
<Button
android:id="@+id/button3"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_alignParentLeft="true"
android:layout_marginBottom="144dp"
android:layout_marginLeft="40dp"
android:layout_toLeftOf="@+id/button2"
android:onClick="silent"
android:text="@string/Silent" />
<Button
android:id="@+id/button4"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button1"
android:layout_alignBottom="@+id/button1"
android:layout_toRightOf="@+id/button1"
android:onClick="ring"
android:text="@string/Ring" />
<Button
android:id="@+id/button1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_above="@+id/button2"
android:layout_alignLeft="@+id/button3"
android:layout_marginBottom="15dp"
android:onClick="mode"
android:text="@string/Mode" />
<TextView
android:id="@+id/textView2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_below="@+id/textView1"
android:layout_centerHorizontal="true"
android:layout_marginTop="46dp"
android:text="@string/Status"
android:textAppearance="?android:attr/textAppearanceMedium" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignBaseline="@+id/button3"
android:layout_alignBottom="@+id/button3"
android:layout_alignRight="@+id/textView1"
android:onClick="vibrate"
android:text="@string/Vibrate" />
</RelativeLayout>
strings.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">Test</string>
<string name="action_settings">Settings</string>
<string name="hello_world">Hello world!</string>
<string name="audio">Set Audio Profiles</string>
<string name="Ring">Ring</string>
<string name="Vibrate">Vibrate</string>
<string name="Silent">Silent</string>
<string name="Mode">Current Mode</string>
<string name="Status">Current Status</string>
</resources>
manifest.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.test"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="22" />
<application
android:allowBackup="true"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name="com.example.test.MainActivity"
android:label="@string/app_name" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<receiver android:name=".RecieveSMS">
<intent-filter>
<action android:name="android.provider.Telephony.SMS_RECEIVED"></action>
</intent-filter>
</receiver>
</application>
<uses-permission android:name="android.permission.RECEIVE_SMS"></uses-permission>
</manifest>
can anyone help me please ??

Related

[Q] chat Client - gtalk

Hey Guys
I am developing a chat client that would connect to gtalk server.. I am just doing this to learn Android programming. I know that I have to use XMPP to connect to google talk server. I am having issues when attempting to do Connection.connect(). I get a whole bunch of errors from FatalException, Networkmainthreadexception and so on...
I ran the same code in a seperate java project and the whole thing ran without any problems.. I have enabled internet in the manifest file.
<uses-sdk android:minSdkVersion="15" />
<uses-permission android:name="android.permission.INTERNET"/>
<application​
Here is my main.xml
Code:
<?xml version="1.0" encoding="utf-8"?>
<TableLayout xmlns:android="(removed due to # of post restriction...)://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:stretchColumns="1">
<TableRow>
<TextView
android:text="@string/user_name"
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<EditText
android:text=""
android:id="@+id/txtUname"
android:layout_width="fill_parent"
android:hint="@string/userName_hint"
android:layout_height="wrap_content">
</EditText>
</TableRow>
<TableRow>
<TextView
android:text="@string/password"
android:id="@+id/TextView02"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
</TextView>
<EditText
android:text=""
android:id="@+id/txtPwd"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:hint="@string/password_hint"
android:password="true">
</EditText>
</TableRow>
<TableRow>
<Button
android:text="Cancel"
android:id="@+id/btnCancel"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</Button>
<Button
android:text="Login"
android:id="@+id/btnLogin"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
</Button>
</TableRow>
</TableLayout>
MyGtalkActivity.java
Code:
package com.tanmay.gtalk;
import android.app.Activity;
import android.os.Bundle;
import android.app.Activity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import org.jivesoftware.smack.ConnectionConfiguration;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smack.packet.Presence;
public class MyGTalkActivity extends Activity {
EditText txtUserName;
EditText txtPassword;
Button btnLogin;
Button btnCancel;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
txtUserName = (EditText) this.findViewById(R.id.txtUname);
txtPassword = (EditText) this.findViewById(R.id.txtPwd);
btnLogin = (Button) this.findViewById(R.id.btnLogin);
btnLogin = (Button) this.findViewById(R.id.btnLogin);
//String userName = (String) getText(R.id.txtUname);
btnLogin.setOnClickListener(new OnClickListener() {
public void onClick(View v) {
// TODO Auto-generated method stub
//Log.i(tag, msg)
/*ConnectionConfiguration connConfig =
new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
XMPPConnection connection = new XMPPConnection(connConfig);*/
ConnectionConfiguration cc = new ConnectionConfiguration("talk.google.com", 5222, "gmail.com");
XMPPConnection xmpp = new XMPPConnection(cc);
try {
System.out.println("testtt");
xmpp.connect();
xmpp.login("[email protected]", "***");
Presence presence = new Presence(Presence.Type.available);
xmpp.sendPacket(presence);
System.out.println("testt123");
//Log.i("XMPPClient", "[SettingsDialog] Connected to " + connection.getHost());
} catch (XMPPException e) {
// TODO Auto-generated catch block
Log.e("XMPPClient", "[SettingsDialog] Failed to connect to " + xmpp.getHost());
Log.e("XMPPClient", e.toString());
//e.printStackTrace();
}
//dismiss();
}
});
}
}
I have attached the errors that i get on my console...Any sugestions ?
thanks
Tanmay
Hey
You are getting the NetworkOnMainThread exception which i'd guess means that Android doesn't take too well to you trying to make a network connection on the applications main thread.
You should try to make a new thread and put the XMPP connection code in that thread and it should get rid of the errors.
I hope you are aware of multithreading and threads. If not, this is a good time to read and learn about it
EDIT: The reason it works well in your Java program is because there is no such restriction in a regular Java program. Android is very different from that.
Thanks for the reply.. I will look up multi-threading...

Developer.Android.com First app crashed, please help me.

Hi,
I started following the 'Building your first app' on developer.android.com,
I like to do it but now after following the instructions fully it is crashing when you click the button.
I used as build platform Android 4.1, but that should not matter...
I included the codes down here, I hope anyone can help.
MyFirstActivity.java:
Code:
package com.example.lesson.one;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.view.Menu;
import android.view.View;
import android.widget.EditText;
public class MyFirstActivity extends Activity {
public final static String EXTRA_MESSAGE = "com.example.myapp.MESSAGE";
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
// It crashes here, because here is the part where you push the button.
public void sendMessage(View view) {
Intent intent = new Intent(this, DisplayMessageActivity.class);
EditText editText = (EditText) findViewById(R.id.edit_message);
String message = editText.getText().toString();
intent.putExtra(EXTRA_MESSAGE, message);
startActivity(intent);
}
}
DisplayMessageActivity.java:
Code:
package com.example.lesson.one;
import android.app.Activity;
import android.content.Intent;
import android.os.Bundle;
import android.widget.TextView;
public class DisplayMessageActivity extends Activity {
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// Get the message from the intent
Intent intent = getIntent();
String message = intent.getStringExtra(MyFirstActivity.EXTRA_MESSAGE);
// Create the text view
TextView textView = new TextView(this);
textView.setTextSize(40);
textView.setText(message);
setContentView(textView);
}
}
AndroidManifest.xml:
Code:
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.MJV.lesson.one"
android:versionCode="1"
android:versionName="1.0" >
<uses-sdk
android:minSdkVersion="8"
android:targetSdkVersion="15" />
<application
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".MyFirstActivity"
android:label="@string/title_activity_my_first" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity android:name="com.example.myapp.DisplayMessageActivity" />
</application>
</manifest>
Strings.xml:
Code:
<resources>
<string name="app_name">Lesson ONE</string>
<string name="hello_world">Hello world!</string>
<string name="menu_settings">Settings</string>
<string name="title_activity_my_first">MyFirstActivity</string>
<string name="edit_message">Enter a message</string>
<string name="button_send">Send</string>
</resources>
Main.xml:
Code:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="horizontal">
<EditText android:id="@+id/edit_message"
android:layout_weight="1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:hint="@string/edit_message" />
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/button_send"
android:onClick="sendMessage" />
</LinearLayout>
I hope anyone can help me... Because Eclipse isn't giving any errors...
Edit 1: I tried it again, now without any things in the new activity. ( I mean without any code it must do ).
It still crashes, so its somewhere where it will start the new activity.
Edit 2: I ran a logcat, but I know now it cant find DisplayMessageActivity in androidmanifest.xml... Though its already added.
Edit 3: I found my problem, it was in androidmanifest.xml. I stated DisplayMessageActivity wrong! I read too quickly and skipped that part...

Couldn't resolve resource @string/app_name

Hi Everyone.. I'm a beginner in Android programming, I have a problem in string reference. Please help.. Thanks
Here's my code..
activity_main.xml
Code:
<LinearLayout xmlns:android="h t t p : / / schemas . android . com / apk / res / android"
xmlns:tools="h t t p : / / schemas . android . com / tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity" >
<TextView
android:id="@+id/tvDisplay"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="@string/score"
android:textSize="45sp"
android:layout_gravity="center"
android:gravity="center" />
<Button
android:id="@+id/bAdd"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="@string/add"
android:layout_gravity="center"
android:textSize="20sp" />
<Button
android:id="@+id/bSub"
android:layout_width="250dp"
android:layout_height="wrap_content"
android:text="@string/sub"
android:layout_gravity="center"
android:textSize="20sp" />
</LinearLayout>
string.xml
Code:
display.setText("Your total is " + counter);<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">My First App</string>
<string name="action_settings">Settings</string>
<string name="score">Your Score is 0</string>
<string name="add">Add one</string>
<string name="sub">Subtract one</string>
</resources>
MainActivity.java
Code:
package com.ben.myfirstapp;
import android.os.Bundle;
import android.app.Activity;
import android.view.Menu;
import android.view.View;
import android.widget.Button;
import android.widget.TextView;
public class MainActivity extends Activity {
int counter;
Button add, sub;
TextView display;
[user=439709]@override[/user]
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
counter = 0;
add = (Button)findViewById(R.id.bAdd);
sub = (Button)findViewById(R.id.bSub);
display = (TextView)findViewById(R.id.tvDisplay);
add.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
counter++;
display.setText("Your total is " + counter);
}
});
sub.setOnClickListener(new View.OnClickListener()
{
public void onClick(View v)
{
counter--;
display.setText("Your total is " + counter);
}
});
}
[user=439709]@override[/user]
public boolean onCreateOptionsMenu(Menu menu)
{
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.main, menu);
return true;
}
}
Here's a screenshot of the Graphic Layout..
Issue is in your string.xml file... The first line remove
>>> display.setText("...);<<< and it should work

Integrating Text Embedding in Xamarin (Android) using Huawei ML Kit

What is Text Embedding?
Text Embedding is a class of techniques where individual words are represented as real-value vectors in a predefined vector space. In this technique, each word is mapped with one vector.
Introduction
Huawei ML Kit provides Text Embedding feature which helps to get matching vector value of words or sentences. Using this feature, we can improve our research based on the result. It provides similarity between two words or sentences and similar words of a particular word searched. We can also improve searching and browsing efficiency using after getting result related to search text.
Let us start with the project configuration part:
Step 1: Create an app on App Gallery Connect.
Step 2: Enable the ML Kit in Manage APIs menu.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Step 3: Create new Xamarin (Android) project.
Step 4: Change your app package name same as AppGallery app's package name.
Right click on your app in Solution Explorer and select properties.
Select Android Manifest on lest side menu.
Change your Package name as shown in below image.
Step 5: Generate SHA 256 key.
Select Build Type as Release.
Right click on your app in Solution Explorer and select Archive.
If Archive is successful, click on Distribute button as shown in below image.
Select Ad Hoc.
Click Add Icon.
Enter the details in Create Android Keystore and click on Create button.
Double click on your created keystore and you will get your SHA 256 key. Save it.
Add the SHA 256 key to App Gallery.
Step 6: Sign the .APK file using the keystore for Release configuration.
Right-click on your app in Solution Explorer and select properties.
Select Android Packaging Signing and add the Keystore file path and enter details as shown in image.
Step 7: Enable the Service.
Step 8: Install Huawei ML NuGet Package.
Step 9: Install Huawei.Hms.MlNlpTextembedding package using Step 8.
Step 10: Integrate HMS Core SDK.
Step 11: Add SDK Permissions.
Let us start with the implementation part:
Step 1: Create activity_main.xml for Text Similarity, Sentence Similarity and Similar Word buttons.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp"
android:orientation="vertical">
<Button
android:id="@+id/word_similarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Word Similarity"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:padding="10dp"
android:textSize="18dp"/>
<Button
android:id="@+id/sentence_similarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sentence Similarity"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:padding="10dp"
android:textSize="18dp"/>
<Button
android:id="@+id/find_similar_word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Find Similar Word"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:padding="10dp"
android:textSize="18dp"/>
</LinearLayout>
Step 2: Create MainActivity.cs for button click listener.
Code:
using Android.App;
using Android.OS;
using Android.Support.V7.App;
using Android.Runtime;
using Android.Widget;
using Huawei.Agconnect.Config;
using Android.Content;
namespace TextEmbedding
{
[Activity(Label = "@string/app_name", Theme = "@style/AppTheme", MainLauncher = true)]
public class MainActivity : AppCompatActivity
{
private Button btnWordSimilarity;
private Button btnSentenceSimilarity;
private Button btnFindSimilarWords;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
// Set our view from the "main" layout resource
SetContentView(Resource.Layout.activity_main);
btnWordSimilarity = (Button)FindViewById(Resource.Id.word_similarity);
btnSentenceSimilarity = (Button)FindViewById(Resource.Id.sentence_similarity);
btnFindSimilarWords = (Button)FindViewById(Resource.Id.find_similar_word);
btnWordSimilarity.Click += delegate
{
StartActivity(new Intent(this, typeof(WordSimilarActivity)));
};
btnSentenceSimilarity.Click += delegate
{
StartActivity(new Intent(this, typeof(SentenceSimilarActivity)));
};
btnFindSimilarWords.Click += delegate
{
StartActivity(new Intent(this, typeof(FindSimilarWordActivity)));
};
}
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);
}
protected override void AttachBaseContext(Context context)
{
base.AttachBaseContext(context);
AGConnectServicesConfig config = AGConnectServicesConfig.FromContext(context);
config.OverlayWith(new HmsLazyInputStream(context));
}
}
}
Step 3: Initialize MLtextEmbedding inside MainActivity.cs OnCreate() method.
Code:
private MLTextEmbeddingSetting setting;
public static MLTextEmbeddingAnalyzer analyzer;
// Initialize MLTextEmbedding
setting = new MLTextEmbeddingSetting.Factory().SetLanguage(MLTextEmbeddingSetting.LanguageEn).Create();
analyzer = MLTextEmbeddingAnalyzerFactory.Instance.GetMLTextEmbeddingAnalyzer(setting);
Word Similarity Implementation
Step 1: Create word_similarity.xml.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Word Similarity"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/colorAccent"
android:gravity="center"/>
<EditText
android:id="@+id/firstword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="First Word"
android:inputType="text"/>
<EditText
android:id="@+id/secondword"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Second Word"
android:layout_marginTop="10dp"
android:inputType="text"/>
<TextView
android:id="@+id/similarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Similarity : "
android:textSize="18sp"
android:layout_marginTop="10dp"/>
<Button
android:id="@+id/check_word_similarity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</LinearLayout>
Step 2: Create WordSimilarActivity.cs for getting similarity between two words.
Code:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TextEmbedding
{
[Activity(Label = "WordSimilarActivity", Theme = "@style/AppTheme")]
public class WordSimilarActivity : AppCompatActivity
{
private EditText edtxtFirstWord;
private EditText edtxtSecondWord;
private Button btnCheckWordSimilarity;
private TextView txtSimilarity;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.word_similarity);
edtxtFirstWord = (EditText)FindViewById(Resource.Id.firstword);
edtxtSecondWord = (EditText)FindViewById(Resource.Id.secondword);
btnCheckWordSimilarity = (Button)FindViewById(Resource.Id.check_word_similarity);
txtSimilarity = (TextView)FindViewById(Resource.Id.similarity);
btnCheckWordSimilarity.Click += delegate
{
CheckWordSimilarity();
};
}
private async void CheckWordSimilarity()
{
String firstWord = edtxtFirstWord.Text.ToString();
String secondWord = edtxtSecondWord.Text.ToString();
try
{
Task<float> wordSimilarityTask = MainActivity.analyzer.AnalyseWordsSimilarityAsync(firstWord, secondWord);
await wordSimilarityTask;
if (wordSimilarityTask.IsCompleted)
{
Toast.MakeText(this, "Success", ToastLength.Short).Show();
var result = wordSimilarityTask.Result;
txtSimilarity.Text = "Similarity : "+ result;
}
else
{
Toast.MakeText(this, "Failure", ToastLength.Short).Show();
}
}
catch(Exception e)
{
Toast.MakeText(this, "Exception", ToastLength.Short).Show();
}
}
}
}
Sentence Similarity Implementation
Step 1: Create sentence_similarity.xml.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Sentence Similarity"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/colorAccent"
android:gravity="center"/>
<EditText
android:id="@+id/first_sentence"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="First Sentence"
android:inputType="text"/>
<EditText
android:id="@+id/second_sentence"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Second Sentence"
android:layout_marginTop="10dp"
android:inputType="text"/>
<TextView
android:id="@+id/similarity"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Similarity : "
android:textSize="18sp"
android:layout_marginTop="10dp"/>
<Button
android:id="@+id/check_sentence_similarity"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Check"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"/>
</LinearLayout>
Step 2: Create SentenceSimilarActivity.cs for getting similarity between two sentences.
Code:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TextEmbedding
{
[Activity(Label = "SentenceSimilarActivity", Theme = "@style/AppTheme")]
public class SentenceSimilarActivity : AppCompatActivity
{
private EditText edtxtFirstSentence;
private EditText edtxtSecondSentence;
private Button btnCheckSentenceSimilarity;
private TextView txtSimilarity;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.sentence_similarity);
edtxtFirstSentence = (EditText)FindViewById(Resource.Id.first_sentence);
edtxtSecondSentence = (EditText)FindViewById(Resource.Id.second_sentence);
btnCheckSentenceSimilarity = (Button)FindViewById(Resource.Id.check_sentence_similarity);
txtSimilarity = (TextView)FindViewById(Resource.Id.similarity);
btnCheckSentenceSimilarity.Click += delegate
{
CheckSentenceSimilarity();
};
}
private async void CheckSentenceSimilarity()
{
String firstSentence = edtxtFirstSentence.Text.ToString();
String secondSentence = edtxtSecondSentence.Text.ToString();
try
{
Task<float> sentenceSimilarityTask = MainActivity.analyzer.AnalyseSentencesSimilarityAsync(firstSentence, secondSentence);
await sentenceSimilarityTask;
if(sentenceSimilarityTask.IsCompleted && sentenceSimilarityTask?.Result != null)
{
Toast.MakeText(this, "Success", ToastLength.Short).Show();
var result = sentenceSimilarityTask.Result;
txtSimilarity.Text = "Similarity : " + result;
}
else
{
Toast.MakeText(this, "Failure", ToastLength.Short).Show();
}
}
catch(Exception e)
{
Toast.MakeText(this, "Exception", ToastLength.Short).Show();
}
}
}
}
Similar Word Implementation
Step 1: Create similar_words.xml.
Code:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:padding="10dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Find Similar Words"
android:textSize="20sp"
android:textStyle="bold"
android:textColor="@color/colorAccent"
android:gravity="center"/>
<EditText
android:id="@+id/word"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:hint="Enter text"
android:inputType="text"/>
<TextView
android:id="@+id/txt_result"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textSize="18sp"
android:layout_marginTop="10dp"/>
<Button
android:id="@+id/find_words"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Find Similar Words"
android:textColor="@color/colorWhite"
android:textAllCaps="false"
android:background="@color/colorPrimary"
android:layout_gravity="center"
android:layout_marginTop="20dp"
android:padding="10dp"/>
</LinearLayout>
Step 2: Create FindSimilarWordActivity.cs for getting the similar word of a particular word search.
Code:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Support.V7.App;
using Android.Util;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace TextEmbedding
{
[Activity(Label = "FindSimilarWordActivity")]
public class FindSimilarWordActivity : AppCompatActivity
{
private Button findSimilarWords;
private EditText text;
private TextView txtResult;
protected override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
Xamarin.Essentials.Platform.Init(this, savedInstanceState);
SetContentView(Resource.Layout.similar_words);
findSimilarWords = (Button)FindViewById(Resource.Id.find_words);
text = (EditText)FindViewById(Resource.Id.word);
txtResult = (TextView)FindViewById(Resource.Id.txt_result);
findSimilarWords.Click += delegate
{
String inputText = text.Text.ToString();
GetSimilarWords(inputText);
};
}
private async void GetSimilarWords(String text)
{
try
{
Task<Java.Lang.Object> similarWordsTask = MainActivity.analyzer.AnalyseSimilarWordsAsync(text, 5);
await similarWordsTask;
if(similarWordsTask.IsCompleted && similarWordsTask.Result != null)
{
Toast.MakeText(this, "Success", ToastLength.Short).Show();
Java.Util.ArrayList wordList = similarWordsTask.Result.JavaCast<Java.Util.ArrayList>();
StringBuilder sb = new StringBuilder();
foreach(String word in wordList.ToArray())
{
sb = sb.Append(word+" , ");
}
txtResult.Text = "Similar Words : "+sb.ToString();
}
else
{
Toast.MakeText(this, "Failure", ToastLength.Short).Show();
}
}
catch(Exception e)
{
Toast.MakeText(this, "Exception", ToastLength.Short).Show();
Log.Error("FindSimilarWordActivity", e.Message);
}
}
}
}
Now Implementation part done.
Result
Tips and Tricks
1. Do not forget to add internet permission in AndroidManifest.xml file as Text Embedding feature depends on-cloud API for recognition.
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.INTERNET" />
2. Please use Manifest Merger inside ProjectName > ProjectName.csproj file.
Code:
<PropertyGroup>
<AndroidManifestMerger>manifestmerger.jar</AndroidManifestMerger>
</PropertyGroup>
3. Please set API Key inside MainActivity.cs OnCreate() method.
Code:
MLApplication.Instance.ApiKey = "Your API Key will come here ";
Conclusion
In this article, we have learnt about getting the similarity between two words or sentences and also getting the similar words of a particular word search. This helps to improve user search experience.
Thanks for reading! If you enjoyed this story, please provide Likes and Comments.
Reference
Implementing ML Kit Text Embedding
Original Source

Expert: Courier App MVVM Jetpack (HMS Location and Map Kit) in Android using Kotlin- Part-5

Overview
In this article, I will create a Courier android application using Kotlin in which I will integrate HMS Core kits such as HMS Account, Push, CloudDB, AuthService, Push Kit Uplink Message, Location and Map Kit.
We have integrated HMS Account and AuthService Kit in part-, Push Notification Using HMS Push Kit in Part-2, Cloud DB Kit in Part-3 and Huawei Client Push integration in Part4 of this series. Kindly go through the link below-
Part-1 https://forums.developer.huawei.com/forumPortal/en/topic/0202841957497640128
Part-2 https://forums.developer.huawei.com/forumPortal/en/topic/0201847982965230092
part-3 https://forums.developer.huawei.com/forumPortal/en/topic/0201854022878900124?fid=0101187876626530001
App will make use of android MVVM clean architecture using Jetpack components such as DataBinding, AndroidViewModel, Observer, LiveData and much more.
In this article, we are going to implement DataBinding using Observable pattern.
Map Kit Introduction
Map Kit covers map data of more than 200 countries and regions, and supports over 70 languages. User can easily integrate map-based functions into your apps using SDK. It optimizes and enriches the map detail display capability. Map Kit supports gestures including zoom, rotation, moving and tilt gestures to ensure smooth interaction experience.
Location Kit introduction
Location Kit combines the GPS, Wi-Fi and base station location functionalities in your app to build up global positioning capabilities, allows to provide flexible location-based services targeted at users around globally. Currently, it provides three main capabilities: fused location, activity identification and geo-fence. You can call one or more of these capabilities as required.
Prerequisite
Huawei Phone EMUI 3.0 or later.
Non-Huawei phones Android 4.4 or later (API level 19 or higher).
HMS Core APK 4.0.0.300 or later
Android Studio
AppGallery Account
App Gallery Integration process
Sign In and Create or Choose a project on AppGallery Connect portal.
{
"lightbox_close": "Close",
"lightbox_next": "Next",
"lightbox_previous": "Previous",
"lightbox_error": "The requested content cannot be loaded. Please try again later.",
"lightbox_start_slideshow": "Start slideshow",
"lightbox_stop_slideshow": "Stop slideshow",
"lightbox_full_screen": "Full screen",
"lightbox_thumbnails": "Thumbnails",
"lightbox_download": "Download",
"lightbox_share": "Share",
"lightbox_zoom": "Zoom",
"lightbox_new_window": "New window",
"lightbox_toggle_sidebar": "Toggle sidebar"
}
Navigate to Project settings and download the configuration file.
Navigate to General Information, and then provide Data Storage location.
App Development
Add Required Dependencies:
Launch Android studio and create a new project. Once the project is ready.
Navigate to the Gradle scripts folder and open build.gradle (project: app).
Code:
ext.kotlin_version = "1.4.21"
repositories {
google()
jcenter()
maven {url 'https://developer.huawei.com/repo/'}
}
dependencies {
classpath "com.android.tools.build:gradle:4.0.1"
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath 'com.huawei.agconnect:agcp:1.4.2.300'
Add following dependency for HMS Loaction and Map Kits
// Huawei Map
implementation 'com.huawei.hms:maps:6.2.0.301'
// Huawei Location Kit
implementation 'com.huawei.hms:location:6.2.0.300'
Navigate to the Gradle scripts folder and open build.gradle (module: app).
Code:
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'com.huawei.agconnect'
apply plugin: 'kotlin-kapt'
android {
compileSdkVersion 31
buildToolsVersion "29.0.3" buildFeatures {
dataBinding = true
} compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
} defaultConfig {
applicationId "com.hms.corrierapp"
minSdkVersion 27
targetSdkVersion 31
versionCode 1
versionName "1.0" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
} buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
}dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation "org.jetbrains.kotlin:kotlin-stdlib:$kotlin_version"
implementation 'androidx.core:core-ktx:1.7.0'
implementation 'androidx.appcompat:appcompat:1.4.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.3'
testImplementation 'junit:junit:4.12'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
implementation "android.arch.lifecycle:extensions:1.1.1" implementation 'com.google.android.material:material:1.2.0' implementation 'com.squareup.retrofit2:retrofit:2.6.2'
implementation 'com.squareup.retrofit2:converter-gson:2.5.0'
implementation 'com.squareup.retrofit2:converter-scalars:2.5.0'
implementation 'com.squareup.okhttp3:logging-interceptor:4.2.2'
implementation(
[group: 'com.fasterxml.jackson.core', name: 'jackson-core', version: '2.4.1'],
[group: 'com.fasterxml.jackson.core', name: 'jackson-annotations', version: '2.4.1'],
[group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: '2.4.1'],
) //HMS Kits
implementation 'com.huawei.agconnect:agconnect-core:1.5.0.300'
implementation 'com.huawei.hms:hwid:5.3.0.302' implementation 'com.huawei.hms:push:4.0.3.301' implementation 'com.huawei.agconnect:agconnect-cloud-database:1.5.0.300'
implementation "com.huawei.agconnect:agconnect-auth-huawei:1.6.0.300"
implementation 'com.huawei.agconnect:agconnect-auth:1.5.0.300' // Huawei Map
implementation 'com.huawei.hms:maps:6.2.0.301'
// Huawei Location Kit
implementation 'com.huawei.hms:location:6.2.0.300'}
Code Implementation
Created following package model, push, viewmodel.
Model: In your primary folder, create a new package and name it model.
MapActivity.kt:
Code:
package com.hms.corrierapp.map
import android.Manifest
import android.content.IntentSender
import android.content.pm.PackageManager
import android.location.Location
import android.os.*
import android.util.Log
import android.widget.Chronometer
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
import androidx.core.app.ActivityCompat
import com.hms.corrierapp.R
import com.huawei.hmf.tasks.Task
import com.huawei.hms.common.ApiException
import com.huawei.hms.common.ResolvableApiException
import com.huawei.hms.location.*
import com.huawei.hms.maps.*
import com.huawei.hms.maps.model.*
import java.io.File
import java.text.DecimalFormat
class MapActivity : AppCompatActivity(), OnMapReadyCallback {
private lateinit var mMapView: MapView
private var mHwMap: HuaweiMap? = null
private var mPolylineOptions: PolylineOptions? = null
private var mListener: LocationSource.OnLocationChangedListener? = null
private var mMarkerStart: Marker? = null
private var mMarkerEnd: Marker? = null
private var mLocationRequest: LocationRequest? = null
private var mTvStart: TextView? = null
private var mTvDistance: TextView? = null
private var mTime: Chronometer? = null
private var fusedLocationProviderClient: FusedLocationProviderClient? = null
private val mPath: PathBean = PathBean()
private var mSeconds: Long = 0
private val mHandler = Handler(Looper.getMainLooper())
private val mDecimalFormat = DecimalFormat("0.00")
private var mIsRunning = false
private val mTimeRunnable: Runnable = object : Runnable {
override fun run() {
mTime!!.text = formatSeconds()
mHandler.postDelayed(this, 1000)
}
}
private var mLocationCallback: LocationCallback? = null
// GPS Data
private var mGpsDataThread: HandlerThread? = null
private var mGpsDataHandler: Handler? = null
private var mGpsDataFile: File? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_map)
checkPermission()
fusedLocationProviderClient = LocationServices.getFusedLocationProviderClient(this)
// check location settings
checkLocationSettings()
// init MapView
mMapView = findViewById(R.id.hw_mapview)
var mapViewBundle: Bundle? = null
if (savedInstanceState != null) {
mapViewBundle = savedInstanceState.getBundle(MAPVIEW_BUNDLE_KEY)
}
mMapView.onCreate(mapViewBundle)
mMapView.getMapAsync(this)
mTvDistance = findViewById(R.id.tv_distance)
mTime = findViewById(R.id.cm_time)
mTvStart = findViewById(R.id.tv_start)
mTvStart!!.setOnClickListener({ processStartClick() })
// Initializing Map Kit Polyline
mPolylineOptions = PolylineOptions()
mPolylineOptions!!.color(resources.getColor(R.color.colorAccent))
mPolylineOptions!!.width(5f)
// Recording GPS Data
mGpsDataFile = File(getExternalFilesDir(null), "GpsData.txt")
}
private fun checkPermission() {
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.P) {
Log.i(TAG, "sdk <= 28 Q")
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED
&& ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
val strings = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION
)
ActivityCompat.requestPermissions(this, strings, 1)
}
} else {
// Dynamically apply for permissions required for SDK > 28. Add the android.permission.ACCESS_BACKGROUND_LOCATION permission.
if (ActivityCompat.checkSelfPermission(
this,
Manifest.permission.ACCESS_FINE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(
this,
Manifest.permission.ACCESS_COARSE_LOCATION
) != PackageManager.PERMISSION_GRANTED && ActivityCompat.checkSelfPermission
(
this,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
) != PackageManager.PERMISSION_GRANTED
) {
val strings = arrayOf(
Manifest.permission.ACCESS_FINE_LOCATION,
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_BACKGROUND_LOCATION
)
ActivityCompat.requestPermissions(this, strings, 2)
}
}
}
override fun onMapReady(huaweiMap: HuaweiMap?) {
Log.d(TAG, "onMapReady: ")
mHwMap = huaweiMap
mHwMap?.isMyLocationEnabled = true
mHwMap?.uiSettings?.isZoomControlsEnabled = false
// Add Location Source
mHwMap?.setLocationSource(object : LocationSource {
override fun activate(onLocationChangedListener: LocationSource.OnLocationChangedListener?) {
mListener = onLocationChangedListener
}
override fun deactivate() {}
})
// Obtains the current position and updates the map camera.
try {
val lastLocation: Task<Location> = fusedLocationProviderClient!!.lastLocation
lastLocation.addOnSuccessListener { location ->
if (location ==null) [email protected]
mListener!!.onLocationChanged(location)
if (mListener != null) {
mListener!!.onLocationChanged(location)
val cameraUpdate: CameraUpdate = CameraUpdateFactory.newLatLngZoom(
LatLng(location.latitude, location.longitude), 15f
)
mHwMap!!.animateCamera(cameraUpdate)
}
}.addOnFailureListener {
Log.d(TAG, "onMapReady: Obtains the current position failure")
}
} catch (e: Exception) {
}
}
companion object {
private const val MAPVIEW_BUNDLE_KEY = "MapViewBundleKey"
private const val TAG = "MapActivity"
}
override fun onStart() {
super.onStart()
mMapView.onStart()
}
override fun onStop() {
super.onStop()
mMapView.onStop()
}
override fun onDestroy() {
removeLocationUpdatesWithCallback()
super.onDestroy()
mHandler.removeCallbacksAndMessages(null)
mMapView.onDestroy()
}
override fun onPause() {
mMapView.onPause()
super.onPause()
mGpsDataThread!!.quitSafely()
try {
mGpsDataThread!!.join()
mGpsDataThread = null
mGpsDataHandler = null
} catch (e: InterruptedException) {
e.printStackTrace()
}
}
override fun onResume() {
super.onResume()
mMapView.onResume()
mGpsDataThread = HandlerThread("DotThread")
mGpsDataThread!!.start()
mGpsDataHandler = Handler(mGpsDataThread!!.looper)
}
override fun onLowMemory() {
super.onLowMemory()
mMapView.onLowMemory()
}
private fun checkLocationSettings() {
val builder: LocationSettingsRequest.Builder = LocationSettingsRequest.Builder()
val locationSettingsRequest: LocationSettingsRequest = builder.build()
val settingsClient: SettingsClient = LocationServices.getSettingsClient(this)
settingsClient.checkLocationSettings(locationSettingsRequest)
.addOnSuccessListener { requestLocationUpdate() }.addOnFailureListener { e ->
when ((e as ApiException).statusCode) {
LocationSettingsStatusCodes.RESOLUTION_REQUIRED -> try {
val rae: ResolvableApiException = e as ResolvableApiException
rae.startResolutionForResult([email protected], 0)
} catch (sie: IntentSender.SendIntentException) {
}
}
}
}
private fun requestLocationUpdate() {
mLocationRequest = LocationRequest()
mLocationRequest!!.interval = 5000
mLocationRequest!!.priority = LocationRequest.PRIORITY_HIGH_ACCURACY
mLocationCallback = object : LocationCallback() {
override fun onLocationResult(locationResult: LocationResult) {
super.onLocationResult(locationResult)
writeGpsData2Sdcard(locationResult.lastLocation)
if (mIsRunning) {
processLocationChange(locationResult.lastLocation)
}
}
override fun onLocationAvailability(locationAvailability: LocationAvailability?) {
super.onLocationAvailability(locationAvailability)
}
}
fusedLocationProviderClient
?.requestLocationUpdates(mLocationRequest, mLocationCallback, Looper.getMainLooper())
?.addOnSuccessListener { Log.i(TAG, "request location updates success") }
?.addOnFailureListener { e ->
Log.e(TAG, "request location updates failed, error: " + e.message)
}
}
// Removed when the location update is no longer required.
private fun removeLocationUpdatesWithCallback() {
try {
val voidTask: Task<Void> =
fusedLocationProviderClient!!.removeLocationUpdates(mLocationCallback)
voidTask.addOnSuccessListener { }.addOnFailureListener { }
} catch (e: Exception) {
Log.e(TAG, "removeLocationUpdatesWithCallback Exception : $e")
}
}
private fun processStartClick() {
if (mIsRunning) {
mIsRunning = false
mPath.endTime = (System.currentTimeMillis())
mTvStart!!.text = "Start"
mHandler.removeCallbacks(mTimeRunnable)
if (mPath.mPathLinePoints!!.size > 0) {
mPath.endPoint = (mPath.mPathLinePoints!!.get(mPath.mPathLinePoints!!.size - 1))
if (null != mMarkerStart && null != mMarkerEnd) {
mMarkerStart!!.remove()
mMarkerEnd!!.remove()
}
val startPointOptions: MarkerOptions = MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_marker))
.position(mPath.mStartPoint)
startPointOptions.title("Start Point")
startPointOptions.snippet("Start Point")
mMarkerStart = mHwMap!!.addMarker(startPointOptions)
val endPointOptions: MarkerOptions = MarkerOptions()
.icon(BitmapDescriptorFactory.fromResource(R.drawable.ic_location_marker))
.position(mPath.mEndPoint)
endPointOptions.title("End Point")
endPointOptions.snippet("End Point")
mMarkerEnd = mHwMap!!.addMarker(endPointOptions)
}
} else {
mIsRunning = true
mPath.reset()
mPath.startTime = System.currentTimeMillis()
mHandler.post(mTimeRunnable)
mTvStart!!.text = "Stop"
}
}
private fun processLocationChange(location: android.location.Location) {
val latLng = LatLng(location.latitude, location.longitude)
if (mPath.mStartPoint == null) {
mPath.mStartPoint = latLng
}
mPath.addPoint(latLng)
val distance: Float = mPath.updateDistance()
val sportMile = distance / 1000.0
if (mSeconds > 0) {
val distribution = mSeconds.toDouble() / 60.0 / sportMile
mPath.setDistribution(distribution)
mTvDistance!!.text = mDecimalFormat.format(sportMile)
} else {
mPath.setDistribution(0.0)
mTvDistance!!.text = "0.00"
}
mPolylineOptions!!.add(latLng)
mHwMap!!.addPolyline(mPolylineOptions)
if (mListener != null) {
mListener!!.onLocationChanged(location)
val cameraUpdate: CameraUpdate = CameraUpdateFactory.newLatLngZoom(
LatLng(location.latitude, location.longitude), 15f
)
mHwMap!!.animateCamera(cameraUpdate)
}
}
fun formatSeconds(): String {
val hh = if (mSeconds / 3600 > 9) mSeconds / 3600 else mSeconds / 3600
val mm =
if (mSeconds % 3600 / 60 > 9) mSeconds % 3600 / 60 else mSeconds % 3600 / 60
mSeconds++
return "$hh:$mm"
}
private fun writeGpsData2Sdcard(location: Location) {
Log.d(
TAG,
"write latitude and longitude, latitude: " + location.latitude + ", longitude: " + location.longitude
)
mGpsDataHandler!!.post(
GpsDataSaver(
mGpsDataFile, """
${location.latitude}, ${location.longitude}
""".trimIndent()
)
)
}
override fun onRequestPermissionsResult(
requestCode: Int,
permissions: Array<String>,
grantResults: IntArray
) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults)
if (grantResults[0] == PackageManager.PERMISSION_GRANTED) {
}
}
}
activity_map.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:map="http://schemas.android.com/apk/res-auto"
android:id="@+id/sport_content"
android:layout_width="match_parent"
android:layout_height="match_parent"> <com.huawei.hms.maps.MapView
android:id="@+id/hw_mapview"
android:layout_width="match_parent"
android:layout_height="match_parent"
map:mapType="normal"
map:uiCompass="true"
map:uiZoomControls="true" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:layout_marginStart="15dp"
android:layout_marginTop="60dp"
android:layout_marginEnd="15dp"
android:background="@color/white"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_weight="1"
android:orientation="vertical"> <TextView
android:id="@+id/tv_distance"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:ellipsize="end"
android:gravity="center_horizontal"
android:maxLength="8"
android:text="0.00"
android:textColor="#000000"
android:textSize="25sp"
android:textStyle="bold" /> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginBottom="2.5dp"
android:gravity="center_horizontal"
android:text="km"
android:textColor="#88000000"
android:textSize="18sp" />
</LinearLayout> <LinearLayout
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:layout_marginTop="20dp"
android:layout_weight="2"
android:orientation="vertical"> <Chronometer
android:id="@+id/cm_time"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="20dp"
android:ellipsize="end"
android:format="00:00"
android:gravity="center"
android:textColor="#000000"
android:textSize="22sp"
android:textStyle="bold" /> <TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginStart="6dp"
android:layout_marginBottom="2.5dp"
android:gravity="center_horizontal"
android:text="Total time"
android:textColor="#88000000"
android:textSize="18sp" />
</LinearLayout> </LinearLayout> <TextView
android:id="@+id/tv_start"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
android:layout_marginBottom="30dp"
android:gravity="center"
android:text="Track Courier Location"
android:textColor="@color/colorPrimary"
android:textSize="21sp"
android:textStyle="bold" /></RelativeLayout>
activity_delivery_status.xml:
Code:
<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"> <RelativeLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="@color/white"> <ScrollView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_centerVertical="true"> <LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="vertical"
android:padding="16dp">
<TextView
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center"
android:padding="5dp"
android:text="@string/delivery"
android:textAlignment="center"
android:textColor="@color/colorPrimaryDark"
android:textSize="34sp"
android:textStyle="bold" /> <LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.1"
android:gravity="center"
android:orientation="vertical"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_location_marker" /> <View
android:layout_width="5dp"
android:layout_height="match_parent"
android:background="@android:color/black" /> </LinearLayout> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.9"
android:gravity="center_vertical"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Booking"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="20sp"
android:textStyle="bold" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Done"
android:textAlignment="center"
android:textColor="@color/green"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Payment Pending"
android:textAlignment="center"
android:textColor="@color/red"
android:textSize="18sp"
android:textStyle="bold" /> </LinearLayout> </LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.1"
android:gravity="center"
android:orientation="vertical"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_location_marker" /> <View
android:layout_width="5dp"
android:layout_height="match_parent"
android:background="@android:color/black" /> </LinearLayout> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.9"
android:gravity="center_vertical"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="PickUp"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="20sp"
android:textStyle="bold" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Done"
android:textAlignment="center"
android:textColor="@color/green"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Shipping"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="18sp"
android:textStyle="bold" /> </LinearLayout> </LinearLayout> <LinearLayout
android:layout_width="match_parent"
android:layout_height="100dp"
android:orientation="horizontal"> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.1"
android:gravity="center"
android:orientation="vertical"> <ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:background="@drawable/ic_location_marker" /> <View
android:layout_width="5dp"
android:layout_height="match_parent"
android:background="@android:color/black" /> </LinearLayout> <LinearLayout
android:layout_width="0dp"
android:layout_height="100dp"
android:layout_weight="0.9"
android:gravity="center_vertical"
android:orientation="vertical"> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Delivery"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="20sp"
android:textStyle="bold" /> <TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="On It's Way"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="5dp"
android:text="Tracking ID: 12231223"
android:textAlignment="center"
android:textColor="@color/gray"
android:textSize="18sp"
android:textStyle="bold" /> </LinearLayout> </LinearLayout>
<Button
android:id="@+id/btn_done"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="20dp"
android:layout_marginBottom="5dp"
android:background="@color/colorPrimaryDark"
android:text="See On Map"
android:textColor="@color/white"
android:textStyle="bold" />
</LinearLayout> </ScrollView> </RelativeLayout>
</layout>
App Build Result
Tips and Tricks
Set minSDK version to 24 or later, otherwise you will get AndriodManifest merge issue.
Make sure you have added the agconnect-services.json file to app folder.
Make sure you have added SHA-256 fingerprint without fail.
Make sure all the dependencies are added properly.
Conclusion
In this article, we have learned how to integrate HMS Account, Push, CloudDB, AuthService, Push Kit Uplink Message, Location and Map Kit in Android application. After completely read this article user can easily implement Location and Map Kit in the Courier android application using Kotlin.
Thanks for reading this article. Be sure to like and comment to this article, if you found it helpful. It means a lot to me.
References
HMS Docs:
https://developer.huawei.com/consum.../HMSCore-Guides/introduction-0000001050048870
https://developer.huawei.com/consum...droid-sdk-brief-introduction-0000001061991343
https://developer.huawei.com/consum...-Guides/android-introduction-0000001121930588
Location and Map Kit Training Video:
https://developer.huawei.com/consumer/en/training/course/video/201575277450653242

Categories

Resources