在工做和生活中,碰見新的同事或者合做夥伴,交換名片是一個常見的用戶需求,紙質名片常忘帶、易丟失,是客戶的一個痛點。所以,市場上出現了不少交換電子名片的APP和小程序。那麼,如何給本身的APP開發一個名片交換功能呢?java
咱們能夠接入華爲近距離通訊服務,經過近距離設備間消息訂閱(Nearby Message),快速實現一對一或一對多名片交換。下圖是功能演示:android
若是你對實現方式感興趣,能夠去Github去下載源代碼,你們能夠基於具體的應用場景優化。git
Github demo下載地址:https://github.com/HMS-Core/hms-nearby-demo/tree/master/NearbyCardExchangegithub
開發具體步驟以下:json
若是您已是華爲的開發者,能夠省略此步驟。若是您之前沒有集成華爲移動服務的經驗,那麼須要先配置AppGallery Connect,開通近距離通訊服務並集成HMS SDK。相關步驟請參考官方文檔。小程序
在使用Nearby Message以前,須要添加網絡權限、藍牙權限、位置權限。在工程的AndroidManifest.xml文件中添加以下權限:網絡
<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" />
檢查藍牙開關、位置開關是否打開、網絡是否可用,並對位置權限進行動態權限申請app
@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); } }
訂閱到的名片消息(onFound),把名片添加到查找名片對話框中顯示;名片消息丟失時(onLost),從查找名片對話框中刪除該名片ide
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); }
面對面交換名片交換碼,發佈我的名片成功後,訂閱名片消息優化
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; }
收藏名片時把名片加入收藏列表,名片取消收藏時把名片從參數列表中刪除,並把數據保存到本地存儲中。
@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(); }
本次給你們演示的demo用到了華爲HMS Nearby service的近距離設備間消息訂閱功能。基於Nearby Message能力不單單能夠用來作面對面交換名片,還能夠幫助開發者實現不少有趣的功能,例如:
更詳細的開發指南參考華爲開發者聯盟官網:https://developer.huawei.com/consumer/cn/doc/development/HMS-Guides/nearby-service-introduction
往期連接:教你如何開發一個完敗Miracast的投屏新功能
原文連接:https://developer.huawei.com/consumer/cn/forum/topicview?tid=0201276303118820181&fid=18原做者:趙照