1. Android Framework基础功能定制概述
作为一名有多年Android Framework开发经验的工程师,我经常需要为新设备进行基础功能定制。这些定制看似简单,但实际操作中却有很多细节需要注意。本文将基于展锐和MTK两大主流平台,详细讲解Android Framework层的基础功能定制方法,包括分区大小调整、时区语言设置、UI定制等核心内容。
在开始之前,我们需要明确几个基本概念:
- Framework定制主要涉及Android系统底层的修改
- 不同芯片平台(展锐/MTK)的实现方式可能有差异
- 大部分修改都需要重新编译系统才能生效
2. 分区大小调整
2.1 展锐平台分区调整
展锐平台的分区大小调整需要修改两个地方:
- BoardConfig.mk文件:
makefile复制-BOARD_SYSTEMIMAGE_PARTITION_SIZE := 367001600
+BOARD_SYSTEMIMAGE_PARTITION_SIZE := 1610612736
这里将system分区从350M调整为1536M(1536x1024x1024=1610612736字节)
- 分区表XML文件:
xml复制- <Partition id="system" size="350"/>
+ <Partition id="system" size="1536"/>
注意:展锐平台的分区表XML文件路径通常为device/sprd/[芯片型号]/[项目名称]/partition.xml,具体路径可能因项目而异。
2.2 MTK平台分区调整
MTK平台的分区调整相对简单,只需修改BoardConfig.mk文件:
makefile复制-BOARD_MTK_SYSTEM_SIZE_KB := 1253376
+BOARD_MTK_SYSTEM_SIZE_KB := 1553568
MTK平台不需要修改分区表XML文件,这是与展锐平台的主要区别之一。
3. 时区与语言设置
3.1 时区设置
Android系统的默认时区可以通过以下三种方式设置:
- buildinfo.sh脚本:
bash复制echo "persist.sys.timezone=Asia/Shanghai"
- PRODUCT_PROPERTY_OVERRIDES:
在device.mk或类似文件中添加:
makefile复制PRODUCT_PROPERTY_OVERRIDES += persist.sys.timezone=Asia/Shanghai
- ADDITIONAL_BUILD_PROPERTIES:
makefile复制ADDITIONAL_BUILD_PROPERTIES += persist.sys.timezone=Asia/Shanghai
3.2 语言设置
3.2.1 通用设置方法
修改build/target/product/full_base.mk:
makefile复制#PRODUCT_LOCALES := en_US
PRODUCT_LOCALES := zh_CN
3.2.2 MTK平台额外设置
MTK平台需要额外修改buildinfo.sh:
bash复制echo "persist.sys.locale=zh-CN"
echo "ro.product.locale=zh-CN"
同时注释掉原有的locale设置:
bash复制#if [ -n "$PRODUCT_DEFAULT_LOCALE" ] ; then
# echo "ro.product.locale=$PRODUCT_DEFAULT_LOCALE"
#fi
3.2.3 展锐平台设置
展锐平台需要修改languages_default.mk:
makefile复制PRODUCT_LOCALES := \
zh_CN \
en_US \
...(其他语言保持不变)
4. 显示相关设置
4.1 屏幕密度(density)
修改device/[厂商]/[项目]/module/display/md.mk或device.mk:
makefile复制ro.sf.lcd_density=240
提示:常见的density值有120(low)、160(mdpi)、240(hdpi)、320(xhdpi)、480(xxhdpi)等,应根据实际屏幕尺寸和分辨率选择合适的值。
4.2 开机动画与Logo
4.2.1 MTK平台
在device.mk中添加:
makefile复制# 自定义Logo
$(shell rm -rf vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/out)
$(shell mkdir vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/out)
$(shell cp -rf device/mediateksample/$(MTK_TARGET_PROJECT)/custom/logo/$(BOOT_LOGO)/* vendor/mediatek/proprietary/bootable/bootloader/lk/dev/logo/out/$(BOOT_LOGO)/)
# 自定义开机动画
PRODUCT_COPY_FILES += device/mediateksample/$(MTK_TARGET_PROJECT)/custom/bootanim/bootanimation.zip:system/media/bootanimation.zip
PRODUCT_COPY_FILES += device/mediateksample/$(MTK_TARGET_PROJECT)/custom/bootanim/bootaudio.mp3:system/media/bootaudio.mp3
4.2.2 展锐平台
在device/sprd/[芯片]/[项目]/module/product/main.mk中添加:
makefile复制PRODUCT_COPY_FILES += device/sprd/$(CHIP_NAME)/$(TARGET_BOARD)/custom/bootanim/bootanimation.zip:product/media/bootanimation.zip
PRODUCT_COPY_FILES += device/sprd/$(CHIP_NAME)/$(TARGET_BOARD)/custom/bootanim/bootsound.mp3:product/media/bootsound.mp3
5. 系统行为定制
5.1 屏保与锁屏设置
5.1.1 默认关闭屏保
修改frameworks/base/core/res/res/values/config.xml:
xml复制- <bool name="config_dreamsEnabledByDefault">true</bool>
+ <bool name="config_dreamsEnabledByDefault">false</bool>
5.1.2 默认不锁屏
修改两个文件:
- config.xml:
xml复制- <bool name="config_disableLockscreenByDefault">false</bool>
+ <bool name="config_disableLockscreenByDefault">true</bool>
- defaults.xml:
xml复制- <bool name="def_lockscreen_disabled">false</bool>
+ <bool name="def_lockscreen_disabled">true</bool>
5.2 蓝牙设置
5.2.1 自动确认蓝牙开启
修改packages/apps/Settings/res/values/config.xml:
xml复制- <bool name="auto_confirm_bluetooth_activation_dialog">false</bool>
+ <bool name="auto_confirm_bluetooth_activation_dialog">true</bool>
5.2.2 蓝牙配对不弹窗
修改BluetoothPairingRequest.java:
java复制/* 注释原有代码
Intent pairingIntent = BluetoothPairingService.getPairingDialogIntent(context, intent);
...
context.startServiceAsUser(intent, UserHandle.CURRENT);
*/
// 添加直接确认逻辑
BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
device.setPairingConfirmation(true);
6. 状态栏与导航栏定制
6.1 隐藏状态栏和导航栏
修改frameworks/base/core/res/res/values/dimens.xml:
xml复制- <dimen name="status_bar_height_portrait">24dp</dimen>
+ <dimen name="status_bar_height_portrait">0dp</dimen>
- <dimen name="navigation_bar_height">48dp</dimen>
+ <dimen name="navigation_bar_height">0dp</dimen>
- <dimen name="navigation_bar_height_landscape">48dp</dimen>
+ <dimen name="navigation_bar_height_landscape">0dp</dimen>
6.2 禁用下拉栏
修改StatusBarManager.java:
java复制public void disable(int what) {
what = what | DISABLE_EXPAND; // 添加禁用下拉栏标志
try {
final int userId = Binder.getCallingUserHandle().getIdentifier();
final IStatusBarService svc = getService();
if (svc != null) {
svc.disableForUser(what, mToken, mContext.getPackageName(), userId);
}
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
}
7. 壁纸设置
7.1 通用修改方法
替换以下默认壁纸文件:
code复制frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.png
frameworks/base/core/res/res/drawable-sw600dp-nodpi/default_wallpaper.png
frameworks/base/core/res/res/drawable-sw720dp-nodpi/default_wallpaper.png
7.2 MTK平台专用方法
Android 8.0:
code复制frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.jpg
Android 11:
code复制device/mediatek/system/common/overlay/ago/frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.jpg
8. 音量设置
8.1 不显示音量条
修改config.xml,注释掉VolumeUI:
xml复制- <item>com.android.systemui.volume.VolumeUI</item>
+ <!-- <item>com.android.systemui.volume.VolumeUI</item> -->
8.2 音量最大等级
修改AudioService.java中的MAX_STREAM_VOLUME数组:
java复制protected static int[] MAX_STREAM_VOLUME = new int[] {
5, // STREAM_VOICE_CALL
7, // STREAM_SYSTEM
7, // STREAM_RING
15, // STREAM_MUSIC
7, // STREAM_ALARM
7, // STREAM_NOTIFICATION
15, // STREAM_BLUETOOTH_SCO
7, // STREAM_SYSTEM_ENFORCED
15, // STREAM_DTMF
15, // STREAM_TTS
15, // STREAM_ACCESSIBILITY
15 // STREAM_ASSISTANT
};
9. 电话相关设置
9.1 禁止闪屏
- 在AndroidManifest.xml中添加:
xml复制android:windowDisablePreview="true"
- 修改styles.xml:
xml复制<item name="android:windowIsTranslucent">true</item>
<item name="android:windowBackground">@android:color/transparent</item>
<item name="android:windowShowWallpaper">false</item>
9.2 禁止未接电话通知
修改MissedCallNotifier.java:
java复制public Void doInBackground(@Nullable Bundle input) throws Throwable {
/* 注释原有通知代码
int count = 0;
String number = "";
String subText = "";
...
updateMissedCallNotification(count, number, subText);
*/
return null;
}
10. 通知设置
10.1 屏蔽短信通知
修改BugleNotifications.java:
java复制- notificationManager.notify(notificationTag, type, notification);
+ //notificationManager.notify(notificationTag, type, notification);
11. 常见问题与解决方案
在实际开发过程中,我遇到过以下几个典型问题:
-
修改不生效:
- 确保修改了正确的文件版本(有些文件在多个位置存在)
- 执行make clean后再重新编译
- 检查文件权限是否正确
-
编译报错:
- 检查语法是否正确,特别是makefile中的缩进
- 确认所有修改的文件都已被git add
-
运行时崩溃:
- 检查是否有语法错误
- 确认修改的API与当前Android版本兼容
-
UI显示异常:
- 检查density设置是否合理
- 确认图片资源的分辨率适配当前屏幕
12. 经验分享
经过多个项目的实践,我总结了以下几点经验:
-
版本控制:
- 每次修改前先创建git分支
- 提交时写清修改内容和原因
- 重要修改添加注释说明
-
调试技巧:
- 使用adb logcat实时查看系统日志
- 对于UI问题,可以截图后用工具分析布局层级
- 复杂问题可以添加临时日志辅助调试
-
性能考量:
- 频繁调用的代码要特别注意性能
- 避免在主线程执行耗时操作
- 合理使用缓存减少重复计算
-
兼容性处理:
- 考虑不同Android版本的API差异
- 处理各种边界条件
- 测试不同分辨率和尺寸的设备
这些定制方法虽然看似简单,但在实际项目中却能大大提高产品的用户体验。希望这些经验能对各位Android Framework开发者有所帮助。
