在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

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

3天內不再提示

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

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

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

接下來分享下我的制作過程,我使用的開發(fā)環(huán)境是:

IDE:DevEco Studio 2.1 Release

SDK:API Version 5

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

服務卡片設計

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

①尺寸規(guī)格

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

基礎模板如下圖:

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

②功能設計

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

③開發(fā)語言

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

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

界面實現(xiàn)

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

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

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

①div:基礎容器組件

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

代碼如下:

《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%; /*卡片在不同設備,尺寸會發(fā)生變化,所以最好使用百分比進行標注。*/

border-radius: 10px;

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

}

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

.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; /*設置文本的最大行數(shù)。*/

text-overflow: ellipsis; /*根據(jù)父容器大小顯示,顯示不下的文本用省略號代替。需配合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:列表容器組件

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

代碼如下:

《list class=“l(fā)ist”》

《list-item for=“{{cards}}” class=“l(fā)ist-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 是可以實現(xiàn)上下、左右滑動操作的。但是放置在桌面上的服務卡片,在左右滑動操作的時候,會使系統(tǒng)分不清楚用戶是要左右滑動屏幕,還是左右滑動卡片。

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

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

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

API 數(shù)據(jù)請求

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

①添加聯(lián)網(wǎng)權限

要在 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 請求

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

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

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

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

代碼實現(xiàn):

//獲取Bilibili粉絲數(shù),這里就要用到第二步我們添加的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 進行數(shù)據(jù)解析。

先按照 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, “解析失敗”);

}

總結:一定要添加聯(lián)網(wǎng)權限不然是獲取不到數(shù)據(jù)的。添加了 2 個依賴包,可以很方便的提取數(shù)據(jù)。

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

數(shù)據(jù)更新

要想將數(shù)據(jù)更新到服務卡片,得先了解服務卡片的運作機制。如果是通過 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) 方法下執(zhí)行數(shù)據(jù)獲取更新。

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

“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 數(shù)據(jù),解析 JSON,開啟服務卡片的周期性更新,就可以在 updateFormData() 實現(xiàn)服務卡片的數(shù)據(jù)更新了。

截取 follower 數(shù)據(jù)更新的部分代碼如下:

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

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

//這部分用來獲取粉絲數(shù)

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.將要刷新的數(shù)據(jù)存放在一個ZSONObject實例中

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

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, “解析失敗”);

}

}

});

}

②手動更新

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

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

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

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

@Overrideprotected ProviderFormInfo onCreateForm(Intent intent) {

。。。 。。。

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

onUpdateForm(formId);

return formController.bindFormData();

}

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

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

功能直達

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

詳細說明參考官方文檔:

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

①跳轉事件

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

以番劇更新的卡片為例:

首先我們要先添加一個要跳轉的頁面。如下圖所示添加一個 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(“頁面跳轉中”);

// 隨機圖片數(shù)組

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); // 如果網(wǎng)頁需要使用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 中給要觸發(fā)的控件上添加 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,跳轉事件要多加一個參數(shù)“abilityName”,指定要跳轉的頁面,并且攜帶參數(shù) url。

{

“data”: {

},

“actions”: {

“routerEvent1”: {

“action”: “router”,

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

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

“params”: {

“url”: “{{url1}}”

}

},

“routerEvent2”: {

。。。 。。。

}

②消息事件

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

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

在 index.hml 中給要觸發(fā)的控件上添加 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”: “l(fā)eft”,

“index”: “{{index}}”

}

},

“sendMessageEvent1”: {

“action”: “message”,

“params”: {

“p1”: “right”,

“index”: “{{index}}”

}

}

}

}

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

@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中的參數(shù)

ZSONObject data = ZSONObject.stringToZSON(message);

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

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

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

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

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

if(index == indexMax){index = -1;} //實現(xiàn)循環(huán)滾動

index = index+1;

zsonObject.put(“index”,index);

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

if(index == 0){index = indexMax+1;} //實現(xiàn)循環(huán)滾動

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=“l(fā)ist” else》

《list-item for=“{{list}}” class=“l(fā)ist-item”》

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

。。。 。。。

《/div》

《/list-item》

《/list》

這個坑折磨了我好久,最終我發(fā)現(xiàn)在 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 的點擊事件之后,才發(fā)現(xiàn)這歌控件真是好用。能用 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》

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

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

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

webView.getWebConfig().setJavaScriptPermit(true); // 如果網(wǎng)頁需要使用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());

/**

* 使用關系型數(shù)據(jù)庫[讀?。軨ookie

* @param preferences

* @param url

*/

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

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

//先從數(shù)據(jù)庫中取出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.寫入數(shù)據(jù),只能一條一條寫

}

}

/**

* 使用關系型數(shù)據(jù)庫[保存]Cookie

* @param preferences 數(shù)據(jù)庫的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寫入數(shù)據(jù)庫

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;

}

}

偏好型數(shù)據(jù)庫

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

①獲取 Preferences 實例

public class PreferenceDataBase {

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

/**

* 獲取Preferences實例

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

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

* @return //返回對應數(shù)據(jù)庫的Preferences實例

*/

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

DatabaseHelper databaseHelper = new DatabaseHelper(context);

Preferences preferences = databaseHelper.getPreferences(name);

return preferences;

}

。。。 。。。

}

②從數(shù)據(jù)庫中保存和讀取 Map

/**

* Map[保存]到偏好型數(shù)據(jù)庫

* @param preferences 數(shù)據(jù)庫的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.將數(shù)據(jù)寫入Preferences實例,

}

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

}

/**

* 從偏好型數(shù)據(jù)庫[讀?。軲ap

* @param preferences 數(shù)據(jù)庫的Preferences實例

* @return 要讀取的map

*/

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

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

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

return map;

}

③提取某些 Cookie 的值

/**

* 獲取Cookie中的SESSDATA值

* @param context 上下文用來指定數(shù)據(jù)文件存儲路徑

* @return Cookie中的SESSDATA值

*/

public static String getSessData(Context context){

// 開啟數(shù)據(jù)庫

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

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

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

return SESSDATA;

}

/**

* 獲取Cookie中的Vmid值

* @param context

* @return Cookie中的Vmid值

*/

public static String getVmid(Context context){

// 開啟數(shù)據(jù)庫

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

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

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

return DedeUserID;

}

編輯:jq

聲明:本文內容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權轉載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內容侵權或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • 數(shù)據(jù)

    關注

    8

    文章

    7233

    瀏覽量

    90772
  • 代碼
    +關注

    關注

    30

    文章

    4880

    瀏覽量

    70021
  • 鴻蒙
    +關注

    關注

    57

    文章

    2469

    瀏覽量

    43652

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

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

收藏 人收藏

    評論

    相關推薦

    效率大升!AI賦能鴻蒙萬能卡片開發(fā)

    萬能卡片,作為鴻蒙生態(tài)應用和元服務的重要展示形式,憑借將關鍵信息和核心操作前置,實現(xiàn)服務直達、減少跳轉層級的體驗效果,備受用戶和開發(fā)者青睞。但傳統(tǒng)
    的頭像 發(fā)表于 01-13 13:44 ?460次閱讀
    效率大升!AI賦能<b class='flag-5'>鴻蒙</b>萬能<b class='flag-5'>卡片</b>開發(fā)

    鴻蒙原生開發(fā)手記:04-一個完整元服務案例

    文章,或下方的參考資料。 完整代碼 完整的代碼見代碼倉庫 https://gitee.com/zacks/arkts-ohos-demo 參考資料 鴻蒙原生開發(fā)手記:01-元服務開發(fā) 鴻蒙原生開發(fā)手記:02-
    發(fā)表于 12-27 10:35

    服務卡片數(shù)據(jù)更新(初次嘗試,未長期驗證,僅供參考)

    服務卡片數(shù)據(jù)更新(初次嘗試,未長期驗證,僅供參考)
    發(fā)表于 11-26 14:20

    鴻蒙原生開發(fā)手記:03-元服務開發(fā)全流程(開發(fā)元服務,只需要看這一篇文章)

    導讀 本文帶來非常詳細的元服務開發(fā)及上架全流程介紹包含元服務介紹、創(chuàng)建、服務卡片、簽名、開發(fā)測試、簽名打包、上架審核等一應俱全。 元服務簡介
    發(fā)表于 11-23 21:52

    HarmonyOS NEXT應用元服務開發(fā)Intents Kit(意圖框架服務)習慣推薦方案概述

    。 卡片展示效果 意圖框架提供各垂域習慣推薦在小藝建議中展示使用的標準模板卡片,開發(fā)者無需開發(fā)展示卡片。在展示模板上,會展示應用/元服務名稱與logo和內容必要信息,比如音樂名、音樂圖
    發(fā)表于 11-19 17:59

    鴻蒙原生開發(fā)手記:02-服務卡片開發(fā)

    介紹 服務卡片是一直桌面小組件,可以放置在桌面上等位置,一觸即達。 服務卡片分為靜態(tài)卡片和動態(tài)卡片
    發(fā)表于 11-14 17:48

    鴻蒙原生開發(fā)手記:01-元服務開發(fā)

    同樣的使用方法。 服務卡片服務可以添加服務卡片,詳細介紹見《
    發(fā)表于 11-14 17:28

    HarmonyOS NEXT應用元服務開發(fā)Intents Kit(意圖框架服務)事件推薦方案概述

    詳情頁,用戶可在該頁面完成電影取票。 2.卡片展示效果 意圖框架將提供系統(tǒng)標準的事件模板卡片,無需開發(fā)者開發(fā),開發(fā)者只需按照具體垂域事件的意圖Schema將事件推送至智慧分發(fā)平臺服務器即可。各垂域事件
    發(fā)表于 11-13 10:38

    HarmonyOS NEXT應用元服務開發(fā)Intents Kit(意圖框架服務)本地搜索方案概述

    用戶感興趣的歌曲,那么后續(xù)用戶在小藝搜索入口中搜索歌名時,系統(tǒng)將會在應用/元服務共享的數(shù)據(jù)中檢索對應內容,并使用卡片的形式展示內容結果,當用戶點擊對應卡片熱區(qū)時,可以跳轉進具體音樂播放頁或者直接后臺執(zhí)行
    發(fā)表于 11-06 10:59

    HarmonyOS Next元服務開發(fā)快速入門案例

    ;base>media下添加圖片 二、創(chuàng)建卡片widget 1.創(chuàng)建微、小、中、大卡片 2.依次創(chuàng)建卡片 3.卡片創(chuàng)建完成,修改
    發(fā)表于 10-08 10:51

    基于鴻蒙Next模擬卡片數(shù)據(jù)數(shù)據(jù)更新

    一、介紹 基于鴻蒙Next模擬卡片數(shù)據(jù)數(shù)據(jù)更新二、場景需求 電商平臺產(chǎn)品信息更新、 客戶關系管理(CRM)系統(tǒng)、 社交媒體用戶資料更新、 健康管理系統(tǒng)、 項目管理工具、 金融服務應用、 教育管理系統(tǒng)
    發(fā)表于 08-30 15:32

    服務體驗-服務管理與分享

    服務管理 通過桌面、負一屏、應用市場、元服務等場景對元服務進行添加、收藏、移除等管理操作。 服務分享 元
    發(fā)表于 07-16 15:43

    鴻蒙Ability Kit(程序框架服務)【ExtensionAbility組件】

    ExtensionAbility組件是基于特定場景(例如服務卡片、輸入法等)提供的應用組件,以便滿足更多的使用場景。
    的頭像 發(fā)表于 06-04 15:54 ?894次閱讀
    <b class='flag-5'>鴻蒙</b>Ability Kit(程序框架<b class='flag-5'>服務</b>)【ExtensionAbility組件】

    萬里紅榮獲“首批鴻蒙原生應用開發(fā)服務商和培訓服務商”授牌

    近日,鴻蒙原生應用合作交流推介會在深圳召開,作為鴻蒙生態(tài)重要合作伙伴,萬里紅受邀出席,并榮獲“首批鴻蒙原生應用開發(fā)服務商和培訓服務商”授牌。
    的頭像 發(fā)表于 05-28 10:56 ?833次閱讀
    萬里紅榮獲“首批<b class='flag-5'>鴻蒙</b>原生應用開發(fā)<b class='flag-5'>服務</b>商和培訓<b class='flag-5'>服務</b>商”授牌

    鴻蒙開發(fā)接口Ability框架:【@ohos.application.formBindingData (卡片數(shù)據(jù)綁定類)】

    卡片數(shù)據(jù)綁定模塊提供卡片數(shù)據(jù)綁定的能力。包括FormBindingData對象的創(chuàng)建、相關信息的描述。
    的頭像 發(fā)表于 05-06 17:25 ?649次閱讀
    <b class='flag-5'>鴻蒙</b>開發(fā)接口Ability框架:【@ohos.application.formBindingData (<b class='flag-5'>卡片</b>數(shù)據(jù)綁定類)】
    主站蜘蛛池模板: 种子在线搜索bt | 人人入人人爱 | 日本久久黄色 | 一级片免费在线播放 | 国产精品三级国语在线看 | 91精品久久国产青草 | 亚洲午夜久久久久久91 | 日本媚薬痉挛在线观看免费 | 深夜视频免费在线观看 | 免费看啪啪的网站 | 日韩精品在线一区二区 | 国产精品久久久久乳精品爆 | 久久婷婷六月 | 乱j伦小说在线阅读 | 亚洲一级毛片免观看 | 韩国三级精品 | 久久婷婷丁香 | 男人和女人做a免费视频 | 国产成人毛片视频不卡在线 | 欧美日韩一区二区三区视频 | 狠狠干天天爱 | 国产精品黄网站免费进入 | 日韩欧美卡一卡二卡新区 | 免费一级特黄 欧美大片 | 天堂在线观看 | 三级网站在线免费观看 | 一级a爰片久久毛片 | 一级视频在线观看 | 色婷婷激婷婷深爱五月小说 | 看视频免费 | 国产精品久久精品福利网站 | 插白浆| 四虎国产精品永久免费网址 | aaa视频| 国产又色又爽又黄的网站在线一级 | 久久亚洲国产精品五月天 | 午夜欧美精品 | 久久黄色网 | 午夜传媒 | 全部免费a级毛片 | 午夜黄色毛片 |