KaiOS APN Settings模块代码

19 篇文章 0 订阅
16 篇文章 0 订阅

一、模块简介

APN界面在Settings应用菜单实现,代码归属gaia/apps/settings。

KaiOS panel 生命周期:onInit->onBeforeShow->onShow->onBeforeHide->onHide

官方参考文档:Gaia/Settings/docs - MozillaWiki

二、KaiO3.1应用通用目录结构

源码路径gaia/apps(感觉就是个网站网页开发),手机目录

文件(夹)作用说明
manifest.webapp该文件作用类似于AndroidManifest.xml文件,在其中进行应用名称,默认语言,所需权限,开发者等信息的设置
index.html主页,相当于MainActivity.java,应用启动的第一个页面,需要在manifest.webapp文件中配置
js/src文件夹

module;

JavaScript源代码、模块化代码文件、模块间交互引用

element文件夹html文件
style文件夹资源文件,如css样式,image图片,icons图标等
locales文件夹

string资源。

如Settings应用用到字符串位置:gaia/locales/en-US/apps/settings/settings.properties

resources文件夹资源文件,类似Android res目录
test文件夹

包含单元测试等功能文件

三、代码路径

1、【UI】APN列表页:

  • gaia/apps/settings/elements/apn_list.html 界面结构和布局
  • gaia/apps/settings/js/panels/apn_list/panel.js 逻辑
    • createApnSettingsPanel函数创建并返回SettingsPanel面板对象
  • gaia/apps/settings/elements/apn_settings.html
  • gaia/apps/settings/js/panels/apn_settings/panel.js

Kai基原生行为:apn_list(左)和apn_settings(右)是两个不同的界面

  • apn_list:Data Settings,卡匹配的一套APN,以每条APN形式展示
  • apn_settings:APN Settings,针对不同类型的APN分类展示

Note:定制APN菜单项registerSoftkey()——比如运营商需求不可添加APN

2、【UI】APN编辑页:新增、修改APN

  • gaia/apps/settings/elements/apn_editor.html 界面
  • gaia/apps/settings/js/panels/apn_editor/panel.js 逻辑


3、【功能逻辑】

更新数据库APN:/gaia/apps/settings/js/modules/apn/apn_settings.js

gaia/apps/settings/js/modules/apn/apn_settings_manager.js

四 、实现逻辑

KaiOS的APN设置界面是使用HTML和JavaScript动态生成的:

  1. "apn_settings.html"文件中包含APN设置界面的HTML代码,其中包括单选按钮的代码。

  2. "apn_settings.js"文件中包含用于生成和操作单选按钮的JavaScript代码。这个文件中的代码使用模板引擎来生成HTML代码,然后将其插入到页面中。

(一)【UI】卡APN列表:apn_list 

panels.js 实际用APN列表界面
  1. gaia/apps/settings/elements/apn_lists.html 定义了 APN Settings界面的结构和布局
  2. gaia/apps/settings/js/panels/apn_list/panel.js 
  3. gaia/apps/settings/js/panels/apn_list/apn_template_factory.js 界面模板
<!--gaia/apps/settings/elements/apn_list.html-->
<element name="apn_list" extends="section">
  <template>
  
    <gaia-header data-href="#apn_settings">
      <h1 slot="text"></h1>
    </gaia-header>

    <div class ="panel">
      <ul role="menu" class="apn-list"></ul>
      <ul>
      </ul>
    </div>

    <panel data-path="panels/apn_list/panel"><panel>

  </template>
</element>
apn_lists/panel.js接口说明
createApnSettingsPanel()

最外层返回的方法,其他功能函数都嵌套在内。

getFocusPos
registerSoftkey
resetApnWarningDialog
resetApn
updateSoftkey
updateUI
getElementByType
onApnDeleteAfter we deleted an apn , we should remove it from apn-list and reset focus && navigation map && refresh softkeys
SettingsPanel
apn_template_factory.js 字段介绍

gaia/apps/settings/js/panels/apn_list/apn_template_factory.js

要注意const变量的定义,避免引起undefined报错。此模板用于创建DOM节点。

  1. const rawApn = item.apn;
  2. const input = document.createElement('input');     // Create an <input type="radio"> element
  3. const radioSpan = document.createElement('span');      //单选按钮  
  4. const radioLabel = document.createElement('label');     //标签
  5. const nameSpan = document.createElement('span');    
  6. const nameLabel = document.createElement('label');
  7. const li = document.createElement('li');      //每一行
//item参数包含了APN具体信息
function apnTemplate(apnType, onItemclick, onRadioClick, itemsOBJ, item) {
    const rawApn = item.apn;    //从item获取APN对象

    // Create an <input type="radio"> element
    const input = document.createElement('input');    //创建input元素
    input.type = 'radio';    //设置input元素类型是radio(Radio Button控件)
    input.checked = item.active;    //并根据item.active布尔属性值设置是否选中
    input.name = apnType;

    // Include the radio button element in a list item
    const radioSpan = document.createElement('span');    //创建span元素,用于显示Radio Button空间的样式
    const radioLabel = document.createElement('label');    //创建lable元素
    radioLabel.classList.add('pack-radio-large');
    radioLabel.appendChild(input);    //将input元素添加到lable元素中
    radioLabel.appendChild(radioSpan);

    //创建包含APN名称的span元素,并添加其到nameLable元素中
    const nameSpan = document.createElement('span');
    const nameLabel = document.createElement('label');
    nameSpan.classList.add('full-string');
    nameLabel.classList.add('pack-radio-large');
    nameLabel.classList.add('my_radio');
    nameLabel.setAttribute('data-id', item.id);    //为nameLabel元素设置一个data-id属性,用于后续操作中能够识别APN列表项
    itemsOBJ[item.id] = item;
    if (!rawApn.carrier) {
      nameSpan.textContent = rawApn.apn;
    } else {
      nameSpan.textContent = rawApn.carrier;
    }
    nameLabel.appendChild(input);
    nameLabel.appendChild(nameSpan);

    const li = document.createElement('li');
    li.appendChild(nameLabel);    //最后将lable添加到新的列表项返回
    return li;
  }
apn_list 业务逻辑

/gaia/apps/settings/js/modules/apn/apn_list.js

apn_lists.js接口说明
ApnList(key)

ApnList.prototype =包含下列增删查改的方法
schedule(task)As the operations should not be performed concurrently. We use this function to enusre the operations are performed one by one.

export()

commit()
addInternal(apn, category)
removeInternal(id)
updateInternal(id, apn)
items()
item(id)
add(apn, category)
remove(id)
update(id, apn) 
updateByWap(id, apn)
apnList(key)

(二)【UI】分类APN菜单:apn_settings

panels.js

gaia/apps/settings/js/panels/apn_settings/panel.js是KaiOS APN设置界面,包含了生成和操作APN设置界面的所有JavaScript代码,主要功能如下:

  1. 初始化界面:当APN设置界面被加载时,会调用init函数进行初始化。在init函数中,首先检查是否支持APN设置,如果不支持,则显示错误消息并返回。如果支持,则加载APN列表和默认设置,并将其显示在界面上。

  2. 加载APN列表:loadAPNs函数用于从设备中读取APN列表。该函数使用navigator.mozMobileConnections API来获取当前设备上的移动连接,并使用其getAvailableNetworks方法获取APN列表。如果成功获取APN列表,则将其存储在apnList变量中。

  3. 加载默认设置:loadDefaultSetting函数用于加载当前的默认设置。该函数使用navigator.mozSettings API获取当前设备的APN设置,并将其存储在defaultSetting变量中。

  4. 显示APN设置列表:displayAPNList函数用于将APN设置列表显示在界面上。该函数使用Handlebars.js模板引擎生成每个APN设置项目的HTML代码,并将其插入到HTML文档中的相应元素中。

  5. 更新选项状态:updateOptionState函数用于根据用户的选择更新APN设置项的状态。该函数将用户选择的APN设置ID存储在selectedAPN变量中,并使用jQuery选择器更新相应的单选按钮状态。

  6. 保存设置:saveSetting函数用于将用户的选择保存到设备中。该函数使用navigator.mozSettings API将用户选择的APN设置保存到设备的APN设置中。

apn_settings/panels.js接口说明
createApnSettingsPanel()

最外层返回的方法,其他功能函数都嵌套在内,这样内部函数可以访问外部函数createApnSettingsPanel的所有变量和参数。

const APN_KEYS = [

'ril.data.dm.apnSettings.sim1',

'ril.data.dm.apnSettings.sim2'

];

initSoftKey(hasSelect)

接口=界面右侧菜单Options(Edit&Delete&Reset)

menuClassName: 'menu-button',

updateSoftKey(evt)
resetApnWarningDialog()
resetApn()
browseApnItems(evt)

用于处理“浏览APN”按钮的点击事件,打开“浏览APN”面板,即APN编辑页详情。

1、首先检查触发事件的元素是否包含数据集中的“apnType”属性。如果没有,则退出函数。

2、如果存在“apnType”属性,则获取该属性的值,并将其与当前设备的服务ID一起传递给 Settings.setCurrentPanel 函数。

3、Settings.setCurrentPanel 函数用于打开“浏览APN”面板,并设置面板的当前类型和服务ID。

NOTE:在打开编辑面板之前,需要先检查当前设备是否支持APN设置。如果不支持,则应禁用Edit选项。

addClickEventListener()

给apnSettingsList中可见的APN添加click监听

apnSettingsList[i].addEventListener('click', browseApnItems);

removeClickEventListener()移除可见apnSettingsList的click监听
initUI(panel)

用于初始化 APN 设置面板的用户界面。可隐藏Message/A-GPS/Tethering类型的APN项。

1、从 ApiManager.connections 对象中获取与当前服务 ID 相对应的连接信息。
2、创建一个 Promise 数组,将连接信息的 getSupportedNetworkTypes 方法调用添加到其中。

promises.push(conn.getSupportedNetworkTypes());
3、调用 Promise.all 方法,等待所有 Promise 都完成后执行后续操作。

4、在 Promise.all 方法的回调函数中,获取 getSupportedNetworkTypes 方法返回的值,即当前连接支持的网络类型列表。(Note:使用promise异步方法中获取支持的网络类型列表,首次进入界面可能会存在延迟)

Promise.all(promises).then(values => {});

5、获取界面中 ID 为“ims”的元素,并检查该元素是否存在。如果存在,则根据当前连接支持的网络类型决定是否显示该元素。

SettingsPanel()

createApnSettingsPanel最后return SettingsPanel()。

实现了onInit(panel)、onBeforeShow(panel, options)和onHide()接口。

1、onInit:数据查询apnSettingsList = panel.querySelectorAll('a[data-apn-type]');

2、onBeforeShow:调用initSoftKey和initUI初始化界面,并添加监听addClickEventListener()

3、onHide():调用removeClickEventListener()移除监听

apn_settings.js

(三)【功能】增删查改 APN:apn_settings_manager.js

otegaia/apps/settings/js/modules/apn/apn_settings_manager.jsN

Note:JS接口可以形参和实参个数不同,如果只输入一个参数就是第一个参数,第二个参数默认是undefined。

apn_settings_manager.js接口

ApnSettingsManager.prototype =

功能
 ready(serviceId)

Ensures the current apn items are up-to-date. When the current plmn does not equal to the cached plmn, we should restore the apn items.

确保当前 apn 项目是最新的。当当前 plmn 不等于缓存的 plmn 时,我们应该恢复 apn 项。

addObservers(serviceId) 

Register default APN changed observer

注册default APN观察者。

getPlmnAndMvnoInfo(serviceId)

Get current mcc/mnc information

获取当前卡MCCMNC信息。

deriveActiveApnIdFromItems(serviceId, apnType)

Returns the id of the first preset apn item.

返回第一个预设的 APN 项的ID。

deriveActiveApnIdFromSettings(serviceId, apnType)

Returns the id of the apn item that matches the current apn setting of the specified apn type.

从指定的 APN 类型的当前 APN 设置中返回匹配的 APN 项的 ID。

getApnAppliedType(serviceId, apnId)

Return the apn type an apn that is actively being used for.

返回正在使用的 APN 类型。

storeApnSettingByType(serviceId, apnType)

Store the current apn selection to apn settings to the settings database.

将当前 APN 选择的 APN 设置存储到设置数据库中。

apnList(serviceId)

Get the apn item list of a sim slot.

获取 SIM 卡槽的 APN 项列表。

apnItems(serviceId, apnType) 

Get the apn items of an apn type for a sim slot.

获取 SIM 卡槽指定 APN 类型的 APN 项列表。

restoreApnItemsOfCategory(apnList, apnsForRestoring, category)Restore the apn items of a category.
getServiceIdMcc(serviceId) Get current carrier mcc code by service Id
restore(serviceId, mode)

Restore the apn items and apn settings to the default. Apn items of the category ApnItem.APN_CATEGORY.PRESET and ApnItem.APN_CATEGORY.EU are restored. User created apn items (custom apns) will be delete. Therestored. User created apn items (custom apns) will be delete. The preset apn items are from the apn.json database and client provisioning messages.

将 apn 项和 apn 设置恢复为默认值。类别 ApnItem.APN_CATEGORY 的 APN 项。PRESET 和 ApnItem.APN_CATEGORY.EU 已恢复。用户创建的 apn 项(自定义 apns)将被删除。那里存储。用户创建的 apn 项(自定义 apns)将被删除。预设的 apn 项来自 apn.json 数据库和客户端预配消息。

queryApns(serviceId, apnType)查询一张卡的APN。查询匹配 apn.json 数据库中的 mcc/mnc 代码和通过客户端配置消息接收到的代码的 APN 项。返回ApnItem数组。
addApn(serviceId, apn, category)向SIM卡新增一条APN,并指定 APN 项的分类。如果未指定分类,则默认将 APN 项分类为自定义。
removeApn(serviceId, id)删除一条APN
updateApn(serviceId, id, apn)更新一条APN
getActiveApnId(serviceId, apnType)获取正在激活使用的APN。
setActiveApnId(serviceId, apnType, id)将指定id的 APN 设置为使用APN。

定义名为ApnSettingsManager的类,包含多个属性(this)

  /**
   * @class ApnSettingsManager
   * @requires module:modules/async_storage
   * @requires module:modules/apn/apn_const
   * @requires module:modules/apn/apn_utils
   * @requires module:modules/apn/apn_item
   * @requires module:modules/apn/apn_settings
   * @requires module:modules/apn/apn_list
   * @requires module:modules/apn/apn_selections
   * @returns {ApnSettingsManager} 注释指出,该实例会被返回给调用者
   */  
 function ApnSettingsManager() {
    this._apnLists = {};    //APN列表
    this._apnSelections = ApnSelections();    //存储APN选择
    this._apnSettings = ApnSettings();    //存储APN设置设置
    //可自定义新增属性,如下:
    //this.apnSelectedId = '';    //存储选中的APN的ID

    this._readyPromises = {};
    //客制化
    //this.defaultApnSettingChanged = {};
    
    //定义RESTORE_MODE只读属性,其值是常量RESTORE_MODE,是一个外部模块或变量的引用。
    Object.defineProperty(this, 'RESTORE_MODE', {
      configurable: false,
      get: function() {    //等同 get() {get() {
        return RESTORE_MODE;    
      }
    });
  }

(四)【UI】APN编辑页:apn_editor

APN编辑页面 apn_editor/apn_editor.js 
/**
 * The apn editor module
 */
'use strict';
define(function(require) { //eslint-disable-line
  const ApnEditorConst = require('panels/apn_editor/apn_editor_const');
  const ApnEditorSession = require('panels/apn_editor/apn_editor_session');

  const { APN_PROPERTIES } = ApnEditorConst;
  const { APN_PROPERTY_DEFAULTS } = ApnEditorConst;
  const { VALUE_CONVERTERS } = ApnEditorConst;
  function ApnEditor(rootElement) {}
  ApnEditor.prototype = {};

  return function apnEditor(rootElement) {
    return new ApnEditor(rootElement);
  };
});

ApnEditor.prototype功能
convertValue
fillInputElements定制APN 每一项参数的可编辑性
createApn
editApn
编辑业务功能 apn_editor/panels.js 

gaia/apps/settings/js/panels/apn_editor/panel.js

//结构组成
'use strict';
define(function(require) { //eslint-disable-line
    const SettingsPanel = require('modules/settings_panel');
    const ApnSettingsManager = require('modules/apn/apn_settings_manager');
    return function apnEditorPanel(){
        const DM_PROTOCOL = 'dm.apnSettings.protocol';

        //多个业务功能方法,主要都是编辑和保存功能

        return SettingsPanel{};
    };
});

五、用户功能

将apn_list和apn_settings融合定制

界面文字提示功能介绍
Add APN左上功能键:添加APN
Options右上功能键:菜单选项(包含编辑、删除、重置APN)
Seleted上下键移动APN列表光标,点击ok可切换选中APN,右边单选按钮变化 

六、其他

卡和运营商相关文件operator_variant

<!--gaia/shared/resources/apn/operator_variant.xml-->
<variant version="1">
<operator
       name="Movistar"
       mcc="214"
       mnc="07"
       enableStrict7BitEncodingForSms="true"
       operatorSizeLimitation="512000"
   />
</variant>

apnItem结构

//提交APN信息的结构,apnItem
{
  "itemId":"mlxfslzn2",
  "itemCategory":"preset",
  "itemApn":{
    "apn":"tad",
    "authtype":"notDefined",
    "carrier":"tad",
    "category":"custom",
    "id":"zdd2mblgk",
    "mmsc":"",
    "mmsport":"",
    "mmsproxy":"",
    "password":"",
    "port":"",
    "protocol":"notDefined",
    "proxy":"",
    "roaming_protocol":"notDefined",
    "types":["default"],
    "user":""
  }
}

itemId和iitemApn里面的id是不同的

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值