Hi Guys,
Currently I am working on an application build in Unity that controls Numato Lab USBGPIO8 module (it will simply turn on and off channels on gpio when conditions in a separate script in app would be met). Whole project is based on ARFoundation.
Opening and controlling serial port using Unity editor and PC works fine (my PC uses COM4 port). However, when building on Android I am getting an "IOException error: permission denied" when script tries to open serial port (gpio is now connected to smartphone through usb cable):
IOException: Permission denied
System.IO.Ports.SerialPortStream.ThrowIOException () (at :0) System.IO.Ports.SerialPortStream..ctor (System.String portName, System.Int32 baudRate, System.Int32 dataBits, System.IO.Ports.Parity parity, System.IO.Ports.StopBits stopBits, System.Boolean dtrEnable, System.Boolean rtsEnable, System.IO.Ports.Handshake handshake, System.Int32 readTimeout, System.Int32 writeTimeout, System.Int32 readBufferSize, System.Int32 writeBufferSize) (at :0) (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPortStream..ctor(string,int,int,System.IO.Ports.Parity,System.IO.Ports.StopBits,bool,bool,System.IO.Ports.Handshake,int,int,int,int) System.IO.Ports.SerialPort.Open () (at :0) (wrapper remoting-invoke-with-check) System.IO.Ports.SerialPort.Open() SerialConnector.OpenPort () (at :0) SerialConnector.Start () (at :0)
Click to expand...
Click to collapse
USB Device Info app shows the device path is /dev/bus/usb/001/002, so I use this as a port adress in the script:
C#:
using UnityEngine;
using System.IO.Ports;
using System.Threading;
public class SerialConnector : MonoBehaviour
{
SerialPort serialPort = new SerialPort("/dev/bus/usb/001/002");
//COM4 in unity editor pc
void Start()
{
OpenPort();
GPIOSetChannelOn(1);
}
private void OpenPort()
{
Debug.Log("Opening port");
if (!serialPort.IsOpen)
serialPort.Open();
serialPort.BaudRate = 19200;
}
private void GPIOSetChannelOn(int channel)
{
...
}
private void GPIOSetChannelOff(int channel)
{
...
}
}
I have added a line to manifest file, that allows external read write using custom AndroidManifest.xml file in Assets/Plugins/Android folder:
JavaScript:
<?xml version="1.0" encoding="UTF-8"?>
<manifest xmlns:tools="http://schemas.android.com/tools" package="com.unity3d.player" xmlns:android="http://schemas.android.com/apk/res/android" tools:node="merge">
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<application>
<activity android:theme="@style/UnityThemeSelector" android:name="com.unity3d.player.UnityPlayerActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<meta-data android:name="unityplayer.UnityActivity" android:value="true"/>
</activity>
</application>
</manifest>
Despite these steps, the problem persists. Is there a way to resolve this issue without rooting my smartphone?
Related
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...
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 ??
I decided to implement Google Cloud Messaging push notifications to notify users about news. I think it is topic messaging. For implement I took the Google GCM sample. I added all needed services, permissions and receiver in manifest. When I send a post request to Google GCM server, the response is true with message ID, but device doesn't notify. What is the matter? I tested in Bluestacks.
My manifest:
Code:
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="..."
xmlns:tools="..."
package="packagename" >
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.GET_ACCOUNTS" />
<uses-permission android:name="com.google.android.c2dm.permission.RECEIVE" />
<uses-permission android:name="packagename.permission.C2D_MESSAGE" />
<permission android:name="packagename.permission.C2D_MESSAGE"
android:protectionLevel="signature" />
<application
android:name=".App"
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:theme="@style/AppTheme" >
<activity
android:name=".activities.MainActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/app_name"
android:launchMode="singleTop" >
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<activity
android:name=".activities.BiographyActivity"
android:configChanges="keyboardHidden|orientation|screenSize"
android:label="@string/title_biography"
android:parentActivityName=".activities.MainActivity"
tools:ignore="UnusedAttribute" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<activity
android:name=".activities.AboutActivity"
android:label="@string/title_about_app" >
<meta-data
android:name="android.support.PARENT_ACTIVITY"
android:value=".activities.MainActivity" />
</activity>
<activity android:name=".activities.CrashReportDialog"
android:theme="@style/Theme.Dialog"
android:process=":error_report"
android:launchMode="singleInstance"
android:excludeFromRecents="true"
android:finishOnTaskLaunch="true" />
<meta-data
android:name="com.google.android.gms.version"
android:value="@integer/google_play_services_version" />
<receiver
android:name="com.google.android.gms.gcm.GcmReceiver"
android:exported="true"
android:permission="com.google.android.c2dm.permission.SEND" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
<action android:name="com.google.android.c2dm.intent.REGISTRATION" />
<category android:name="packagename" />
</intent-filter>
</receiver>
<service
android:name="packagename.AppGcmListenerService"
android:exported="false" >
<intent-filter>
<action android:name="com.google.android.c2dm.intent.RECEIVE" />
</intent-filter>
</service>
<service
android:name="packagename.AppInstanceIDListenerService"
android:exported="false">
<intent-filter>
<action android:name="com.google.android.gms.iid.InstanceID"/>
</intent-filter>
</service>
<service
android:name="packagename.RegistrationIntentService"
android:exported="false">
</service>
</application>
</manifest>
Main Activity:
Code:
public class MainActivity extends AppCompatActivity {
private BroadcastReceiver mRegistrationBroadcastReceiver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mRegistrationBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
SharedPreferences sharedPreferences =
PreferenceManager.getDefaultSharedPreferences(context);
boolean sentToken = sharedPreferences
.getBoolean(GcmPreferences.SENT_TOKEN_TO_SERVER, false);
if (sentToken) {
Log.i("GCM", "Success!");
} else {
Log.i("GCM", "Error!");
}
}
};
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
GCM Listener Service:
Code:
public class AppGcmListenerService extends GcmListenerService {
private static final String TAG = "GCM";
/**
* Called when message is received.
*
* @param from SenderID of the sender.
* @param data Data bundle containing message data as key/value pairs.
* For Set of keys use data.keySet().
*/
@Override
public void onMessageReceived(String from, Bundle data) {
String message = data.getString("message");
Log.d(TAG, "From: " + from);
Log.d(TAG, "Message: " + message);
/**
* Production applications would usually process the message here.
* Eg: - Syncing with server.
* - Store message in local database.
* - Update UI.
*/
/**
* In some cases it may be useful to show a notification indicating to the user
* that a message was received.
*/
sendNotification(message);
}
/**
* Create and show a simple notification containing the received GCM message.
*
* @param message GCM message received.
*/
private void sendNotification(String message) {
Intent intent = new Intent(this, MainActivity.class);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
PendingIntent pendingIntent = PendingIntent.getActivity(this, 0 /* Request code */, intent,
PendingIntent.FLAG_ONE_SHOT);
Uri defaultSoundUri= RingtoneManager.getDefaultUri(RingtoneManager.TYPE_NOTIFICATION);
NotificationCompat.Builder notificationBuilder = new NotificationCompat.Builder(this)
.setSmallIcon(R.drawable.ic_app)
.setContentTitle("GCM Message")
.setContentText(message)
.setAutoCancel(true)
.setSound(defaultSoundUri)
.setContentIntent(pendingIntent);
NotificationManager notificationManager =
(NotificationManager) getSystemService(Context.NOTIFICATION_SERVICE);
notificationManager.notify(0 /* ID of notification */, notificationBuilder.build());
}
}
Instance ID Listener Service:
public class AppInstanceIDListenerService extends InstanceIDListenerService {
/**
* Called if InstanceID token is updated. This may occur if the security of
* the previous token had been compromised. This call is initiated by the
* InstanceID provider.
*/
@Override
public void onTokenRefresh() {
// Fetch updated Instance ID token and notify our app's server of any changes (if applicable).
Intent intent = new Intent(this, RegistrationIntentService.class);
startService(intent);
}
}
Registration Intent Service:
Code:
public class RegistrationIntentService extends IntentService {
private static final String TAG = "GCM";
public RegistrationIntentService() {
super(TAG);
}
@Override
protected void onHandleIntent(Intent intent) {
SharedPreferences sharedPreferences = PreferenceManager.getDefaultSharedPreferences(this);
try {
// In the (unlikely) event that multiple refresh operations occur simultaneously,
// ensure that they are processed sequentially.
synchronized (TAG) {
// Initially this call goes out to the network to retrieve the token, subsequent calls
// are local.
InstanceID instanceID = InstanceID.getInstance(this);
String token = instanceID.getToken(getString(R.string.gcm_defaultSenderId),
GoogleCloudMessaging.INSTANCE_ID_SCOPE, null);
Log.d(TAG, "GCM Registration Token: " + token);
subscribeTopics(token);
// You should store a boolean that indicates whether the generated token has been
// sent to your server. If the boolean is false, send the token to your server,
// otherwise your server should have already received the token.
sharedPreferences.edit().putBoolean(GcmPreferences.SENT_TOKEN_TO_SERVER, true).apply();
}
} catch (Exception e) {
Log.d(TAG, "Failed to complete token refresh", e);
// If an exception happens while fetching the new token or updating our registration data
// on a third-party server, this ensures that we'll attempt the update at a later time.
sharedPreferences.edit().putBoolean(GcmPreferences.SENT_TOKEN_TO_SERVER, false).apply();
}
// Notify UI that registration has completed, so the progress indicator can be hidden.
Intent registrationComplete = new Intent(GcmPreferences.REGISTRATION_COMPLETE);
LocalBroadcastManager.getInstance(this).sendBroadcast(registrationComplete);
}
/**
* Subscribe to any GCM topics of interest, as defined by the TOPICS constant.
*
* @param token GCM token
* @throws IOException if unable to reach the GCM PubSub service
*/
private void subscribeTopics(String token) throws IOException {
GcmPubSub.getInstance(this).subscribe(token, "/topics/global", null);
}
}
My POST request:
Code:
GCM Server
Content-Type:application/json
Authorization:key=mykey
{
"to": "/topics/global",
"data": {
"message": "This is a GCM Topic Message!",
}
}
I tested POST request. Android app tested on Bluestacks App Player. I noticed also the app is not in the running services in the settings. Also I tested the app on real phone, but notifications still does not come I have no use for a long time working on it. The issue is strangely. I checked my code - whole is true as in the Google sample and documentation.
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
Xamarin is a popular cross platform framework to build mobile applications using .net
A number of AppGallery Connect services support many cross platform frameworks including Xamarin. Today we are going to take a look at how you can use one of these services, App Linking within your Xamarin project.
Enabling App Linking in AppGallery Connect
Create an app or use an existing app in AppGallery Connect. Click My projects, go to Grow > App Linking, and click Use now on the displayed page.
On the displayed App Linking page, click the URL prefixes tab and then click New URL prefix to create a unique URL prefix.
{
"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"
}
Preparing the Xamarin Android Development EnvironmentCompleting Android SetupDownload the JSON file from AppGallery Connect and copy the file to your project’s Assets directory.
Set a package name. Right-click your project and choose Properties. Click Android Manifest on the displayed page and set the same package name to that in the JSON file.
Implement LazyInputStream to read the agconnect-services.json file.
Right-click your project, and choose Add > New Item. In the displayed window, select Class and name the new class HmsLazyInputStream.cs.
Implement LazyInputStream to read the agconnect-services.json file.
Right-click your project, and choose Add > New Item. In the displayed window, select Class and name the new class HmsLazyInputStream.cs.
C-like:
using System;
using System.IO;
using Android.Content;
using Android.Util;
using Huawei.Agconnect.Config;
namespace AppLinking1
{
public class HmsLazyInputStream : LazyInputStream
{
public HmsLazyInputStream(Context context)
: base(context)
{
}
public override Stream Get(Context context)
{
try
{
return context.Assets.Open("agconnect-services.json");
}
catch (Exception e)
{
Log.Error("Hms", $"Failed to get input stream" + e.Message);
return null;
}
}
}
}
Create another new class as described in the preceding steps and read the agconnect-services.json file before your app is launched. You can name the new class CustomContentProvider.cs, which extends the ContentProvider class, and set the authorities and InitOrder attributes for the new class.
C-like:
using System;
using Android.Content;
using Android.Database;
using Huawei.Agconnect.Config;
namespace AppLinking1
{
[ContentProvider(new string[] { "com.huawei.applinkingdemo.CustomContentProvider" }, InitOrder = 99)]
class CustomContentProvider : ContentProvider
{
public override int Delete(Android.Net.Uri uri, string selection, string[] selectionArgs)
{
throw new NotImplementedException();
}
public override string GetType(Android.Net.Uri uri)
{
throw new NotImplementedException();
}
public override Android.Net.Uri Insert(Android.Net.Uri uri, ContentValues values)
{
throw new NotImplementedException();
}
public override bool OnCreate()
{
AGConnectServicesConfig config = AGConnectServicesConfig.FromContext(Context);
config.OverlayWith(new HmsLazyInputStream(Context));
return false; throw new NotImplementedException();
}
public override ICursor Query(Android.Net.Uri uri, string[] projection, string selection, string[] selectionArgs, string sortOrder)
{
throw new NotImplementedException();
}
public override int Update(Android.Net.Uri uri, ContentValues values, string selection, string[] selectionArgs)
{
throw new NotImplementedException();
}
}
}
Installing the Service SDK for AndroidRight-click your project and choose Manage NuGet Packages.
Search for AppLinking on the Browse tab. Click Xamarin.Android bindings for AGC — Applinking in the search results and install it.
Agree to the service agreement as prompted.
Developing Your AppCreating an App Linking LinkTo specify the layout of your app, open the activity_main file under Resources > layout. Sample code:
XML:
<?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:layout_margin="16dp"
android:orientation="vertical"
tools:context=".MainActivity">
<TextView
android:id="@+id/textDeepLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DeepLink:"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/deepLink"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/create"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Create Link" />
<TextView
android:id="@+id/ShortLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Short Link:"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/textShortLink"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/LongLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Long Link:"
android:textSize="18sp"
android:textStyle="bold"
/>
<TextView
android:id="@+id/textLongLink"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<Button
android:id="@+id/shareShort"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Share Short Link" />
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="80dp" />
</LinearLayout>
Open the MainActivity.cs file and import the following packages
C-like:
using Android.App;
using Android.OS;
using Android.Runtime;
using Android.Widget;
using AndroidX.AppCompat.App;
using System;
using Huawei.Agconnect.Applinking;
using Uri = Android.Net.Uri;
using Debug = System.Diagnostics.Debug;
using Android.Content;
Configure button actions in the onCreate method
C-like:
FindViewById<Button>(Resource.Id.create).Click += CreateAppLink;
FindViewById<Button>(Resource.Id.shareShort).Click += ShareShortAppLink;
Create an App Linking link and implement the method for sharing the link.
C-like:
private AppLinking.Builder builder;
public static string longLink = null;
public static string shortLink = null;
public static string UriPrefix = "https://applinkingtest.drcn.agconnect.link";
public static string OpenApp_Link = "https://open.androiddemoapp.com";
public static string OpenDetail_Link = "https://open.androiddemoapp.com/detail?id=358";
private async void CreateAppLink(object sender, EventArgs e)
{
builder = new AppLinking.Builder();
// Set a URL prefix.
builder.SetUriPrefix(UriPrefix);
// Set a deep link.
builder.SetDeepLink(Uri.Parse(OpenApp_Link));
//Set the link preview type. If this method is not called, the preview page with app information is displayed by default.
builder.SetPreviewType(AppLinking.LinkingPreviewType.AppInfo);
// (Optional) Set Android link behavior.
var behaviorBuilder = new AppLinking.AndroidLinkInfo.Builder();
// Set an earliest version. If a user's app version is earlier than the earliest version, your app will redirect the user to update the app on AppGallery.
behaviorBuilder.SetMinimumVersion(1);
builder.SetAndroidLinkInfo(behaviorBuilder.Build());
longLink = builder.BuildAppLinking().Uri.ToString();
FindViewById<TextView>(Resource.Id.textLongLink).Text = longLink;
}
private void ShareShortAppLink(object sender, EventArgs e)
{
string agcLink = FindViewById<TextView>(Resource.Id.textShortLink).Text;
Intent intent = new Intent(Intent.ActionSend);
intent.SetType("text/plain");
intent.PutExtra(Intent.ExtraText, agcLink);
intent.AddFlags(ActivityFlags.NewTask);
StartActivity(intent);
}
Receiving an App Linking LinkConfigure the code of the activity for receiving an App Linking link.
Right-click the project, choose add > New Item, select Activity, and name it DetailActivity.
The sample code is as follows:
C-like:
using Android.App;
using Android.Content;
using Android.OS;
using Android.Runtime;
using Android.Views;
using Android.Widget;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Huawei.Agconnect.Applinking;
namespace AppLinking1
{
//[Activity(Label = "DetailActivity")]
[Activity(Name = "com.company.app.DetailActivity", Label = "DetailActivity", Theme = "@style/AppTheme")]
public class DetailActivity : Activity
{
protected async override void OnCreate(Bundle savedInstanceState)
{
base.OnCreate(savedInstanceState);
SetContentView(Resource.Layout.activity_detail);
// Create your app here.
try
{
//To receive links, initialize the AGConnectAppLinking instance.
AGConnectAppLinking appLinkInstance = AGConnectAppLinking.Instance;
//Call GetAppLinkingAsync() to check links of App Linking to be processed
ResolvedLinkData resolvedLinkData = await appLinkInstance.GetAppLinkingAsync(this);
String deepLink = null;
if (resolvedLinkData != null)
{
deepLink = resolvedLinkData.DeepLink.ToString();
FindViewById<TextView>(Resource.Id.deepLink).Text = deepLink;
}
}
catch (System.Exception ex)
{
FindViewById<TextView>(Resource.Id.message).Text = ex.Message;
}
}
}
}
Configure the layout for the page of receiving an App Linking link.
Right-click the project, choose add > New Item, select Android Layout, and name it activity_detail. The sample code is as follows:
XML:
<?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:layout_margin="16dp"
android:orientation="vertical"
tools:context=".DetailActivity">
<TextView
android:id="@+id/textDeepLink"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="DeepLink:"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/deepLink"
android:layout_width="match_parent"
android:layout_height="wrap_content" />
<TextView
android:id="@+id/textMessage"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="message:"
android:textSize="18sp"
android:textStyle="bold" />
<TextView
android:id="@+id/message"
android:layout_width="match_parent"
android:layout_height="80dp" />
</LinearLayout>
Configure the Manifest file. Find the Properties directory and open the AndroidManifest file in the directory. Configure the following content in the element.
XML:
<activity android:name="com.company.app.DetailActivity" >
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:host="open.androiddemoapp.com" android:scheme="https" />
<data android:host="open.androiddemoapp.com" android:scheme="http" />
</intent-filter>
<!--App Linking SDK reads content on the clipboard each time the app is launched.-->
<meta-data android:name="com.huawei.agconnect.applinking.READ_CLIPBOARD_PERMISSION" android:value="Available" />
</activity>
Testing Your AppClick Run to test your app.
References
Getting started with Xamarin
App Linking (Android)