More articles like this, you can visit HUAWEI Developer Forum and Medium.
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
Medium link: https://medium.com/huawei-developers
Forum link: https://forums.developer.huawei.com/forumPortal/en/home
Medium link: https://medium.com/huawei-developers
It is a tradition to exchange business cards with new colleges or partners, but keeping physical business cards is not easy at all. To solve this problem, many apps and mini programs providing the electronic business card function have emerged. You must be wondering how to develop such a function for your app.
Try integrating HUAWEI Nearby Service and use its Nearby Message feature to quickly implement the point-to-point business card exchange function. Check out the function demo below.
If you are interested in the implementation details, download the source code from GitHub. You can optimize the code based on your app requirements.
Github demo link: https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCardExchange
The development procedure is as follows:
1. Getting Started
If you are already a Huawei developer, skip this step. If you are new to Huawei Mobile Services (HMS), you need to configure app information in AppGallery Connect, enable Nearby Service on the HUAWEI Developers console, and integrate the HMS Core SDK. For details, please refer to the documentation.
2. Adding Permissions
Before using Nearby Message, add the network, Bluetooth, and location permissions. Add the following permissions to the AndroidManifest.xml file of your project:
Code:
<uses-permission android:name="android.permission.INTERNET " />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<!-- The location permission is also required in Android 6.0 or later. -->
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
1. Code Development
2.1 Submitting a Dynamic Permission Application
Ensure that the Bluetooth and location functions are enabled and the device has been connected to the Internet properly. Then submit a dynamic permission application for the location permission.
Code:
@Override
public void onStart() {
super.onStart();
getActivity().getApplication().registerActivityLifecycleCallbacks(this);
checkPermission();
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
for (int i = 0; i < permissions.length; ++i) {
if (grantResults[i] != 0) {
showWarnDialog(Constants.LOCATION_ERROR);
}
}
}
private void checkPermission() {
if (!BluetoothCheckUtil.isBlueEnabled()) {
showWarnDialog(Constants.BLUETOOTH_ERROR);
return;
}
if (!LocationCheckUtil.isLocationEnabled(this.getActivity())) {
showWarnDialog(Constants.LOCATION_SWITCH_ERROR);
return;
}
if (!NetCheckUtil.isNetworkAvailable(this.getActivity())) {
showWarnDialog(Constants.NETWORK_ERROR);
return;
}
String[] deniedPermission = PermissionUtil.getDeniedPermissions(this.getActivity(), new String[] {
Manifest.permission.ACCESS_COARSE_LOCATION,
Manifest.permission.ACCESS_FINE_LOCATION
});
if (deniedPermission.length > 0) {
PermissionUtil.requestPermissions(this.getActivity(), deniedPermission, 10);
}
}
2.2 Encapsulating the Business Card Publishing and Subscription APIs
When a subscribed business card message is detected by the onFound method, display it in the business card searching pop-up; when a business card message is no longer discoverable (onLost), delete it from the business card searching pop-up.
Code:
private MessageHandler mMessageHandler = new MessageHandler() {
@Override
public void onFound(Message message) {
CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),
CardInfo.class);
if (cardInfo == null) {
return;
}
mSearchCardDialogFragment.addCardInfo(cardInfo);
}
@Override
public void onLost(Message message) {
CardInfo cardInfo = JsonUtils.json2Object(new String(message.getContent(), Charset.forName("UTF-8")),
CardInfo.class);
if (cardInfo == null) {
return;
}
mSearchCardDialogFragment.removeCardInfo(cardInfo);
}
};
private void publish(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener) {
Message message = new Message(JsonUtils.object2Json(mCardInfo).getBytes(Charset.forName("UTF-8")), type,
namespace);
Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();
PutOption option = new PutOption.Builder().setPolicy(policy).build();
Nearby.getMessageEngine(getActivity()).put(message, option).addOnCompleteListener(listener);
}
private void subscribe(String namespace, String type, int ttlSeconds, OnCompleteListener<Void> listener,
GetCallback callback) {
Policy policy = new Policy.Builder().setTtlSeconds(ttlSeconds).build();
MessagePicker picker = new MessagePicker.Builder().includeNamespaceType(namespace, type).build();
GetOption.Builder builder = new GetOption.Builder().setPolicy(policy).setPicker(picker);
if (callback != null) {
builder.setCallback(callback);
}
Nearby.getMessageEngine(getActivity()).get(mMessageHandler, builder.build()).addOnCompleteListener(listener);
}
2.3 Processing the Business Card Exchange Menu
When two users exchange business cards face to face, exchange the business card exchange codes. When the business card message of the remote endpoint is published, subscribe to it.
Code:
private boolean onExchangeItemSelected() {
PinCodeDialogFragment dialogFragment = new PinCodeDialogFragment(passwrod -> {
MyCardFragment.this.publish(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_MAX, result -> {
if (!result.isSuccessful()) {
String str = "Exchange card fail, because publish my card fail. exception: "
+ result.getException().getMessage();
Log.e(TAG, str);
Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();
return;
}
MyCardFragment.this.subscribe(passwrod, passwrod, Policy.POLICY_TTL_SECONDS_INFINITE, ret -> {
if (!ret.isSuccessful()) {
MyCardFragment.this.unpublish(passwrod, passwrod, task -> {
String str = "Exchange card fail, because subscribe is fail, exception("
+ ret.getException().getMessage() + ")";
if (!task.isSuccessful()) {
str = str + " and unpublish fail, exception(" + task.getException().getMessage()
+ ")";
}
Log.e(TAG, str);
Toast.makeText(getActivity(), str, Toast.LENGTH_LONG).show();
});
return;
}
mSearchCardDialogFragment.setOnCloseListener(() -> {
MyCardFragment.this.unpublish(passwrod, passwrod, task -> {
if (!task.isSuccessful()) {
Toast.makeText(getActivity(), "Unpublish my card fail, exception: "
+ task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
});
MyCardFragment.this.unsubscribe(task -> {
if (!task.isSuccessful()) {
Toast.makeText(getActivity(), "Unsubscribe fail, exception: "
+ task.getException().getMessage(), Toast.LENGTH_LONG).show();
}
});
});
mSearchCardDialogFragment.show(getParentFragmentManager(), "Search Card");
}, null);
});
});
dialogFragment.show(getParentFragmentManager(), "pin code");
return true;
}
2.4 Adding a Business Card to Favorites
When a user adds a business card to favorites, add the card to the favorites list; when a user removes a business card from favorites, remote the card from the favorites list. In addition, store related data locally.
Code:
@Override
public void onFavorite(CardInfo cardInfo, boolean isFavorite) {
if (isFavorite) {
mFavoriteMap.put(cardInfo.getId(), cardInfo);
} else {
mFavoriteMap.remove(cardInfo.getId());
}
Set<String> set = new HashSet<>(mFavoriteMap.size());
for (CardInfo card : mFavoriteMap.values()) {
set.add(JsonUtils.object2Json(card));
}
SharedPreferences sharedPreferences = getContext().getSharedPreferences("data", Context.MODE_PRIVATE);
sharedPreferences.edit().putStringSet(Constants.MY_FAVORITES_KEY, set).apply();
}
5. Conclusion
This demo uses Nearby Message feature of HUAWEI Nearby Service. What Nearby Message is capable of is more than just developing functions for exchanging business cards face-to-face. Here are some examples:
1. Face-to-face teaming in multiplayer sports games
2. Face-to-face round joining in board games
3. Near-field go-Dutch payment function
4. Music sharing
If you are interested and want to learn more, check our development guide at
https://developer.huawei.com/consumer/en/doc/development/HMS-Guides/nearby-service-introduction
Find more Huawei HMS development guides in the XDA HMS community forums.