问题分析
问题:
客户需求,底部导航栏可选隐藏与显示。
分析:
正常来讲,Android11自带的有系统导航可选"三按钮"导航跟手势导航。打开位置有两个
1.设置——>无障碍——>系统导航
2.设置——>系统——>手势——>系统导航
可是如下图所示并未显示出来
分析可能是布局或者是activity隐藏了,最后发现是应为自定义的overlay把他隐藏掉了,本文最后将会详细了解一下android源码的overlay
代码位置
alps/device/mediatek/vendor/common/overlay/ago/frameworks/base/core/res/res/values/config.xml alps/vendor/mediatek/proprietary/packages/apps/MtkSettings/src/com/android/settings/gestures/SystemNavigationPreferenceController.java alps/vendor/mediatek/proprietary/packages/overlay/vendor/FrameworkResOverlay/ago/res/values/config.xml
具体代码
static boolean isGestureAvailable(Context context) {
// Skip if the swipe up settings are not available
if (!context.getResources().getBoolean(
com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
Log.w(TAG,"lyzlyzlyz01----------------------------------------------------------------------------");
return false;
}
// Skip if the recents component is not defined
final ComponentName recentsComponentName = ComponentName.unflattenFromString(
context.getString(com.android.internal.R.string.config_recentsComponentName));
if (recentsComponentName == null) {
return false;
}
// Skip if the overview proxy service exists
final Intent quickStepIntent = new Intent(ACTION_QUICKSTEP)
.setPackage(recentsComponentName.getPackageName());
if (context.getPackageManager().resolveService(quickStepIntent,
PackageManager.MATCH_SYSTEM_ONLY) == null) {
return false;
}
return true;
}
- <bool name="config_swipe_up_gesture_setting_available">false</bool>
+ <bool name="config_swipe_up_gesture_setting_available">true</bool>
代码分析
首先找到gestures(手势)布局
alps\vendor\mediatek\proprietary\packages\apps\MtkSettings\res\xml\gestures.xml
在里面找到导航栏的布局文件
<Preference
android:key="gesture_system_navigation_input_summary"
android:title="@string/system_navigation_title"
android:fragment="com.android.settings.gestures.SystemNavigationGestureSettings"
settings:controller="com.android.settings.gestures.SystemNavigationPreferenceController"
settings:keywords="@string/keywords_system_navigation" />
进入controller代码查看问题,log查看发现isGestureAvailable方法中存在疑点
if (!context.getResources().getBoolean(
com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
return false;
}
grep查询后发现
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps$ cd device/
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/device$ grep "config_swipe_up_gesture_setting_available" * -rn
google/coral/overlay/frameworks/base/core/res/res/values/config.xml:268: <bool name="config_swipe_up_gesture_setting_available">true</bool>
mediatek/build/mcs/Q0.basic_hiddenapi-stub-flags.txt:243583:Lcom/android/internal/R$bool;->config_swipe_up_gesture_setting_available:I
mediatek/vendor/common/overlay/ago/frameworks/base/core/res/res/values/config.xml:26: <bool name="config_swipe_up_gesture_setting_available">false</bool>
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/device$ cd ../
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps$ cd vendor/mediatek/
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/vendor/mediatek$ grep "config_swipe_up_gesture_setting_available" * -rn
proprietary/packages/apps/MtkSettings/src/com/android/settings/gestures/SystemNavigationPreferenceController.java:63: com.android.internal.R.bool.config_swipe_up_gesture_setting_available)) {
proprietary/packages/apps/MtkSettings/tests/robotests/src/com/android/settings/gestures/SystemNavigationPreferenceControllerTest.java:74: SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
proprietary/packages/apps/MtkSettings/tests/robotests/src/com/android/settings/gestures/SystemNavigationPreferenceControllerTest.java:113: SettingsShadowResources.overrideResource(R.bool.config_swipe_up_gesture_setting_available,
proprietary/packages/overlay/vendor/FrameworkResOverlay/ago/res/values/config.xml:27: <bool name="config_swipe_up_gesture_setting_available">false</bool>
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/vendor/mediatek$ cd ../../
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps$ cd frameworks/base/
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/frameworks/base$ grep "config_swipe_up_gesture_setting_available" * -rn
config/hiddenapi-greylist-max-o.txt:91412:Lcom/android/internal/R$bool;->config_swipe_up_gesture_setting_available:I
core/res/res/values/config.xml:3824: <bool name="config_swipe_up_gesture_setting_available">true</bool>
core/res/res/values/symbols.xml:3574: <java-symbol type="bool" name="config_swipe_up_gesture_setting_available" />
cts-15@cts-15:/code2/W869/mt6580_r_v1/alps/frameworks/base$ ^C
把false改为true问题解决。
overlay详解
Android Overlay是一种资源替换机制,它能在不重新打包apk的情况下,实现资源文件的替换(res目录非assert目录),Overlay又分为静态Overlay(Static Resource Overlay)与运行时Overlay(Runtime Resource Overlay),他有自己的局限性,它无法替换java文件。
Android Override是一种文件替换方式,注意是文件替换,他有自己的局限性,它无法覆盖一个APK中的某一个文件,但是可以直接覆盖APK。
我们可以将Android资源类型分为三类:
列表类型的xml资源文件,该类型的文件内部包含了多个资源项,典型的就是strings.xml,很多项目会有config.xml也大都是这种类型的文件。
值类型的xml文件,该类型的一个文件对应了一个资源项,比如layout目录下的布局文件,以及某些项目menu目录下的xml文件也大都是这种类型。
数据型资源文件,比如图片,音频,视频以及其他数据类型的文件,该类型的一个文件对应一个资源项。
在最终的安装包中第三种数据类型的资源文件会原封不动的保留。第二种值类型的xml资源文件,也会按照原有的目录结构和文件名字放入安装包中, 只是原有的xml格式会被压缩成特定的二进制流。列表型xml资源文件的内容会被全部编译到resources.arsc中。而我们的overlay就是替换resources.arsc中的资源文件
所以,一般overlay放在项目的vendor frameworks device 三个地方,编译的时候overlay会覆盖原来的资源文件。修改以前项目的修改后系统导航出现并可以正常使用。效果如下: