How to use HMS Nearby Service to develop a business card exchange function for your APP?

Posted by Japher on Fri, 19 Jun 2020 04:07:33 +0200

                         . As a result, there are many apps and small programs for exchanging business cards in the market. So, how to develop a business card exchange function for your APP?

                        . The following figure shows the function:

   if you are interested in the implementation, you can go to Github to download the source code, and you can optimize based on the specific application scenarios.

Download location of Github demo: https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCardExchange

The specific development steps are as follows:

1. Development preparation

   if you are already a developer of Huawei, you can omit this step. If you have no experience in integrating Huawei mobile services before, you need to configure AppGallery Connect, open the short distance communication service and integrate the HMS SDK. Please refer to Official documents.

2. Add permission

   before using Nearby Message, you need to add network permission, Bluetooth permission and location permission. In Engineering AndroidManifest.xml Add the following permissions to the file:

<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" />

3. Code development

3.1 dynamic authority application

   check whether Bluetooth switch, position switch are turned on, whether network is available, and apply for dynamic permission for position permission

@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);
     }
 }

3.2 encapsulate the business card publishing interface and business card subscription interface

                        

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);
 }

3.3 business card exchange menu processing

                   

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;
 }

3.4 collect business card processing

                       .

@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();
 }

4. Conclusion

                      . The ability based on Nearby Message can not only be used for face-to-face business card exchange, but also help developers realize many interesting functions, such as:

  1. The function of face-to-face team formation in competitive hand games
  2. The function of face-to-face match making in hand games of chess and cards
  3. Near field AA collection function
  4. Music track sharing

For more detailed development guide, please refer to the official website of Huawei developer Alliance: https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/nearby-service-introduction

Previous links: Teach you how to develop a new function of screen casting for a failed Miracast
Original link: https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201276303118820181&fid=18
Original author: Zhao Zhao

Topics: Android github network Mobile