HarmonyOS 项目实战之通讯录(Java)
1 簡介
通訊錄demo主要分為聯系人界面、設置緊急聯系人、服務卡片3個模塊,分為Java和JS兩個版本,本篇主要講解用盡可能的用Java去實現。
1.1 原型
感興趣的小伙伴,可以自己根據原型效果自己嘗試著去實現【通訊錄demo簡易原型】
1.2 場景示例
通過學習與練習本demo,可以延伸至以下場景
1.3 項目實戰
《HarmonyOS 項目實戰之通訊錄Demo(JS)》
《HarmonyOS 項目實戰之通訊錄(Java)》
《HarmonyOS 項目實戰之新聞頭條(ArkUI-TS》
2 功能開發
2.1 聯系人列表
2.1.1 實現效果
2.1.2 核心代碼
參考:ListContainer-常用組件開發指導-Java UI框架-UI-開發-HarmonyOS應用開發
- ListContainer設置StickyContactProvider適配器
- HeaderDecor頭部聯動效果設置
- ContactData數據處理相關類,sortContactData方法用于排序等數據處理
sortContactData方法數據處理,排序,字母索引:
public?void?sortContactData()?{?List<ContactBean>?mContactList?=?new?ArrayList<>();?Map<String,?String>?map?=?new?HashMap<>();?for?(ContactBean?contactBean?:?mContactBeans)?{?String?pinyin?=?Utils.getPingYin(contactBean.getName());?map.put(pinyin,?contactBean.getName());?contactBean.setNamepy(pinyin);?mContactList.add(contactBean);?}?mContactList.sort(new?ContactComparator());?characterList?=?new?ArrayList<>();?resultList?=?new?ArrayList<>();?for?(ContactBean?contactBean?:?mContactList)?{?String?namepy?=?contactBean.getNamepy();?String?character?=?(namepy.charAt(0)?+?"").toUpperCase(Locale.ENGLISH);?if?(!characterList.contains(character))?{?if?(character.hashCode()?>=?"A".hashCode()?&&?character.hashCode()?<=?"Z".hashCode())?{?//?是字母?characterList.add(character);?resultList.add(new?ContactBean(character,?ContactBean.ITEM_TYPE.ITEM_TYPE_CHARACTER.ordinal()));?}?else?{?if?(!characterList.contains("#"))?{?characterList.add("#");?resultList.add(new?ContactBean("#",?ContactBean.ITEM_TYPE.ITEM_TYPE_CHARACTER.ordinal()));?}?}?}?resultList.add(new?ContactBean(contactBean.getName(),?contactBean.getTelephone(),?map.get(namepy),?ContactBean.ITEM_TYPE.ITEM_TYPE_CONTACT.ordinal()));?}? }?2.2 數據的增刪改查
2.2.1 實現效果
2.2.2 增刪改查實現
ListContainer刪除實現
categoryData.deleteContactBeans(item);? categoryData.sortContactData();? mStickyContactProvider.setDataListChanged(categoryData.getResultList());?隨機添加一個聯系人
categoryData.addContactBean("胡六一",?"15269856587");? categoryData.sortContactData();? mStickyContactProvider.setDataListChanged(categoryData.getResultList());?ContactData數據處理效果類,實現數據增刪改查
//?Generate?the?javaBean?of?ContactData? public?static?ContactData?get()?{?return?new?ContactData();? }?public?List<ContactBean>?getDefaultContactBeans()?{?return?mDefaultContactBeans;? }?public?List<ContactBean>?getContactBeans()?{?return?mContactBeans;? }?public?void?addContactBean(String?name,?String?phone)?{?mContactBeans.add(new?ContactBean(name,?phone));? }?public?List<ContactBean>?deleteContactBeans(ContactBean?item)?{?mContactBeans.removeIf(contactBean?->?contactBean.getName().equals(item.getName()));?return?mContactBeans;? }?public?List<ContactBean>?getResultList()?{?return?resultList;? }?public?List<String>?getCharacterList()?{?return?characterList;? }?public?int?getScrollPosition(String?character)?{?if?(characterList.contains(character))?{?for?(int?i?=?0;?i?<?resultList.size();?i++)?{?if?(resultList.get(i).getCharacter().equals(character))?{?return?i;?}?}?}?return?-1;?//?-1不會滑動? }?2.2.3 緊急聯系人數據存儲
輕量級數據存儲:輕量級數據存儲概述-輕量級數據存儲-數據管理-開發-HarmonyOS應用開發
Key-Value數據結構
一種鍵值結構數據類型。Key是不重復的關鍵字,Value是數據值。
運作機制
- 本模塊提供輕量級數據存儲的操作類,應用通過這些操作類完成數據庫操作。
- 借助DatabaseHelper API,應用可以將指定文件的內容加載到Preferences實例,每個文件最多有一個Preferences實例,系統會通過靜態容器將該實例存儲在內存中,直到應用主動從內存中移除該實例或者刪除該文件。
- 獲取到文件對應的Preferences實例后,應用可以借助Preferences API,從Preferences實例中讀取數據或者將數據寫入Preferences實例,通過flush或者flushSync將Preferences實例持久化。
核心代碼實現
添加緊急聯系人,并通知java卡片更新
ZSONObject?zsonObject?=?new?ZSONObject();? zsonObject.put("urgent1",?nameTf1.getText());? zsonObject.put("urgentPhone1",?phoneTf1.getText());? zsonObject.put("urgent2",?nameTf2.getText());? zsonObject.put("urgentPhone2",?phoneTf2.getText());? PreferenceUtils.putString(getContext(),"urgentPerson",?ZSONObject.toZSONString(zsonObject));? FormBindingData?formBindingData?=?new?FormBindingData(zsonObject);? ((ContactPersonAbility)?getAbility()).confirmUpdateForm(formBindingData);?PreferenceUtils封裝工具類,實現數據存儲
public?class?PreferenceUtils?{?private?static?String?PREFERENCE_FILE_NAME?=?"prefrence_file";?private?static?Preferences?preferences;?private?static?DatabaseHelper?databaseHelper;?private?static?Preferences.PreferencesObserver?mPreferencesObserver;?private?static?void?initPreference(Context?context)?{?if?(databaseHelper?==?null)?{?databaseHelper?=?new?DatabaseHelper(context);?}?if?(preferences?==?null)?{?preferences?=?databaseHelper.getPreferences(PREFERENCE_FILE_NAME);?}?}?//存放、獲取時傳入的context必須是同一個context,否則存入的數據無法獲取?public?static?void?putString(Context?context,?String?key,?String?value)?{?initPreference(context);?preferences.putString(key,?value);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取的String?默認值為:null?*/?public?static?String?getString(Context?context,?String?key)?{?initPreference(context);?return?preferences.getString(key,?null);?}?public?static?String?getString(Context?context,?String?key,?String?d)?{?initPreference(context);?return?preferences.getString(key,?d);?}?public?static?void?putInt(Context?context,?String?key,?int?value)?{?initPreference(context);?preferences.putInt(key,?value);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取int的默認值為:-1?*/?public?static?int?getInt(Context?context,?String?key)?{?initPreference(context);?return?preferences.getInt(key,?-1);?}?public?static?void?putLong(Context?context,?String?key,?long?value)?{?initPreference(context);?preferences.putLong(key,?value);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取long的默認值為:-1?*/?public?static?long?getLong(Context?context,?String?key)?{?initPreference(context);?return?preferences.getLong(key,?-1L);?}?public?static?void?putBoolean(Context?context,?String?key,?boolean?value)?{?initPreference(context);?preferences.putBoolean(key,?value);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取boolean的默認值為:false?*/?public?static?boolean?getBoolean(Context?context,?String?key)?{?initPreference(context);?return?preferences.getBoolean(key,?false);?}?public?static?void?putFloat(Context?context,?String?key,?float?value)?{?initPreference(context);?preferences.putFloat(key,?value);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取float的默認值為:0.0?*/?public?static?float?getFloat(Context?context,?String?key)?{?initPreference(context);?return?preferences.getFloat(key,?0.0F);?}?public?static?void?putStringSet(Context?context,?String?key,?Set<String>?set)?{?initPreference(context);?preferences.putStringSet(key,?set);?preferences.flush();?}?/**?*?@param?context?上下文?*?@param?key?????鍵?*?@return?獲取set集合的默認值為:null?*/?public?static?Set<String>?getStringSet(Context?context,?String?key)?{?initPreference(context);?return?preferences.getStringSet(key,?null);?}?public?static?boolean?deletePreferences(Context?context)?{?initPreference(context);?boolean?isDelete?=?databaseHelper.deletePreferences(PREFERENCE_FILE_NAME);?return?isDelete;?}?public?static?void?registerObserver(Context?context,?Preferences.PreferencesObserver?preferencesObserver)?{?initPreference(context);?mPreferencesObserver?=?preferencesObserver;?preferences.registerObserver(mPreferencesObserver);?}?public?static?void?unregisterObserver()?{?if?(mPreferencesObserver?!=?null)?{?//?向preferences實例注銷觀察者?preferences.unregisterObserver(mPreferencesObserver);?}?}?2.3 第三方跳轉
2.3.1 實現效果
2.3.2 撥打電話與發送短信
/**?*?跳轉系統短信?*/?private?void?doMessage(String?telephone)?{?Intent?intent?=?new?Intent();?Operation?operation?=?new?Intent.OperationBuilder()? //????????????????.withAction("android.intent.action.SENDTO")?//?Android寫法?android.intent.action.SENDTO?.withAction(IntentConstants.ACTION_SEND_SMS)?.withUri(Uri.parse("smsto:"?+?telephone))?//?設置號碼?.withFlags(Intent.FLAG_NOT_OHOS_COMPONENT)?.build();?intent.setOperation(operation);?context.startAbility(intent,?11);?}?/**?*?申請撥打電話權限?*/?private?boolean?requestPermissions()?{?if?(context.verifySelfPermission("android.permission.CALL_PHONE")?!=?IBundleManager.PERMISSION_GRANTED)?{?//?應用未被授予權限?if?(context.canRequestPermission("android.permission.CALL_PHONE"))?{?//?是否可以申請彈框授權(首次申請或者用戶未選擇禁止且不再提示)?context.requestPermissionsFromUser(new?String[]{"android.permission.CALL_PHONE"},?100);?}?return?false;?}?else?{?//?權限已被授予?return?true;?}?}?/**?*?直接撥打電話?*?需要申請權限?*/?private?void?doCall(String?destinationNum)?{?if?(!requestPermissions())?{?return;?}?Intent?intent?=?new?Intent();?Operation?operation?=?new?Intent.OperationBuilder()?.withAction("android.intent.action.CALL")?//?系統應用撥號盤?.withUri(Uri.parse("tel:"?+?destinationNum))?//?設置號碼?.withFlags(2)?.build();?intent.setOperation(operation);?//?啟動Ability?context.startAbility(intent,?10);?}?/**?*?跳轉系統撥打電話界面?*/?private?void?doDial(String?destinationNum)?{?Intent?intent?=?new?Intent();?Operation?operation?=?new?Intent.OperationBuilder()?.withAction(IntentConstants.ACTION_DIAL)?//?系統應用撥號盤? //????????????????.withBundleName(context.getCallingBundle())?//?應用撥號選擇器?.withUri(Uri.parse("tel:"?+?destinationNum))?//?設置號碼?.withFlags(2)?.build();?intent.setOperation(operation);?//?啟動Ability?context.startAbility(intent,?10);?}?2.4 JS服務卡片
2.4.1 實現效果
2.4.2 創建卡片模板
使用DevEco Studio創建卡片工程
創建成功后,在config.json的module中會生成js模塊,用于對應卡片的js相關資源,配置示例如下:
"js":?[?{?"pages":?[?"pages/index/index"?],?"name":?"widget",?"window":?{?"designWidth":?720,?"autoDesignWidth":?true?},?"type":?"form"?}? ]?config.json文件“abilities”配置forms模塊細節如下:
"name":?"com.huhu.contact.ContactPersonAbility",? "icon":?"$media:icon",? "description":?"$string:contactpersonability_description",? "formsEnabled":?true,? "label":?"$string:contact_ContactPersonAbility",? "type":?"page",? "forms":?[?{?"jsComponentName":?"widget",?"isDefault":?true,?"scheduledUpdateTime":?"10:30",?"defaultDimension":?"2*2",?"name":?"widget",?"description":?"This?is?a?service?widget",?"colorMode":?"auto",?"type":?"JS",?"supportDimensions":?[?"2*2"?],?"updateEnabled":?true,?"updateDuration":?1?}? ]?創建一個ContactPersonAbility,覆寫卡片相關回調函數。
- onCreateForm(Intent intent)
- onUpdateForm(long formId)
- onDeleteForm(long formId)
- onCastTempForm(long formId)
- onEventNotify(Map
- onTriggerFormEvent(long formId, String message)
- onAcquireFormState(Intent intent)
當卡片使用方請求獲取卡片時,卡片提供方會被拉起并調用onCreateForm(Intent intent)回調,intent中會帶有卡片ID、卡片名稱和卡片外觀規格信息,可按需獲取使用。
開發JS卡片時,FormAbility可以繼承AceAbility或Ability,繼承Ability時,需在onStart()方法中額外設置路由信息。
2.4.3 卡片數據綁定
@Override?public?ProviderFormInfo?bindFormData()?{?HiLog.info(TAG,?"bind?form?data");?ProviderFormInfo?providerFormInfo?=?new?ProviderFormInfo();?String?urgentPersonStr?=?PreferenceUtils.getString(context,?"urgentPerson",?"");?ZSONObject?zsonObject?=?ZSONObject.stringToZSON(urgentPersonStr);?if?(dimension?==?DEFAULT_DIMENSION_2X2)?{?if?(zsonObject?!=?null)?{?providerFormInfo.setJsBindingData(new?FormBindingData(zsonObject));?}?}?return?providerFormInfo;?}?2.4.4 卡片數據更新
public?void?confirmUpdateForm(FormBindingData?formBindingData)?{?FormControllerManager?formControllerManager?=?FormControllerManager.getInstance(this);?List<Long>?allFormIdFromSharePreference?=?formControllerManager.getAllFormIdFromSharePreference();?if?(allFormIdFromSharePreference?==?null?||?allFormIdFromSharePreference.isEmpty())?return;?Long?formId?=?allFormIdFromSharePreference.get(0);?try?{?updateForm(formId,formBindingData);?}?catch?(FormException?e)?{?e.printStackTrace();?}?2.4.5 卡片事件處理
{?"data":?{?"text_content":?"Name",?"cardPrimaryText":?"Contacts",?"cardSecondaryText":?"+8612345678912",?"urgent1":?"無",?"urgent2":?"無",?"urgentPhone1":?"+8612345678912",?"urgentPhone2":?"+8612345678915"?},?"actions":?{?"urgentCall1":?{?"action":?"message",?"params":?{?"action":?"urgentCall1",?"phoneNumber":?"10086"?}?},?"urgentCall2":?{?"action":?"message",?"params":?{?"action":?"urgentCall2",?"phoneNumber":?"15565339857"?}?},?"startMainRouter":?{?"action":?"router",?"abilityName":?"com.huhu.contact.ContactPersonAbility"?}?}? }?卡片支持觸發事件,覆寫onTriggerFormEvent方法實現對事件的觸發,
doCall就是前面的播打電話的方法
@Override? protected?void?onTriggerFormEvent(long?formId,?String?message)?{?super.onTriggerFormEvent(formId,?message);?HiLog.info(loglabel,?"onTriggerFormEvent:?"?+?message);?FormControllerManager?formControllerManager?=?FormControllerManager.getInstance(this);?FormController?formController?=?formControllerManager.getController(formId);?formController.onTriggerFormEvent(formId,?message);?ZSONObject?params?=?ZSONObject.stringToZSON(message);?String?action?=?params.getString("action");?String?phoneNumber?=?params.getString("phoneNumber");?HiLog.info(loglabel,?"onTriggerFormEvent:?action:"?+?action);?String?urgentPersonStr?=?PreferenceUtils.getString(this,?"urgentPerson",?"");?ZSONObject?zsonObject?=?ZSONObject.stringToZSON(urgentPersonStr);?switch?(action)?{?case?"urgentCall1":?String?urgentPhone1?=?zsonObject.getString("urgentPhone1");?doCall(urgentPhone1);?break;?case?"urgentCall2":?String?urgentPhone2?=?zsonObject.getString("urgentPhone2");?doCall(urgentPhone2);?break;?default:?break;?}? }?3 注意事項
Demo還有很多需要完善的地方
滑動時,上滑頭部聯動效果,索引有時會錯亂;
緊急聯系人沒有和列表數據聯動。
搜索功能未實現;
4 總結
有不對或者更優的處理技術方案請多多指教,共同學習,共同進步。
代碼地址: https://gitee.com/hu-lingqing/contact-person.git
總結
以上是生活随笔為你收集整理的HarmonyOS 项目实战之通讯录(Java)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: ping不通docker_初识docke
- 下一篇: java美元兑换,(Java实现) 美元