<acronym id="s8ci2"><small id="s8ci2"></small></acronym>
<rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
<acronym id="s8ci2"></acronym>
<acronym id="s8ci2"><center id="s8ci2"></center></acronym>
0
  • 聊天消息
  • 系統消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發帖/加入社區
創作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內不再提示

B站添加鴻蒙服務卡片教程

華為麒麟 ? 來源:鴻蒙技術社區 ? 作者:亮子力 ? 2021-08-12 10:07 ? 次閱讀

????????6 月 2 日鴻蒙發布,今年的六月已經被鴻蒙刷屏了。從安卓到鴻蒙,最直觀的變化應該就是服務卡片了。我也是在學習鴻蒙的同時,實際體驗一下服務卡片的開發。

接下來分享下我的制作過程,我使用的開發環境是:

IDE:DevEco Studio 2.1 Release

SDK:API Version 5

軟件安裝和項目建立的部分就跳過了,相信大家都比較熟悉了。直奔主題服務卡片的制作。

服務卡片設計

首先要先了解服務卡片,都有哪些尺寸,支持哪些組件,使用什么語言。然后規劃好要實現哪些功能。

①尺寸規格

服務卡片有 4 種尺寸,分別是微卡片、小卡片、中卡片、大卡片。官方提供了 4 種基礎模板,12 種高級模板可以選擇。

基礎模板如下圖:

78df57c6-fab5-11eb-9bcf-12bb97331649.png

②功能設計

服務卡片設計的初衷就是信息顯示、服務直達。依照這個原則,我找了幾個 Bilibili 中我比較常用的功能,來制作服務卡片,比如追番列表。

③開發語言

看下表就一目了然了,就是推薦 JS。表格來源:

7fec67de-fab5-11eb-9bcf-12bb97331649.png

界面實現

本著學習的目的,卡片界面就不使用模板了。不過我們還是要通過 IDE→File→New→Service Widget 來添加服務卡片,這樣添加 IDE 會自動添加配置和管理相關文件。

然后服務卡片的界面重新編寫。服務卡片常用的的容器組件有 div、list、stack、swiper 等。

我使用了 4 種尺寸的卡片,并盡可能的使用到所有的容器組件。

①div:基礎容器組件

就是用來劃分區域的。比較常用。比如追番服務卡片。

代碼如下:

《div class=“div_root” 》《!--在服務卡片設置一個 根div 橫向布局--》

《div class=“div_container”》《!--在根div 橫向放置4個div,每個div內部從上往下排列--》

《image class=“item_image” src=“{{ src1 }}” onclick=“routerEvent1”》《/image》

《text class=“item_title”》{{ itemTitle1 }}《/text》

《text class=“item_content”》{{ itemContent1 }}《/text》

《/div》

《div class=“div_container”》《!--第二列--》

《image class=“item_image” src=“{{ src2 }}” onclick=“routerEvent2”》《/image》

《text class=“item_title”》{{ itemTitle2 }}《/text》

《text class=“item_content”》{{ itemContent2 }}《/text》

《/div》

《div class=“div_container”》《!--第三列--》

《image class=“item_image” src=“{{ src3 }}” onclick=“routerEvent3”》《/image》

《text class=“item_title”》{{ itemTitle3 }}《/text》

《text class=“item_content”》{{ itemContent3 }}《/text》

《/div》

《div class=“div_container”》《!--第四列--》

《image class=“item_image” src=“{{ src4 }}” onclick=“routerEvent4”》《/image》

《text class=“item_title”》{{ itemTitle4 }}《/text》

《text class=“item_content”》{{ itemContent4 }}《/text》

《/div》

《/div》

.div_root {

flex-direction: row; /*flex容器主軸方向,row:水平方向從左到右。*/

justify-content: center; /*flex容器當前行的主軸對齊格式,center:項目位于容器的中心。*/

margin:6px; /*外邊距屬性:只有一個值時,這個值會被指定給全部的四個邊。*/

border-radius: 10px; /*設置元素的外邊框圓角半徑。*/

}

.div_container {

flex-direction: column; /*flex容器主軸方向,column:垂直方向從上到下。*/

justify-content: flex-start; /*flex容器當前行的主軸對齊格式,flex-start:項目位于容器的開頭。*/

margin:6px;

}

.item_image {

height: 60%; /*卡片在不同設備,尺寸會發生變化,所以最好使用百分比進行標注。*/

border-radius: 10px;

background-color: #F1F3F5; /*設置背景顏色。*/

}

@media (dark-mode: true) { /*當前系統為深色模式時,使用這里的配置,如果沒有顏色設置,可以不設置*/

.item_image {

height: 60%;

border-radius: 10px;

background-color: #202224;

}

}

.item_title {

margin-top: 10px; /*設置上邊距。*/

font-size: 12px; /*設置文本的尺寸。*/

font-weight: bold; /*設置文本的字體粗細。取值[100, 900],默認為400。*/

max-lines:1; /*設置文本的最大行數。*/

text-overflow: ellipsis; /*根據父容器大小顯示,顯示不下的文本用省略號代替。需配合max-lines使用。*/

color: #e5000000; /*設置文本的顏色。*/

}

.item_content {

margin-top: 5px;

font-size: 9px;

font-weight: bold;

text-overflow: ellipsis;

max-lines:1;

color: #99000000;

}

Note:其實這個服務卡片的布局,每一列的內容都是相同的,是應該使用 list 組件的。

②list:列表容器組件

就如上面所說的連續相同的部分,可以使用這個組件,List 不但可以顯示更多的內容,而且代碼更少。

代碼如下:

《list class=“list”》

《list-item for=“{{cards}}” class=“list-item”》

《div class=“div” onclick=“sendRouteEvent”》

《image class=“item_image” src=“{{ $item.pic }}”》《/image》

《text class=“item_name”》{{ $item.name }}《/text》

《text class=“item_title”》{{ $item.title }}《/text》

《/div》

《/list-item》

《/list》

.list{

align-items:center; /*list每一列交叉軸上的對齊格式:元素在交叉軸居中*/

}

.list-item{

border-radius: 15px;

background-color: #f2f2f2;

margin-bottom: 5px;

}

.div{

flex-direction: column;

}

.item_image {

border-top-right-radius: 15px;

border-top-left-radius: 15px;

}

.item_name {

margin:5px 8px 0px;

font-size: 12px;

color: #262626;

}

.item_title{

margin:3px 8px 8px;

font-size: 10px;

color: #AAAAAA;

max-lines: 2;

text-overflow: ellipsis; /* 省略號 */

}

③stack:堆疊容器組件

簡單來說就是可以在一張圖片上堆疊顯示另一張圖片,例如下圖藍框的圖片覆蓋在紅框圖片的上面。

④swiper:滑動容器組件

正常情況下 swiper 是可以實現上下、左右滑動操作的。但是放置在桌面上的服務卡片,在左右滑動操作的時候,會使系統分不清楚用戶是要左右滑動屏幕,還是左右滑動卡片。

所以目前服務卡片的 swiper 容器是不支持手勢滑動切換子組件的。下圖是通過點擊圖片側面的控制條實現上下滑動的。

但是我個人覺得上下滑動其實還是挺好用的,畢竟在 list 組件上是可以上下滑動的,只可惜目前還不支持。

總結:服務卡片的設計比較簡單,零基礎也沒關系,官方還貼心的準備了模板。只要挑選模板,設置變量也能快速構建。

API 數據請求

卡片設計好之后,就需要通過 Bilibili 的 API 來獲取數據了。主要就是給權限添加依賴,然后發送網絡請求,通過 API 獲取 JSON 的返回值,然后解析 JSON 得到我們需要的數據。

①添加聯網權限

要在 config.json 配置文件的 module 中添加:“reqPermissions”: [{“name”:“ohos.permission.INTERNET”}]。

{

。。。 。。。

“module”: {

。。。 。。。

“reqPermissions”: [{“name”:“ohos.permission.INTERNET”}]

}

}

②添加依賴包

找到 entry/build.gradle 文件,在 dependencies 下添加:

dependencies {

implementation fileTree(dir: ‘libs’, include: [‘*.jar’, ‘*.har’])

testImplementation ‘junit4.13’

ohosTestImplementation ‘com.huawei.ohos.testkit1.0.0.100’

// ZZRHttp 可以單獨一個進程進行http請求

implementation ‘com.zzrv5.zzrhttp1.0.1’

// fastjson 可以解析JSON格式

implementation group: ‘com.alibaba’, name: ‘fastjson’, version: ‘1.2.75’

}

③http 請求

以獲取粉絲數為例,如果在瀏覽器中輸入 https://api.bilibili.com/x/relation/stat?vmid=383565952。

8343abae-fab5-11eb-9bcf-12bb97331649.png

其中 vmid:是要查詢的用戶 ID,follower 的值就是粉絲數。

網絡訪問我們可以使用 HttpURLConnection,或者 okhttp 等依賴包,但是需要開啟子線程、處理異常等操作,所以這里使用的是 ZZR 老師封裝好的 ZZRHttp。

代碼實現:

//獲取Bilibili粉絲數,這里就要用到第二步我們添加的ZZRHttp

String url = “https://api.bilibili.com/x/relation/stat?vmid=383565952”;

ZZRHttp.get(url, new ZZRCallBack.CallBackString() {

@Override

public void onFailure(int i, String s) {

HiLog.info(TAG, “API返回失敗”);

}

@Override

public void onResponse(String s) {

HiLog.info(TAG, “API返回成功”);

// 如果返回成功,返回的結果就會保存在 String s 中。

// s = {“code”:0,“message”:“0”,“ttl”:1,“data”:{“mid”:383565952,“following”:70,“whisper”:0,“black”:0,“follower”:5384}}

}

});

④解析 JSON

得到的是 JSON 格式的返回值,要得到 follower 的值,還需要對 JSON 進行數據解析。

先按照 JSON 的內容,生成 JAVA 類??梢宰约簩?,也可以百度搜 ”JSON 生成 Java 實體類“,可直接生成。

代碼如下:

public class BilibiliFollower {

public static class Data{

private int follower;

public int getFollower() {

return follower;

}

public void setFollower(int follower) {

this.follower = follower;

}

}

private BilibiliFollower.Data data;

public BilibiliFollower.Data getData() {

return data;

}

public void setData(BilibiliFollower.Data data) {

this.data = data;

}

}

//解析JSON,使用第二步我們添加的fastjson包try {

//1.調用fastjson解析,結果保存在JSON對應的類

BilibiliFollower bilibiliFollower = JSON.parseObject(s,BilibiliFollower.class);

//2.get方法獲取解析內容

BilibiliFollower.Data data= bilibiliFollower.getData();

System.out.println(“解析成功”+data.getFollower());

} catch (Exception e) {

HiLog.info(TAG, “解析失敗”);

}

總結:一定要添加聯網權限不然是獲取不到數據的。添加了 2 個依賴包,可以很方便的提取數據。

獲取其他的卡片數據的方式同理,不過代碼比較多,就不一一展示了,感興趣可以下載全量代碼看。

數據更新

要想將數據更新到服務卡片,得先了解服務卡片的運作機制。如果是通過 IDE→File→New→Service Widget 添加的服務卡片,那么在 MainAbility 中會添加卡片的生命周期回調方法。

參考下面的代碼:

public class MainAbility extends Ability {

。。。 。。。

protected ProviderFormInfo onCreateForm(Intent intent) {。。。}//在服務卡片上右擊》》服務卡片(或上滑)時,通知接口

protected void onUpdateForm(long formId) {。。。}//在服務卡片請求更新,定時更新時,通知接口

protected void onDeleteForm(long formId) {。。}//在服務卡片被刪除時,通知接口

protected void onTriggerFormEvent(long formId, String message) {。。。}//JS服務卡片click時,通知接口

}

①定時更新

按照上述分析,我們只需要在 config.json 中開啟服務卡片的周期性更新,在 onUpdateForm(long formId) 方法下執行數據獲取更新。

config.json 文件“abilities”的 forms 模塊配置細節如下:

“forms”: [

{

“jsComponentName”: “widget2”,

“isDefault”: true,

“scheduledUpdateTime”: “10:30”,//定點刷新的時刻,采用24小時制,精確到分鐘?!皍pdateDuration”: 0時,才會生效。

“defaultDimension”: “1*2”,

“name”: “widget2”,

“description”: “This is a service widget”,

“colorMode”: “auto”,

“type”: “JS”,

“supportDimensions”: [

“1*2”

],

“updateEnabled”: true, //表示卡片是否支持周期性刷新

“updateDuration”: 1 //卡片定時刷新的更新周期,1為30分鐘,2為60分鐘,N為30*N分鐘

}

這樣結合我們在上一步獲取 API 數據,解析 JSON,開啟服務卡片的周期性更新,就可以在 updateFormData() 實現服務卡片的數據更新了。

截取 follower 數據更新的部分代碼如下:

public void updateFormData(long formId, Object.。。 vars) {

HiLog.info(TAG, “update form data: formId” + formId);

//這部分用來獲取粉絲數

String url = “https://api.bilibili.com/x/relation/stat?vmid=383565952”;

ZZRHttp.get(url, new ZZRCallBack.CallBackString() {

@Override

public void onFailure(int i, String s) {HiLog.info(TAG, “API返回失敗”);}

@Override

public void onResponse(String s) {

HiLog.info(TAG, “API返回成功”);

try {

//1.調用fastjson解析,結果保存在JSON對應的類

BilibiliFollower bilibiliFollower = JSON.parseObject(s,BilibiliFollower.class);

//2.get方法獲取解析內容

BilibiliFollower.Data data= bilibiliFollower.getData();

System.out.println(“解析成功”+data.getFollower());

//這部分用來更新卡片信息

ZSONObject zsonObject = new ZSONObject(); //1.將要刷新的數據存放在一個ZSONObject實例中

zsonObject.put(“follower”,data.getFollower()); //2.更新數據,data.getFollower()就是在API數據請求中獲取的粉絲數。

FormBindingData formBindingData = new FormBindingData(zsonObject); //3.將其封裝在一個FormBindingData的實例中

try {

((MainAbility)context).updateForm(formId,formBindingData); //4.調用MainAbility的方法updateForm(),并將formBindingData作為第二個實參

} catch (FormException e) {

e.printStackTrace();

HiLog.info(TAG, “更新卡片失敗”);

}

} catch (Exception e) {

HiLog.info(TAG, “解析失敗”);

}

}

});

}

②手動更新

正常來說這樣就可以正常更新數據了,但是會有個問題。就是在服務卡片首次創建添加到桌面的時候,在添加完的至少 30 分鐘里,數據是不會更新的。

此時如果在 index.json 中設置初始信息,那么在添加完成的前 30 分鐘數據都是寫死在 data 中的。如果不設置初始信息那么卡片就是空白的。

所以按照前面服務卡片的運作機制的分析,我們還需要在卡片初始化 onCreateForm() 的時候進行一次更新。

這個非常簡單用 onCreateForm() 調用 onUpdateForm(formId) 即可。

@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {

。。。 。。。

//初始化時先在線更新一下卡片

onUpdateForm(formId);

return formController.bindFormData();

}

總結:這里的 onUpdateForm(formId) 中 API 的網絡請求一定要新開一個子線程,不然會影響頁面加載。

這也是前面說的用 ZZRhttp 的原因。不過現在也遇到一個問題,當卡片數量變多時,同時在線更新這么多的卡片會變得非常緩慢,這個問題還有待解決。

功能直達

目前服務卡片僅支持 click 通用事件,事件類型:跳轉事件(router)和消息事件(message)。

詳細說明參考官方文檔:

https://developer.harmonyos.com/cn/docs/documentation/doc-references/js-service-widget-syntax-hml-0000001152828575

①跳轉事件

接下來實現與服務卡片的交互,當點擊服務卡片時,會跳轉到相應的頁面,所以這里使用跳轉事件。

以番劇更新的卡片為例:

首先我們要先添加一個要跳轉的頁面。如下圖所示添加一個 Page Ability,比如:VideoSlice。

8490703c-fab5-11eb-9bcf-12bb97331649.png

新建完成之后會增加 VideoSlice 和 slice/VideoSliceSlice 兩個文件,和 base/layout/ability_bilibili_page.xml 頁面文件。

@Overridepublic void onStart(Intent intent) {

super.onStart(intent);

super.setUIContent(ResourceTable.Layout_ability_video);

Text text = (Text) findComponentById(ResourceTable.Id_text);

text.setText(“頁面跳轉中”);

// 隨機圖片數組

int[] resource = {ResourceTable.Media_36e,ResourceTable.Media_36g,ResourceTable.Media_36h,ResourceTable.Media_38p};

Component component = findComponentById(ResourceTable.Id_image);

if (component instanceof Image) {

Image image = (Image) component;

image.setPixelMap(resource[(int)(Math.random()*3)]);//隨機顯示一張圖片

}

String url = “https://m.bilibili.com”;

String param = intent.getStringParam(“params”);//從intent中獲取 跳轉事件定義的params字段的值

if(param !=null){

ZSONObject data = ZSONObject.stringToZSON(param);

url = data.getString(“url”);

}

webview(url);

}

//啟動webviewpublic void webview(String url){

WebView webView = (WebView) findComponentById(ResourceTable.Id_webview);

webView.getWebConfig().setJavaScriptPermit(true); // 如果網頁需要使用JavaScript,增加此行;如何使用JavaScript下文有詳細介紹

webView.load(url);

}

增加 webview,將頁面默認的 Text 控件修改為 webview。

《?xml version=“1.0” encoding=“utf-8”?》《DirectionalLayout

xmlns:ohos=“http://schemas.huawei.com/res/ohos”

ohos:height=“match_parent”

ohos:width=“match_parent”

ohos:alignment=“center”

ohos:orientation=“vertical”》

《ohos.agp.components.webengine.WebView

ohos:id=“$+id:webview”

ohos:height=“match_parent”

ohos:width=“match_parent”》

《/ohos.agp.components.webengine.WebView》《/DirectionalLayout》

在 index.hml 中給要觸發的控件上添加 onclick,比如:onclick=“routerEvent1”。

《div class=“div_root” 》《!--在服務卡片設置一個 根div 橫向布局--》

《div class=“div_container”》《!--在根div 橫向放置4個div,每個div內部從上往下排列--》

《image class=“item_image” src=“{{ src1 }}” onclick=“routerEvent1”》《/image》

《text class=“item_title”》{{ itemTitle1 }}《/text》

《text class=“item_content”》{{ itemContent1 }}《/text》

《/div》

。。。 。。。

《/div》

在 index.json 中,添加對應的 actions,跳轉事件要多加一個參數“abilityName”,指定要跳轉的頁面,并且攜帶參數 url。

{

“data”: {

},

“actions”: {

“routerEvent1”: {

“action”: “router”,

“bundleName”: “com.liangzili.servicewidget”,

“abilityName”: “com.liangzili.servicewidget.VideoSlice”,

“params”: {

“url”: “{{url1}}”

}

},

“routerEvent2”: {

。。。 。。。

}

②消息事件

這里使用視頻動態服務卡片,做一個消息事件的測試,效果如下圖,點擊左右邊,實現服務卡片的滑動。

在小卡片上這樣的操作體驗不好。所以消息事件中的例子,只是為了測試,并沒有加到項目里。

在 index.hml 中給要觸發的控件上添加 onclick,比如:onclick=“sendMessageEvent”。

《-- 為了方便測試,直接將onclick添加在左右兩側的div組件上 --》《div class=“div” onclick=“sendMessageEvent0”》

《image class=“item_image” src=“{{ src0 }}”》《/image》

《text class=“item_title”》{{ itemTitle0 }}《/text》

《text class=“item_content”》{{ itemContent0 }}《/text》《/div》《div class=“div” onclick=“sendMessageEvent1”》

《image class=“item_image” src=“{{ src1 }}”》《/image》

《text class=“item_title”》{{ itemTitle1 }}《/text》

《text class=“item_content”》{{ itemContent1 }}《/text》《/div》

在 index.json 中,添加對應的 actions。

{

“data”: {

},

“actions”: {

“sendMessageEvent0”: {

“action”: “message”,

“params”: {

“p1”: “left”,

“index”: “{{index}}”

}

},

“sendMessageEvent1”: {

“action”: “message”,

“params”: {

“p1”: “right”,

“index”: “{{index}}”

}

}

}

}

如果是消息事件(message)當點擊帶有 onclick 的控件時,會觸發 MainAbility 下的這個函數。

@Overrideprotected void onTriggerFormEvent(long formId, String message) {

HiLog.info(TAG, “onTriggerFormEvent: ” + message); //params的內容就通過message傳遞過來

super.onTriggerFormEvent(formId, message);

FormControllerManager formControllerManager = FormControllerManager.getInstance(this);

FormController formController = formControllerManager.getController(formId);//通過formId得到卡片控制器

formController.onTriggerFormEvent(formId, message);//接著再調用,對應的控制器 WidgetImpl

}

最后調用卡片控制器 WidgetImpl 中的 onTriggerFormEvent()。

public void onTriggerFormEvent(long formId, String message) {

HiLog.info(TAG, “onTriggerFormEvent.”+message);

//先獲取message中的參數

ZSONObject data = ZSONObject.stringToZSON(message);

String p1 = data.getString(“p1”);

Integer index = data.getIntValue(“index”);

ZSONObject zsonObject = new ZSONObject(); //將要刷新的數據存放在一個ZSONObject實例中

Integer indexMax = 2; //有N個滑塊組件就設置N-1

if(p1.equals(“right”)){ //判斷點擊方向,如果是右側

if(index == indexMax){index = -1;} //實現循環滾動

index = index+1;

zsonObject.put(“index”,index);

}else { //判斷點擊方向,如果是左側

if(index == 0){index = indexMax+1;} //實現循環滾動

index = index-1;

zsonObject.put(“index”,index);

}

FormBindingData formBindingData = new FormBindingData(zsonObject);

try {

((MainAbility)context).updateForm(formId,formBindingData);

} catch (FormException e) {

e.printStackTrace();

HiLog.info(TAG, “更新卡片失敗”);

}

}

③list 跳轉事件

list 組件只能添加一個 onclick,而且在點擊的同時還需要獲取點擊的是list列表中的哪一項,這個比較特殊。

《list class=“list” else》

《list-item for=“{{list}}” class=“list-item”》

《div class=“div” onclick=“sendRouteEvent”》

。。。 。。。

《/div》

《/list-item》

《/list》

這個坑折磨了我好久,最終我發現在 index.json 中,可以使用 item,item,idx 獲取到 hml 頁面 list 的元素變量和索引。

但是在官方文檔并沒有找到相關的內容,嘗試了很久才解決這個問題。之后的部分就和跳轉事件一樣了,使用 Video 頁面解析 url 進行播放就可以了。

“actions”: {

“sendRouteEvent”: {

“action”: “router”,

“bundleName”: “com.liangzili.demos”,

“abilityName”: “com.liangzili.demos.Video”,

“params”: {

“url”: “{{$item.short_url}}”,

“index”: “{{$idx}}”

}

}

}

總結:解決了 list 的點擊事件之后,才發現這歌控件真是好用。能用 list 還是 list 方便。

加載頁面,保存 Cookie

啟動之后的頁面主要是為了登錄賬號,因為大部分的 API 是需要登錄之后才可以獲取到的。

①webview 加載頁面

在 base/layout/ability_main.xml 中添加 webview 組件,代碼如下:

《ohos.agp.components.webengine.WebView

ohos:id=“$+id:webview”

ohos:height=“match_parent”

ohos:width=“match_parent”》

《/ohos.agp.components.webengine.WebView》

然后在啟動頁面執行加載操作。但其實加載前需要先從數據庫中提取 cookie 信息,這個接下來說。

String url = “https://m.bilibili.com”;

WebView webView = (WebView) findComponentById(ResourceTable.Id_webview);

webView.getWebConfig().setJavaScriptPermit(true); // 如果網頁需要使用JavaScript,增加此行;如何使用JavaScript下文有詳細介紹

webView.load(url);

②Cookie 的讀取和保存類

com/liangzili/demos/utils/CookieUtils.java:

public class CookieUtils {

private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG,0x0,CookieUtils.class.getName());

/**

* 使用關系型數據庫[讀?。軨ookie

* @param preferences

* @param url

*/

public static void ExtarctCookie(Preferences preferences, String url){

Map《String, ?》 map = new HashMap《》();

//先從數據庫中取出cookie

map = PreferenceDataBase.GetCookieMap(preferences);

//然后寫入到cookieStore

CookieStore cookieStore = CookieStore.getInstance();//1.獲取一個CookieStore的示例

for (Map.Entry《String, ?》 entry : map.entrySet()) {

HiLog.info(TAG,entry.getKey()+“=”+entry.getValue().toString());

cookieStore.setCookie(url,entry.getKey()+“=”+entry.getValue().toString());//2.寫入數據,只能一條一條寫

}

}

/**

* 使用關系型數據庫[保存]Cookie

* @param preferences 數據庫的Preferences實例

* @param url 指定Cookie對應的域名

*/

public static void SaveCookie(Preferences preferences,String url){

//先取出要保存的cookie

CookieStore cookieStore = CookieStore.getInstance();

String cookieStr = cookieStore.getCookie(url);

HiLog.info(TAG,“saveCookie(String url)”+url+cookieStr);

//然后將cooke轉成map

Map《String,String》 cookieMap = cookieToMap(cookieStr);

//最后將map寫入數據庫

PreferenceDataBase.SaveMap(preferences,cookieMap);

}

// cookieToMap

public static Map《String,String》 cookieToMap(String value) {

Map《String, String》 map = new HashMap《String, String》();

value = value.replace(“ ”, “”);

if (value.contains(“;”)) {

String values[] = value.split(“;”);

for (String val : values) {

String vals[] = val.split(“=”);

map.put(vals[0], vals[1]);

}

} else {

String values[] = value.split(“=”);

map.put(values[0], values[1]);

}

return map;

}

}

偏好型數據庫

數據庫的操作主要是 com/liangzili/demos/database/PreferenceDataBase.java 這個類。使用輕量級偏好型數據庫,更符合我們這里的需求。

①獲取 Preferences 實例

public class PreferenceDataBase {

private static final HiLogLabel TAG = new HiLogLabel(HiLog.DEBUG,0x0,PreferenceDataBase.class.getName());

/**

* 獲取Preferences實例

* @param context 數據庫文件將存儲在由context上下文指定的目錄里。

* @param name fileName表示文件名,其取值不能為空,也不能包含路徑

* @return //返回對應數據庫的Preferences實例

*/

public static Preferences register(Context context,String name) {

DatabaseHelper databaseHelper = new DatabaseHelper(context);

Preferences preferences = databaseHelper.getPreferences(name);

return preferences;

}

。。。 。。。

}

②從數據庫中保存和讀取 Map

/**

* Map[保存]到偏好型數據庫

* @param preferences 數據庫的Preferences實例

* @param map 要保存的map

*/

public static void SaveMap(Preferences preferences,Map《String,String》 map){

// 遍歷map

for (Map.Entry《String, String》 entry : map.entrySet()) {

HiLog.info(TAG,entry.getKey() + “=” + entry.getValue());

preferences.putString(entry.getKey(),entry.getValue());//3.將數據寫入Preferences實例,

}

preferences.flushSync();//4.通過flush()或者flushSync()將Preferences實例持久化。

}

/**

* 從偏好型數據庫[讀?。軲ap

* @param preferences 數據庫的Preferences實例

* @return 要讀取的map

*/

public static Map《String,?》 GetCookieMap(Preferences preferences){

Map《String, ?》 map = new HashMap《》();

map = preferences.getAll();//3.讀取數據

return map;

}

③提取某些 Cookie 的值

/**

* 獲取Cookie中的SESSDATA值

* @param context 上下文用來指定數據文件存儲路徑

* @return Cookie中的SESSDATA值

*/

public static String getSessData(Context context){

// 開啟數據庫

DatabaseHelper databaseHelper = new DatabaseHelper(context);//1.創建數據庫使用數據庫操作的輔助類

Preferences preferences = databaseHelper.getPreferences(“bilibili”);//2.獲取到對應文件名的Preferences實例,filename是String類型

String SESSDATA = preferences.getString(“SESSDATA”,“”); //3.讀取數據

return SESSDATA;

}

/**

* 獲取Cookie中的Vmid值

* @param context

* @return Cookie中的Vmid值

*/

public static String getVmid(Context context){

// 開啟數據庫

DatabaseHelper databaseHelper = new DatabaseHelper(context);//1.創建數據庫使用數據庫操作的輔助類

Preferences preferences = databaseHelper.getPreferences(“bilibili”);//2.獲取到對應文件名的Preferences實例,filename是String類型

String DedeUserID = preferences.getString(“DedeUserID”,“”); //3.讀取數據

return DedeUserID;

}

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網站授權轉載。文章觀點僅代表作者本人,不代表電子發燒友網立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規問題,請聯系本站處理。 舉報投訴
  • 數據
    +關注

    關注

    8

    文章

    6520

    瀏覽量

    87715
  • 代碼
    +關注

    關注

    30

    文章

    4566

    瀏覽量

    66992
  • 鴻蒙
    +關注

    關注

    55

    文章

    1807

    瀏覽量

    42160

原文標題:我為B站添加鴻蒙服務卡片!

文章出處:【微信號:Huawei_Kirin,微信公眾號:華為麒麟】歡迎添加關注!文章轉載請注明出處。

收藏 人收藏

    評論

    相關推薦

    OpenHarmony開發案例:【電影卡片

    基于元服務卡片的能力,實現帶有卡片的電影應用,介紹卡片的開發過程和生命周期實現。
    的頭像 發表于 04-15 17:53 ?987次閱讀
    OpenHarmony開發案例:【電影<b class='flag-5'>卡片</b>】

    鴻蒙OS實戰開發:【多設備自適應服務卡片

    服務卡片的布局和使用,其中卡片內容顯示使用了一次開發,多端部署的能力實現多設備自適應。 用到了卡片擴展模塊接口,[@ohos.app.form.FormExtensionAbil
    的頭像 發表于 04-09 09:20 ?526次閱讀
    <b class='flag-5'>鴻蒙</b>OS實戰開發:【多設備自適應<b class='flag-5'>服務</b><b class='flag-5'>卡片</b>】

    鴻蒙OS開發實例:【手擼服務卡片

    服務卡片指導文檔位于“**開發/應用模型/Stage模型開發指導/Stage模型應用組件**”路徑下,說明其極其重要。本篇文章將分享實現服務卡片的過程和代碼
    的頭像 發表于 03-28 22:11 ?759次閱讀
    <b class='flag-5'>鴻蒙</b>OS開發實例:【手擼<b class='flag-5'>服務</b><b class='flag-5'>卡片</b>】

    鴻蒙實戰項目開發:【短信服務

    數據管理 電話服務 分布式應用開發 通知與窗口管理 多媒體技術 安全技能 任務管理 WebGL 國際化開發 應用測試 DFX面向未來設計 鴻蒙系統移植和裁剪定制 …… ? 《鴻蒙開發實戰》 ArkTS實踐
    發表于 03-03 21:29

    鴻蒙HarmonyOS元服務-“文學素養”說明

    1.概述 文學素養將中華傳統文化中的常用漢字解釋,優秀的經、文、楚辭、漢賦、唐詩、宋詞、原曲、明清小說,多音字,生僻字,成語測試等和HarmonyOS具備的元服務、萬能卡片能力進行融合,嘗試用一種
    發表于 01-10 10:11

    鴻蒙原生應用/元服務開發-AGC分發如何下載管理Profile

    一、收到通知 尊敬的開發者: 您好,為支撐鴻蒙生態發展,HUAWEI AppGallery Connect已于X月XX日完成存量HarmonyOS應用/元服務的Profile文件更新,更新后
    發表于 11-29 15:10

    一張服務卡片,三個設計原則,讓HarmonyOS元服務卡片獲得更多用戶觸點

    服務是一種基于HarmonyOS API的全新服務提供方式,對于開發者來說僅需要開發一次,即可支持多終端設備運行,以鴻蒙萬能卡片等多種呈現形態,向用戶提供更輕量化的
    的頭像 發表于 11-17 15:43 ?297次閱讀

    鴻蒙原生應用開發-折疊屏、平板設備服務卡片適配

    的間距在標準尺寸下占整體比例的 16%,這樣當卡片尺寸擴展到 200vp 時,卡片邊距也就變成了 32vp,以此類推,能夠保證一定程度下的適配效果。 二、卡片對應宮格比例對照表 服務
    發表于 11-16 10:10

    爆款元服務!教你如何設計高使用率卡片

    卡片作為桌面上的“顯眼包”,必然要具備給人帶來愉悅享受的價值,許多用戶甚至會單純為了裝飾桌面而將卡片添加到桌面上。因此請各位開發者在設計時,不僅要關注卡片的功能,也要打磨
    發表于 11-15 11:15

    鴻蒙原生應用開發-元服務分發方式的調整及趨勢

    一屏,因此部分鴻蒙3.0的手機通過對角線滑動也打不開服務中心,那該如何進行開放式測試呢? 我們只需將服務中心卡片添加至桌面,然后點擊
    發表于 11-14 16:02

    誠邁科技成為華為終端云服務“元服務服務商”

    共同推動鴻蒙生態的繁榮發展。 元服務是一種基于HarmonyOS API的全新服務提供方式,支持運行在1+8+N設備上,以鴻蒙萬能卡片(其他
    的頭像 發表于 09-25 17:13 ?773次閱讀

    HarmonyOS元服務開發實踐:桌面卡片字典

    和密碼不能為空\" }) } }) }) 7.其他云服務 說明:這是云模板初始業務,如有其他業務需求,可自行添加。 四、卡片開發 按需求添加卡片
    發表于 08-24 16:55

    HarmonyOS/OpenHarmony元服務開發-配置卡片的配置文件

    ;supportDimensions\": [ \"2*2\" ] } ] } *附件:HarmonyOSOpenHarmony元服務開發-配置卡片的配置文件.docx
    發表于 08-01 11:45

    OpenHarmony上使用服務卡片

    服務卡片是一種界面展示形式,將服務的重要信息以卡片的形式展示給用戶,用戶可通過輕量交互行為實現服務直達、減少層級跳轉的目的。
    的頭像 發表于 06-25 15:12 ?355次閱讀
    OpenHarmony上使用<b class='flag-5'>服務</b><b class='flag-5'>卡片</b>

    HarmonyOS 3.1上實現計步卡片

    本篇帖子是參考 Codelab 基于 Stage 模型 JS 服務卡片,使用最新 ArkTS 元服務開發的,實現帶有卡片的計步應用,用于介紹卡片
    的頭像 發表于 05-29 11:10 ?532次閱讀
    亚洲欧美日韩精品久久_久久精品AⅤ无码中文_日本中文字幕有码在线播放_亚洲视频高清不卡在线观看
    <acronym id="s8ci2"><small id="s8ci2"></small></acronym>
    <rt id="s8ci2"></rt><rt id="s8ci2"><optgroup id="s8ci2"></optgroup></rt>
    <acronym id="s8ci2"></acronym>
    <acronym id="s8ci2"><center id="s8ci2"></center></acronym>