Open fWX228941 opened 6 months ago
双待双通方案设计
1.Launcher的设计方案 1.1.基本需求 1)Launcher增加一屏,变为两屏小部件显示; 2)两屏之间通过左右键来切换,支持循环切换; 3)第一屏永远为PTT键控制的模式; 4)不在该应用小部件界面,需要显示该应用后台通话悬浮窗; 5)小部件菜单进入对应工作模式的菜单列表,需去掉“工作模式”设置项; 1.2.方案设计与实现 1.2.1.整体方案 该方案基本原则: 尽量不对echat, pdt这些模式模式应用进行修改,应用在其对应的工作模式正常运行即可。
方案设计: 1)针对模式应用,查询当前系统工作模式,得到是应用当前正常运行应该所处的工作模式。
如果是echat-dmd双通模式,echat应用调用上面接口查询时,得到永远是工作模式6(echat模式),而不是数据库保存的真正值。而如果是pdt应用查询时,得到的是数据库真正保存的模式值,可能是dmd(2数字常规),也可能是dma(1模拟常规) 。而对于Launcher来说,查询的结果应该是数据库的值。 由于目前Launcher小部件,菜单,按键,未读数等都是依赖具体的工作模式值, 并且echat, pdt应用也是按照其对应的工作模式进行配置的,如果查询得到的不是应用对应的工作模式,应用需要进行该工作模式配置,否则运行会出错,因此改动较大。
2)系统需要提供接口,表示当前双待双通具体对应哪两种模式,第一屏应该显示哪个工作模式(即PTT键控制的工作模式)。 例如:双通对应echat, pdt的数字常规模式, 第一屏显示为pdt模式,设计如下:
当进行PTT按键,以及侧上键自定义配置后,会更新该双通模式值。
利用该值,可以作为系统是否为双通模式的功能定制,如下:
注意: 双通模式保存的PDT模式仅用于表示为PDT模式,具体是PDT哪个模式,是数字常规DMD,还是模拟常规DMA, 需要通过调用下面接口得到:
因为假如双通配置的是PDT的DMD模式,在切换到模拟信道后,工作模式会切换到PDT的DMA模式,而这个时候双通配置的模式还是DMD跟echat模式,因此会出现不匹配问题。
3)Launcher上很多场景需要根据当前小部件页面,得到对应的应用工作模式,然后根据该模式,跳转到不同应用的界面或执行不同的逻辑。实现如下:
1.2.2.具体设计与实现 1.2.2.1.主界面 1)要求: 双屏小部件显示,循环切换,状态栏是独立,不属于两屏小部件页面。
2)之前应用界面架构设计如下:
小部件页面fragment布局为:
3)如果是双通模式,应用界面架构设计为:
小部件页面Fragment布局为:
整个UI实现逻辑: 1)根据双通模式,选择加载launcher的布局为R.layout.layout_launcher_dual_pass,该布局主要包含状态栏以及页面容器ViewPager,状态栏不再属于小部件页面的一部分。如下:
2)状态栏显示控制,通过创建StatusbarViewController控制器来统一管理。如下:
StatusbarViewController初始化了状态栏信号,状态图标,通知,电量等所有相关业务控制器,最后用于控制状态栏LauncherStatusbarView对应View的显示,如下:
(之前这些业务控制器是放在小部件界面AppWidgetFragment初始化的,因为其不仅控制状态栏相关view的显示,同时还要控制下拉快捷设置的显示等)
3)往页面容器ViewPager添加两屏的小部件界面, 每个小部件界面设计为ModeWidgetFragment,同时FragmentPageAdapter设计为页面可循环切换。
小部件界面显示实现: 1)之前的小部件显示流程如下:
其中的loadWorkspace方法去获取当前工作模式下,解析应用meta-data配置的小部件,分配小部件id,生成小部件信息LauncherAppWidgetInfo, 将其保存到内存全局变量中。如下:
然后bindWidget方法,根据小部件appWidgetId, 生成小部件hostView,添加到小部件容器widget_container。
由于startLoader整个流程结束后,AppwidgetFragment还没有进入onCreateView方法,因此需要在onCreateView中调用getWidgetInfo方法获取解析到小部件信息,然后生成hostView,添加到小部件容器中。
2)如果是双通模式,流程如下: 2.1)loadWorkspaces方法,去加载两屏小部件页面对应的小部件信息。根据配置的双通模式,获取两个页面pageIndex对应的真正的工作模式值,然后分别解析工作模式对应的应用meta-data配置的小部件信息,分配小部件id,最后生成两屏小部件页面对应的小部件信息LauncherAppWidgetInfo, 将其保存到内存全局变量中,如下:
2.2)LauncherActivity的bindWidgets方法,根据页面pageIndex, 选择对应的小部件信息,最后调用对应页面fragment的bindWidget,构造小部件hostView,添加到小部件容器。如下:
ModeWidgetFragment需要在onCreateView中调用getWidgetInfo(int pageIndex)方法获取解析到小部件信息,然后生成hostView,添加到小部件容器中。
2.3)LauncherMode需要监听双通模式配置变化,重新loadWorkspaces以及bindWidgets用于触发两屏小部件界面刷新。 1.2.2.2.菜单设置项
1)要求: 点击当前小部件界面的菜单,进入该模式对应的菜单设置列表界面。如下:
同时需要去掉“工作模式”菜单项。
2)之前菜单界面是通过CalttaMenuActivity,内部加载CalttaMenuFragment实现的。 菜单项数据是通过子线程,通过MetaDataProvider解析当前模式下的各应用配置的菜单项来完成的。
每个应用只需要在其Activity进行相关配置即可,如下:
3)如果是双通模式,则需要判断是从第几屏小部件进入的菜单界面,知道第几屏后,就可以获取到对应的工作模式workMode,从而去调用MetaDataProvider加载各应用配置的菜单项,然后进行显示。(注意:小部件里的菜单可能是点击,也可能是按键触发的)
实现流程: 1)进入CalttaMenuFragment的onCreate方法时,获取ViewPager当前所在页index即第几屏。如下:
2)查询双通模式,根据当前页index,获取对应的工作模式值workMode。如下:
3)将工作模式workMode值传递给reloadAllTiles方法加载菜单项即可,如下:
4)去掉工作模式菜单项,只需要判断是双通模式,在加载的菜单项数据中过滤掉“工作模式”该菜单即可。 1.2.2.3.未读数 1)要求: 未读数显示包含两部分: 1.1)当前小部件界面的未读图标,仅显示当前小部件所在工作模式是否存在未读。 1.2)小部件菜单进入后各菜单项显示的未读数,仅对应该工作模式,同菜单设置项一样。 如下:
2)之前的设计 2.1)小部件界面上的未读图标,是通过获取当前工作模式,然后查询当前模式下所有应用配置的未读数的总和,如果总数>0则显示图标,否则不显示。 2.2)菜单每个设置项,是通过获取当前工作模式,然后查询当前模式下该菜单设置项配置的未读数,最后进行显示。 2.3)监听未读数变化,及时刷新。
3)如果是双通模式,未读数的实现基本与之前是相同的,最主要是根据当前所在页,去获取对应的工作模式,然后去查询数据库值。 1.2.2.4.按键的处理 1)要求: 左右键能够切换小部件界面, 左中右三个按键,触发当前小部件界面下面三个按钮。 拨号数字键跳转到当前小部件界面应用对应的拨号盘界面。 通话键跳转到当前小部件界面应用对应的通话记录界面
2)之前设计,Launcher应用处于前台时,按键交由LauncherActivity拦截分发。 左右键未处理。 左中右三个按键,由小部件界面AppWidgetFragment处理,按键启动的Activity的intent为:
获取当前工作模式,然后选择不同的三个按键启动的intent,然后跳转到对应模式应用界面。
拨号数字键,获取当前工作模式,选择拨号盘intent,然后跳转。
而对于拨号键,目前只针对PDT,btrunc进行跳转,在代码里都是写死的,获取当前模式,然后进行跳转对应应用的通话记录activity。
3)如果是双通模式,最主要就是获取当前所在页对应的工作模式,然后将该工作模式传递给要启动的intent。 左右键切换页面实现比较简单:计算要切换到的下一页pageIndex,然后调用mViewPager的setCurrentItem(pageIndex)即可。 1.2.2.5.后台的通话悬浮窗 1)要求: 应用在通话时,如果当前正处于该应用小部件界面,并且是处于前台则不需要显示该应用后台通话悬浮窗。否则都需要显示后台通话悬浮窗。
2)之前应用通话是否需要显示悬浮窗,是由Launcher发送广播进行通知的。实现方式如下:
各应用监听该广播,根据参数is_in_home_page决定是否要显示通话悬浮窗。 通知场景: Launcher应用处于前台时,并且当前页面是小部件界面,则通知is_in_home_page=true Launcher应用处于后台时,并且当前页面是小部件界面,则通知is_in_home_page=false
Launcher应用 ViewPager切换页面,如果当前页面是小部件界面,则通知is_in_home_page=true,否则通知is_in_home_page=false
3)如果是双通模式,处于两个模式应用echat, pdt应用尽量不修改的原则,根据应用场景,通过指定包名显示广播还是隐式广播发送,用于特定应用接收还是所有应用都能接收。
4)各种场景如下: 4.1)Launcher应用处于前台时,获取当前页index,然后得到当前页对应的工作模式workMode值。根据工作模式,通过解析应用小部件meta-data配置的对应工作模式workMode的包名, 然后指定该包名发送显式广播,通知该应用。
4.2)Launcher应用处于前台,页面切换时,通知当前模式对应应用不显示悬浮窗,另一个模式应用需要显示悬浮窗。
4.3)Launcher应用处于后台时,则需要通知两个模式应用,显示通话悬浮窗。不指定包名发送广播进行通知,保证两个模式应用都能够收到。
4.4)由于当前echat, pdt这些模式应用的后台通话悬浮窗都显示在屏幕的最右上方,因此会出现两个悬浮窗重叠现象。因此需额外对PDT应用的悬浮窗位置进行定制修改。 1.2.2.6.状态栏图标 当前状态栏是独立于双通模式下的echat, pdt小部件界面的,由于对当前小部件界面上的状态栏图标显示没有要求,当在echat或pdt小部件界面,状态栏上可以同时显示pdt, echat状态图标。如果后续要求,可以进行修改。
2.按键的设计方案 2.1.按键的注册 正常情况下,只有当前模式的应用才会注册按键事件,非当前模式的应用会取消按键的注册。为了能让多个应用都可能收到按键事件,需要应用去掉模式的判断,不管什么模式,都注册按键。 考虑到尽可能不修改应用,所以按如下思路实现:
终端默认数模常规 修改Settings数据库,如果是eChat应用来获取模式,固定返回eChat模式(让eChat应用误以为是eChat模式,从而注册按键),其他应用获取,按实际情况返回 去掉限制eChat仅在eChat模式下才能启动的限制 2.2.按键的配置 CalttaSettings提供UI给用户配置按键,具体以交互为准,这里不做考虑。为了扩展,配置结果的保存方式,不考虑具体需求,采用通用的规则 以“config_keytarget”+具体键值为key,应用的包名为value,多个包名之间用英文逗号间隔,代表这个键要给这些应用。比如config_key_target_287 = com.zte.pdt,代表287这个键需要传递给PDT应用 以“config_key_main”为key,应用的包名为value,代表按键以哪个应用为主,对于用户来说,就是平时以哪个种业务为主。 “config_keyreplace”+具体键值为key,valeu也为具体键值,代表需要在分发的时候将特定的键值替换成另一个键值来分发。 “config_key_target”的优先级高于“config_key_main”,即对于一个具体的按键,如果没有配置“config_key_target”,则传递给“config_key_main”对应的应用。 以上规则只适用于GotaKeyMonitor分发按键,如果是Android原生的按键传递方式,则不受上述配置影响
按定制需求,按键的配置如下: PTT键:config_key_target_287默认为com.mcptt,允许用户修改 侧上键:config_key_target_288默认为com.zte.pdt,允许用户修改,config_key_replace_288默认为287,不允许用户修改 挂断键:config_key_target_6默认为com.mcptt,不允许用户修改(常规无法挂断呼叫,所以挂断键只需要给eChat) 拨号键:config_key_target_5默认为com.mcptt,不允许用户修改(PDT应用不需要通过GotaKeyMonitor传递拨号键) SOS键、旋钮键:默认不配置,也不允许用户修改,跟着PTT键走
注:这套配置规则中的value都是包名,后续不利于融合应用来实现双通,如果是融合应用实现双通,不管用户怎么配置,value都是融合应用的包名,但是融合应用收到PTT键的时候,也不知道发起什么呼叫好,需要用额外的key来帮助融合应用判断发起什么业务。value如果不是包名,而是具体业务类型,那么按键分发的时候,按键服务就得知道哪个业务类型对应哪个包名。各有利弊 2.3.按键的分发 按键的分发由GotaKeyMonitor负责。正常情况下,GotaKeyMonitor只将按键发给最后一个注册按键的应用,为了实现双PTT键的效果,需要GotaKeyMonitor根据配置情况调整分发流程:
分发过程中,要对工厂模式做特殊处理,工厂模式下无视一切配置,只给工厂模式分发按键。避免工厂模式按键无法测试 2.4.按键的处理 按键的处理主要由PhoneWindowManager负责。当前处理按键的时候,判断了模式,不同模式下,可能处理逻辑不一样,但现在需要去掉模式的判断,因为模式永远都是PDT模式,但也需要判断eChat的情况。可能的修改如下: 侧上键:非工厂模式下要拦截,不要通过Android的按键传递到应用,避免触发快捷功能 Power键:PDT和eChat都不在通话中时,回到launcher。PDT在通话中时不传递挂断键,eChat通话中时,通过GotaKeyMonitor传递挂断键键值 拨号键:PDT和eChat任意一个在通话中时,按拨号键拉起luancher(当只有一路通话时launcher如何知道显示哪一路的小部件)并拦截拨号键。两者都不在通话中时,不要拦截拨号键,传递给当前界面。 3.CalttaSettings 系统设置需要增加按键的配置入口,具体参考交互。用户修改按键配置时,需要修改同时修改以下几个数据库值 PTT键和侧上键,互斥,不允许配置同一种业务 修改config_key_target与用户的设置结果保存一致 修改config_key_main的值,与PTT键的值保持一致 修改dual_pass_mode的值,PTT键对应的模式在前,侧上键对应的模式在后,英文逗号间隔 4.SettingsProvider 当前SettingsProvider提供了工作模式(cluster_mode_pdt_mpt)的数据库查询接口,为了实现双待双通,额外增加了双通模式的(dual_pass_mode)的保存,用于判断当前是哪两个模式双通,且第一个模式作为PTT键控制的模式。结合需求,需要修改的点如下: 当有应用获取工作模式(cluster_mode_pdt_mpt)时,判断包名,如果是eChat应用则固定返回eChat模式(6),其他应用则返回真实的数据 当PDT应用修改工作模式(cluster_mode_pdt_mpt)为模拟常规或着数字常规时,在SettingsProvider的服务端把双通模式中的PDT模式值也一并修改 默认配置dual_pass_mode为6,2;cluster_mode_pdt_mpt为2 5.快捷键 当前的快捷键功能,有部分是与模式相关的,比如短信功能,在DMR模式下打开的是DMR的短信,在eChat模式下打开的是eChat的短信。双待双通下,这类功能只响应PTT键对应的业务,比如PTT键控制eChat业务,则短信只会拉起eChat的短信。 同时部分快捷功能与双待双通冲突,也需要一起去掉。 要修改的点如下: 去掉侧上键快捷设置 去掉工作模式的快捷功能 判断工作模式的时候,优先判断双通模式dual_pass_mode,不存在时,才根据cluster_mode_pdt_mpt获取当前的模式 6.息屏显示 当前息屏的时候只会显示当前模式的信息,双待双通下,需求明确只显示PTT键对应的业务信息。所以息屏显示应用做出如下调整: 监听数据库dual_pass_mode字段的变化,提取第一个模式,并显示该模式对应的业务信息 dual_pass_mode的优先级高于cluster_mode_pdt_mpt
7.指示灯 当前的指示灯,按通知的优先级来控制灯,同等优先级下,以最后一个通知为准。双待双通时,可能存在两路通话,一路在讲,一路在听,此时指示灯的状态可能显示的是讲的状态,也可能是听的状态。这点改起来比较麻烦,需求层面,不对指示灯做具体要求,保持现状。
双待双通方案设计
1.Launcher的设计方案 1.1.基本需求 1)Launcher增加一屏,变为两屏小部件显示; 2)两屏之间通过左右键来切换,支持循环切换; 3)第一屏永远为PTT键控制的模式; 4)不在该应用小部件界面,需要显示该应用后台通话悬浮窗; 5)小部件菜单进入对应工作模式的菜单列表,需去掉“工作模式”设置项; 1.2.方案设计与实现 1.2.1.整体方案 该方案基本原则: 尽量不对echat, pdt这些模式模式应用进行修改,应用在其对应的工作模式正常运行即可。
方案设计: 1)针对模式应用,查询当前系统工作模式,得到是应用当前正常运行应该所处的工作模式。
如果是echat-dmd双通模式,echat应用调用上面接口查询时,得到永远是工作模式6(echat模式),而不是数据库保存的真正值。而如果是pdt应用查询时,得到的是数据库真正保存的模式值,可能是dmd(2数字常规),也可能是dma(1模拟常规) 。而对于Launcher来说,查询的结果应该是数据库的值。 由于目前Launcher小部件,菜单,按键,未读数等都是依赖具体的工作模式值, 并且echat, pdt应用也是按照其对应的工作模式进行配置的,如果查询得到的不是应用对应的工作模式,应用需要进行该工作模式配置,否则运行会出错,因此改动较大。
2)系统需要提供接口,表示当前双待双通具体对应哪两种模式,第一屏应该显示哪个工作模式(即PTT键控制的工作模式)。 例如:双通对应echat, pdt的数字常规模式, 第一屏显示为pdt模式,设计如下:
当进行PTT按键,以及侧上键自定义配置后,会更新该双通模式值。
利用该值,可以作为系统是否为双通模式的功能定制,如下:
注意: 双通模式保存的PDT模式仅用于表示为PDT模式,具体是PDT哪个模式,是数字常规DMD,还是模拟常规DMA, 需要通过调用下面接口得到:
因为假如双通配置的是PDT的DMD模式,在切换到模拟信道后,工作模式会切换到PDT的DMA模式,而这个时候双通配置的模式还是DMD跟echat模式,因此会出现不匹配问题。
3)Launcher上很多场景需要根据当前小部件页面,得到对应的应用工作模式,然后根据该模式,跳转到不同应用的界面或执行不同的逻辑。实现如下:
1.2.2.具体设计与实现 1.2.2.1.主界面 1)要求: 双屏小部件显示,循环切换,状态栏是独立,不属于两屏小部件页面。
2)之前应用界面架构设计如下:
小部件页面fragment布局为:
3)如果是双通模式,应用界面架构设计为:
小部件页面Fragment布局为:
整个UI实现逻辑: 1)根据双通模式,选择加载launcher的布局为R.layout.layout_launcher_dual_pass,该布局主要包含状态栏以及页面容器ViewPager,状态栏不再属于小部件页面的一部分。如下:
2)状态栏显示控制,通过创建StatusbarViewController控制器来统一管理。如下:
StatusbarViewController初始化了状态栏信号,状态图标,通知,电量等所有相关业务控制器,最后用于控制状态栏LauncherStatusbarView对应View的显示,如下:
(之前这些业务控制器是放在小部件界面AppWidgetFragment初始化的,因为其不仅控制状态栏相关view的显示,同时还要控制下拉快捷设置的显示等)
3)往页面容器ViewPager添加两屏的小部件界面, 每个小部件界面设计为ModeWidgetFragment,同时FragmentPageAdapter设计为页面可循环切换。
小部件界面显示实现: 1)之前的小部件显示流程如下:
其中的loadWorkspace方法去获取当前工作模式下,解析应用meta-data配置的小部件,分配小部件id,生成小部件信息LauncherAppWidgetInfo, 将其保存到内存全局变量中。如下:
然后bindWidget方法,根据小部件appWidgetId, 生成小部件hostView,添加到小部件容器widget_container。
由于startLoader整个流程结束后,AppwidgetFragment还没有进入onCreateView方法,因此需要在onCreateView中调用getWidgetInfo方法获取解析到小部件信息,然后生成hostView,添加到小部件容器中。
2)如果是双通模式,流程如下: 2.1)loadWorkspaces方法,去加载两屏小部件页面对应的小部件信息。根据配置的双通模式,获取两个页面pageIndex对应的真正的工作模式值,然后分别解析工作模式对应的应用meta-data配置的小部件信息,分配小部件id,最后生成两屏小部件页面对应的小部件信息LauncherAppWidgetInfo, 将其保存到内存全局变量中,如下:
2.2)LauncherActivity的bindWidgets方法,根据页面pageIndex, 选择对应的小部件信息,最后调用对应页面fragment的bindWidget,构造小部件hostView,添加到小部件容器。如下:
ModeWidgetFragment需要在onCreateView中调用getWidgetInfo(int pageIndex)方法获取解析到小部件信息,然后生成hostView,添加到小部件容器中。
2.3)LauncherMode需要监听双通模式配置变化,重新loadWorkspaces以及bindWidgets用于触发两屏小部件界面刷新。 1.2.2.2.菜单设置项
1)要求: 点击当前小部件界面的菜单,进入该模式对应的菜单设置列表界面。如下:
同时需要去掉“工作模式”菜单项。
2)之前菜单界面是通过CalttaMenuActivity,内部加载CalttaMenuFragment实现的。 菜单项数据是通过子线程,通过MetaDataProvider解析当前模式下的各应用配置的菜单项来完成的。
每个应用只需要在其Activity进行相关配置即可,如下:
3)如果是双通模式,则需要判断是从第几屏小部件进入的菜单界面,知道第几屏后,就可以获取到对应的工作模式workMode,从而去调用MetaDataProvider加载各应用配置的菜单项,然后进行显示。(注意:小部件里的菜单可能是点击,也可能是按键触发的)
实现流程: 1)进入CalttaMenuFragment的onCreate方法时,获取ViewPager当前所在页index即第几屏。如下:
2)查询双通模式,根据当前页index,获取对应的工作模式值workMode。如下:
3)将工作模式workMode值传递给reloadAllTiles方法加载菜单项即可,如下:
4)去掉工作模式菜单项,只需要判断是双通模式,在加载的菜单项数据中过滤掉“工作模式”该菜单即可。 1.2.2.3.未读数 1)要求: 未读数显示包含两部分: 1.1)当前小部件界面的未读图标,仅显示当前小部件所在工作模式是否存在未读。 1.2)小部件菜单进入后各菜单项显示的未读数,仅对应该工作模式,同菜单设置项一样。 如下:
2)之前的设计 2.1)小部件界面上的未读图标,是通过获取当前工作模式,然后查询当前模式下所有应用配置的未读数的总和,如果总数>0则显示图标,否则不显示。 2.2)菜单每个设置项,是通过获取当前工作模式,然后查询当前模式下该菜单设置项配置的未读数,最后进行显示。 2.3)监听未读数变化,及时刷新。
3)如果是双通模式,未读数的实现基本与之前是相同的,最主要是根据当前所在页,去获取对应的工作模式,然后去查询数据库值。 1.2.2.4.按键的处理 1)要求: 左右键能够切换小部件界面, 左中右三个按键,触发当前小部件界面下面三个按钮。 拨号数字键跳转到当前小部件界面应用对应的拨号盘界面。 通话键跳转到当前小部件界面应用对应的通话记录界面
2)之前设计,Launcher应用处于前台时,按键交由LauncherActivity拦截分发。 左右键未处理。 左中右三个按键,由小部件界面AppWidgetFragment处理,按键启动的Activity的intent为:
获取当前工作模式,然后选择不同的三个按键启动的intent,然后跳转到对应模式应用界面。
拨号数字键,获取当前工作模式,选择拨号盘intent,然后跳转。
而对于拨号键,目前只针对PDT,btrunc进行跳转,在代码里都是写死的,获取当前模式,然后进行跳转对应应用的通话记录activity。
3)如果是双通模式,最主要就是获取当前所在页对应的工作模式,然后将该工作模式传递给要启动的intent。 左右键切换页面实现比较简单:计算要切换到的下一页pageIndex,然后调用mViewPager的setCurrentItem(pageIndex)即可。 1.2.2.5.后台的通话悬浮窗 1)要求: 应用在通话时,如果当前正处于该应用小部件界面,并且是处于前台则不需要显示该应用后台通话悬浮窗。否则都需要显示后台通话悬浮窗。
2)之前应用通话是否需要显示悬浮窗,是由Launcher发送广播进行通知的。实现方式如下:
各应用监听该广播,根据参数is_in_home_page决定是否要显示通话悬浮窗。 通知场景: Launcher应用处于前台时,并且当前页面是小部件界面,则通知is_in_home_page=true Launcher应用处于后台时,并且当前页面是小部件界面,则通知is_in_home_page=false
Launcher应用 ViewPager切换页面,如果当前页面是小部件界面,则通知is_in_home_page=true,否则通知is_in_home_page=false
3)如果是双通模式,处于两个模式应用echat, pdt应用尽量不修改的原则,根据应用场景,通过指定包名显示广播还是隐式广播发送,用于特定应用接收还是所有应用都能接收。
4)各种场景如下: 4.1)Launcher应用处于前台时,获取当前页index,然后得到当前页对应的工作模式workMode值。根据工作模式,通过解析应用小部件meta-data配置的对应工作模式workMode的包名, 然后指定该包名发送显式广播,通知该应用。
4.2)Launcher应用处于前台,页面切换时,通知当前模式对应应用不显示悬浮窗,另一个模式应用需要显示悬浮窗。
4.3)Launcher应用处于后台时,则需要通知两个模式应用,显示通话悬浮窗。不指定包名发送广播进行通知,保证两个模式应用都能够收到。
4.4)由于当前echat, pdt这些模式应用的后台通话悬浮窗都显示在屏幕的最右上方,因此会出现两个悬浮窗重叠现象。因此需额外对PDT应用的悬浮窗位置进行定制修改。 1.2.2.6.状态栏图标 当前状态栏是独立于双通模式下的echat, pdt小部件界面的,由于对当前小部件界面上的状态栏图标显示没有要求,当在echat或pdt小部件界面,状态栏上可以同时显示pdt, echat状态图标。如果后续要求,可以进行修改。
2.按键的设计方案 2.1.按键的注册 正常情况下,只有当前模式的应用才会注册按键事件,非当前模式的应用会取消按键的注册。为了能让多个应用都可能收到按键事件,需要应用去掉模式的判断,不管什么模式,都注册按键。 考虑到尽可能不修改应用,所以按如下思路实现:
终端默认数模常规 修改Settings数据库,如果是eChat应用来获取模式,固定返回eChat模式(让eChat应用误以为是eChat模式,从而注册按键),其他应用获取,按实际情况返回 去掉限制eChat仅在eChat模式下才能启动的限制 2.2.按键的配置 CalttaSettings提供UI给用户配置按键,具体以交互为准,这里不做考虑。为了扩展,配置结果的保存方式,不考虑具体需求,采用通用的规则 以“config_keytarget”+具体键值为key,应用的包名为value,多个包名之间用英文逗号间隔,代表这个键要给这些应用。比如config_key_target_287 = com.zte.pdt,代表287这个键需要传递给PDT应用 以“config_key_main”为key,应用的包名为value,代表按键以哪个应用为主,对于用户来说,就是平时以哪个种业务为主。 “config_keyreplace”+具体键值为key,valeu也为具体键值,代表需要在分发的时候将特定的键值替换成另一个键值来分发。 “config_key_target”的优先级高于“config_key_main”,即对于一个具体的按键,如果没有配置“config_key_target”,则传递给“config_key_main”对应的应用。 以上规则只适用于GotaKeyMonitor分发按键,如果是Android原生的按键传递方式,则不受上述配置影响
按定制需求,按键的配置如下: PTT键:config_key_target_287默认为com.mcptt,允许用户修改 侧上键:config_key_target_288默认为com.zte.pdt,允许用户修改,config_key_replace_288默认为287,不允许用户修改 挂断键:config_key_target_6默认为com.mcptt,不允许用户修改(常规无法挂断呼叫,所以挂断键只需要给eChat) 拨号键:config_key_target_5默认为com.mcptt,不允许用户修改(PDT应用不需要通过GotaKeyMonitor传递拨号键) SOS键、旋钮键:默认不配置,也不允许用户修改,跟着PTT键走
注:这套配置规则中的value都是包名,后续不利于融合应用来实现双通,如果是融合应用实现双通,不管用户怎么配置,value都是融合应用的包名,但是融合应用收到PTT键的时候,也不知道发起什么呼叫好,需要用额外的key来帮助融合应用判断发起什么业务。value如果不是包名,而是具体业务类型,那么按键分发的时候,按键服务就得知道哪个业务类型对应哪个包名。各有利弊 2.3.按键的分发 按键的分发由GotaKeyMonitor负责。正常情况下,GotaKeyMonitor只将按键发给最后一个注册按键的应用,为了实现双PTT键的效果,需要GotaKeyMonitor根据配置情况调整分发流程:
分发过程中,要对工厂模式做特殊处理,工厂模式下无视一切配置,只给工厂模式分发按键。避免工厂模式按键无法测试 2.4.按键的处理 按键的处理主要由PhoneWindowManager负责。当前处理按键的时候,判断了模式,不同模式下,可能处理逻辑不一样,但现在需要去掉模式的判断,因为模式永远都是PDT模式,但也需要判断eChat的情况。可能的修改如下: 侧上键:非工厂模式下要拦截,不要通过Android的按键传递到应用,避免触发快捷功能 Power键:PDT和eChat都不在通话中时,回到launcher。PDT在通话中时不传递挂断键,eChat通话中时,通过GotaKeyMonitor传递挂断键键值 拨号键:PDT和eChat任意一个在通话中时,按拨号键拉起luancher(当只有一路通话时launcher如何知道显示哪一路的小部件)并拦截拨号键。两者都不在通话中时,不要拦截拨号键,传递给当前界面。 3.CalttaSettings 系统设置需要增加按键的配置入口,具体参考交互。用户修改按键配置时,需要修改同时修改以下几个数据库值 PTT键和侧上键,互斥,不允许配置同一种业务 修改config_key_target与用户的设置结果保存一致 修改config_key_main的值,与PTT键的值保持一致 修改dual_pass_mode的值,PTT键对应的模式在前,侧上键对应的模式在后,英文逗号间隔 4.SettingsProvider 当前SettingsProvider提供了工作模式(cluster_mode_pdt_mpt)的数据库查询接口,为了实现双待双通,额外增加了双通模式的(dual_pass_mode)的保存,用于判断当前是哪两个模式双通,且第一个模式作为PTT键控制的模式。结合需求,需要修改的点如下: 当有应用获取工作模式(cluster_mode_pdt_mpt)时,判断包名,如果是eChat应用则固定返回eChat模式(6),其他应用则返回真实的数据 当PDT应用修改工作模式(cluster_mode_pdt_mpt)为模拟常规或着数字常规时,在SettingsProvider的服务端把双通模式中的PDT模式值也一并修改 默认配置dual_pass_mode为6,2;cluster_mode_pdt_mpt为2 5.快捷键 当前的快捷键功能,有部分是与模式相关的,比如短信功能,在DMR模式下打开的是DMR的短信,在eChat模式下打开的是eChat的短信。双待双通下,这类功能只响应PTT键对应的业务,比如PTT键控制eChat业务,则短信只会拉起eChat的短信。 同时部分快捷功能与双待双通冲突,也需要一起去掉。 要修改的点如下: 去掉侧上键快捷设置 去掉工作模式的快捷功能 判断工作模式的时候,优先判断双通模式dual_pass_mode,不存在时,才根据cluster_mode_pdt_mpt获取当前的模式 6.息屏显示 当前息屏的时候只会显示当前模式的信息,双待双通下,需求明确只显示PTT键对应的业务信息。所以息屏显示应用做出如下调整: 监听数据库dual_pass_mode字段的变化,提取第一个模式,并显示该模式对应的业务信息 dual_pass_mode的优先级高于cluster_mode_pdt_mpt
7.指示灯 当前的指示灯,按通知的优先级来控制灯,同等优先级下,以最后一个通知为准。双待双通时,可能存在两路通话,一路在讲,一路在听,此时指示灯的状态可能显示的是讲的状态,也可能是听的状态。这点改起来比较麻烦,需求层面,不对指示灯做具体要求,保持现状。